-
Notifications
You must be signed in to change notification settings - Fork 131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/rsmd-guidelines #4014
Open
ivanmrsulja
wants to merge
12
commits into
vivo-project:main
Choose a base branch
from
ivanmrsulja:feature/rsmd
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+720
−4
Open
Feature/rsmd-guidelines #4014
Changes from 10 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
e5f6cf6
Added software controller with fetching operations.
ivanmrsulja 428c4ce
Small refactor.
ivanmrsulja 3304969
Added support for keywords.
ivanmrsulja 9204f51
Added support for isPartOf and hasPart.
ivanmrsulja 0346d49
Added support for all software CRUD operations.
ivanmrsulja 6a91400
Fixed small bug.
ivanmrsulja c7be0ca
Aligned CRUD to codemeta standards. Deletion now goes through generic…
ivanmrsulja 0839d9b
Fixed funders support.
ivanmrsulja e631cde
Added initial language set for labels. Improved grant persistence.
ivanmrsulja a1738f9
Refactored code. Extracted common logic into utility files. Built Ins…
ivanmrsulja 55c5ce4
Refactored code. Moved logic that is not related to VIVO in Vitro.
ivanmrsulja d64d5ca
Fixed minor security issue. Small refactor.
ivanmrsulja File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
10 changes: 10 additions & 0 deletions
10
api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/software/AuthorDTO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package edu.cornell.mannlib.vitro.webapp.controller.software; | ||
|
||
public class AuthorDTO { | ||
|
||
public String name; | ||
|
||
public String type; | ||
|
||
public String identifier; | ||
} |
10 changes: 10 additions & 0 deletions
10
api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/software/FunderRequestDTO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package edu.cornell.mannlib.vitro.webapp.controller.software; | ||
|
||
public class FunderRequestDTO { | ||
|
||
public String name; | ||
|
||
public String type; | ||
|
||
public String grantName; | ||
} |
8 changes: 8 additions & 0 deletions
8
...src/main/java/edu/cornell/mannlib/vitro/webapp/controller/software/FunderResponseDTO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package edu.cornell.mannlib.vitro.webapp.controller.software; | ||
|
||
public class FunderResponseDTO { | ||
|
||
public String name; | ||
|
||
public String type; | ||
} |
126 changes: 126 additions & 0 deletions
126
.../edu/cornell/mannlib/vitro/webapp/controller/software/IndividualApiCommonCRUDUtility.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package edu.cornell.mannlib.vitro.webapp.controller.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<GraphStore, String> 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()); | ||
} | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
...ava/edu/cornell/mannlib/vitro/webapp/controller/software/IndividualApiNetworkUtility.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package edu.cornell.mannlib.vitro.webapp.controller.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> T parseRequestBody(HttpServletRequest req, Class<T> 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); | ||
e.printStackTrace(w); | ||
} | ||
} |
95 changes: 95 additions & 0 deletions
95
...java/edu/cornell/mannlib/vitro/webapp/controller/software/IndividualApiSparqlUtility.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package edu.cornell.mannlib.vitro.webapp.controller.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<Map<String, String>> parseBindings(String jsonResponse) throws IOException { | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
JsonNode rootNode = objectMapper.readTree(jsonResponse); | ||
|
||
JsonNode bindingsNode = rootNode.path("results").path("bindings"); | ||
|
||
List<Map<String, String>> recordsList = new ArrayList<>(); | ||
|
||
for (JsonNode bindingNode : bindingsNode) { | ||
Map<String, String> recordMap = new HashMap<>(); | ||
|
||
Iterator<Map.Entry<String, JsonNode>> fieldsIterator = bindingNode.fields(); | ||
while (fieldsIterator.hasNext()) { | ||
Map.Entry<String, JsonNode> 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: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n") | ||
.append("PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n") | ||
.append("PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n") | ||
.append("PREFIX owl: <http://www.w3.org/2002/07/owl#>\n") | ||
.append("PREFIX swrl: <http://www.w3.org/2003/11/swrl#>\n") | ||
.append("PREFIX swrlb: <http://www.w3.org/2003/11/swrlb#>\n") | ||
.append("PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#>\n") | ||
.append("PREFIX bibo: <http://purl.org/ontology/bibo/>\n") | ||
.append("PREFIX c4o: <http://purl.org/spar/c4o/>\n") | ||
.append("PREFIX cito: <http://purl.org/spar/cito/>\n") | ||
.append("PREFIX dcterms: <http://purl.org/dc/terms/>\n") | ||
.append("PREFIX event: <http://purl.org/NET/c4dm/event.owl#>\n") | ||
.append("PREFIX fabio: <http://purl.org/spar/fabio/>\n") | ||
.append("PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n") | ||
.append("PREFIX geo: <http://aims.fao.org/aos/geopolitical.owl#>\n") | ||
.append("PREFIX obo: <http://purl.obolibrary.org/obo/>\n") | ||
.append("PREFIX vivo: <http://vivoweb.org/ontology/core#>\n") | ||
.append("PREFIX vcard: <http://www.w3.org/2006/vcard/ns#>\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); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
...cornell/mannlib/vitro/webapp/controller/software/InformationContentEntityResponseDTO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package edu.cornell.mannlib.vitro.webapp.controller.software; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class InformationContentEntityResponseDTO { | ||
|
||
public String internalIdentifier; | ||
|
||
public String name; | ||
|
||
public String datePublished; | ||
|
||
public List<AuthorDTO> authors = new ArrayList<>(); | ||
|
||
public List<String> fundings = new ArrayList<>(); | ||
|
||
public List<FunderResponseDTO> funders = new ArrayList<>(); | ||
} |
50 changes: 50 additions & 0 deletions
50
...ell/mannlib/vitro/webapp/controller/software/InformationContentEntityResponseUtility.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package edu.cornell.mannlib.vitro.webapp.controller.software; | ||
|
||
import java.util.Map; | ||
import java.util.Objects; | ||
|
||
public class InformationContentEntityResponseUtility { | ||
|
||
public static void addAuthorToICE(Map<String, String> binding, InformationContentEntityResponseDTO entity) { | ||
if (!Objects.nonNull(binding.get("author"))) { | ||
return; | ||
} | ||
|
||
if (entity.authors.stream().anyMatch(author -> author.name.equals(binding.get("author")))) { | ||
return; | ||
} | ||
|
||
AuthorDTO author = new AuthorDTO(); | ||
author.name = binding.getOrDefault("author", null); | ||
author.type = binding.getOrDefault("authorType", null); | ||
author.identifier = binding.getOrDefault("authorIdentifier", null); | ||
entity.authors.add(author); | ||
} | ||
|
||
public static void addFundingToICE(Map<String, String> binding, InformationContentEntityResponseDTO entity) { | ||
if (!Objects.nonNull(binding.get("funding"))) { | ||
return; | ||
} | ||
|
||
if (entity.fundings.stream().anyMatch(funding -> funding.equals(binding.get("funding")))) { | ||
return; | ||
} | ||
|
||
entity.fundings.add(binding.get("funding")); | ||
} | ||
|
||
public static void addFundersToICE(Map<String, String> binding, InformationContentEntityResponseDTO entity) { | ||
if (!Objects.nonNull(binding.get("funder"))) { | ||
return; | ||
} | ||
|
||
if (entity.funders.stream().anyMatch(funder -> funder.name.equals(binding.get("funder")))) { | ||
return; | ||
} | ||
|
||
FunderResponseDTO funder = new FunderResponseDTO(); | ||
funder.name = binding.get("funder"); | ||
funder.type = binding.getOrDefault("funderType", null); | ||
entity.funders.add(funder); | ||
} | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Check warning
Code scanning / CodeQL
Information exposure through a stack trace