diff --git a/pom.xml b/pom.xml index 3fe1c79..2ba078b 100644 --- a/pom.xml +++ b/pom.xml @@ -141,6 +141,12 @@ + + + org.apache.jena + jena-ontapi + 6.1.0 + org.slf4j jcl-over-slf4j diff --git a/src/main/java/com/atomgraph/core/Application.java b/src/main/java/com/atomgraph/core/Application.java index 7697813..d7815b5 100644 --- a/src/main/java/com/atomgraph/core/Application.java +++ b/src/main/java/com/atomgraph/core/Application.java @@ -33,11 +33,8 @@ import com.atomgraph.core.riot.RDFLanguages; import com.atomgraph.core.riot.lang.RDFPostReaderFactory; import com.atomgraph.core.server.Dispatcher; -import com.atomgraph.core.util.jena.DataManager; -import com.atomgraph.core.util.jena.DataManagerImpl; import com.atomgraph.core.vocabulary.A; import com.atomgraph.core.vocabulary.SD; -import java.util.HashMap; import jakarta.annotation.PostConstruct; import jakarta.servlet.ServletConfig; import jakarta.ws.rs.client.Client; @@ -48,7 +45,6 @@ import org.apache.jena.riot.Lang; import org.apache.jena.riot.RDFDataMgr; import org.apache.jena.riot.resultset.ResultSetLang; -import org.apache.jena.util.LocationMapper; import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.server.ResourceConfig; @@ -73,7 +69,6 @@ public class Application extends ResourceConfig implements com.atomgraph.core.mo private final Service service; private final MediaTypes mediaTypes; private final Client client; - private final DataManager dataManager; private final Integer maxGetRequestSize; private final boolean preemptiveAuth; @@ -143,9 +138,6 @@ public Application(final Dataset dataset, ResourceFactory.createResource(endpointURI), ResourceFactory.createResource(graphStoreURI), ResourceFactory.createResource(quadStoreURI), authUser, authPwd, maxGetRequestSize); } - - dataManager = new DataManagerImpl(LocationMapper.get(), new HashMap<>(), GraphStoreClient.create(client, mediaTypes), - cacheModelLoads, preemptiveAuth); } @PostConstruct @@ -207,10 +199,6 @@ public Integer getMaxGetRequestSize() return maxGetRequestSize; } - public DataManager getDataManager() - { - return dataManager; - } public boolean isPreemptiveAuth() { diff --git a/src/main/java/com/atomgraph/core/factory/DataManagerFactory.java b/src/main/java/com/atomgraph/core/factory/DataManagerFactory.java deleted file mode 100644 index 50910dc..0000000 --- a/src/main/java/com/atomgraph/core/factory/DataManagerFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright 2014 Martynas Jusevičius - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.atomgraph.core.factory; - -import com.atomgraph.core.util.jena.DataManager; -import org.glassfish.hk2.api.Factory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * JAX-RS provider for data manager. - * Needs to be registered in the JAX-RS application. - * - * @author Martynas Jusevičius {@literal } - * @see com.atomgraph.core.util.jena.DataManager - * @see jakarta.ws.rs.core.Context - */ -public class DataManagerFactory implements Factory -{ - - private static final Logger log = LoggerFactory.getLogger(DataManagerFactory.class); - - private final DataManager dataManager; - - public DataManagerFactory(final DataManager dataManager) - { - this.dataManager = dataManager; - } - - @Override - public DataManager provide() - { - return getDataManager(); - } - - @Override - public void dispose(DataManager dataManager) - { - } - - /** - * Returns default data manager instance. - * @return data manager instance - */ - public DataManager getDataManager() - { - return dataManager; - } - -} \ No newline at end of file diff --git a/src/main/java/com/atomgraph/core/io/DatasetProvider.java b/src/main/java/com/atomgraph/core/io/DatasetProvider.java index caa0a9e..77a0501 100644 --- a/src/main/java/com/atomgraph/core/io/DatasetProvider.java +++ b/src/main/java/com/atomgraph/core/io/DatasetProvider.java @@ -32,8 +32,10 @@ import org.apache.jena.rdf.model.Model; import org.apache.jena.riot.Lang; import org.apache.jena.riot.RDFDataMgr; +import org.apache.jena.riot.RDFFormat; import org.apache.jena.riot.RDFLanguages; import org.apache.jena.riot.RDFParserRegistry; +import org.apache.jena.riot.RDFWriter; import org.apache.jena.riot.RDFWriterRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -112,7 +114,14 @@ public void writeTo(Dataset dataset, Class type, Type genericType, Annotation Lang lang = RDFLanguages.contentTypeToLang(formatType.toString()); // cannot be null - isWritable() checks that // if we need to provide triples, then we write only the default graph of the dataset - if (RDFLanguages.isTriples(lang)) dataset.getDefaultModel().write(entityStream, lang.getName()); + if (RDFLanguages.isTriples(lang)) + { + RDFFormat format = Lang.RDFXML.equals(lang) ? RDFFormat.RDFXML_PLAIN : RDFWriterRegistry.defaultSerialization(lang); // keep basic (plain) RDF/XML, not the abbreviated default + RDFWriter.create(). + format(format). + source(dataset.getDefaultModel()). + output(entityStream); + } else RDFDataMgr.write(entityStream, dataset, lang); } diff --git a/src/main/java/com/atomgraph/core/io/ModelProvider.java b/src/main/java/com/atomgraph/core/io/ModelProvider.java index 53c9079..6306fe9 100644 --- a/src/main/java/com/atomgraph/core/io/ModelProvider.java +++ b/src/main/java/com/atomgraph/core/io/ModelProvider.java @@ -31,9 +31,11 @@ import jakarta.ws.rs.ext.MessageBodyWriter; import jakarta.ws.rs.ext.Provider; import org.apache.jena.riot.Lang; +import org.apache.jena.riot.RDFFormat; import org.apache.jena.riot.RDFLanguages; import org.apache.jena.riot.RDFParser; import org.apache.jena.riot.RDFParserRegistry; +import org.apache.jena.riot.RDFWriter; import org.apache.jena.riot.RDFWriterRegistry; import org.apache.jena.riot.system.ErrorHandler; import org.apache.jena.riot.system.ErrorHandlerFactory; @@ -158,7 +160,12 @@ public Model write(Model model, OutputStream os, Lang lang, String baseURI) String syntax = lang.getName(); if (log.isDebugEnabled()) log.debug("Syntax used to write Model: {}", syntax); - return model.write(os, syntax); + RDFFormat format = Lang.RDFXML.equals(lang) ? RDFFormat.RDFXML_PLAIN : RDFWriterRegistry.defaultSerialization(lang); // keep basic (plain) RDF/XML, not the abbreviated default + RDFWriter.create(). + format(format). + source(model). + output(os); + return model; } public UriInfo getUriInfo() diff --git a/src/main/java/com/atomgraph/core/util/jena/DataManager.java b/src/main/java/com/atomgraph/core/util/jena/DataManager.java deleted file mode 100644 index c09eded..0000000 --- a/src/main/java/com/atomgraph/core/util/jena/DataManager.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2020 Martynas Jusevičius . - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.atomgraph.core.util.jena; - -import com.atomgraph.core.MediaTypes; -import java.net.URI; -import jakarta.ws.rs.client.Client; -import jakarta.ws.rs.client.WebTarget; -import jakarta.ws.rs.core.Response; -import java.util.Map; -import org.apache.jena.rdf.model.Model; -import org.apache.jena.ontology.models.ModelGetter; - -/** - * - * @author Martynas Jusevičius {@literal } - */ -public interface DataManager extends ModelGetter -{ - - Map getModelCache(); - -// Client getClient(); - -// MediaTypes getMediaTypes(); - - //WebTarget getEndpoint(URI endpointURI); - - Response get(String uri, jakarta.ws.rs.core.MediaType[] acceptedTypes); // TO-DO: deprecate? - - boolean usePreemptiveAuth(); - - Model loadModel(String uri); - -} diff --git a/src/main/java/com/atomgraph/core/util/jena/DataManagerImpl.java b/src/main/java/com/atomgraph/core/util/jena/DataManagerImpl.java deleted file mode 100644 index 3e4ef91..0000000 --- a/src/main/java/com/atomgraph/core/util/jena/DataManagerImpl.java +++ /dev/null @@ -1,246 +0,0 @@ -/** - * Copyright 2012 Martynas Jusevičius - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package com.atomgraph.core.util.jena; - -import org.apache.jena.rdf.model.Model; -import org.apache.jena.util.LocationMapper; -import java.net.URI; -import com.atomgraph.core.client.GraphStoreClient; -import java.util.Map; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriBuilder; -import java.util.Collections; -import org.apache.jena.rdf.model.ModelFactory; -import org.apache.jena.rdf.model.ModelReader; -import org.apache.jena.util.FileManagerImpl; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** -* Utility class for retrieval of RDF models from remote URLs. -* -* @author Martynas Jusevičius {@literal } -* @see org.apache.jena.util.FileManager -* @see com.atomgraph.core.client.GraphStoreClient -*/ - -public class DataManagerImpl extends FileManagerImpl implements DataManager -{ - - private static final Logger log = LoggerFactory.getLogger(DataManagerImpl.class); - - private final boolean preemptiveAuth; - private final GraphStoreClient gsc; - private boolean cacheModelLoads; - private final Map modelCache; - - /** - * Creates data manager. - * - * @param mapper location mapper - * @param modelCache model cache map - * @param gsc Graph Store client - * @param cacheModelLoads if true, cache models after loading, using locations as keys - * @param preemptiveAuth if true, preemptive HTTP authentication will be used - */ - public DataManagerImpl(LocationMapper mapper, Map modelCache, - GraphStoreClient gsc, - boolean cacheModelLoads, boolean preemptiveAuth) - { - super(mapper); - if (modelCache == null) throw new IllegalArgumentException("Model cache Map must be not null"); - this.modelCache = modelCache; - this.cacheModelLoads = cacheModelLoads; - this.preemptiveAuth = preemptiveAuth; - this.gsc = gsc; - - addLocatorFile() ; - addLocatorURL() ; - addLocatorClassLoader(getClass().getClassLoader()) ; - } - - public URI getEndpoint(URI endpointURI) - { - if (endpointURI == null) throw new IllegalArgumentException("Endpoint URI must be not null"); - - return UriBuilder.fromUri(endpointURI).fragment(null).build().normalize(); // cannot use the URI class because query string with special chars such as '+' gets decoded - } - - @Override - public Response get(String uri, jakarta.ws.rs.core.MediaType[] acceptedTypes) - { - return getGraphStoreClient().get(getEndpoint(URI.create(uri)), acceptedTypes); - } - - @Override - public Model loadModel(String uri) - { - // only handle HTTP/HTTPS URIs, leave the rest to Jena - if (!hasCachedModel(uri)) - { - String mappedURI = mapURI(uri); - if (mappedURI.startsWith("http") || mappedURI.startsWith("https")) - { - Model model = getGraphStoreClient().getModel(getEndpoint(URI.create(uri)).toString()); - - if (isCachingModels()) addCacheModel(uri, model) ; - - return model; - } - } - - return super.loadModelInternal(uri); - } - - @Override - public Model getModel(String uri) - { - return loadModel(uri); - } - - @Override - public Model getModel(String uri, ModelReader loadIfAbsent) - { - Model model = getModel(uri); - - if (model == null) return loadIfAbsent.readModel(ModelFactory.createDefaultModel(), uri); - - return model; - } - - @Override - public Model readModel(Model model, String uri) - { - String mappedURI = mapURI(uri); - if (mappedURI.startsWith("http") || mappedURI.startsWith("https")) - return model.add(getGraphStoreClient().getModel(getEndpoint(URI.create(uri)).toString())); - - return super.readModelInternal(model, uri); - } - - /** - * Returns an immutable copy of the model cache - * - * @return immutable cache map - */ - @Override - public Map getModelCache() - { - return Collections.unmodifiableMap(modelCache); - } - - /** - * Reset the model cache - */ - @Override - public void resetCache() - { - modelCache.clear() ; - } - - /** - * Change the state of model cache : does not clear the cache. - * Deprecated - use constructor argument instead. - * - * @param state true to enable caching - */ - @Override - @Deprecated - public void setModelCaching(boolean state) - { - this.cacheModelLoads = state; - } - - /** - * Return whether caching is on of off - * - * @return true if caching is enabled - */ - @Override - public boolean isCachingModels() - { - return cacheModelLoads; - } - - /** - * Read out of the cache - return null if not in the cache - * - * @param filenameOrURI the location to load model from - * @return model instance or null if it's not cached or caching is off - */ - @Override - public Model getFromCache(String filenameOrURI) - { - if (!isCachingModels()) return null; - - return modelCache.get(filenameOrURI); - } - - /** - * Check if model is cached for a given URI - * - * @param filenameOrURI model location - * @return true if cached, if it's not cached or caching is off - */ - @Override - public boolean hasCachedModel(String filenameOrURI) - { - if (!isCachingModels()) return false; - - return modelCache.containsKey(filenameOrURI) ; - } - - /** - * Add model to cache using given URI as key - * - * @param uri model URI (cache key) - * @param m the model - */ - @Override - public void addCacheModel(String uri, Model m) - { - if (isCachingModels()) modelCache.put(uri, m); - } - - /** - * Remove cache from model using given URI key - * - * @param uri cache key - */ - @Override - public void removeCacheModel(String uri) - { - if (isCachingModels()) modelCache.remove(uri) ; - } - - @Override - public boolean usePreemptiveAuth() - { - return preemptiveAuth; - } - - /** - * Returns Graph Store client. - * - * @return client instance - */ - public GraphStoreClient getGraphStoreClient() - { - return gsc; - } - -} \ No newline at end of file diff --git a/src/main/java/com/atomgraph/core/vocabulary/A.java b/src/main/java/com/atomgraph/core/vocabulary/A.java index 1b91754..701da46 100644 --- a/src/main/java/com/atomgraph/core/vocabulary/A.java +++ b/src/main/java/com/atomgraph/core/vocabulary/A.java @@ -16,11 +16,11 @@ */ package com.atomgraph.core.vocabulary; -import org.apache.jena.ontology.DatatypeProperty; -import org.apache.jena.ontology.ObjectProperty; -import org.apache.jena.ontology.OntModel; -import org.apache.jena.ontology.OntModelSpec; -import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.ontapi.OntModelFactory; +import org.apache.jena.ontapi.OntSpecification; +import org.apache.jena.ontapi.model.OntModel; +import org.apache.jena.rdf.model.Property; + import org.apache.jena.rdf.model.Resource; /** @@ -29,8 +29,13 @@ */ public final class A { + + static + { + org.apache.jena.sys.JenaSystem.init(); // ensure Jena (RDFS vocab) is initialized before ontapi touches it + } /**

The RDF model that holds the vocabulary terms

*/ - private static OntModel m_model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, null); + private static OntModel m_model = OntModelFactory.createModel(OntSpecification.OWL2_FULL_MEM); /**

The namespace of the vocabulary as a string

*/ public static final String NS = "https://w3id.org/atomgraph/core#"; @@ -47,33 +52,33 @@ public static String getURI() public static final Resource NAMESPACE = m_model.createResource( NS ); /** Dataset file property */ - public static final DatatypeProperty dataset = m_model.createDatatypeProperty( NS + "dataset" ); + public static final Property dataset = m_model.createDataProperty( NS + "dataset" ); /** Graph Store URL property */ - public static final ObjectProperty graphStore = m_model.createObjectProperty( NS + "graphStore" ); + public static final Property graphStore = m_model.createObjectProperty( NS + "graphStore" ); /** Quad store URL property */ - public static final ObjectProperty quadStore = m_model.createObjectProperty( NS + "quadStore" ); + public static final Property quadStore = m_model.createObjectProperty( NS + "quadStore" ); /** Cache-Control property **/ - public static final DatatypeProperty cacheControl = m_model.createDatatypeProperty( NS + "cacheControl" ); + public static final Property cacheControl = m_model.createDataProperty( NS + "cacheControl" ); /** Result limit property */ - public static final DatatypeProperty resultLimit = m_model.createDatatypeProperty( NS + "resultLimit" ); + public static final Property resultLimit = m_model.createDataProperty( NS + "resultLimit" ); /** Cache models property */ - public static final DatatypeProperty cacheModelLoads = m_model.createDatatypeProperty( NS + "cacheModelLoads" ); + public static final Property cacheModelLoads = m_model.createDataProperty( NS + "cacheModelLoads" ); /** Preemptive HTTP Basic auth property */ - public static final DatatypeProperty preemptiveAuth = m_model.createDatatypeProperty( NS + "preemptiveAuth" ); + public static final Property preemptiveAuth = m_model.createDataProperty( NS + "preemptiveAuth" ); /** Max GET request size property */ - public static final DatatypeProperty maxGetRequestSize = m_model.createDatatypeProperty( NS + "maxGetRequestSize" ); + public static final Property maxGetRequestSize = m_model.createDataProperty( NS + "maxGetRequestSize" ); /** HTTP Basic auth user property */ - public static final DatatypeProperty authUser = m_model.createDatatypeProperty( NS + "authUser" ); + public static final Property authUser = m_model.createDataProperty( NS + "authUser" ); /** HTTP Basic auth password property */ - public static final DatatypeProperty authPwd = m_model.createDatatypeProperty( NS + "authPwd" ); + public static final Property authPwd = m_model.createDataProperty( NS + "authPwd" ); } \ No newline at end of file diff --git a/src/main/java/com/atomgraph/core/vocabulary/SD.java b/src/main/java/com/atomgraph/core/vocabulary/SD.java index 2b2d773..886312c 100644 --- a/src/main/java/com/atomgraph/core/vocabulary/SD.java +++ b/src/main/java/com/atomgraph/core/vocabulary/SD.java @@ -16,12 +16,11 @@ */ package com.atomgraph.core.vocabulary; -import org.apache.jena.ontology.Individual; -import org.apache.jena.ontology.ObjectProperty; -import org.apache.jena.ontology.OntClass; -import org.apache.jena.ontology.OntModel; -import org.apache.jena.ontology.OntModelSpec; -import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.ontapi.OntModelFactory; +import org.apache.jena.ontapi.OntSpecification; +import org.apache.jena.ontapi.model.OntClass; +import org.apache.jena.ontapi.model.OntModel; +import org.apache.jena.rdf.model.Property; import org.apache.jena.rdf.model.Resource; /** @@ -30,12 +29,18 @@ */ public class SD { + + static + { + org.apache.jena.sys.JenaSystem.init(); // ensure Jena (RDFS vocab) is initialized before ontapi touches it + } + /**

The RDF model that holds the vocabulary terms

*/ - private static OntModel m_model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, null); - + private static OntModel m_model = OntModelFactory.createModel(OntSpecification.OWL2_FULL_MEM); + /**

The namespace of the vocabulary as a string

*/ public static final String NS = "http://www.w3.org/ns/sparql-service-description#"; - + /**

The namespace of the vocabulary as a string

* @return namespace URI * @see #NS */ @@ -43,36 +48,36 @@ public static String getURI() { return NS; } - + /**

The namespace of the vocabulary as a resource

*/ public static final Resource NAMESPACE = m_model.createResource( NS ); - - public static final OntClass Dataset = m_model.createClass( NS + "Dataset" ); - public static final OntClass Service = m_model.createClass( NS + "Service" ); + public static final OntClass Dataset = m_model.createOntClass( NS + "Dataset" ); + + public static final OntClass Service = m_model.createOntClass( NS + "Service" ); + + public static final OntClass Graph = m_model.createOntClass( NS + "Graph" ); + + public static final OntClass NamedGraph = m_model.createOntClass( NS + "NamedGraph" ); + + public static final OntClass Language = m_model.createOntClass( NS + "Language" ); + + public static final Property endpoint = m_model.createObjectProperty( NS + "endpoint" ); + + public static final Property graph = m_model.createObjectProperty( NS + "graph" ); + + public static final Property name = m_model.createObjectProperty( NS + "name" ); - public static final OntClass Graph = m_model.createClass( NS + "Graph" ); - - public static final OntClass NamedGraph = m_model.createClass( NS + "NamedGraph" ); - - public static final OntClass Language = m_model.createClass( NS + "Language" ); - - public static final ObjectProperty endpoint = m_model.createObjectProperty( NS + "endpoint" ); + public static final Property defaultGraph = m_model.createObjectProperty( NS + "defaultGraph" ); - public static final ObjectProperty graph = m_model.createObjectProperty( NS + "graph" ); + public static final Property namedGraph = m_model.createObjectProperty( NS + "namedGraph" ); - public static final ObjectProperty name = m_model.createObjectProperty( NS + "name" ); + public static final Property supportedLanguage = m_model.createObjectProperty( NS + "supportedLanguage" ); - public static final ObjectProperty defaultGraph = m_model.createObjectProperty( NS + "defaultGraph" ); + public static final Resource SPARQL10Query = m_model.createIndividual(NS + "SPARQL10Query", Language); - public static final ObjectProperty namedGraph = m_model.createObjectProperty( NS + "namedGraph" ); - - public static final ObjectProperty supportedLanguage = m_model.createObjectProperty( NS + "supportedLanguage" ); - - public static final Individual SPARQL10Query = m_model.createIndividual(NS + "SPARQL10Query", Language); - - public static final Individual SPARQL11Query = m_model.createIndividual(NS + "SPARQL11Query", Language); + public static final Resource SPARQL11Query = m_model.createIndividual(NS + "SPARQL11Query", Language); - public static final Individual SPARQL11Update = m_model.createIndividual(NS + "SPARQL11Update", Language); + public static final Resource SPARQL11Update = m_model.createIndividual(NS + "SPARQL11Update", Language); }