From 33f7a33f25acb9ac82749bd2c6397108aeca41ef Mon Sep 17 00:00:00 2001 From: Ivan Mrsulja Date: Wed, 25 Sep 2024 16:45:40 +0200 Subject: [PATCH 1/3] Added software controller to read software entity. --- .../api/software/SoftwareController.java | 191 ++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/SoftwareController.java diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/SoftwareController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/SoftwareController.java new file mode 100644 index 0000000000..a88788b2ae --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/SoftwareController.java @@ -0,0 +1,191 @@ +package edu.cornell.mannlib.vitro.webapp.controller.api.software; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery.InvalidQueryTypeException; +import edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery.SparqlQueryApiExecutor; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; +import edu.cornell.mannlib.vitro.webapp.utils.http.AcceptHeaderParsingException; +import edu.cornell.mannlib.vitro.webapp.utils.http.NotAcceptableException; +import org.apache.jena.query.QueryParseException; + +@WebServlet(name = "softwareController", urlPatterns = {"/software", "/software/*"}, loadOnStartup = 5) +public class SoftwareController extends HttpServlet { + + private final String FIND_ALL_QUERY = + "PREFIX rdf: \n" + + "PREFIX rdfs: \n" + + "PREFIX xsd: \n" + + "PREFIX owl: \n" + + "PREFIX swrl: \n" + + "PREFIX swrlb: \n" + + "PREFIX vitro: \n" + + "PREFIX bibo: \n" + + "PREFIX c4o: \n" + + "PREFIX cito: \n" + + "PREFIX dcterms: \n" + + "PREFIX event: \n" + + "PREFIX fabio: \n" + + "PREFIX foaf: \n" + + "PREFIX geo: \n" + + "PREFIX obo: \n" + + "PREFIX vivo: \n" + + "PREFIX vcard: \n" + + "\n" + + "SELECT ?label ?author ?authorIdentifier ?datePublished ?funding ?funder ?keywords " + + "?version ?abstract ?identifier ?sameAs ?url\n" + + "WHERE\n" + + "{\n" + + " ?software rdf:type obo:ERO_0000071\n" + + " OPTIONAL { ?software rdfs:label ?label }\n" + + " OPTIONAL { ?software vivo:relatedBy ?relatedObject .\n" + + " ?relatedObject vitro:mostSpecificType vivo:Authorship .\n" + + " OPTIONAL { ?relatedObject vivo:relates ?authorObject .\n" + + " OPTIONAL { ?authorObject rdfs:label ?author }\n" + + " OPTIONAL { ?authorObject vivo:orcidId ?authorIdentifier }\n" + + " }\n" + + " FILTER (?author != ?label)\n" + + " }\n" + + " OPTIONAL { ?software vivo:dateTimeValue ?dateObject .\n" + + " OPTIONAL { ?dateObject vivo:dateTime ?datePublished }\n" + + " }\n" + + " OPTIONAL { ?software vivo:informationResourceSupportedBy ?funderObject .\n" + + " OPTIONAL { ?funderObject vivo:assignedBy ?funder }\n" + + " OPTIONAL { ?funderObject rdfs:label ?funding }\n" + + " }\n" + + " OPTIONAL { ?software vivo:freetextKeywords ?keywords }\n" + + " OPTIONAL { ?software obo:ERO_0000072 ?version }\n" + + " OPTIONAL { ?software bibo:abstract ?abstract }\n" + + " OPTIONAL { ?software vivo:swhid ?identifier }\n" + + " OPTIONAL { ?software owl:sameAs ?sameAsObject .\n" + + " OPTIONAL { ?sameAsObject rdfs:label ?sameAs }\n" + + " }\n" + + " OPTIONAL { ?software obo:ARG_2000028 ?contactInfo .\n" + + " OPTIONAL { ?contactInfo vcard:hasURL ?url }\n" + + " }\n" + + "} LIMIT 20\n"; + + private final String FIND_BY_ID_QUERY_TEMPLATE = + "PREFIX rdf: \n" + + "PREFIX rdfs: \n" + + "PREFIX xsd: \n" + + "PREFIX owl: \n" + + "PREFIX swrl: \n" + + "PREFIX swrlb: \n" + + "PREFIX vitro: \n" + + "PREFIX bibo: \n" + + "PREFIX c4o: \n" + + "PREFIX cito: \n" + + "PREFIX dcterms: \n" + + "PREFIX event: \n" + + "PREFIX fabio: \n" + + "PREFIX foaf: \n" + + "PREFIX geo: \n" + + "PREFIX obo: \n" + + "PREFIX vivo: \n" + + "PREFIX vcard: \n" + + "\n" + + "SELECT ?label ?author ?authorIdentifier ?datePublished ?funding ?funder ?keywords " + + "?version ?abstract ?identifier ?sameAs ?url\n" + + "WHERE\n" + + "{\n" + + " BIND (<%s> AS ?software)\n" + + " ?software rdf:type obo:ERO_0000071\n" + + " OPTIONAL { ?software rdfs:label ?label }\n" + + " OPTIONAL { ?software vivo:relatedBy ?relatedObject .\n" + + " ?relatedObject vitro:mostSpecificType vivo:Authorship .\n" + + " OPTIONAL { ?relatedObject vivo:relates ?authorObject .\n" + + " OPTIONAL { ?authorObject rdfs:label ?author }\n" + + " OPTIONAL { ?authorObject vivo:orcidId ?authorIdentifier }\n" + + " }\n" + + " FILTER (?author != ?label)\n" + + " }\n" + + " OPTIONAL { ?software vivo:dateTimeValue ?dateObject .\n" + + " OPTIONAL { ?dateObject vivo:dateTime ?datePublished }\n" + + " }\n" + + " OPTIONAL { ?software vivo:informationResourceSupportedBy ?funderObject .\n" + + " OPTIONAL { ?funderObject vivo:assignedBy ?funder }\n" + + " OPTIONAL { ?funderObject rdfs:label ?funding }\n" + + " }\n" + + " OPTIONAL { ?software vivo:freetextKeywords ?keywords }\n" + + " OPTIONAL { ?software obo:ERO_0000072 ?version }\n" + + " OPTIONAL { ?software bibo:abstract ?abstract }\n" + + " OPTIONAL { ?software vivo:swhid ?identifier }\n" + + " OPTIONAL { ?software owl:sameAs ?sameAsObject .\n" + + " OPTIONAL { ?sameAsObject rdfs:label ?sameAs }\n" + + " }\n" + + " OPTIONAL { ?software obo:ARG_2000028 ?contactInfo .\n" + + " OPTIONAL { ?contactInfo vcard:hasURL ?url }\n" + + " }\n" + + "}\n"; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws IOException, ServletException { + + String pathInfo = req.getPathInfo(); + String queryString; + + if (pathInfo != null && pathInfo.length() > 1) { + String softwareId = pathInfo.substring(1); + String softwareUri = "http://vivo.mydomain.edu/individual/" + softwareId; + queryString = String.format(FIND_BY_ID_QUERY_TEMPLATE, softwareUri); + } else { + queryString = FIND_ALL_QUERY; + } + + RDFService rdfService = ModelAccess.on(getServletContext()).getRDFService(); + + try { + String format = "application/sparql-results+json"; + SparqlQueryApiExecutor core = SparqlQueryApiExecutor.instance( + rdfService, queryString, format); + resp.setContentType(core.getMediaType()); + + core.executeAndFormat(resp.getOutputStream()); + } catch (InvalidQueryTypeException e) { + do400BadRequest("Query type is not SELECT, ASK, CONSTRUCT, " + + "or DESCRIBE: '" + queryString + "'", resp); + } catch (QueryParseException e) { + do400BadRequest("Failed to parse query: '" + queryString + "''", e, + resp); + } catch (NotAcceptableException | AcceptHeaderParsingException e) { + do500InternalServerError("Problem with the page fields: the " + + "selected fields do not include an " + + "acceptable content type.", e, resp); + } catch (RDFServiceException e) { + do500InternalServerError("Problem executing the query.", e, resp); + } + } + + private void do400BadRequest(String message, HttpServletResponse resp) + throws IOException { + resp.setStatus(400); + resp.getWriter().println(message); + } + + private void do400BadRequest(String message, Exception e, + HttpServletResponse resp) throws IOException { + resp.setStatus(400); + PrintWriter w = resp.getWriter(); + w.println(message); + e.printStackTrace(w); + } + + private void do500InternalServerError(String message, Exception e, + HttpServletResponse resp) throws IOException { + resp.setStatus(500); + PrintWriter w = resp.getWriter(); + w.println(message); + e.printStackTrace(w); + } +} From 31079faeb9e6ed45f1a3aa14a8823e47890760b0 Mon Sep 17 00:00:00 2001 From: Ivan Mrsulja Date: Thu, 26 Sep 2024 14:43:26 +0200 Subject: [PATCH 2/3] Moved code. --- .../api/software/SoftwareController.java | 191 ------------------ 1 file changed, 191 deletions(-) delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/SoftwareController.java diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/SoftwareController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/SoftwareController.java deleted file mode 100644 index a88788b2ae..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/SoftwareController.java +++ /dev/null @@ -1,191 +0,0 @@ -package edu.cornell.mannlib.vitro.webapp.controller.api.software; - -import java.io.IOException; -import java.io.PrintWriter; - -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery.InvalidQueryTypeException; -import edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery.SparqlQueryApiExecutor; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; -import edu.cornell.mannlib.vitro.webapp.utils.http.AcceptHeaderParsingException; -import edu.cornell.mannlib.vitro.webapp.utils.http.NotAcceptableException; -import org.apache.jena.query.QueryParseException; - -@WebServlet(name = "softwareController", urlPatterns = {"/software", "/software/*"}, loadOnStartup = 5) -public class SoftwareController extends HttpServlet { - - private final String FIND_ALL_QUERY = - "PREFIX rdf: \n" + - "PREFIX rdfs: \n" + - "PREFIX xsd: \n" + - "PREFIX owl: \n" + - "PREFIX swrl: \n" + - "PREFIX swrlb: \n" + - "PREFIX vitro: \n" + - "PREFIX bibo: \n" + - "PREFIX c4o: \n" + - "PREFIX cito: \n" + - "PREFIX dcterms: \n" + - "PREFIX event: \n" + - "PREFIX fabio: \n" + - "PREFIX foaf: \n" + - "PREFIX geo: \n" + - "PREFIX obo: \n" + - "PREFIX vivo: \n" + - "PREFIX vcard: \n" + - "\n" + - "SELECT ?label ?author ?authorIdentifier ?datePublished ?funding ?funder ?keywords " + - "?version ?abstract ?identifier ?sameAs ?url\n" + - "WHERE\n" + - "{\n" + - " ?software rdf:type obo:ERO_0000071\n" + - " OPTIONAL { ?software rdfs:label ?label }\n" + - " OPTIONAL { ?software vivo:relatedBy ?relatedObject .\n" + - " ?relatedObject vitro:mostSpecificType vivo:Authorship .\n" + - " OPTIONAL { ?relatedObject vivo:relates ?authorObject .\n" + - " OPTIONAL { ?authorObject rdfs:label ?author }\n" + - " OPTIONAL { ?authorObject vivo:orcidId ?authorIdentifier }\n" + - " }\n" + - " FILTER (?author != ?label)\n" + - " }\n" + - " OPTIONAL { ?software vivo:dateTimeValue ?dateObject .\n" + - " OPTIONAL { ?dateObject vivo:dateTime ?datePublished }\n" + - " }\n" + - " OPTIONAL { ?software vivo:informationResourceSupportedBy ?funderObject .\n" + - " OPTIONAL { ?funderObject vivo:assignedBy ?funder }\n" + - " OPTIONAL { ?funderObject rdfs:label ?funding }\n" + - " }\n" + - " OPTIONAL { ?software vivo:freetextKeywords ?keywords }\n" + - " OPTIONAL { ?software obo:ERO_0000072 ?version }\n" + - " OPTIONAL { ?software bibo:abstract ?abstract }\n" + - " OPTIONAL { ?software vivo:swhid ?identifier }\n" + - " OPTIONAL { ?software owl:sameAs ?sameAsObject .\n" + - " OPTIONAL { ?sameAsObject rdfs:label ?sameAs }\n" + - " }\n" + - " OPTIONAL { ?software obo:ARG_2000028 ?contactInfo .\n" + - " OPTIONAL { ?contactInfo vcard:hasURL ?url }\n" + - " }\n" + - "} LIMIT 20\n"; - - private final String FIND_BY_ID_QUERY_TEMPLATE = - "PREFIX rdf: \n" + - "PREFIX rdfs: \n" + - "PREFIX xsd: \n" + - "PREFIX owl: \n" + - "PREFIX swrl: \n" + - "PREFIX swrlb: \n" + - "PREFIX vitro: \n" + - "PREFIX bibo: \n" + - "PREFIX c4o: \n" + - "PREFIX cito: \n" + - "PREFIX dcterms: \n" + - "PREFIX event: \n" + - "PREFIX fabio: \n" + - "PREFIX foaf: \n" + - "PREFIX geo: \n" + - "PREFIX obo: \n" + - "PREFIX vivo: \n" + - "PREFIX vcard: \n" + - "\n" + - "SELECT ?label ?author ?authorIdentifier ?datePublished ?funding ?funder ?keywords " + - "?version ?abstract ?identifier ?sameAs ?url\n" + - "WHERE\n" + - "{\n" + - " BIND (<%s> AS ?software)\n" + - " ?software rdf:type obo:ERO_0000071\n" + - " OPTIONAL { ?software rdfs:label ?label }\n" + - " OPTIONAL { ?software vivo:relatedBy ?relatedObject .\n" + - " ?relatedObject vitro:mostSpecificType vivo:Authorship .\n" + - " OPTIONAL { ?relatedObject vivo:relates ?authorObject .\n" + - " OPTIONAL { ?authorObject rdfs:label ?author }\n" + - " OPTIONAL { ?authorObject vivo:orcidId ?authorIdentifier }\n" + - " }\n" + - " FILTER (?author != ?label)\n" + - " }\n" + - " OPTIONAL { ?software vivo:dateTimeValue ?dateObject .\n" + - " OPTIONAL { ?dateObject vivo:dateTime ?datePublished }\n" + - " }\n" + - " OPTIONAL { ?software vivo:informationResourceSupportedBy ?funderObject .\n" + - " OPTIONAL { ?funderObject vivo:assignedBy ?funder }\n" + - " OPTIONAL { ?funderObject rdfs:label ?funding }\n" + - " }\n" + - " OPTIONAL { ?software vivo:freetextKeywords ?keywords }\n" + - " OPTIONAL { ?software obo:ERO_0000072 ?version }\n" + - " OPTIONAL { ?software bibo:abstract ?abstract }\n" + - " OPTIONAL { ?software vivo:swhid ?identifier }\n" + - " OPTIONAL { ?software owl:sameAs ?sameAsObject .\n" + - " OPTIONAL { ?sameAsObject rdfs:label ?sameAs }\n" + - " }\n" + - " OPTIONAL { ?software obo:ARG_2000028 ?contactInfo .\n" + - " OPTIONAL { ?contactInfo vcard:hasURL ?url }\n" + - " }\n" + - "}\n"; - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws IOException, ServletException { - - String pathInfo = req.getPathInfo(); - String queryString; - - if (pathInfo != null && pathInfo.length() > 1) { - String softwareId = pathInfo.substring(1); - String softwareUri = "http://vivo.mydomain.edu/individual/" + softwareId; - queryString = String.format(FIND_BY_ID_QUERY_TEMPLATE, softwareUri); - } else { - queryString = FIND_ALL_QUERY; - } - - RDFService rdfService = ModelAccess.on(getServletContext()).getRDFService(); - - try { - String format = "application/sparql-results+json"; - SparqlQueryApiExecutor core = SparqlQueryApiExecutor.instance( - rdfService, queryString, format); - resp.setContentType(core.getMediaType()); - - core.executeAndFormat(resp.getOutputStream()); - } catch (InvalidQueryTypeException e) { - do400BadRequest("Query type is not SELECT, ASK, CONSTRUCT, " - + "or DESCRIBE: '" + queryString + "'", resp); - } catch (QueryParseException e) { - do400BadRequest("Failed to parse query: '" + queryString + "''", e, - resp); - } catch (NotAcceptableException | AcceptHeaderParsingException e) { - do500InternalServerError("Problem with the page fields: the " - + "selected fields do not include an " - + "acceptable content type.", e, resp); - } catch (RDFServiceException e) { - do500InternalServerError("Problem executing the query.", e, resp); - } - } - - private void do400BadRequest(String message, HttpServletResponse resp) - throws IOException { - resp.setStatus(400); - resp.getWriter().println(message); - } - - private void do400BadRequest(String message, Exception e, - HttpServletResponse resp) throws IOException { - resp.setStatus(400); - PrintWriter w = resp.getWriter(); - w.println(message); - e.printStackTrace(w); - } - - private void do500InternalServerError(String message, Exception e, - HttpServletResponse resp) throws IOException { - resp.setStatus(500); - PrintWriter w = resp.getWriter(); - w.println(message); - e.printStackTrace(w); - } -} From cf5a4d885797231ef9b0e79d8931573e8001e64b Mon Sep 17 00:00:00 2001 From: Ivan Mrsulja Date: Wed, 2 Oct 2024 11:36:47 +0200 Subject: [PATCH 3/3] Moved API utility classes to Vitro. --- .../IndividualApiCommonCRUDUtility.java | 126 ++++++++++++++++++ .../software/IndividualApiNetworkUtility.java | 73 ++++++++++ .../software/IndividualApiSparqlUtility.java | 95 +++++++++++++ 3 files changed, 294 insertions(+) create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/IndividualApiCommonCRUDUtility.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/IndividualApiNetworkUtility.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/IndividualApiSparqlUtility.java diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/IndividualApiCommonCRUDUtility.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/IndividualApiCommonCRUDUtility.java new file mode 100644 index 0000000000..13587e965d --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/IndividualApiCommonCRUDUtility.java @@ -0,0 +1,126 @@ +package edu.cornell.mannlib.vitro.webapp.controller.api.software; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.Objects; +import java.util.UUID; +import java.util.function.BiConsumer; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils; +import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; +import edu.cornell.mannlib.vitro.webapp.modules.searchIndexer.SearchIndexer; +import org.apache.jena.query.Dataset; +import org.apache.jena.query.ReadWrite; +import org.apache.jena.update.GraphStore; +import org.apache.jena.update.GraphStoreFactory; + +public class IndividualApiCommonCRUDUtility { + + public static void executeWithTransaction(HttpServletRequest req, HttpServletResponse resp, + BiConsumer action) throws IOException { + VitroRequest vreq = new VitroRequest(req); + SearchIndexer indexer = ApplicationUtils.instance().getSearchIndexer(); + Dataset ds = new RDFServiceDataset(vreq.getUnfilteredRDFService()); + GraphStore graphStore = GraphStoreFactory.create(ds); + + String entityUri; + if (req.getMethod().equalsIgnoreCase("POST")) { + entityUri = IndividualApiSparqlUtility.buildIndividualUri(UUID.randomUUID().toString()); + } else { + String pathInfo = req.getPathInfo(); + if (Objects.isNull(pathInfo) || pathInfo.isEmpty()) { + IndividualApiNetworkUtility.do400BadRequest("You have to provide a record identifier.", resp); + return; + } + + entityUri = IndividualApiSparqlUtility.buildIndividualUri(pathInfo.substring(1)); + } + + try { + pauseIndexer(indexer); + beginTransaction(ds); + + action.accept(graphStore, entityUri); + + } finally { + commitTransaction(ds); + unpauseIndexer(indexer); + } + } + + private static void pauseIndexer(SearchIndexer indexer) { + if (indexer != null) { + indexer.pause(); + } + } + + private static void unpauseIndexer(SearchIndexer indexer) { + if (indexer != null) { + indexer.unpause(); + } + } + + private static void beginTransaction(Dataset ds) { + if (ds.supportsTransactions()) { + ds.begin(ReadWrite.WRITE); + } + } + + private static void commitTransaction(Dataset ds) { + if (ds.supportsTransactions()) { + ds.commit(); + ds.end(); + } + } + + public static void performDeleteOperation(HttpServletRequest req, HttpServletResponse resp) + throws IOException { + String pathInfo = req.getPathInfo(); + if (Objects.isNull(pathInfo) || pathInfo.isEmpty()) { + IndividualApiNetworkUtility.do400BadRequest("You have to provide a record identifier.", resp); + return; + } + + VitroRequest vreq = new VitroRequest(req); + ApplicationBean appBean = vreq.getAppBean(); + String appName = appBean.getApplicationName().toLowerCase(); + URL url = new URL("http://" + req.getServerName() + ":" + req.getServerPort() + "/" + appName + + "/deleteIndividualController?individualUri=" + + URLEncoder.encode(IndividualApiSparqlUtility.buildIndividualUri(pathInfo.substring(1))) + + "&redirectUrl=%2F"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setRequestProperty("Accept", "application/json"); + + addCookiesToRequest(req, connection); + + connection.getResponseCode(); + + resp.setStatus(HttpServletResponse.SC_NO_CONTENT); + + connection.disconnect(); + } + + private static void addCookiesToRequest(HttpServletRequest req, HttpURLConnection connection) { + Cookie[] cookies = req.getCookies(); + if (cookies != null) { + StringBuilder cookieHeader = new StringBuilder(); + for (Cookie cookie : cookies) { + cookieHeader.append(cookie.getName()).append("=").append(cookie.getValue()).append("; "); + } + // Remove the trailing "; " at the end of the cookie string + if (cookieHeader.length() > 0) { + cookieHeader.setLength(cookieHeader.length() - 2); + } + connection.setRequestProperty("Cookie", cookieHeader.toString()); + } + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/IndividualApiNetworkUtility.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/IndividualApiNetworkUtility.java new file mode 100644 index 0000000000..ebab9182d0 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/IndividualApiNetworkUtility.java @@ -0,0 +1,73 @@ +package edu.cornell.mannlib.vitro.webapp.controller.api.software; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery.InvalidQueryTypeException; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; +import org.apache.jena.query.QueryParseException; + +public class IndividualApiNetworkUtility { + + public static void handleResponseContentType(HttpServletRequest req, HttpServletResponse resp) { + String acceptHeader = req.getHeader("Accept"); + if (acceptHeader != null && !acceptHeader.isEmpty()) { + resp.setContentType(acceptHeader); + } else { + resp.setContentType("application/json"); + } + } + + public static String serializeToJSON(Object serializationObject) throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.enable(SerializationFeature.INDENT_OUTPUT); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); + return objectMapper.writeValueAsString(serializationObject); + } + + public static boolean isJsonRequest(HttpServletRequest req) { + String acceptHeader = req.getHeader("Accept"); + return acceptHeader != null && acceptHeader.equals("application/json"); + } + + public static T parseRequestBody(HttpServletRequest req, Class clazz) throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(req.getInputStream(), clazz); + } + + public static void handleException(Exception e, String queryString, HttpServletResponse resp) throws IOException { + if (e instanceof InvalidQueryTypeException) { + do400BadRequest("Invalid query type: '" + queryString + "'", resp); + } else if (e instanceof QueryParseException) { + do400BadRequest("Failed to parse query: '" + queryString + "'", resp); + } else if (e instanceof RDFServiceException) { + do500InternalServerError("Problem executing the query.", e, resp); + } + } + + public static void do400BadRequest(String message, HttpServletResponse resp) + throws IOException { + resp.setStatus(400); + resp.getWriter().println(message); + } + + public static void do404NotFound(String message, HttpServletResponse resp) + throws IOException { + resp.setStatus(404); + resp.getWriter().println(message); + } + + public static void do500InternalServerError(String message, Exception e, + HttpServletResponse resp) throws IOException { + resp.setStatus(500); + PrintWriter w = resp.getWriter(); + w.println(message); + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/IndividualApiSparqlUtility.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/IndividualApiSparqlUtility.java new file mode 100644 index 0000000000..73df118ea5 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/software/IndividualApiSparqlUtility.java @@ -0,0 +1,95 @@ +package edu.cornell.mannlib.vitro.webapp.controller.api.software; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery.SparqlQueryApiExecutor; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; +import org.apache.commons.lang3.StringEscapeUtils; +import org.apache.jena.update.GraphStore; +import org.apache.jena.update.UpdateAction; +import org.apache.jena.update.UpdateFactory; +import org.apache.jena.update.UpdateRequest; + +public class IndividualApiSparqlUtility { + + public static String getSparqlQueryResponse(SparqlQueryApiExecutor core) throws IOException, RDFServiceException { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + core.executeAndFormat(outputStream); + + String sparqlResponse = outputStream.toString("UTF-8"); + + outputStream.close(); + + return sparqlResponse; + } + + public static List> parseBindings(String jsonResponse) throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode rootNode = objectMapper.readTree(jsonResponse); + + JsonNode bindingsNode = rootNode.path("results").path("bindings"); + + List> recordsList = new ArrayList<>(); + + for (JsonNode bindingNode : bindingsNode) { + Map recordMap = new HashMap<>(); + + Iterator> fieldsIterator = bindingNode.fields(); + while (fieldsIterator.hasNext()) { + Map.Entry field = fieldsIterator.next(); + + String fieldName = field.getKey(); + String fieldValue = field.getValue().path("value").asText(); + + recordMap.put(fieldName, fieldValue); + } + + recordsList.add(recordMap); + } + + return recordsList; + } + + public static void addPrefixClauses(StringBuilder queryBuilder) { + queryBuilder + .append("PREFIX rdf: \n") + .append("PREFIX rdfs: \n") + .append("PREFIX xsd: \n") + .append("PREFIX owl: \n") + .append("PREFIX swrl: \n") + .append("PREFIX swrlb: \n") + .append("PREFIX vitro: \n") + .append("PREFIX bibo: \n") + .append("PREFIX c4o: \n") + .append("PREFIX cito: \n") + .append("PREFIX dcterms: \n") + .append("PREFIX event: \n") + .append("PREFIX fabio: \n") + .append("PREFIX foaf: \n") + .append("PREFIX geo: \n") + .append("PREFIX obo: \n") + .append("PREFIX vivo: \n") + .append("PREFIX vcard: \n"); + } + + public static void executeUpdate(GraphStore graphStore, String query) { + UpdateRequest updateRequest = UpdateFactory.create(query); + UpdateAction.execute(updateRequest, graphStore); + } + + public static String buildIndividualUri(String entityId) { + String defaultNamespace = + Objects.requireNonNull(ConfigurationProperties.getInstance().getProperty("Vitro.defaultNamespace")); + return defaultNamespace + StringEscapeUtils.escapeJava(entityId); + } +}