MARMOTTA-440: align implementation with current w3c working draft
Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/bb132089 Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/bb132089 Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/bb132089 Branch: refs/heads/develop Commit: bb13208947e6ec1b05a3a9eddcb5c3a617041afc Parents: 3319435 Author: Jakob Frank <[email protected]> Authored: Tue Mar 11 11:48:31 2014 +0100 Committer: Jakob Frank <[email protected]> Committed: Tue Mar 11 11:56:48 2014 +0100 ---------------------------------------------------------------------- .../apache/marmotta/commons/vocabulary/LDP.java | 5 ++- .../marmotta/platform/ldp/api/LdpService.java | 4 ++ .../platform/ldp/services/LdpServiceImpl.java | 29 +++++++++++- .../platform/ldp/webservices/LdpWebService.java | 46 ++++++++++---------- .../ldp/webservices/LdpWebServiceTest.java | 6 +-- 5 files changed, 60 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/marmotta/blob/bb132089/commons/marmotta-sesame-tools/marmotta-model-vocabs/src/main/java/org/apache/marmotta/commons/vocabulary/LDP.java ---------------------------------------------------------------------- diff --git a/commons/marmotta-sesame-tools/marmotta-model-vocabs/src/main/java/org/apache/marmotta/commons/vocabulary/LDP.java b/commons/marmotta-sesame-tools/marmotta-model-vocabs/src/main/java/org/apache/marmotta/commons/vocabulary/LDP.java index 967d1c9..7357b96 100644 --- a/commons/marmotta-sesame-tools/marmotta-model-vocabs/src/main/java/org/apache/marmotta/commons/vocabulary/LDP.java +++ b/commons/marmotta-sesame-tools/marmotta-model-vocabs/src/main/java/org/apache/marmotta/commons/vocabulary/LDP.java @@ -80,8 +80,9 @@ public class LDP { /** * A HTTP-addressable resource with a RDF Source representation. + * FIXME: Not yet part of the vocab, but used in the spec. (2014-03-11) */ - public static final URI RdfResource; + public static final URI RDFSource; /** * A HTTP-addressable resource with a Non-RDF Source representation. @@ -132,7 +133,7 @@ public class LDP { Container = factory.createURI(LDP.NAMESPACE, "Container"); Page = factory.createURI(LDP.NAMESPACE, "Page"); Resource = factory.createURI(LDP.NAMESPACE, "Resource"); - RdfResource = factory.createURI(LDP.NAMESPACE, "RdfResource"); //TODO: missing term in the vocab + RDFSource = factory.createURI(LDP.NAMESPACE, "RDFSource"); //TODO: missing term in the vocab NonRdfResource = factory.createURI(LDP.NAMESPACE, "NonRdfResource"); //TODO: missing term in the vocab contains = factory.createURI(LDP.NAMESPACE, "contains"); containerSortPredicates = factory.createURI(LDP.NAMESPACE, "containerSortPredicates"); http://git-wip-us.apache.org/repos/asf/marmotta/blob/bb132089/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/api/LdpService.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/api/LdpService.java b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/api/LdpService.java index e099bb6..f998028 100644 --- a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/api/LdpService.java +++ b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/api/LdpService.java @@ -110,4 +110,8 @@ public interface LdpService { String getMimeType(RepositoryConnection connection, String resource) throws RepositoryException; String getMimeType(RepositoryConnection connection, URI uri) throws RepositoryException; + + URI getRdfSourceForNonRdfSource(RepositoryConnection connection, URI uri) throws RepositoryException; + + URI getRdfSourceForNonRdfSource(RepositoryConnection connection, String resource) throws RepositoryException; } http://git-wip-us.apache.org/repos/asf/marmotta/blob/bb132089/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpServiceImpl.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpServiceImpl.java b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpServiceImpl.java index 1d2ce22..4818d19 100644 --- a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpServiceImpl.java +++ b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpServiceImpl.java @@ -111,6 +111,33 @@ public class LdpServiceImpl implements LdpService { } @Override + public URI getRdfSourceForNonRdfSource(final RepositoryConnection connection, URI uri) throws RepositoryException { + // FIXME: someone should double check this (jakob) + final FilterIteration<Statement, RepositoryException> it = + new FilterIteration<Statement, RepositoryException>(connection.getStatements(uri, DCTERMS.isFormatOf, null, true, ldpContext)) { + @Override + protected boolean accept(Statement statement) throws RepositoryException { + return statement.getObject() instanceof URI + && connection.hasStatement((URI) statement.getObject(), RDF.TYPE, LDP.RDFSource, true, ldpContext); + } + }; + try { + if (it.hasNext()) { + return (URI) it.next().getObject(); + } else { + return null; + } + }finally { + it.close(); + } + } + + @Override + public URI getRdfSourceForNonRdfSource(RepositoryConnection connection, String resource) throws RepositoryException { + return getRdfSourceForNonRdfSource(connection, buildURI(resource)); + } + + @Override public void exportResource(RepositoryConnection connection, String resource, OutputStream output, RDFFormat format) throws RepositoryException, RDFHandlerException { exportResource(connection, buildURI(resource), output, format); } @@ -189,7 +216,7 @@ public class LdpServiceImpl implements LdpService { connection.add(container, DCTERMS.modified, now, ldpContext); connection.add(resource, RDF.TYPE, LDP.Resource, ldpContext); - connection.add(resource, RDF.TYPE, LDP.RdfResource, ldpContext); + connection.add(resource, RDF.TYPE, LDP.RDFSource, ldpContext); connection.add(resource, DCTERMS.created, now, ldpContext); connection.add(resource, DCTERMS.modified, now, ldpContext); http://git-wip-us.apache.org/repos/asf/marmotta/blob/bb132089/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/webservices/LdpWebService.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/webservices/LdpWebService.java b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/webservices/LdpWebService.java index 88d5a54..c4f68d3 100644 --- a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/webservices/LdpWebService.java +++ b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/webservices/LdpWebService.java @@ -45,14 +45,12 @@ import javax.ws.rs.core.*; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.lang.annotation.Annotation; -import java.util.*; +import java.util.List; +import java.util.UUID; /** * Linked Data Platform web services. * - * FIXME: Try using less transactions, i.e. use a single RepositoryConnection per request - * * @see <a href="http://www.w3.org/TR/ldp/">http://www.w3.org/TR/ldp/</a> * * @author Sergio Fernández @@ -78,6 +76,7 @@ public class LdpWebService { @PostConstruct protected void initialize() { // TODO: basic initialisation + log.info("Starting up LDP WebService Endpoint"); } @GET @@ -106,15 +105,14 @@ public class LdpWebService { conn.rollback(); return resp; } else { - log.trace("{} hasType, continuing", resource); + log.trace("{} exists, continuing", resource); } - // TODO: Maybe this is a LDP-BR? // TODO: Proper content negotiation final RDFFormat format = Rio.getWriterFormatForMIMEType(type.toString()); if (format == null) { - log.warn("GET to <{}> with non-RDF format {}, so looking for a LDP-BR", resource, type); + log.debug("GET to <{}> with non-RDF format {}, so looking for a LDP-BR", resource, type); final StreamingOutput entity = new StreamingOutput() { @Override public void write(OutputStream out) throws IOException, WebApplicationException { @@ -140,8 +138,8 @@ public class LdpWebService { conn.commit(); return resp; } else { - // Deliver all triples with <subject> as subject. - log.info("GET to <{}> with RDF format {}, providing LPD-RR data", resource, format.getDefaultMIMEType()); + // Deliver all triples from the <subject> context. + log.debug("GET to <{}> with RDF format {}, providing LPD-RR data", resource, format.getDefaultMIMEType()); final StreamingOutput entity = new StreamingOutput() { @Override public void write(OutputStream output) throws IOException, WebApplicationException { @@ -216,7 +214,7 @@ public class LdpWebService { final String base = newResource; do { final String candidate = base + "-" + (++i); - log.trace("<{}> already hasType, trying <{}>", newResource, candidate); + log.trace("<{}> already exists, trying <{}>", newResource, candidate); newResource = candidate; } while (ldpService.exists(conn, newResource)); log.debug("resolved name clash, new resource will be <{}>", newResource); @@ -226,12 +224,12 @@ public class LdpWebService { log.debug("POST to <{}> will create new LDP-R <{}>", container, newResource); final String mimeType = LdpUtils.getMimeType(type); - //checking if resource (container) hasType is done later in the service + //checking if resource (container) exists is done later in the service try { String location = ldpService.addResource(conn, container, newResource, mimeType, postBody); final Response.ResponseBuilder response = createResponse(conn, Response.Status.CREATED, container).location(java.net.URI.create(location)); if (newResource.compareTo(location) != 0) { - response.link(newResource, "describedby"); //Sec. 6.2.3.12, see also http://www.w3.org/2012/ldp/track/issues/15 + response.link(newResource, "describedby"); //FIXME: Sec. 6.2.3.12, see also http://www.w3.org/2012/ldp/track/issues/15 } conn.commit(); return response.build(); @@ -296,7 +294,7 @@ public class LdpWebService { * * clients should not be allowed to update LDPC-membership triples -> 409 Conflict (Sec. 6.5.1) * - * if the target resource hasType, replace ALL data of the target. + * if the target resource exists, replace ALL data of the target. */ final Response.ResponseBuilder resp = createResponse(con, Response.Status.NOT_IMPLEMENTED, resource); con.rollback(); @@ -401,7 +399,7 @@ public class LdpWebService { } /** - * Handle OPTIONS (Sec. 5.9, Sec. 6.9) + * Handle OPTIONS (Sec. 4.2.8, Sec. ??) */ @OPTIONS public Response OPTIONS(@Context final UriInfo uriInfo) throws RepositoryException { @@ -416,20 +414,15 @@ public class LdpWebService { Response.ResponseBuilder builder = createResponse(con, Response.Status.OK, resource); - // Sec. 5.9.2 + // Sec. 4.2.8.2 builder.allow("GET", "HEAD", "POST", "PATCH", "OPTIONS"); - // Sec. 6.4.14 / Sec. 8.1 - // builder.header("Accept-Post", "text/turtle, */*"); - builder.header("Accept-Post", "text/turtle"); + // Sec. 4.2.3 / Sec. ?? + builder.header("Accept-Post", "text/turtle, */*"); - // Sec. 5.8.2 + // Sec. 4.2.7.1 builder.header("Accept-Patch", RdfPatchParser.MIME_TYPE); - - // TODO: Sec. 6.9.1 - //builder.link(resource, "meta"); - con.commit(); return builder.build(); } catch (final Throwable t) { @@ -474,6 +467,11 @@ public class LdpWebService { } } + final URI rdfSource = ldpService.getRdfSourceForNonRdfSource(connection, resource); + if (rdfSource != null) { + rb.link(rdfSource.stringValue(), "describedby"); //FIXME: Sec. 6.2.3.12, see also http://www.w3.org/2012/ldp/track/issues/15 + } + // ETag (Sec. 5.2.7) rb.tag(ldpService.generateETag(connection, resource)); @@ -489,7 +487,7 @@ public class LdpWebService { * @param rb the ResponseBuilder to decorate * @return the updated ResponseBuilder for chaining */ - private Response.ResponseBuilder createResponse(Response.ResponseBuilder rb) { + protected Response.ResponseBuilder createResponse(Response.ResponseBuilder rb) { // Link rel='describedby' (Sec. 5.2.11) rb.link("http://wiki.apache.org/marmotta/LDPImplementationReport", "describedby"); http://git-wip-us.apache.org/repos/asf/marmotta/blob/bb132089/platform/marmotta-ldp/src/test/java/org/apache/marmotta/platform/ldp/webservices/LdpWebServiceTest.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-ldp/src/test/java/org/apache/marmotta/platform/ldp/webservices/LdpWebServiceTest.java b/platform/marmotta-ldp/src/test/java/org/apache/marmotta/platform/ldp/webservices/LdpWebServiceTest.java index 1ebcc91..d1d7d08 100644 --- a/platform/marmotta-ldp/src/test/java/org/apache/marmotta/platform/ldp/webservices/LdpWebServiceTest.java +++ b/platform/marmotta-ldp/src/test/java/org/apache/marmotta/platform/ldp/webservices/LdpWebServiceTest.java @@ -216,13 +216,13 @@ public class LdpWebServiceTest { .header("Link", CoreMatchers.anyOf( //TODO: RestAssured only checks the FIRST header... HeaderMatchers.isLink("http://wiki.apache.org/marmotta/LDPImplementationReport", "describedby"), HeaderMatchers.isLink(LDP.Resource.stringValue(), "type"), - HeaderMatchers.isLink(LDP.RdfResource.stringValue(), "type")) + HeaderMatchers.isLink(LDP.RDFSource.stringValue(), "type")) ) .header("ETag", HeaderMatchers.hasEntityTag(true)) // FIXME: be more specific here .contentType(RDFFormat.TURTLE.getDefaultMIMEType()) .body(SesameMatchers.rdfStringMatches(RDFFormat.TURTLE.getDefaultMIMEType(), baseUrl + newResource, SesameMatchers.hasStatement(new URIImpl(baseUrl + newResource), RDF.TYPE, LDP.Resource), - SesameMatchers.hasStatement(new URIImpl(baseUrl + newResource), RDF.TYPE, LDP.RdfResource), + SesameMatchers.hasStatement(new URIImpl(baseUrl + newResource), RDF.TYPE, LDP.RDFSource), SesameMatchers.hasStatement(new URIImpl(baseUrl + newResource), DCTERMS.MODIFIED, null), SesameMatchers.hasStatement(new URIImpl(baseUrl + newResource), DCTERMS.HAS_FORMAT, new URIImpl(baseUrl + newResource + ".png")) )) @@ -260,7 +260,7 @@ public class LdpWebServiceTest { .header("Link", CoreMatchers.anyOf( //TODO: RestAssured only checks the FIRST header... HeaderMatchers.isLink("http://wiki.apache.org/marmotta/LDPImplementationReport", "describedby"), HeaderMatchers.isLink(LDP.Resource.stringValue(), "type"), - HeaderMatchers.isLink(LDP.RdfResource.stringValue(), "type")) + HeaderMatchers.isLink(LDP.RDFSource.stringValue(), "type")) ) .header("ETag", HeaderMatchers.hasEntityTag(true)) // FIXME: be more specific here .contentType(mimeType)
