From 3d081a3fc9117a92132638aff18e9c53c8238831 Mon Sep 17 00:00:00 2001 From: Martynas Jusevicius Date: Sun, 27 Apr 2025 13:50:40 +0200 Subject: [PATCH 1/9] [maven-release-plugin] prepare release core-4.0.10 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index cfad35f..9f01149 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ com.atomgraph core - 4.0.10-SNAPSHOT + 4.0.10 ${packaging.type} AtomGraph Core @@ -42,7 +42,7 @@ https://github.com/AtomGraph/Core scm:git:git@github.com:AtomGraph/Core.git scm:git:git@github.com:AtomGraph/Core.git - HEAD + core-4.0.10 From 35aa9fb023d1259f18d4de79321581a72531e2f1 Mon Sep 17 00:00:00 2001 From: Martynas Jusevicius Date: Sun, 27 Apr 2025 13:50:55 +0200 Subject: [PATCH 2/9] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 9f01149..a25ec59 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ com.atomgraph core - 4.0.10 + 4.0.11-SNAPSHOT ${packaging.type} AtomGraph Core @@ -42,7 +42,7 @@ https://github.com/AtomGraph/Core scm:git:git@github.com:AtomGraph/Core.git scm:git:git@github.com:AtomGraph/Core.git - core-4.0.10 + HEAD From 8d8d62665e3d545720cde75dc3646d405bd74dc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martynas=20Jusevi=C4=8Dius?= Date: Sun, 28 Dec 2025 21:57:05 +0100 Subject: [PATCH 3/9] LinkedDataClient incorporated into GraphStoreClient Linked Data is GSP direct graph identification --- .../java/com/atomgraph/core/Application.java | 4 +- .../com/atomgraph/core/client/ClientBase.java | 10 - .../core/client/GraphStoreClient.java | 303 +++++++++++++----- .../core/client/LinkedDataClient.java | 229 ------------- .../impl/remote/DatasetAccessorImpl.java | 2 +- .../core/model/impl/remote/ServiceImpl.java | 13 +- .../core/util/jena/DataManagerImpl.java | 10 +- .../core/client/GraphStoreClientTest.java | 8 +- .../atomgraph/core/io/ModelProviderTest.java | 16 +- .../core/model/impl/GraphStoreImplTest.java | 84 ++--- .../core/model/impl/LocaleEntityTagTest.java | 8 +- .../model/impl/QueriedResourceBaseTest.java | 13 +- 12 files changed, 296 insertions(+), 404 deletions(-) delete mode 100644 src/main/java/com/atomgraph/core/client/LinkedDataClient.java diff --git a/src/main/java/com/atomgraph/core/Application.java b/src/main/java/com/atomgraph/core/Application.java index 8017b93..49882dc 100644 --- a/src/main/java/com/atomgraph/core/Application.java +++ b/src/main/java/com/atomgraph/core/Application.java @@ -16,7 +16,7 @@ */ package com.atomgraph.core; -import com.atomgraph.core.client.LinkedDataClient; +import com.atomgraph.core.client.GraphStoreClient; import com.atomgraph.core.exception.ConfigurationException; import com.atomgraph.core.io.DatasetProvider; import com.atomgraph.core.io.ResultSetProvider; @@ -146,7 +146,7 @@ public Application(final Dataset dataset, authUser, authPwd, maxGetRequestSize); } - dataManager = new DataManagerImpl(LocationMapper.get(), new HashMap<>(), LinkedDataClient.create(client, mediaTypes), + dataManager = new DataManagerImpl(LocationMapper.get(), new HashMap<>(), GraphStoreClient.create(client, mediaTypes), cacheModelLoads, preemptiveAuth); } diff --git a/src/main/java/com/atomgraph/core/client/ClientBase.java b/src/main/java/com/atomgraph/core/client/ClientBase.java index 8750189..c169987 100644 --- a/src/main/java/com/atomgraph/core/client/ClientBase.java +++ b/src/main/java/com/atomgraph/core/client/ClientBase.java @@ -16,17 +16,7 @@ package com.atomgraph.core.client; import com.atomgraph.core.MediaTypes; -import java.util.List; -import java.util.Map; -import jakarta.ws.rs.client.ClientRequestFilter; -import jakarta.ws.rs.client.Entity; -import jakarta.ws.rs.client.Invocation; -import jakarta.ws.rs.client.WebTarget; import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.MultivaluedHashMap; -import jakarta.ws.rs.core.MultivaluedMap; -import jakarta.ws.rs.core.Response; -import org.glassfish.jersey.uri.UriComponent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/com/atomgraph/core/client/GraphStoreClient.java b/src/main/java/com/atomgraph/core/client/GraphStoreClient.java index c1ae0dd..0eafbb4 100644 --- a/src/main/java/com/atomgraph/core/client/GraphStoreClient.java +++ b/src/main/java/com/atomgraph/core/client/GraphStoreClient.java @@ -13,19 +13,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.atomgraph.core.client; import com.atomgraph.core.MediaType; import com.atomgraph.core.MediaTypes; +import com.atomgraph.core.io.ModelProvider; import com.atomgraph.core.model.DatasetAccessor; import jakarta.ws.rs.NotFoundException; -import jakarta.ws.rs.client.ClientRequestFilter; +import java.net.URI; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation; import jakarta.ws.rs.client.WebTarget; import jakarta.ws.rs.core.MultivaluedHashMap; import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import org.apache.jena.rdf.model.Model; +import org.glassfish.jersey.uri.UriComponent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,177 +44,303 @@ * @author Martynas Jusevičius {@literal } * @see SPARQL 1.1 Graph Store HTTP Protocol */ -public class GraphStoreClient extends EndpointClientBase implements DatasetAccessor // TO-DO: make DatasetAccessor a subclass of this and return nulls + +public class GraphStoreClient extends ClientBase implements DatasetAccessor { + private static final Logger log = LoggerFactory.getLogger(GraphStoreClient.class); public static final String DEFAULT_PARAM_NAME = "default"; public static final String GRAPH_PARAM_NAME = "graph"; + + private final Client client; + private final URI endpoint; + private final List components = new ArrayList<>(); - protected GraphStoreClient(MediaTypes mediaTypes, WebTarget endpoint) + protected GraphStoreClient(Client client, MediaTypes mediaTypes, URI endpoint) { - super(mediaTypes, endpoint); + super(mediaTypes); + this.client = client; + this.endpoint = endpoint; } - - protected GraphStoreClient(WebTarget endpoint) + + public static GraphStoreClient create(Client client, MediaTypes mediaTypes, URI endpoint) { - this(new MediaTypes(), endpoint); + return new GraphStoreClient(client, mediaTypes, endpoint); } - - public static GraphStoreClient create(MediaTypes mediaTypes, WebTarget endpoint) + + public static GraphStoreClient create(Client client, MediaTypes mediaTypes) { - return new GraphStoreClient(mediaTypes, endpoint); + return new GraphStoreClient(client, mediaTypes, null); } - public static GraphStoreClient create(WebTarget endpoint) + /** + * Register a JAX-RS component (provider) instance to be applied to all requests. + * Components are applied to each WebTarget created by this client. + * Supports Features, Filters, Interceptors, and other JAX-RS providers. + * + * @param component the component instance to register + * @return this GraphStoreClient instance for method chaining + * @throws IllegalArgumentException if component is null + */ + public GraphStoreClient register(Object component) { - return new GraphStoreClient(endpoint); + if (component == null) throw new IllegalArgumentException("Component cannot be null"); + + components.add(component); + + return this; } /** - * Registers client filter. - * Can cause performance problems with ApacheConnector. - * - * @param filter client request filter - * @return this SPARQL client - * @see How To Use Jersey Client Efficiently + * Register a JAX-RS component (provider) class to be applied to all requests. + * Components are applied to each WebTarget created by this client. + * Supports Features, Filters, Interceptors, and other JAX-RS providers. + * + * @param componentClass the component class to register + * @return this GraphStoreClient instance for method chaining + * @throws IllegalArgumentException if componentClass is null */ - @Override - public GraphStoreClient register(ClientRequestFilter filter) + public GraphStoreClient register(Class componentClass) { - if (filter == null) throw new IllegalArgumentException("ClientRequestFilter cannot be null"); + if (componentClass == null) throw new IllegalArgumentException("Component class cannot be null"); - super.register(filter); + components.add(componentClass); return this; } + + // default graph is not supported @Override - public MediaType getDefaultMediaType() + public Model getModel() { - return MediaType.APPLICATION_NTRIPLES_TYPE; + try (Response cr = get(null)) + { + // some endpoints might include response body which will not cause NotFoundException in Jersey + if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); + + return cr.readEntity(Model.class); + } } @Override - public boolean containsModel(String uri) + public void add(Model model) { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(GRAPH_PARAM_NAME, uri); - - try (Response cr = head(getReadableMediaTypes(Model.class), params)) + try (Response cr = post(null, Entity.entity(model, getDefaultMediaType()), new jakarta.ws.rs.core.MediaType[]{})) { - return cr.getStatusInfo(). - getFamily(). - equals(Response.Status.Family.SUCCESSFUL); + // some endpoints might include response body which will not cause NotFoundException in Jersey + if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); } } - + @Override - public Model getModel() + public void deleteDefault() { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(DEFAULT_PARAM_NAME, Boolean.TRUE.toString()); - - try (Response cr = get(getReadableMediaTypes(Model.class), params)) + try (Response cr = delete(null)) { // some endpoints might include response body which will not cause NotFoundException in Jersey if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); - - return cr.readEntity(Model.class); } } - + @Override - public Model getModel(String uri) + public void putModel(Model model) { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(GRAPH_PARAM_NAME, uri); - - try (Response cr = get(getReadableMediaTypes(Model.class), params)) + try (Response cr = put(null, Entity.entity(model, getDefaultMediaType()), new jakarta.ws.rs.core.MediaType[]{})) { // some endpoints might include response body which will not cause NotFoundException in Jersey if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); - - return cr.readEntity(Model.class); } } - @Override - public void add(Model model) + protected WebTarget getWebTarget(URI uri) { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(DEFAULT_PARAM_NAME, Boolean.TRUE.toString()); + WebTarget target; - try (Response cr = post(model, getDefaultMediaType(), new jakarta.ws.rs.core.MediaType[]{}, params)) + // indirect graph identification + if (getEndpoint() != null) { - // some endpoints might include response body which will not cause NotFoundException in Jersey - if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); + if (uri == null) // default graph - only possible with endpoint + target = getClient().target(getEndpoint()).queryParam(DEFAULT_PARAM_NAME, Boolean.TRUE.toString()); + else // named graph + target = getClient().target(getEndpoint()).queryParam(UriComponent.encode(GRAPH_PARAM_NAME, UriComponent.Type.UNRESERVED), + UriComponent.encode(uri.toString(), UriComponent.Type.UNRESERVED)); + } + // direct graph idntification + else + { + if (uri == null) + throw new UnsupportedOperationException("Default graph is not supported without endpoint -- all RDF graphs in Linked Data are named"); + + target = getClient().target(uri); } + + // Apply all registered components to this WebTarget + for (Object component : components) + target = target.register(component); + + return target; } - @Override - public void add(String uri, Model model) + public Response head(URI uri) + { + return head(uri, null); + } + + public Response head(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes) { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(GRAPH_PARAM_NAME, uri); + return head(uri, acceptedTypes, new MultivaluedHashMap()); + } - try (Response cr = post(model, getDefaultMediaType(), new jakarta.ws.rs.core.MediaType[]{}, params)) + public Response head(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes, MultivaluedMap headers) + { + return applyHeaders(getWebTarget(uri).request(acceptedTypes), headers).head(); + } + + @Override + public boolean containsModel(String uri) + { + try (Response cr = head(URI.create(uri))) { - // some endpoints might include response body which will not cause NotFoundException in Jersey - if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); + return cr.getStatusInfo(). + getFamily(). + equals(Response.Status.Family.SUCCESSFUL); } } - @Override - public void putModel(Model model) + public Response get(URI uri) { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(DEFAULT_PARAM_NAME, Boolean.TRUE.toString()); + return get(uri, getReadableMediaTypes(Model.class)); + } - try (Response cr = put(model, getDefaultMediaType(), new jakarta.ws.rs.core.MediaType[]{}, params)) + public Response get(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes) + { + return get(uri, acceptedTypes, new MultivaluedHashMap()); + } + + public Response get(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes, MultivaluedMap headers) + { + return applyHeaders(getWebTarget(uri).request(acceptedTypes), headers).get(); + } + + @Override + public Model getModel(String uri) + { + try (Response cr = get(URI.create(uri))) { // some endpoints might include response body which will not cause NotFoundException in Jersey if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); + + cr.getHeaders().putSingle(ModelProvider.REQUEST_URI_HEADER, uri); // provide a base URI hint to ModelProvider + return cr.readEntity(Model.class); } } - + + public Response post(URI uri, Entity entity) + { + return post(uri, entity, new jakarta.ws.rs.core.MediaType[]{}, new MultivaluedHashMap()); + } + + public Response post(URI uri, Entity entity, jakarta.ws.rs.core.MediaType[] acceptedTypes) + { + return post(uri, entity, acceptedTypes, new MultivaluedHashMap()); + } + + public Response post(URI uri, Entity entity, jakarta.ws.rs.core.MediaType[] acceptedTypes, MultivaluedMap headers) + { + return applyHeaders(getWebTarget(uri).request(acceptedTypes), headers).post(entity); + } + @Override - public void putModel(String uri, Model model) + public void add(String uri, Model model) { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(GRAPH_PARAM_NAME, uri); - - try (Response cr = put(model, getDefaultMediaType(), new jakarta.ws.rs.core.MediaType[]{}, params)) + try (Response cr = post(URI.create(uri), Entity.entity(model, getDefaultMediaType()))) { // some endpoints might include response body which will not cause NotFoundException in Jersey if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); } } + + public Response put(URI uri, Entity entity) + { + return put(uri, entity, getReadableMediaTypes(Model.class), new MultivaluedHashMap()); + } + + public Response put(URI uri, Entity entity, jakarta.ws.rs.core.MediaType[] acceptedTypes) + { + return put(uri, entity, acceptedTypes, new MultivaluedHashMap()); + } + + public Response put(URI uri, Entity entity, jakarta.ws.rs.core.MediaType[] acceptedTypes, MultivaluedMap headers) + { + return applyHeaders(getWebTarget(uri).request(acceptedTypes), headers).put(entity); + } @Override - public void deleteDefault() + public void putModel(String uri, Model model) { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(DEFAULT_PARAM_NAME, Boolean.TRUE.toString()); - - try (Response cr = delete(new jakarta.ws.rs.core.MediaType[]{}, params)) + try (Response cr = put(URI.create(uri), Entity.entity(model, getDefaultMediaType()))) { // some endpoints might include response body which will not cause NotFoundException in Jersey - if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); + if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); } } + public Response delete(URI uri) + { + return delete(uri, new jakarta.ws.rs.core.MediaType[]{}, new MultivaluedHashMap(), new MultivaluedHashMap()); + } + + public Response delete(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes) + { + return delete(uri, acceptedTypes, new MultivaluedHashMap(), new MultivaluedHashMap()); + } + + public Response delete(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes, MultivaluedMap params) + { + return delete(uri, acceptedTypes, params, new MultivaluedHashMap()); + } + + public Response delete(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes, MultivaluedMap params, MultivaluedMap headers) + { + return applyHeaders(getWebTarget(uri).request(acceptedTypes), headers).delete(); + } + @Override public void deleteModel(String uri) { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(GRAPH_PARAM_NAME, uri); - - try (Response cr = delete(new jakarta.ws.rs.core.MediaType[]{}, params)) + try (Response cr = delete(URI.create(uri))) { // some endpoints might include response body which will not cause NotFoundException in Jersey - if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); + if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); } } + protected Invocation.Builder applyHeaders(Invocation.Builder builder, MultivaluedMap headers) + { + if (headers != null) + for (Map.Entry> entry : headers.entrySet()) + for (Object value : entry.getValue()) + builder = builder.header(entry.getKey(), value); + + return builder; + } + + @Override + public MediaType getDefaultMediaType() + { + return MediaType.APPLICATION_NTRIPLES_TYPE; + } + + public Client getClient() + { + return client; + } + + public URI getEndpoint() + { + return endpoint; + } + } diff --git a/src/main/java/com/atomgraph/core/client/LinkedDataClient.java b/src/main/java/com/atomgraph/core/client/LinkedDataClient.java deleted file mode 100644 index 660ecf3..0000000 --- a/src/main/java/com/atomgraph/core/client/LinkedDataClient.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright 2016 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.client; - -import com.atomgraph.core.MediaType; -import com.atomgraph.core.MediaTypes; -import com.atomgraph.core.io.ModelProvider; -import com.atomgraph.core.model.DatasetAccessor; -import java.net.URI; -import jakarta.ws.rs.client.Client; -import jakarta.ws.rs.client.ClientRequestFilter; -import jakarta.ws.rs.client.Entity; -import jakarta.ws.rs.client.WebTarget; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.Response.Status; -import org.apache.jena.rdf.model.Model; - -/** - * Linked Data client. - * - * @author Martynas Jusevičius {@literal } - */ -public class LinkedDataClient extends ClientBase implements DatasetAccessor -{ - - private final Client client; - - protected LinkedDataClient(Client client, MediaTypes mediaTypes) - { - super(mediaTypes); - this.client = client; - } - - public static LinkedDataClient create(Client client, MediaTypes mediaTypes) - { - return new LinkedDataClient(client, mediaTypes); - } - - /** - * Registers client filter. - * Can cause performance problems with ApacheConnector. - * - * @param filter client request filter - * @return this SPARQL client - * @see How To Use Jersey Client Efficiently - */ - public LinkedDataClient register(ClientRequestFilter filter) - { - if (filter == null) throw new IllegalArgumentException("ClientRequestFilter cannot be null"); - - getClient().register(filter); - - return this; - } - - // default graph is not supported - - @Override - public Model getModel() - { - throw new UnsupportedOperationException("Default graph is not supported -- all RDF graphs in Linked Data are named"); - } - - @Override - public void add(Model model) - { - throw new UnsupportedOperationException("Default graph is not supported -- all RDF graphs in Linked Data are named"); - } - - @Override - public void deleteDefault() - { - throw new UnsupportedOperationException("Default graph is not supported -- all RDF graphs in Linked Data are named"); - } - - @Override - public void putModel(Model model) - { - throw new UnsupportedOperationException("Default graph is not supported -- all RDF graphs in Linked Data are named"); - } - - protected WebTarget getWebTarget(URI uri) - { - return getClient().target(uri); - } - - public Response head(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes) - { - return getWebTarget(uri).request(acceptedTypes).head(); - } - - public Response head(URI uri) - { - return head(uri, getReadableMediaTypes(Model.class)); - } - - @Override - public boolean containsModel(String uri) - { - try (Response cr = head(URI.create(uri))) - { - return cr.getStatusInfo().equals(Status.OK); - } - } - - public Response get(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes) - { - return getWebTarget(uri).request(acceptedTypes).get(); - } - - public Response get(URI uri) - { - return get(uri, getReadableMediaTypes(Model.class)); - } - - @Override - public Model getModel(String uri) - { - try (Response cr = get(URI.create(uri))) - { - cr.getHeaders().putSingle(ModelProvider.REQUEST_URI_HEADER, uri); // provide a base URI hint to ModelProvider - return cr.readEntity(Model.class); - } - } - - public Response post(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes, Entity entity) - { - return getWebTarget(uri).request(acceptedTypes).post(entity); - } - - public Response post(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes, Object body, jakarta.ws.rs.core.MediaType contentType) - { - return post(uri, acceptedTypes, Entity.entity(body, contentType)); - } - - public Response post(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes, Model model) - { - return post(uri, acceptedTypes, model, getDefaultMediaType()); - } - - public Response post(URI uri, Object body, jakarta.ws.rs.core.MediaType contentType) - { - return post(uri, getReadableMediaTypes(Model.class), body, contentType); - } - - public Response post(URI uri, Model model) - { - return post(uri, model, getDefaultMediaType()); - } - - @Override - public void add(String uri, Model model) - { - post(URI.create(uri), getReadableMediaTypes(Model.class), model, getDefaultMediaType()).close(); - } - - public Response put(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes, Entity entity) - { - return getWebTarget(uri).request(acceptedTypes).put(entity); - } - - public Response put(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes, Object body, jakarta.ws.rs.core.MediaType contentType) - { - return put(uri, acceptedTypes, Entity.entity(body, contentType)); - } - - public Response put(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes, Model model) - { - return put(uri, acceptedTypes, model, getDefaultMediaType()); - } - - public Response put(URI uri, Object body, jakarta.ws.rs.core.MediaType contentType) - { - return put(uri, getReadableMediaTypes(Model.class), body, contentType); - } - - public Response put(URI uri, Model model) - { - return put(uri, model, getDefaultMediaType()); - } - - @Override - public void putModel(String uri, Model model) - { - put(URI.create(uri), getReadableMediaTypes(Model.class), model, getDefaultMediaType()).close(); - } - - public Response delete(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes) - { - return getWebTarget(uri).request(getReadableMediaTypes(Model.class)).delete(); - } - - public Response delete(URI uri) - { - return delete(uri, getReadableMediaTypes(Model.class)); - } - - @Override - public void deleteModel(String uri) - { - delete(URI.create(uri)).close(); - } - - @Override - public MediaType getDefaultMediaType() - { - return MediaType.APPLICATION_NTRIPLES_TYPE; - } - - public Client getClient() - { - return client; - } - -} diff --git a/src/main/java/com/atomgraph/core/model/impl/remote/DatasetAccessorImpl.java b/src/main/java/com/atomgraph/core/model/impl/remote/DatasetAccessorImpl.java index 9e1f789..1d0c98f 100644 --- a/src/main/java/com/atomgraph/core/model/impl/remote/DatasetAccessorImpl.java +++ b/src/main/java/com/atomgraph/core/model/impl/remote/DatasetAccessorImpl.java @@ -193,7 +193,7 @@ public void add(String uri, Model model) public String getURI() // needs to align with Jena's Resource.getURI() which returns String { - return getGraphStoreClient().getEndpoint().getUri().toString(); + return getGraphStoreClient().getEndpoint().toString(); } public GraphStoreClient getGraphStoreClient() diff --git a/src/main/java/com/atomgraph/core/model/impl/remote/ServiceImpl.java b/src/main/java/com/atomgraph/core/model/impl/remote/ServiceImpl.java index baba30c..f8bafec 100644 --- a/src/main/java/com/atomgraph/core/model/impl/remote/ServiceImpl.java +++ b/src/main/java/com/atomgraph/core/model/impl/remote/ServiceImpl.java @@ -27,6 +27,7 @@ import com.atomgraph.core.model.RemoteService; import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.WebTarget; +import java.net.URI; import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; /** @@ -105,22 +106,22 @@ public EndpointAccessor getEndpointAccessor() @Override public GraphStoreClient getGraphStoreClient() { - return getGraphStoreClient(getClient().target(getGraphStore().getURI())); + return getGraphStoreClient(URI.create(getGraphStore().getURI())); } - public GraphStoreClient getGraphStoreClient(WebTarget resource) + public GraphStoreClient getGraphStoreClient(URI uri) { - GraphStoreClient graphStoreClient = GraphStoreClient.create(resource); - + GraphStoreClient graphStoreClient = GraphStoreClient.create(getClient(), getMediaTypes(), uri); + if (getAuthUser() != null && getAuthPwd() != null) { HttpAuthenticationFeature authFeature = HttpAuthenticationFeature.basicBuilder(). credentials(getAuthUser(), getAuthPwd()). build(); - graphStoreClient.getEndpoint().register(authFeature); + graphStoreClient.register(authFeature); } - + return graphStoreClient; } diff --git a/src/main/java/com/atomgraph/core/util/jena/DataManagerImpl.java b/src/main/java/com/atomgraph/core/util/jena/DataManagerImpl.java index 3f6b980..78cbcaa 100644 --- a/src/main/java/com/atomgraph/core/util/jena/DataManagerImpl.java +++ b/src/main/java/com/atomgraph/core/util/jena/DataManagerImpl.java @@ -19,7 +19,7 @@ import org.apache.jena.rdf.model.Model; import org.apache.jena.util.LocationMapper; import java.net.URI; -import com.atomgraph.core.client.LinkedDataClient; +import com.atomgraph.core.client.GraphStoreClient; import java.util.Map; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.UriBuilder; @@ -36,7 +36,7 @@ * @author Martynas Jusevičius {@literal } * @see org.apache.jena.util.FileManager * @see org.apache.jena.rdf.model.ModelGetter -* @see com.atomgraph.core.client.LinkedDataClient +* @see com.atomgraph.core.client.GraphStoreClient */ public class DataManagerImpl extends FileManagerImpl implements DataManager @@ -45,7 +45,7 @@ public class DataManagerImpl extends FileManagerImpl implements DataManager private static final Logger log = LoggerFactory.getLogger(DataManagerImpl.class); private final boolean preemptiveAuth; - private final LinkedDataClient ldc; + private final GraphStoreClient ldc; private boolean cacheModelLoads; private final Map modelCache; @@ -59,7 +59,7 @@ public class DataManagerImpl extends FileManagerImpl implements DataManager * @param preemptiveAuth if true, preemptive HTTP authentication will be used */ public DataManagerImpl(LocationMapper mapper, Map modelCache, - LinkedDataClient ldc, + GraphStoreClient ldc, boolean cacheModelLoads, boolean preemptiveAuth) { super(mapper); @@ -239,7 +239,7 @@ public boolean usePreemptiveAuth() * * @return client instance */ - public LinkedDataClient getLinkedDataClient() + public GraphStoreClient getLinkedDataClient() { return ldc; } diff --git a/src/test/java/com/atomgraph/core/client/GraphStoreClientTest.java b/src/test/java/com/atomgraph/core/client/GraphStoreClientTest.java index 0934702..6cd4f98 100644 --- a/src/test/java/com/atomgraph/core/client/GraphStoreClientTest.java +++ b/src/test/java/com/atomgraph/core/client/GraphStoreClientTest.java @@ -19,8 +19,8 @@ import static com.atomgraph.core.model.impl.GraphStoreImplTest.NAMED_GRAPH_URI; import static com.atomgraph.core.model.impl.GraphStoreImplTest.dataset; import jakarta.ws.rs.NotFoundException; -import jakarta.ws.rs.client.WebTarget; import jakarta.ws.rs.core.Application; +import java.net.URI; import java.util.UUID; import org.apache.jena.query.Dataset; import org.apache.jena.query.DatasetFactory; @@ -41,7 +41,7 @@ public class GraphStoreClientTest extends JerseyTest { public com.atomgraph.core.Application system; - public WebTarget endpoint; + public URI endpoint; public GraphStoreClient gsc; @BeforeClass @@ -55,8 +55,8 @@ public static void initClass() @Before public void init() { - endpoint = system.getClient().target(getBaseUri().resolve("service")); - gsc = GraphStoreClient.create(new MediaTypes(), endpoint); + endpoint = getBaseUri().resolve("service"); + gsc = GraphStoreClient.create(system.getClient(), new MediaTypes(), endpoint); } protected Dataset getDataset() diff --git a/src/test/java/com/atomgraph/core/io/ModelProviderTest.java b/src/test/java/com/atomgraph/core/io/ModelProviderTest.java index 525f120..a8bfc9d 100644 --- a/src/test/java/com/atomgraph/core/io/ModelProviderTest.java +++ b/src/test/java/com/atomgraph/core/io/ModelProviderTest.java @@ -18,11 +18,8 @@ import com.atomgraph.core.MediaType; import com.atomgraph.core.MediaTypes; import com.atomgraph.core.client.GraphStoreClient; -import static com.atomgraph.core.client.GraphStoreClient.DEFAULT_PARAM_NAME; -import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.core.Application; -import jakarta.ws.rs.core.MultivaluedHashMap; -import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import java.io.ByteArrayInputStream; import java.io.InputStream; @@ -49,14 +46,14 @@ public class ModelProviderTest extends JerseyTest { public com.atomgraph.core.Application system; - public WebTarget endpoint; + public URI endpoint; public GraphStoreClient gsc; @Before public void init() { - endpoint = system.getClient().target(getBaseUri().resolve("service")); - gsc = GraphStoreClient.create(new MediaTypes(), endpoint); + endpoint = getBaseUri().resolve("service"); + gsc = GraphStoreClient.create(system.getClient(), new MediaTypes(), endpoint); } @Override @@ -115,11 +112,8 @@ public void testTurtleRelativeURIsResolvedInWrittenModel() Model modelWithRelativeURIs = ModelFactory.createDefaultModel(). add(ResourceFactory.createResource(relativeUri), FOAF.name, "Smth"); - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(DEFAULT_PARAM_NAME, Boolean.TRUE.toString()); - // needs to use Turtle in order to allow relative URIs - try (Response cr = gsc.post(modelWithRelativeURIs, MediaType.TEXT_TURTLE_TYPE, new jakarta.ws.rs.core.MediaType[]{}, params)) + try (Response cr = gsc.post(null, Entity.entity(modelWithRelativeURIs, MediaType.TEXT_TURTLE_TYPE), new jakarta.ws.rs.core.MediaType[]{})) { URI absoluteUri = getBaseUri().resolve(relativeUri); Model expected = ModelFactory.createDefaultModel(). diff --git a/src/test/java/com/atomgraph/core/model/impl/GraphStoreImplTest.java b/src/test/java/com/atomgraph/core/model/impl/GraphStoreImplTest.java index 4f81c6d..b1ee15f 100644 --- a/src/test/java/com/atomgraph/core/model/impl/GraphStoreImplTest.java +++ b/src/test/java/com/atomgraph/core/model/impl/GraphStoreImplTest.java @@ -18,22 +18,19 @@ import com.atomgraph.core.MediaType; import com.atomgraph.core.MediaTypes; import com.atomgraph.core.client.GraphStoreClient; -import static com.atomgraph.core.client.GraphStoreClient.DEFAULT_PARAM_NAME; -import static com.atomgraph.core.client.GraphStoreClient.GRAPH_PARAM_NAME; import static com.atomgraph.core.model.impl.SPARQLEndpointImplTest.assertIsomorphic; import jakarta.ws.rs.NotFoundException; +import jakarta.ws.rs.client.Entity; import java.util.UUID; -import jakarta.ws.rs.client.WebTarget; import jakarta.ws.rs.core.Application; import jakarta.ws.rs.core.EntityTag; -import jakarta.ws.rs.core.MultivaluedHashMap; -import jakarta.ws.rs.core.MultivaluedMap; import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST; import static jakarta.ws.rs.core.Response.Status.CREATED; import static jakarta.ws.rs.core.Response.Status.NOT_ACCEPTABLE; import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; import static jakarta.ws.rs.core.Response.Status.NO_CONTENT; import static jakarta.ws.rs.core.Response.Status.UNSUPPORTED_MEDIA_TYPE; +import java.net.URI; import java.util.Arrays; import org.apache.jena.query.Dataset; import org.apache.jena.query.DatasetFactory; @@ -59,7 +56,7 @@ public class GraphStoreImplTest extends JerseyTest public static Dataset dataset; public com.atomgraph.core.Application system; - public WebTarget endpoint; + public URI endpoint; public GraphStoreClient gsc; @BeforeClass @@ -73,8 +70,8 @@ public static void initClass() @Before public void init() { - endpoint = system.getClient().target(getBaseUri().resolve("service")); - gsc = GraphStoreClient.create(new MediaTypes(), endpoint); + endpoint = getBaseUri().resolve("service"); + gsc = GraphStoreClient.create(system.getClient(), new MediaTypes(), endpoint); } protected Dataset getDataset() @@ -114,19 +111,13 @@ public void testGetNamedModel() @Test public void testGetNotFoundNamedModel() { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(GRAPH_PARAM_NAME, "http://host/" + UUID.randomUUID().toString()); - - assertEquals(NOT_FOUND.getStatusCode(), gsc.get(gsc.getReadableMediaTypes(Model.class), params).getStatus()); + assertEquals(NOT_FOUND.getStatusCode(), gsc.get(URI.create("http://host/" + UUID.randomUUID().toString())).getStatus()); } @Test public void testGetNotAcceptableType() { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(DEFAULT_PARAM_NAME, Boolean.TRUE.toString()); - - assertEquals(NOT_ACCEPTABLE.getStatusCode(), gsc.get(new jakarta.ws.rs.core.MediaType[]{ MediaType.APPLICATION_SVG_XML_TYPE}, params).getStatus()); + assertEquals(NOT_ACCEPTABLE.getStatusCode(), gsc.get(null, new jakarta.ws.rs.core.MediaType[]{ MediaType.APPLICATION_SVG_XML_TYPE}).getStatus()); } @Test @@ -149,32 +140,37 @@ public void testAddNamedModel() @Test public void testPostEmptyNamedModel() { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(GRAPH_PARAM_NAME, "http://host/" + UUID.randomUUID().toString()); - - assertEquals(NO_CONTENT.getStatusCode(), gsc.post(ModelFactory.createDefaultModel(), MediaType.TEXT_TURTLE_TYPE, new jakarta.ws.rs.core.MediaType[]{}, params).getStatus()); + assertEquals(NO_CONTENT.getStatusCode(), gsc.post(URI.create("http://host/" + UUID.randomUUID().toString()), + Entity.entity(ModelFactory.createDefaultModel(), MediaType.TEXT_TURTLE_TYPE), + new jakarta.ws.rs.core.MediaType[]{}). + getStatus()); } @Test public void testPostNotFoundNamedModel() { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(GRAPH_PARAM_NAME, "http://host/" + UUID.randomUUID().toString()); - - assertEquals(CREATED.getStatusCode(), gsc.post(ModelFactory.createDefaultModel().createResource().addLiteral(ResourceFactory.createProperty("http://prop"), "obj").getModel(), - MediaType.TEXT_TURTLE_TYPE, new jakarta.ws.rs.core.MediaType[]{}, params).getStatus()); + assertEquals(CREATED.getStatusCode(), gsc.post(URI.create("http://host/" + UUID.randomUUID().toString()), + Entity.entity(ModelFactory.createDefaultModel().createResource().addLiteral(ResourceFactory.createProperty("http://prop"), "obj").getModel(), + MediaType.TEXT_TURTLE_TYPE), + new jakarta.ws.rs.core.MediaType[]{}). + getStatus()); } @Test public void testPostUnsupportedAddType() { - assertEquals(UNSUPPORTED_MEDIA_TYPE.getStatusCode(), gsc.post("BAD RDF", jakarta.ws.rs.core.MediaType.TEXT_XML_TYPE, new jakarta.ws.rs.core.MediaType[]{}).getStatus()); + assertEquals(UNSUPPORTED_MEDIA_TYPE.getStatusCode(), + gsc.post(URI.create(NAMED_GRAPH_URI), Entity.entity("BAD RDF", jakarta.ws.rs.core.MediaType.TEXT_XML_TYPE), + new jakarta.ws.rs.core.MediaType[]{}).getStatus()); } @Test public void testInvalidTurtlePost() { - assertEquals(BAD_REQUEST.getStatusCode(), gsc.post("BAD TURTLE", com.atomgraph.core.MediaType.TEXT_TURTLE_TYPE, new MediaType[]{}).getStatus()); + assertEquals(BAD_REQUEST.getStatusCode(), gsc.post(URI.create(NAMED_GRAPH_URI), + Entity.entity("BAD TURTLE", com.atomgraph.core.MediaType.TEXT_TURTLE_TYPE), + new MediaType[]{}). + getStatus()); } @Test @@ -196,22 +192,28 @@ public void testPutNamedModel() @Test public void testPutNotFoundNamedModel() { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(GRAPH_PARAM_NAME, "http://host/" + UUID.randomUUID().toString()); - - assertEquals(CREATED.getStatusCode(), gsc.put(ModelFactory.createDefaultModel(), MediaType.TEXT_TURTLE_TYPE, new jakarta.ws.rs.core.MediaType[]{}, params).getStatus()); + assertEquals(CREATED.getStatusCode(), gsc.put(URI.create("http://host/" + UUID.randomUUID().toString()), + Entity.entity(ModelFactory.createDefaultModel(), MediaType.TEXT_TURTLE_TYPE), + new jakarta.ws.rs.core.MediaType[]{}). + getStatus()); } @Test public void testNotUnsupportedPutType() { - assertEquals(UNSUPPORTED_MEDIA_TYPE.getStatusCode(), gsc.put("BAD RDF", jakarta.ws.rs.core.MediaType.TEXT_XML_TYPE, new jakarta.ws.rs.core.MediaType[]{}).getStatus()); + assertEquals(UNSUPPORTED_MEDIA_TYPE.getStatusCode(), gsc.put(URI.create(NAMED_GRAPH_URI), + Entity.entity("BAD RDF", jakarta.ws.rs.core.MediaType.TEXT_XML_TYPE), + new jakarta.ws.rs.core.MediaType[]{}). + getStatus()); } @Test public void testInvalidTurtlePut() { - assertEquals(BAD_REQUEST.getStatusCode(), gsc.put("BAD TURTLE", com.atomgraph.core.MediaType.TEXT_TURTLE_TYPE, new MediaType[]{}).getStatus()); + assertEquals(BAD_REQUEST.getStatusCode(), gsc.put(URI.create(NAMED_GRAPH_URI), + Entity.entity("BAD TURTLE", com.atomgraph.core.MediaType.TEXT_TURTLE_TYPE), + new MediaType[]{}). + getStatus()); } @Test @@ -233,23 +235,21 @@ public void testDeleteNamedModel() @Test public void testDeleteNotFoundNamedModel() { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(GRAPH_PARAM_NAME, "http://host/" + UUID.randomUUID().toString()); - - assertEquals(NOT_FOUND.getStatusCode(), gsc.delete(gsc.getReadableMediaTypes(Model.class), params).getStatus()); + assertEquals(NOT_FOUND.getStatusCode(), gsc.delete(URI.create("http://host/" + UUID.randomUUID().toString()), + gsc.getReadableMediaTypes(Model.class)). + getStatus()); } @Test public void testDifferentMediaTypesDifferentETags() { - MultivaluedMap params = new MultivaluedHashMap(); - params.putSingle(GRAPH_PARAM_NAME, NAMED_GRAPH_URI); - - jakarta.ws.rs.core.Response nTriplesResp = gsc.get(Arrays.asList(MediaType.APPLICATION_NTRIPLES_TYPE).toArray(MediaType[]::new), params); + jakarta.ws.rs.core.Response nTriplesResp = gsc.get(URI.create(NAMED_GRAPH_URI), + Arrays.asList(MediaType.APPLICATION_NTRIPLES_TYPE).toArray(MediaType[]::new)); EntityTag nTriplesETag = nTriplesResp.getEntityTag(); assertEquals(nTriplesResp.getLanguage(), null); - jakarta.ws.rs.core.Response rdfXmlResp = gsc.get(Arrays.asList(MediaType.APPLICATION_RDF_XML_TYPE).toArray(MediaType[]::new), params); + jakarta.ws.rs.core.Response rdfXmlResp = gsc.get(URI.create(NAMED_GRAPH_URI), + Arrays.asList(MediaType.APPLICATION_RDF_XML_TYPE).toArray(MediaType[]::new)); EntityTag rdfXmlETag = rdfXmlResp.getEntityTag(); assertEquals(rdfXmlResp.getLanguage(), null); diff --git a/src/test/java/com/atomgraph/core/model/impl/LocaleEntityTagTest.java b/src/test/java/com/atomgraph/core/model/impl/LocaleEntityTagTest.java index 16f9345..5fc827b 100644 --- a/src/test/java/com/atomgraph/core/model/impl/LocaleEntityTagTest.java +++ b/src/test/java/com/atomgraph/core/model/impl/LocaleEntityTagTest.java @@ -16,7 +16,7 @@ package com.atomgraph.core.model.impl; import com.atomgraph.core.MediaTypes; -import com.atomgraph.core.client.LinkedDataClient; +import com.atomgraph.core.client.GraphStoreClient; import com.atomgraph.core.model.Service; import jakarta.inject.Inject; import jakarta.ws.rs.GET; @@ -61,7 +61,7 @@ public class LocaleEntityTagTest extends JerseyTest public static Dataset dataset; private com.atomgraph.core.Application system; - private LinkedDataClient ldc; + private GraphStoreClient ldc; private URI uri, uriLang; @BeforeClass @@ -79,7 +79,7 @@ public void init() { uri = getBaseUri().resolve(RELATIVE_PATH); uriLang = getBaseUri().resolve(RELATIVE_PATH_LANG); - ldc = LinkedDataClient.create(system.getClient(), new MediaTypes()); + ldc = GraphStoreClient.create(system.getClient(), new MediaTypes()); } @Path(RELATIVE_PATH) @@ -204,7 +204,7 @@ protected URI getURI() return uri; } - protected LinkedDataClient getLinkedDataClient() + protected GraphStoreClient getLinkedDataClient() { return ldc; } diff --git a/src/test/java/com/atomgraph/core/model/impl/QueriedResourceBaseTest.java b/src/test/java/com/atomgraph/core/model/impl/QueriedResourceBaseTest.java index d942089..760b99f 100644 --- a/src/test/java/com/atomgraph/core/model/impl/QueriedResourceBaseTest.java +++ b/src/test/java/com/atomgraph/core/model/impl/QueriedResourceBaseTest.java @@ -16,11 +16,12 @@ package com.atomgraph.core.model.impl; import com.atomgraph.core.MediaTypes; -import com.atomgraph.core.client.LinkedDataClient; +import com.atomgraph.core.client.GraphStoreClient; import com.atomgraph.core.model.Service; import java.net.URI; import jakarta.inject.Inject; import jakarta.ws.rs.Path; +import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.core.Application; import jakarta.ws.rs.core.Context; import jakarta.ws.rs.core.EntityTag; @@ -60,7 +61,7 @@ public class QueriedResourceBaseTest extends JerseyTest public static Dataset dataset; public com.atomgraph.core.Application system; - public LinkedDataClient ldc; + public GraphStoreClient ldc; public URI uri; @BeforeClass @@ -74,7 +75,7 @@ public static void initClass() public void init() { uri = getBaseUri().resolve(RELATIVE_PATH); - ldc = LinkedDataClient.create(system.getClient(), new MediaTypes()); + ldc = GraphStoreClient.create(system.getClient(), new MediaTypes()); } @Path(RELATIVE_PATH) @@ -129,19 +130,19 @@ public void testNotFound() @Test public void testNotUnsupportedPostType() { - assertEquals(UNSUPPORTED_MEDIA_TYPE.getStatusCode(), ldc.post(uri, ldc.getReadableMediaTypes(Model.class), "BAD RDF", MediaType.TEXT_XML_TYPE).getStatus()); + assertEquals(UNSUPPORTED_MEDIA_TYPE.getStatusCode(), ldc.post(uri, Entity.entity("BAD RDF", MediaType.TEXT_XML_TYPE), ldc.getReadableMediaTypes(Model.class)).getStatus()); } @Test public void testInvalidTurtlePost() { - assertEquals(BAD_REQUEST.getStatusCode(), ldc.post(uri, ldc.getReadableMediaTypes(Model.class), "BAD TURTLE", com.atomgraph.core.MediaType.TEXT_TURTLE_TYPE).getStatus()); + assertEquals(BAD_REQUEST.getStatusCode(), ldc.post(uri, Entity.entity("BAD TURTLE", com.atomgraph.core.MediaType.TEXT_TURTLE_TYPE), ldc.getReadableMediaTypes(Model.class)).getStatus()); } @Test public void testInvalidTurtlePut() { - assertEquals(BAD_REQUEST.getStatusCode(), ldc.put(uri, ldc.getReadableMediaTypes(Model.class), "BAD TURTLE", com.atomgraph.core.MediaType.TEXT_TURTLE_TYPE).getStatus()); + assertEquals(BAD_REQUEST.getStatusCode(), ldc.put(uri, Entity.entity("BAD TURTLE", com.atomgraph.core.MediaType.TEXT_TURTLE_TYPE), ldc.getReadableMediaTypes(Model.class)).getStatus()); } public static void assertIsomorphic(Model wanted, Model got) From 176fd8e5e6f4a7965964fa8005a78732e951e4f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martynas=20Jusevi=C4=8Dius?= Date: Sun, 28 Dec 2025 22:08:54 +0100 Subject: [PATCH 4/9] SNAPSHOT bump --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a25ec59..bf3494c 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ com.atomgraph core - 4.0.11-SNAPSHOT + 4.0.12-SNAPSHOT ${packaging.type} AtomGraph Core From 4631b01ba3242b5d52dff50a36c8ead4628584b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martynas=20Jusevi=C4=8Dius?= Date: Sun, 28 Dec 2025 22:15:27 +0100 Subject: [PATCH 5/9] `snapshotRepository` fix --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index bf3494c..2542eb0 100644 --- a/pom.xml +++ b/pom.xml @@ -199,8 +199,8 @@ - ossrh - https://oss.sonatype.org/content/repositories/snapshots + central-portal-snapshots + https://central.sonatype.com/repository/maven-snapshots/ From e13c4e9c5d4bbc501a34ac4493565e1289525635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martynas=20Jusevi=C4=8Dius?= Date: Tue, 30 Dec 2025 13:24:51 +0100 Subject: [PATCH 6/9] New `GraphStoreClient` helper methods --- .../atomgraph/core/client/GraphStoreClient.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/atomgraph/core/client/GraphStoreClient.java b/src/main/java/com/atomgraph/core/client/GraphStoreClient.java index 0eafbb4..e48053b 100644 --- a/src/main/java/com/atomgraph/core/client/GraphStoreClient.java +++ b/src/main/java/com/atomgraph/core/client/GraphStoreClient.java @@ -64,6 +64,11 @@ protected GraphStoreClient(Client client, MediaTypes mediaTypes, URI endpoint) this.endpoint = endpoint; } + protected GraphStoreClient(Client client, MediaTypes mediaTypes) + { + this(client, mediaTypes, null); + } + public static GraphStoreClient create(Client client, MediaTypes mediaTypes, URI endpoint) { return new GraphStoreClient(client, mediaTypes, endpoint); @@ -71,7 +76,7 @@ public static GraphStoreClient create(Client client, MediaTypes mediaTypes, URI public static GraphStoreClient create(Client client, MediaTypes mediaTypes) { - return new GraphStoreClient(client, mediaTypes, null); + return new GraphStoreClient(client, mediaTypes); } /** @@ -237,6 +242,11 @@ public Model getModel(String uri) } } + public Response post(URI uri, Model model) + { + return post(uri, Entity.entity(model, getDefaultMediaType()), new jakarta.ws.rs.core.MediaType[]{}, new MultivaluedHashMap()); + } + public Response post(URI uri, Entity entity) { return post(uri, entity, new jakarta.ws.rs.core.MediaType[]{}, new MultivaluedHashMap()); @@ -262,6 +272,11 @@ public void add(String uri, Model model) } } + public Response put(URI uri, Model model) + { + return put(uri, Entity.entity(model, getDefaultMediaType()), getReadableMediaTypes(Model.class), new MultivaluedHashMap()); + } + public Response put(URI uri, Entity entity) { return put(uri, entity, getReadableMediaTypes(Model.class), new MultivaluedHashMap()); From b0067d42186f85d5babebc1ce79640eac664fded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martynas=20Jusevi=C4=8Dius?= Date: Tue, 30 Dec 2025 14:06:29 +0100 Subject: [PATCH 7/9] Renamed fields --- .../core/util/jena/DataManagerImpl.java | 20 +++++++++---------- .../core/model/impl/LocaleEntityTagTest.java | 12 +++++------ .../model/impl/QueriedResourceBaseTest.java | 20 +++++++++---------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/atomgraph/core/util/jena/DataManagerImpl.java b/src/main/java/com/atomgraph/core/util/jena/DataManagerImpl.java index 78cbcaa..9d7c91b 100644 --- a/src/main/java/com/atomgraph/core/util/jena/DataManagerImpl.java +++ b/src/main/java/com/atomgraph/core/util/jena/DataManagerImpl.java @@ -45,7 +45,7 @@ public class DataManagerImpl extends FileManagerImpl implements DataManager private static final Logger log = LoggerFactory.getLogger(DataManagerImpl.class); private final boolean preemptiveAuth; - private final GraphStoreClient ldc; + private final GraphStoreClient gsc; private boolean cacheModelLoads; private final Map modelCache; @@ -54,12 +54,12 @@ public class DataManagerImpl extends FileManagerImpl implements DataManager * * @param mapper location mapper * @param modelCache model cache map - * @param ldc Linked Data client + * @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 ldc, + GraphStoreClient gsc, boolean cacheModelLoads, boolean preemptiveAuth) { super(mapper); @@ -67,7 +67,7 @@ public DataManagerImpl(LocationMapper mapper, Map modelCache, this.modelCache = modelCache; this.cacheModelLoads = cacheModelLoads; this.preemptiveAuth = preemptiveAuth; - this.ldc = ldc; + this.gsc = gsc; addLocatorFile() ; addLocatorURL() ; @@ -84,7 +84,7 @@ public URI getEndpoint(URI endpointURI) @Override public Response get(String uri, jakarta.ws.rs.core.MediaType[] acceptedTypes) { - return getLinkedDataClient().get(getEndpoint(URI.create(uri)), acceptedTypes); + return getGraphStoreClient().get(getEndpoint(URI.create(uri)), acceptedTypes); } @Override @@ -96,7 +96,7 @@ public Model loadModel(String uri) String mappedURI = mapURI(uri); if (mappedURI.startsWith("http") || mappedURI.startsWith("https")) { - Model model = getLinkedDataClient().getModel(getEndpoint(URI.create(uri)).toString()); + Model model = getGraphStoreClient().getModel(getEndpoint(URI.create(uri)).toString()); if (isCachingModels()) addCacheModel(uri, model) ; @@ -128,7 +128,7 @@ public Model readModel(Model model, String uri) { String mappedURI = mapURI(uri); if (mappedURI.startsWith("http") || mappedURI.startsWith("https")) - return model.add(getLinkedDataClient().getModel(getEndpoint(URI.create(uri)).toString())); + return model.add(getGraphStoreClient().getModel(getEndpoint(URI.create(uri)).toString())); return super.readModel(model, uri); } @@ -235,13 +235,13 @@ public boolean usePreemptiveAuth() } /** - * Returns Linked Data client. + * Returns Graph Store client. * * @return client instance */ - public GraphStoreClient getLinkedDataClient() + public GraphStoreClient getGraphStoreClient() { - return ldc; + return gsc; } } \ No newline at end of file diff --git a/src/test/java/com/atomgraph/core/model/impl/LocaleEntityTagTest.java b/src/test/java/com/atomgraph/core/model/impl/LocaleEntityTagTest.java index 5fc827b..7c89e0d 100644 --- a/src/test/java/com/atomgraph/core/model/impl/LocaleEntityTagTest.java +++ b/src/test/java/com/atomgraph/core/model/impl/LocaleEntityTagTest.java @@ -61,7 +61,7 @@ public class LocaleEntityTagTest extends JerseyTest public static Dataset dataset; private com.atomgraph.core.Application system; - private GraphStoreClient ldc; + private GraphStoreClient gsc; private URI uri, uriLang; @BeforeClass @@ -79,7 +79,7 @@ public void init() { uri = getBaseUri().resolve(RELATIVE_PATH); uriLang = getBaseUri().resolve(RELATIVE_PATH_LANG); - ldc = GraphStoreClient.create(system.getClient(), new MediaTypes()); + gsc = GraphStoreClient.create(system.getClient(), new MediaTypes()); } @Path(RELATIVE_PATH) @@ -164,14 +164,14 @@ public void testLocales() { Locale locale = Locale.ENGLISH; - jakarta.ws.rs.core.Response resp = ldc.getClient(). + jakarta.ws.rs.core.Response resp = gsc.getClient(). target(uri). request(com.atomgraph.core.MediaType.APPLICATION_RDF_XML_TYPE). get(); assertEquals(200, resp.getStatus()); assertEquals(null, resp.getLanguage()); - jakarta.ws.rs.core.Response langSpecificResp = ldc.getClient(). + jakarta.ws.rs.core.Response langSpecificResp = gsc.getClient(). target(uriLang). request(com.atomgraph.core.MediaType.APPLICATION_RDF_XML_TYPE). // RDF/XML media type marked as language significant on this endpoint! header(HttpHeaders.ACCEPT_LANGUAGE, locale.getLanguage()). @@ -204,9 +204,9 @@ protected URI getURI() return uri; } - protected GraphStoreClient getLinkedDataClient() + protected GraphStoreClient getGraphStoreClient() { - return ldc; + return gsc; } } diff --git a/src/test/java/com/atomgraph/core/model/impl/QueriedResourceBaseTest.java b/src/test/java/com/atomgraph/core/model/impl/QueriedResourceBaseTest.java index 760b99f..b483e9c 100644 --- a/src/test/java/com/atomgraph/core/model/impl/QueriedResourceBaseTest.java +++ b/src/test/java/com/atomgraph/core/model/impl/QueriedResourceBaseTest.java @@ -61,7 +61,7 @@ public class QueriedResourceBaseTest extends JerseyTest public static Dataset dataset; public com.atomgraph.core.Application system; - public GraphStoreClient ldc; + public GraphStoreClient gsc; public URI uri; @BeforeClass @@ -75,7 +75,7 @@ public static void initClass() public void init() { uri = getBaseUri().resolve(RELATIVE_PATH); - ldc = GraphStoreClient.create(system.getClient(), new MediaTypes()); + gsc = GraphStoreClient.create(system.getClient(), new MediaTypes()); } @Path(RELATIVE_PATH) @@ -111,38 +111,38 @@ protected Application configure() @Test public void testGet() { - assertIsomorphic(getDataset().getDefaultModel(), ldc.getModel(uri.toString())); + assertIsomorphic(getDataset().getDefaultModel(), gsc.getModel(uri.toString())); } @Test public void testNotAcceptableGetType() { - assertEquals(NOT_ACCEPTABLE.getStatusCode(), ldc.get(uri, ldc.getReadableMediaTypes(ResultSet.class)).getStatus()); + assertEquals(NOT_ACCEPTABLE.getStatusCode(), gsc.get(uri, gsc.getReadableMediaTypes(ResultSet.class)).getStatus()); } @Test public void testNotFound() { URI nonExisting = getBaseUri().resolve("non-existing"); - assertEquals(NOT_FOUND.getStatusCode(), ldc.get(nonExisting, ldc.getReadableMediaTypes(Model.class)).getStatus()); + assertEquals(NOT_FOUND.getStatusCode(), gsc.get(nonExisting, gsc.getReadableMediaTypes(Model.class)).getStatus()); } @Test public void testNotUnsupportedPostType() { - assertEquals(UNSUPPORTED_MEDIA_TYPE.getStatusCode(), ldc.post(uri, Entity.entity("BAD RDF", MediaType.TEXT_XML_TYPE), ldc.getReadableMediaTypes(Model.class)).getStatus()); + assertEquals(UNSUPPORTED_MEDIA_TYPE.getStatusCode(), gsc.post(uri, Entity.entity("BAD RDF", MediaType.TEXT_XML_TYPE), gsc.getReadableMediaTypes(Model.class)).getStatus()); } @Test public void testInvalidTurtlePost() { - assertEquals(BAD_REQUEST.getStatusCode(), ldc.post(uri, Entity.entity("BAD TURTLE", com.atomgraph.core.MediaType.TEXT_TURTLE_TYPE), ldc.getReadableMediaTypes(Model.class)).getStatus()); + assertEquals(BAD_REQUEST.getStatusCode(), gsc.post(uri, Entity.entity("BAD TURTLE", com.atomgraph.core.MediaType.TEXT_TURTLE_TYPE), gsc.getReadableMediaTypes(Model.class)).getStatus()); } @Test public void testInvalidTurtlePut() { - assertEquals(BAD_REQUEST.getStatusCode(), ldc.put(uri, Entity.entity("BAD TURTLE", com.atomgraph.core.MediaType.TEXT_TURTLE_TYPE), ldc.getReadableMediaTypes(Model.class)).getStatus()); + assertEquals(BAD_REQUEST.getStatusCode(), gsc.put(uri, Entity.entity("BAD TURTLE", com.atomgraph.core.MediaType.TEXT_TURTLE_TYPE), gsc.getReadableMediaTypes(Model.class)).getStatus()); } public static void assertIsomorphic(Model wanted, Model got) @@ -154,11 +154,11 @@ public static void assertIsomorphic(Model wanted, Model got) @Test public void testDifferentMediaTypesDifferentETags() { - jakarta.ws.rs.core.Response nTriplesResp = ldc.get(uri, Arrays.asList(com.atomgraph.core.MediaType.APPLICATION_NTRIPLES_TYPE).toArray(com.atomgraph.core.MediaType[]::new)); + jakarta.ws.rs.core.Response nTriplesResp = gsc.get(uri, Arrays.asList(com.atomgraph.core.MediaType.APPLICATION_NTRIPLES_TYPE).toArray(com.atomgraph.core.MediaType[]::new)); EntityTag nTriplesETag = nTriplesResp.getEntityTag(); assertEquals(nTriplesResp.getLanguage(), null); - jakarta.ws.rs.core.Response rdfXmlResp = ldc.get(uri, Arrays.asList(com.atomgraph.core.MediaType.APPLICATION_RDF_XML_TYPE).toArray(com.atomgraph.core.MediaType[]::new)); + jakarta.ws.rs.core.Response rdfXmlResp = gsc.get(uri, Arrays.asList(com.atomgraph.core.MediaType.APPLICATION_RDF_XML_TYPE).toArray(com.atomgraph.core.MediaType[]::new)); EntityTag rdfXmlETag = rdfXmlResp.getEntityTag(); assertEquals(rdfXmlResp.getLanguage(), null); From 66650717403cbe9ce263377d95b8459b2f936b88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martynas=20Jusevi=C4=8Dius?= Date: Thu, 1 Jan 2026 15:29:00 +0100 Subject: [PATCH 8/9] `GraphStoreClient` fixes --- pom.xml | 2 +- .../core/client/GraphStoreClient.java | 29 ++++--------------- 2 files changed, 6 insertions(+), 25 deletions(-) diff --git a/pom.xml b/pom.xml index 2542eb0..c771fee 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ com.atomgraph core - 4.0.12-SNAPSHOT + 4.0.14-SNAPSHOT ${packaging.type} AtomGraph Core diff --git a/src/main/java/com/atomgraph/core/client/GraphStoreClient.java b/src/main/java/com/atomgraph/core/client/GraphStoreClient.java index e48053b..73d0744 100644 --- a/src/main/java/com/atomgraph/core/client/GraphStoreClient.java +++ b/src/main/java/com/atomgraph/core/client/GraphStoreClient.java @@ -122,9 +122,6 @@ public Model getModel() { try (Response cr = get(null)) { - // some endpoints might include response body which will not cause NotFoundException in Jersey - if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); - return cr.readEntity(Model.class); } } @@ -132,31 +129,19 @@ public Model getModel() @Override public void add(Model model) { - try (Response cr = post(null, Entity.entity(model, getDefaultMediaType()), new jakarta.ws.rs.core.MediaType[]{})) - { - // some endpoints might include response body which will not cause NotFoundException in Jersey - if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); - } + post(null, Entity.entity(model, getDefaultMediaType()), new jakarta.ws.rs.core.MediaType[]{}).close(); } @Override public void deleteDefault() { - try (Response cr = delete(null)) - { - // some endpoints might include response body which will not cause NotFoundException in Jersey - if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); - } + delete(null).close(); } @Override public void putModel(Model model) { - try (Response cr = put(null, Entity.entity(model, getDefaultMediaType()), new jakarta.ws.rs.core.MediaType[]{})) - { - // some endpoints might include response body which will not cause NotFoundException in Jersey - if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); - } + put(null, Entity.entity(model, getDefaultMediaType()), new jakarta.ws.rs.core.MediaType[]{}).close(); } protected WebTarget getWebTarget(URI uri) @@ -190,7 +175,7 @@ protected WebTarget getWebTarget(URI uri) public Response head(URI uri) { - return head(uri, null); + return head(uri, getReadableMediaTypes(Model.class)); } public Response head(URI uri, jakarta.ws.rs.core.MediaType[] acceptedTypes) @@ -295,11 +280,7 @@ public Response put(URI uri, Entity entity, jakarta.ws.rs.core.MediaType[] accep @Override public void putModel(String uri, Model model) { - try (Response cr = put(URI.create(uri), Entity.entity(model, getDefaultMediaType()))) - { - // some endpoints might include response body which will not cause NotFoundException in Jersey - if (cr.getStatus() == Status.NOT_FOUND.getStatusCode()) throw new NotFoundException(); - } + put(URI.create(uri), Entity.entity(model, getDefaultMediaType())).close(); } public Response delete(URI uri) From 8cbe62213c9a4f444146d6f28592b30fae3a7588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martynas=20Jusevi=C4=8Dius?= Date: Thu, 1 Jan 2026 17:30:32 +0100 Subject: [PATCH 9/9] Response closure fixes Use try-with-resources consistently --- .../core/client/GraphStoreClient.java | 20 +++++++++++++++---- .../core/client/QuadStoreClient.java | 20 +++++++++++++++---- .../atomgraph/core/client/SPARQLClient.java | 7 +++++-- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/atomgraph/core/client/GraphStoreClient.java b/src/main/java/com/atomgraph/core/client/GraphStoreClient.java index 73d0744..1886119 100644 --- a/src/main/java/com/atomgraph/core/client/GraphStoreClient.java +++ b/src/main/java/com/atomgraph/core/client/GraphStoreClient.java @@ -129,19 +129,28 @@ public Model getModel() @Override public void add(Model model) { - post(null, Entity.entity(model, getDefaultMediaType()), new jakarta.ws.rs.core.MediaType[]{}).close(); + try (Response response = post(null, Entity.entity(model, getDefaultMediaType()), new jakarta.ws.rs.core.MediaType[]{})) + { + // Response automatically closed by try-with-resources + } } @Override public void deleteDefault() { - delete(null).close(); + try (Response response = delete(null)) + { + // Response automatically closed by try-with-resources + } } @Override public void putModel(Model model) { - put(null, Entity.entity(model, getDefaultMediaType()), new jakarta.ws.rs.core.MediaType[]{}).close(); + try (Response response = put(null, Entity.entity(model, getDefaultMediaType()), new jakarta.ws.rs.core.MediaType[]{})) + { + // Response automatically closed by try-with-resources + } } protected WebTarget getWebTarget(URI uri) @@ -280,7 +289,10 @@ public Response put(URI uri, Entity entity, jakarta.ws.rs.core.MediaType[] accep @Override public void putModel(String uri, Model model) { - put(URI.create(uri), Entity.entity(model, getDefaultMediaType())).close(); + try (Response response = put(URI.create(uri), Entity.entity(model, getDefaultMediaType()))) + { + // Response automatically closed by try-with-resources + } } public Response delete(URI uri) diff --git a/src/main/java/com/atomgraph/core/client/QuadStoreClient.java b/src/main/java/com/atomgraph/core/client/QuadStoreClient.java index d1fe37c..1a8d122 100644 --- a/src/main/java/com/atomgraph/core/client/QuadStoreClient.java +++ b/src/main/java/com/atomgraph/core/client/QuadStoreClient.java @@ -95,25 +95,37 @@ public Dataset get() @Override public void add(Dataset dataset) { - post(dataset, getDefaultMediaType(), new MediaType[]{}).close(); + try (Response response = post(dataset, getDefaultMediaType(), new MediaType[]{})) + { + // Response automatically closed by try-with-resources + } } @Override public void replace(Dataset dataset) { - put(dataset, getDefaultMediaType(), new MediaType[]{}).close(); + try (Response response = put(dataset, getDefaultMediaType(), new MediaType[]{})) + { + // Response automatically closed by try-with-resources + } } @Override public void delete() { - delete(new MediaType[]{}).close(); + try (Response response = delete(new MediaType[]{})) + { + // Response automatically closed by try-with-resources + } } @Override public void patch(Dataset dataset) { - patch(dataset, new MultivaluedHashMap()).close(); + try (Response response = patch(dataset, new MultivaluedHashMap())) + { + // Response automatically closed by try-with-resources + } } public Response patch(Dataset dataset, MultivaluedMap params) diff --git a/src/main/java/com/atomgraph/core/client/SPARQLClient.java b/src/main/java/com/atomgraph/core/client/SPARQLClient.java index 7297769..ec8f340 100644 --- a/src/main/java/com/atomgraph/core/client/SPARQLClient.java +++ b/src/main/java/com/atomgraph/core/client/SPARQLClient.java @@ -197,8 +197,11 @@ public void update(UpdateRequest updateRequest, MultivaluedMap p MultivaluedMap formData = new MultivaluedHashMap(); if (params != null) formData.putAll(params); formData.putSingle(UPDATE_PARAM_NAME, updateRequest.toString()); - - post(formData, MediaType.APPLICATION_FORM_URLENCODED_TYPE, new MediaType[]{}, null).close(); + + try (Response response = post(formData, MediaType.APPLICATION_FORM_URLENCODED_TYPE, new MediaType[]{}, null)) + { + // Response automatically closed by try-with-resources + } } public int getMaxGetRequestSize()