Commit 99f186ab authored by Petter Goksøyr Åsen's avatar Petter Goksøyr Åsen
Browse files

WIP

parent 6e8e2e46
......@@ -80,7 +80,6 @@
<!-- Checks for imports -->
<!-- See http://checkstyle.sf.net/config_import.html -->
<module name="AvoidStarImport"/>
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
<module name="UnusedImports"/>
......
package no.deichman.services;
import no.deichman.services.datasource.Datasource;
import no.deichman.services.entity.AuthorizedValuesResource;
import no.deichman.services.entity.CirculationResource;
import no.deichman.services.entity.EntityResource;
import no.deichman.services.entity.ResourceBase;
import no.deichman.services.marc.MarcResource;
import no.deichman.services.ontology.AuthorizedValuesResource;
import no.deichman.services.ontology.OntologyResource;
import no.deichman.services.ontology.TemplateResource;
import no.deichman.services.ontology.TranslationResource;
......@@ -109,10 +109,10 @@ public final class App {
// Tells the Jersey Servlet which REST service/class to load.
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_CLASSNAMES,
String.join(",", asList(
AuthorizedValuesResource.class.getCanonicalName(),
EntityResource.class.getCanonicalName(),
OntologyResource.class.getCanonicalName(),
SearchResource.class.getCanonicalName(),
AuthorizedValuesResource.class.getCanonicalName(),
MarcResource.class.getCanonicalName(),
CORSResponseFilter.class.getCanonicalName(),
VersionResource.class.getCanonicalName(),
......
package no.deichman.services.entity;
import no.deichman.services.entity.kohaadapter.KohaAdapter;
import no.deichman.services.ontology.AuthorizedValue;
import no.deichman.services.rdf.DefaultPrefixes;
import no.deichman.services.rdf.JSONLDCreator;
import no.deichman.services.search.SearchService;
import no.deichman.services.uridefaults.BaseURI;
import org.apache.commons.lang3.StringUtils;
import org.apache.jena.rdf.model.Model;
import javax.inject.Singleton;
import javax.servlet.ServletConfig;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import static no.deichman.services.restutils.MimeType.LD_JSON;
import static no.deichman.services.restutils.MimeType.UTF_8;
/**
* Responsibility: Handle requests for authorized values.
*/
@Singleton
@Path("authorized_values")
public final class AuthorizedValuesResource extends ResourceBase {
@Context
private ServletConfig servletConfig;
public AuthorizedValuesResource() {}
AuthorizedValuesResource(EntityService entityService, SearchService searchService, KohaAdapter kohaAdapter) {
super(entityService, searchService, kohaAdapter);
}
@GET
@Path("{type:" + AuthorizedValue.ALL_TYPES_PATTERN + "}")
@Produces(LD_JSON + UTF_8)
public Response getAuthorizedValues(@PathParam("type") String type) {
Model model = getEntityService().retrieveAuthorizedValuesFor(StringUtils.capitalize(type));
DefaultPrefixes ctx = new DefaultPrefixes(BaseURI.ontology());
return Response.ok().entity(new JSONLDCreator().asJSONLD(model, ctx.getForAuthorizedValues())).build();
}
@Override
protected ServletConfig getConfig() {
return servletConfig;
}
}
......@@ -64,13 +64,7 @@ import static javax.ws.rs.core.Response.noContent;
import static javax.ws.rs.core.Response.ok;
import static no.deichman.services.entity.EntityType.PUBLICATION;
import static no.deichman.services.entity.EntityType.WORK;
import static no.deichman.services.restutils.MimeType.DEFAULT;
import static no.deichman.services.restutils.MimeType.JSON;
import static no.deichman.services.restutils.MimeType.LDPATCH_JSON;
import static no.deichman.services.restutils.MimeType.LD_JSON;
import static no.deichman.services.restutils.MimeType.NTRIPLES;
import static no.deichman.services.restutils.MimeType.QS_0_7;
import static no.deichman.services.restutils.MimeType.TURTLE;
import static no.deichman.services.restutils.MimeType.*;
/**
* Responsibility: Expose entities as r/w REST resources.
......
package no.deichman.services.entity;
import no.deichman.services.circulation.CirculationProfile;
import no.deichman.services.entity.repository.RDFRepository;
import no.deichman.services.uridefaults.XURI;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.StmtIterator;
......@@ -73,4 +74,8 @@ public interface EntityService {
void deleteIncomingRelations(XURI xuri);
Model retrieveCompleteResourceById(XURI xuri);
Model retrieveAuthorizedValuesFor(String type);
RDFRepository getRepo();
}
......@@ -34,7 +34,6 @@ import org.apache.jena.query.QuerySolution;
import org.apache.jena.query.ResultSet;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.NodeIterator;
import org.apache.jena.rdf.model.Property;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.ResIterator;
......@@ -90,19 +89,6 @@ public final class EntityServiceImpl implements EntityService {
public static final Integer THREE = 3;
private static final String LANGUAGE_TTL_FILE = "language.ttl";
private static final String AUDIENCE_TTL_FILE = "audience.ttl";
private static final String FORMAT_TTL_FILE = "format.ttl";
private static final String NATIONALITY_TTL_FILE = "nationality.ttl";
private static final String MEDIATYPE_TTL_FILE = "mediaType.ttl";
private static final String WORKTYPE_TTL_FILE = "workType.ttl";
private static final String ROLE_TTL_FILE = "role.ttl";
private static final String LITERARYFORM_TTL_FILE = "literaryForm.ttl";
private static final String CONTENTADAPTATION_TTL_FILE = "contentAdaptation.ttl";
private static final String FORMATADAPTATION_TTL_FILE = "formatAdaptation.ttl";
private static final String WRITINGSYSTEM_TTL_FILE = "writingSystem.ttl";
private static final String BIOGRAPHY_TTL_FILE = "biography.ttl";
private static final String CATALOGUINGSOURCE_TTL_FILE = "cataloguingSource.ttl";
private final RDFRepository repository;
private final KohaAdapter kohaAdapter;
private final Property mainTitleProperty;
......@@ -186,86 +172,6 @@ public final class EntityServiceImpl implements EntityService {
return stream(iterable.spliterator(), false);
}
private Model getLinkedLexvoResource(Model input) {
NodeIterator objects = input.listObjects();
if (objects.hasNext()) {
Set<RDFNode> objectResources = objects.toSet();
objectResources.stream()
.filter(node -> node.toString()
.contains("http://lexvo.org/id/iso639-3/")).collect(toList())
.forEach(lv -> {
input.add(extractNamedResourceFromModel(lv.toString(), EntityServiceImpl.class.getClassLoader().getResourceAsStream(LANGUAGE_TTL_FILE), Lang.TURTLE));
});
}
return input;
}
private Model getLinkedFormatResource(Model input) {
return getLinkedResource(input, "format", FORMAT_TTL_FILE);
}
private Model getLinkedAudienceResource(Model input) {
return getLinkedResource(input, "audience", AUDIENCE_TTL_FILE);
}
private Model getLinkedNationalityResource(Model input) {
return getLinkedResource(input, "nationality", NATIONALITY_TTL_FILE);
}
private Model getLinkedMediaTypeResource(Model input) {
return getLinkedResource(input, "mediaType", MEDIATYPE_TTL_FILE);
}
private Model getLinkedLiteraryFormResource(Model input) {
return getLinkedResource(input, "literaryForm", LITERARYFORM_TTL_FILE);
}
private Model getLinkedContentAdaptationResource(Model input) {
return getLinkedResource(input, "contentAdaptation", CONTENTADAPTATION_TTL_FILE);
}
private Model getLinkedFormatAdaptationResource(Model input) {
return getLinkedResource(input, "formatAdaptation", FORMATADAPTATION_TTL_FILE);
}
private Model getLinkedWorkTypeResource(Model input) {
return getLinkedResource(input, "workType", WORKTYPE_TTL_FILE);
}
private Model getLinkedWritingSystemResource(Model input) {
return getLinkedResource(input, "writingSystem", WRITINGSYSTEM_TTL_FILE);
}
private Model getLinkedBiographySystemResource(Model input) {
return getLinkedResource(input, "biography", BIOGRAPHY_TTL_FILE);
}
private Model getLinkedRoleResource(Model input) {
return getLinkedResource(input, "role", ROLE_TTL_FILE);
}
private Model getLinkedCataloguingSourceSystemResource(Model input) {
return getLinkedResource(input, "cataloguingSource", CATALOGUINGSOURCE_TTL_FILE);
}
private Model getLinkedResource(Model input, String path, String filename) {
NodeIterator objects = input.listObjects();
if (objects.hasNext()) {
Set<RDFNode> objectResources = objects.toSet();
objectResources.stream()
.filter(node -> node.toString()
.contains("http://data.deichman.no/" + path + "#")).collect(toList())
.forEach(result -> {
input.add(extractNamedResourceFromModel(result.toString(), EntityServiceImpl.class.getClassLoader().getResourceAsStream(filename), Lang.TURTLE)
);
});
}
return input;
}
private Model extractNamedResourceFromModel(String resource, InputStream input, Lang lang) {
Model tempModel = ModelFactory.createDefaultModel();
RDFDataMgr.read(tempModel, input, lang);
......@@ -299,19 +205,6 @@ public final class EntityServiceImpl implements EntityService {
Model m = ModelFactory.createDefaultModel();
m.add(repository.retrieveWorkAndLinkedResourcesByURI(xuri));
m = addInversePublicationRelations(m, xuri);
m = getLinkedLexvoResource(m);
m = getLinkedFormatResource(m);
m = getLinkedAudienceResource(m);
m = getLinkedNationalityResource(m);
m = getLinkedMediaTypeResource(m);
m = getLinkedLiteraryFormResource(m);
m = getLinkedContentAdaptationResource(m);
m = getLinkedFormatAdaptationResource(m);
m = getLinkedWorkTypeResource(m);
m = getLinkedRoleResource(m);
m = getLinkedWritingSystemResource(m);
m = getLinkedBiographySystemResource(m);
m = getLinkedCataloguingSourceSystemResource(m);
return m;
}
......@@ -330,18 +223,17 @@ public final class EntityServiceImpl implements EntityService {
@Override
public Model retrievePersonWithLinkedResources(XURI xuri) {
Model m = ModelFactory.createDefaultModel();
m.add(repository.retrievePersonAndLinkedResourcesByURI(xuri.getUri()));
m = getLinkedNationalityResource(m);
return m;
return repository.retrievePersonAndLinkedResourcesByURI(xuri.getUri());
}
@Override
public Model retrieveCorporationWithLinkedResources(XURI xuri) {
Model m = ModelFactory.createDefaultModel();
m.add(repository.retrieveCorporationAndLinkedResourcesByURI(xuri.getUri()));
m = getLinkedNationalityResource(m);
return m;
return repository.retrieveCorporationAndLinkedResourcesByURI(xuri.getUri());
}
@Override
public Model retrieveAuthorizedValuesFor(String type) {
return repository.retrieveAuthorizedValuesFor(type);
}
@Override
......@@ -696,11 +588,7 @@ public final class EntityServiceImpl implements EntityService {
@Override
public Model retrieveWorksByCreator(XURI xuri) {
Model m = ModelFactory.createDefaultModel();
m = repository.retrieveWorksByCreator(xuri);
m = getLinkedRoleResource(m);
m = getLinkedWorkTypeResource(m);
return m;
return repository.retrieveWorksByCreator(xuri);
}
@Override
......@@ -971,6 +859,11 @@ public final class EntityServiceImpl implements EntityService {
return stream(predicates).anyMatch(p -> s.getPredicate().equals(ResourceFactory.createResource(p)));
}
@Override
public RDFRepository getRepo() {
return repository;
}
}
......@@ -48,7 +48,7 @@ public abstract class ResourceBase {
protected abstract ServletConfig getConfig();
protected final EntityService getEntityService() {
public final EntityService getEntityService() {
if (entityService == null) {
RDFRepository repository = getRdfRepository();
entityService = new EntityServiceImpl(repository, getKohaAdapter());
......
......@@ -56,6 +56,8 @@ public interface RDFRepository {
Model retrievePersonAndLinkedResourcesByURI(String uri);
Model retrieveTranslationResources();
boolean askIfResourceExists(XURI xuri);
boolean askIfStatementExists(Statement statement);
......@@ -74,6 +76,8 @@ public interface RDFRepository {
Model retrieveCorporationAndLinkedResourcesByURI(String uri);
Model retrieveAuthorizedValuesFor(String type);
List<String> retrieveRecordIdsByWork(XURI xuri);
Map getNumberOfRelationsForResource(XURI uri);
......
......@@ -495,4 +495,20 @@ public abstract class RDFRepositoryBase implements RDFRepository {
((QueryEngineHTTP) qexec).setAllowCompression(false);
}
}
@Override
public final Model retrieveTranslationResources() {
try (QueryExecution qexec = getQueryExecution(sqb.describeTranslationResources())) {
disableCompression(qexec);
return qexec.execDescribe();
}
}
@Override
public final Model retrieveAuthorizedValuesFor(String type) {
try (QueryExecution qexec = getQueryExecution(sqb.retrieveAuthorizedValuesFor(type))) {
disableCompression(qexec);
return qexec.execDescribe();
}
}
}
......@@ -59,8 +59,8 @@ public final class SPARQLQueryBuilder {
+ "PREFIX deichman: <http://data.deichman.no/ontology#>\n"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
+ "DESCRIBE <__WORKURI__> ?publication ?workContributor ?compType ?format ?mediaType ?subject\n"
+ " ?genre ?instrument ?publicationPart ?litform ?hasWorkType ?serial ?nation\n"
+ " ?pubContrib ?publicationContributor ?place ?publishedBy ?publicationPartValues\n"
+ " ?genre ?instrument ?publicationPart ?litform ?workType ?serial ?nation ?language \n"
+ " ?pubContrib ?publicationContributor ?place ?publishedBy ?publicationPartValues \n"
+ " ?bio ?country ?contentAdaptation ?relatedWork ?workSeries ?workAsSubjectAgent ?subPlace ?relworkMainEntry\n"
+ "WHERE {\n"
+ " { <__WORKURI__> a deichman:Work }\n"
......@@ -72,7 +72,7 @@ public final class SPARQLQueryBuilder {
+ " }\n"
+ " UNION { <__WORKURI__> deichman:contributor ?workContrib .\n"
+ " ?workContrib a deichman:Contribution ;\n"
+ " deichman:agent ?workContributor . \n"
+ " deichman:agent ?workContributor \n"
+ " OPTIONAL { ?workContributor deichman:nationality ?nation }"
+ " }\n"
+ " UNION { ?publication deichman:publicationOf <__WORKURI__> ; \n"
......@@ -88,6 +88,7 @@ public final class SPARQLQueryBuilder {
+ " ?serialIssue deichman:serial ?serial . }\n"
+ " OPTIONAL { ?publication deichman:hasPlaceOfPublication ?place }\n"
+ " OPTIONAL { ?publication deichman:publishedBy ?publishedBy }\n"
+ " OPTIONAL { ?publication deichman:language ?pubLang }\n"
+ " OPTIONAL { ?publication deichman:hasPublicationPart ?hasPublicationPart ."
+ " ?hasPublicationPart a deichman:PublicationPart;"
+ " ?publicationPartProperties ?publicationPartValues ."
......@@ -104,10 +105,12 @@ public final class SPARQLQueryBuilder {
+ " ?instrumentation deichman:hasInstrument ?instrument }\n"
+ " UNION { <__WORKURI__> deichman:genre ?genre }\n"
+ " UNION { <__WORKURI__> deichman:literaryForm ?litform }\n"
+ " UNION { <__WORKURI__> deichman:hasWorkType ?hasWorkType }\n"
+ " UNION { <__WORKURI__> deichman:hasWorkType ?workType }\n"
+ " UNION { <__WORKURI__> deichman:hasCompositionType ?compType }\n"
+ " UNION { <__WORKURI__> deichman:biography ?bio }\n"
+ " UNION { <__WORKURI__> deichman:language ?language }\n"
+ " UNION { <__WORKURI__> deichman:nationality ?country }\n"
+ " UNION { <__WORKURI__> deichman:fictionNonfiction ?fictionNonfiction }\n"
+ " UNION { <__WORKURI__> deichman:contentAdaptation ?contentAdaptation }\n"
+ " UNION { <__WORKURI__> deichman:isPartOfWorkSeries ?workSeriesPart . \n"
+ " ?workSeriesPart a deichman:WorkSeriesPart ;\n"
......@@ -122,17 +125,15 @@ public final class SPARQLQueryBuilder {
String queryString = format("#\n"
+ "PREFIX deichman: <%1$s>\n"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
+ "DESCRIBE <%2$s> ?name ?birth ?death ?personTitle ?nationality ?nationalityLabel ?work\n"
+ "DESCRIBE <%2$s> ?name ?birth ?death ?personTitle ?nationality ?work ?role\n"
+ "WHERE {\n"
+ " <%2$s> a deichman:Person .\n"
+ " optional { <%2$s> deichman:name ?name . }\n"
+ " optional { <%2$s> deichman:birthYear ?birth . }\n"
+ " optional { <%2$s> deichman:deathYear ?death . }\n"
+ " optional { <%2$s> deichman:personTitle ?personTitle . }\n"
+ " optional { <%2$s> deichman:nationality ?nationality . \n"
+ " ?nationality rdfs:label ?nationalityLabel .\n"
+ " }"
+ " optional { ?work a deichman:Work ; deichman:contributor [ a deichman:Contribution ; deichman:agent <%2$s> ] }\n"
+ " optional { <%2$s> deichman:nationality ?nationality . }\n"
+ " optional { ?work a deichman:Work ; deichman:contributor [ a deichman:Contribution ; deichman:agent <%2$s> ; deichman:role ?role ] }\n"
+ "}", BaseURI.ontology(), personId);
return QueryFactory.create(queryString);
}
......@@ -141,13 +142,11 @@ public final class SPARQLQueryBuilder {
String queryString = format("#\n"
+ "PREFIX deichman: <%1$s>\n"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
+ "DESCRIBE <%2$s> ?nationality ?nationalityLabel ?place\n"
+ "DESCRIBE <%2$s> ?nationality ?place\n"
+ "WHERE {\n"
+ " {\n"
+ " <%2$s> a deichman:Corporation .\n"
+ " optional { <%2$s> deichman:nationality ?nationality . \n"
+ " ?nationality rdfs:label ?nationalityLabel .\n"
+ " }\n"
+ " optional { <%2$s> deichman:nationality ?nationality }\n"
+ " } \n"
+ " UNION {"
+ " <%2$s> deichman:place ?place . \n"
......@@ -343,11 +342,11 @@ public final class SPARQLQueryBuilder {
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n"
+ "PREFIX dcterms: <http://purl.org/dc/terms/>\n"
+ "DESCRIBE ?work <%2$s>\n"
+ "DESCRIBE ?work <%2$s> ?role\n"
+ "WHERE {\n"
+ " ?work a deichman:Work ;\n"
+ " deichman:contributor ?contrib .\n"
+ " ?contrib deichman:agent <%2$s> .\n"
+ " ?contrib deichman:agent <%2$s> ; deichman:role ?role .\n"
+ "}", BaseURI.ontology(), xuri.getUri());
return QueryFactory.create(q);
}
......@@ -1043,4 +1042,36 @@ public final class SPARQLQueryBuilder {
+ " ?uri duo:templateMatch ?templateMatch . ?templateMatch ?condPred ?condObj \n"
+ "}\n", BaseURI.root());
}
public Query describeTranslationResources() {
return QueryFactory.create("PREFIX : <http://data.deichman.no/utility#>\n"
+ "DESCRIBE ?r WHERE {\n"
+ "\t?r a ?class .\n"
+ "\tVALUES ?class {\n"
+ "\t\t:Binding\n"
+ "\t\t:Format\n"
+ "\t\t<http://lexvo.org/ontology#Language>\n"
+ "\t\t:Audience\n"
+ "\t\t:Nationality\n"
+ "\t\t:LiteraryForm\n"
+ "\t\t:Biography\n"
+ "\t\t:Key\n"
+ "\t\t:Role\n"
+ "\t\t:Branch\n"
+ "\t\t:MediaType\n"
+ "\t\t:FictionNonfiction\n"
+ "\t\t:ContentAdaptation\n"
+ "\t\t:FormatAdaptation\n"
+ "\t\t:RelationType\n"
+ "\t}\n"
+ "}");
}
public Query retrieveAuthorizedValuesFor(String type) {
return QueryFactory.create(format("PREFIX : <http://data.deichman.no/utility#>\n"
+ "DESCRIBE ?r WHERE {\n"
+ "\t{?r a <http://data.deichman.no/utility#%s>. } UNION \n"
+ "\t{?r a <http://lexvo.org/ontology#%s>. } \n"
+ "}", type, type));
}
}
package no.deichman.services.ontology;
import no.deichman.services.rdf.RDFModelUtil;
import org.apache.commons.io.IOUtils;
import org.apache.jena.riot.Lang;
import javax.inject.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import java.io.IOException;
import static no.deichman.services.restutils.MimeType.LD_JSON;
import static no.deichman.services.restutils.MimeType.UTF_8;
/**
* Responsibility: Return authorized values for resources.
*/
@Singleton
@Path("authorized_values")
public final class AuthorizedValuesResource {
@GET
@Path("{valueRangeName:" + AuthorizedValue.ALL_TYPES_PATTERN + "}")
@Produces(LD_JSON + UTF_8)
public Response getValueRange(@PathParam("valueRangeName") String valueRangeName) throws IOException {
return getJsonLdResponse(valueRangeName + ".ttl");
}
private Response getJsonLdResponse(String filename) throws IOException {
return Response.ok().entity(
RDFModelUtil.stringFrom(
RDFModelUtil.modelFrom(
IOUtils.toString(
this.getClass().getClassLoader().getResourceAsStream(filename)),
Lang.TURTLE),
Lang.JSONLD))
.build();
}
}
package no.deichman.services.ontology;
import com.google.gson.Gson;
import no.deichman.services.rdf.RDFModelUtil;
import no.deichman.services.utils.ResourceReader;
import no.deichman.services.entity.EntityResource;
import no.deichman.services.entity.repository.RDFRepository;
import org.apache.jena.query.QueryExecution;
import org.apache.jena.query.QueryExecutionFactory;
import org.apache.jena.query.ResultSet;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.riot.Lang;
import javax.inject.Singleton;
import javax.ws.rs.GET;
......@@ -26,8 +24,6 @@ import java.util.Map;
@Singleton
@Path("translations")
public class TranslationResource {
private String[] inputFiles = {"binding.ttl", "format.ttl", "language.ttl", "audience.ttl", "nationality.ttl", "literaryForm.ttl", "biography.ttl", "key.ttl",
"role.ttl", "branches.ttl", "mediaType.ttl", "fictionNonfiction.ttl", "relationType.ttl", "contentAdaptation.ttl", "formatAdaptation.ttl"};
private String[] locales = {"no", "en"};
private Map<String, String> cachedTranslations = new HashMap<>();
private String query = ""
......@@ -37,17 +33,23 @@ public class TranslationResource {
+ "}";
public TranslationResource() {
Model model = ModelFactory.createDefaultModel();
for (String translateableFile : inputFiles) {
model.add(RDFModelUtil.modelFrom(new ResourceReader().readFile(translateableFile), Lang.TURTLE));
}
EntityResource res = new EntityResource();
initCachedTranslations(res.getEntityService().getRepo());
}