Repository: marmotta Updated Branches: refs/heads/ldp 96097b4dd -> 673ddc35d
MARMOTTA-440: aligned LDP implementation with the curren WD (http://www.w3.org/TR/2014/WD-ldp-20140311/) Implementation Report available at https://wiki.apache.org/marmotta/LDPImplementationReport/2014-03-11 Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/673ddc35 Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/673ddc35 Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/673ddc35 Branch: refs/heads/ldp Commit: 673ddc35dbf9bfd66df49ceb1e3db5a3ba7a238f Parents: 96097b4 Author: Jakob Frank <[email protected]> Authored: Wed Mar 12 12:36:28 2014 +0100 Committer: Jakob Frank <[email protected]> Committed: Wed Mar 12 12:40:26 2014 +0100 ---------------------------------------------------------------------- .../apache/marmotta/commons/vocabulary/LDP.java | 119 +++++-------------- .../platform/ldp/api/LdpBinaryStoreService.java | 3 + .../ldp/services/LdpBinaryStoreServiceImpl.java | 16 +++ .../platform/ldp/services/LdpServiceImpl.java | 30 ++++- .../marmotta/platform/ldp/util/LdpUtils.java | 20 ++++ .../platform/ldp/webservices/LdpWebService.java | 5 +- 6 files changed, 98 insertions(+), 95 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/marmotta/blob/673ddc35/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 aa17814..d76ca13 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 @@ -17,6 +17,7 @@ package org.apache.marmotta.commons.vocabulary; import org.openrdf.model.URI; +import org.openrdf.model.Value; import org.openrdf.model.ValueFactory; import org.openrdf.model.impl.ValueFactoryImpl; @@ -29,104 +30,46 @@ public class LDP { public static final String PREFIX = "ldp"; - /** - * FIXME: Not yet part of the official vocab, but used in the Spec. (2014-03-11) - */ - public static final URI DirectContainer; - - /** - * FIXME: Not yet part of the official vocab, but used in the Spec. (2014-02-18) - */ + + public static final URI BasicContainer; - - /** - * FIXME: Not yet part of the official vocab, but used in the Spec. (2014-03-11) - */ - public static final URI IndirectContainer; - - /** - * A Linked Data Platform Resource (LDPR) that also conforms to - * additional patterns and conventions for managing membership. - * Readers should refer to the specification defining this ontology for the list of - * behaviors associated with it. - */ public static final URI Container; - - /** - * A resource that represents a limited set of members of a LDP Container. - */ - public static final URI Page; - - /** - * A HTTP-addressable resource with a linked data representation. - */ - public static final URI Resource; - - /** - * 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 RDFSource; - - /** - * A HTTP-addressable resource with a Non-RDF Source representation. - * FIXME: Not yet part of the vocab, but used in the spec. (2014-03-11) - */ - public static final URI NonRdfResource; - - /** - * FIXME: Not yet part of the vocab, but used in the spec. (2014-02-24) - */ public static final URI contains; - - /** - * List of predicates that indicate the ascending order of the members in a page. - */ - public static final URI containerSortPredicates; - - /** - * FIXME: Not yet part of the vocab, but used in the spec. (2014-02-18) - */ + public static final URI DirectContainer; + public static final URI hasMemberRelation; + public static final URI IndirectContainer; + public static final URI insertedContentRelation; + public static final URI isMemberOfRelation; public static final URI member; - - /** - * Indicates which predicate of the container should be used to determine the membership. - */ - public static final URI membershipPredicate; - - /** - * Indicates which resource is the subject for the members of the container. - */ - public static final URI membershipSubject; - - /** - * From a known page, how to indicate the next or last page as rdf:nil. - */ - public static final URI nextPage; - - /** - * Associated a page with its container. - */ - public static final URI pageOf; - + public static final URI membershipResource; + public static final URI MemberSubject; + public static final URI NonRdfResource; + public static final URI PreferContainment; + public static final URI PreferEmptyContainer; + public static final URI PreferMembership; + public static final URI RDFSource; + public static final URI Resource; static { ValueFactory factory = ValueFactoryImpl.getInstance(); - DirectContainer = factory.createURI(LDP.NAMESPACE, "DirectContainer"); //TODO: missing term in the vocab BasicContainer = factory.createURI(LDP.NAMESPACE, "BasicContainer"); //TODO: missing term in the vocab + Container = factory.createURI(LDP.NAMESPACE, "Container"); //TODO: missing term in the vocab + contains = factory.createURI(LDP.NAMESPACE, "contains"); //TODO: missing term in the vocab + DirectContainer = factory.createURI(LDP.NAMESPACE, "DirectContainer"); //TODO: missing term in the vocab + hasMemberRelation = factory.createURI(LDP.NAMESPACE, "hasMemberRelation"); //TODO: missing term in the vocab IndirectContainer = factory.createURI(LDP.NAMESPACE, "IndirectContainer"); //TODO: missing term in the vocab - Container = factory.createURI(LDP.NAMESPACE, "Container"); - Page = factory.createURI(LDP.NAMESPACE, "Page"); - Resource = factory.createURI(LDP.NAMESPACE, "Resource"); - RDFSource = factory.createURI(LDP.NAMESPACE, "RDFSource"); //TODO: missing term in the vocab + insertedContentRelation = factory.createURI(LDP.NAMESPACE, "insertedContentRelation"); //TODO: missing term in the vocab + isMemberOfRelation = factory.createURI(LDP.NAMESPACE, "isMemberOfRelation"); //TODO: missing term in the vocab + member = factory.createURI(LDP.NAMESPACE, "member"); //TODO: missing term in the vocab + membershipResource = factory.createURI(LDP.NAMESPACE, "membershipResource"); //TODO: missing term in the vocab + MemberSubject = factory.createURI(LDP.NAMESPACE, "MemberSubject"); //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"); - member = factory.createURI(LDP.NAMESPACE, "member"); - membershipPredicate = factory.createURI(LDP.NAMESPACE, "membershipPredicate"); - membershipSubject = factory.createURI(LDP.NAMESPACE, "membershipSubject"); - nextPage = factory.createURI(LDP.NAMESPACE, "nextPage"); - pageOf = factory.createURI(LDP.NAMESPACE, "pageOf"); + PreferContainment = factory.createURI(LDP.NAMESPACE, "PreferContainment"); //TODO: missing term in the vocab + PreferEmptyContainer = factory.createURI(LDP.NAMESPACE, "PreferEmptyContainer"); //TODO: missing term in the vocab + PreferMembership = factory.createURI(LDP.NAMESPACE, "PreferMembership"); //TODO: missing term in the vocab + RDFSource = factory.createURI(LDP.NAMESPACE, "RDFSource"); //TODO: missing term in the vocab + Resource = factory.createURI(LDP.NAMESPACE, "Resource"); //TODO: missing term in the vocab + } } http://git-wip-us.apache.org/repos/asf/marmotta/blob/673ddc35/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/api/LdpBinaryStoreService.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/api/LdpBinaryStoreService.java b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/api/LdpBinaryStoreService.java index 6e8f46a..6624a8e 100644 --- a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/api/LdpBinaryStoreService.java +++ b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/api/LdpBinaryStoreService.java @@ -41,4 +41,7 @@ public interface LdpBinaryStoreService { String getHash(String resource); String getHash(URI uri); + + boolean delete(URI uri); + boolean delete(String resource); } http://git-wip-us.apache.org/repos/asf/marmotta/blob/673ddc35/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpBinaryStoreServiceImpl.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpBinaryStoreServiceImpl.java b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpBinaryStoreServiceImpl.java index 09f34c6..290f658 100644 --- a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpBinaryStoreServiceImpl.java +++ b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpBinaryStoreServiceImpl.java @@ -129,4 +129,20 @@ public class LdpBinaryStoreServiceImpl implements LdpBinaryStoreService { public String getHash(URI uri) { return getHash(uri.stringValue()); } + + @Override + public boolean delete(URI uri) { + return delete(uri.stringValue()); + } + + @Override + public boolean delete(String resource) { + try { + final Path file = getFile(resource); + return Files.deleteIfExists(file); + } catch (IOException | URISyntaxException e) { + log.error("Error while deleting {}: {}", resource, e.getMessage()); + return false; + } + } } http://git-wip-us.apache.org/repos/asf/marmotta/blob/673ddc35/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 1aa1425..1e9acb0 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 @@ -122,7 +122,7 @@ public class LdpServiceImpl implements LdpService { @Override public boolean isNonRdfSourceResource(RepositoryConnection connection, String resource) throws RepositoryException { - return isRdfSourceResource(connection, buildURI(resource)); + return isNonRdfSourceResource(connection, buildURI(resource)); } @Override @@ -252,11 +252,14 @@ public class LdpServiceImpl implements LdpService { final Literal now = valueFactory.createLiteral(new Date()); + // FIXME: This is redundant if the container already existed as a Resource! + connection.add(container, RDF.TYPE, LDP.Resource, ldpContext); + connection.add(container, RDF.TYPE, LDP.RDFSource, ldpContext); + // end connection.add(container, RDF.TYPE, LDP.Container, ldpContext); // TODO: For the future we might need to check for other container types here first. connection.add(container, RDF.TYPE, LDP.BasicContainer, ldpContext); - connection.add(container, LDP.contains, resource, ldpContext); connection.remove(container, DCTERMS.modified, null, ldpContext); connection.add(container, DCTERMS.modified, now, ldpContext); @@ -272,6 +275,8 @@ public class LdpServiceImpl implements LdpService { Literal format = valueFactory.createLiteral(type); URI binaryResource = valueFactory.createURI(resource.stringValue() + LdpUtils.getExtension(type)); + connection.add(container, LDP.contains, binaryResource, ldpContext); + connection.add(binaryResource, DCTERMS.created, now, ldpContext); connection.add(binaryResource, DCTERMS.modified, now, ldpContext); connection.add(binaryResource, RDF.TYPE, LDP.Resource, ldpContext); @@ -290,6 +295,7 @@ public class LdpServiceImpl implements LdpService { return binaryResource.stringValue(); } else { log.debug("POST creates new LDP-RR, data provided as {}", rdfFormat.getName()); + connection.add(container, LDP.contains, resource, ldpContext); // FIXME: We are (are we?) allowed to filter out server-managed properties here connection.add(stream, resource.stringValue(), rdfFormat, resource); @@ -402,7 +408,7 @@ public class LdpServiceImpl implements LdpService { final Literal now = connection.getValueFactory().createLiteral(new Date()); // Delete corresponding containment and membership triples (Sec. 5.2.5.1) - RepositoryResult<Statement> stmts = connection.getStatements(null, LDP.member, resource, false, ldpContext); + RepositoryResult<Statement> stmts = connection.getStatements(null, LDP.contains, resource, false, ldpContext); try { while (stmts.hasNext()) { Statement st = stmts.next(); @@ -413,8 +419,22 @@ public class LdpServiceImpl implements LdpService { } finally { stmts.close(); } - // FIXME: 5.2.5.2 When an LDPR identified by the object of a containment triple is deleted, and the LDPC server created an associated LDP-RS, the LDPC server must also remove the associated LDP-RS it created. - // FIXME: Delete LDP-NR (binary) + // Sec. 5.2.5.2: When an LDPR identified by the object of a containment triple is deleted, and the LDPC server created an associated LDP-RS, the LDPC server must also remove the associated LDP-RS it created. + RepositoryResult<Statement> associated = connection.getStatements(resource, DCTERMS.isFormatOf, null, false, ldpContext); + try { + while (associated.hasNext()) { + Statement st = associated.next(); + if (st.getObject() instanceof Resource) { + connection.remove((Resource) st.getObject(), null, null); + } + connection.remove(st); + } + } finally { + associated.close(); + } + + // Delete LDP-NR (binary) + binaryStore.delete(resource); // Delete the resource meta connection.remove(resource, null, null, ldpContext); http://git-wip-us.apache.org/repos/asf/marmotta/blob/673ddc35/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/util/LdpUtils.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/util/LdpUtils.java b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/util/LdpUtils.java index ceba28d..039c923 100644 --- a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/util/LdpUtils.java +++ b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/util/LdpUtils.java @@ -18,6 +18,7 @@ package org.apache.marmotta.platform.ldp.util; import info.aduna.iteration.CloseableIteration; +import org.apache.commons.lang3.StringUtils; import org.apache.marmotta.commons.vocabulary.LDP; import org.apache.marmotta.commons.vocabulary.XSD; import org.apache.tika.mime.MimeTypeException; @@ -27,10 +28,14 @@ import org.openrdf.model.URI; import org.openrdf.model.vocabulary.DCTERMS; import org.openrdf.model.vocabulary.RDF; import org.openrdf.repository.RepositoryException; +import org.openrdf.rio.RDFFormat; import org.openrdf.rio.RDFHandlerException; +import org.openrdf.rio.RDFParserRegistry; import org.openrdf.rio.RDFWriter; import javax.ws.rs.core.MediaType; +import java.util.Iterator; +import java.util.Set; /** * Various Util-Methods for the {@link org.apache.marmotta.platform.ldp.api.LdpService}. @@ -111,4 +116,19 @@ public class LdpUtils { writer.endRDF(); } + public static String getAcceptPostHeader(String extraFormats) { + final Set<RDFFormat> rdfFormats = RDFParserRegistry.getInstance().getKeys(); + final StringBuilder sb = new StringBuilder(); + for (RDFFormat rdfFormat : rdfFormats) { + sb.append(rdfFormat.getDefaultMIMEType()); + sb.append(", "); + } + if (StringUtils.isNotBlank(extraFormats)) { + sb.append(extraFormats); + } else { + sb.delete(sb.length()-2, sb.length()); + } + return sb.toString(); + } + } http://git-wip-us.apache.org/repos/asf/marmotta/blob/673ddc35/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 8bf49b4..0901011 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 @@ -61,6 +61,7 @@ import java.util.UUID; public class LdpWebService { public static final String PATH = "/ldp"; //FIXME: imho this should be root '/' (jakob) + public static final String LDP_SERVER_CONSTRAINTS = "https://wiki.apache.org/marmotta/LDPImplementationReport/2014-03-11"; private Logger log = org.slf4j.LoggerFactory.getLogger(this.getClass()); @@ -439,7 +440,7 @@ public class LdpWebService { builder.allow("GET", "HEAD", "POST", "PATCH", "OPTIONS"); // Sec. 4.2.3 / Sec. ?? // TODO: LDP Interaction Model! - builder.header("Accept-Post", "text/turtle, */*"); + builder.header("Accept-Post", LdpUtils.getAcceptPostHeader("*/*")); // Sec. 4.2.7.1 builder.header("Accept-Patch", RdfPatchParser.MIME_TYPE); } @@ -517,7 +518,7 @@ public class LdpWebService { */ protected Response.ResponseBuilder createResponse(Response.ResponseBuilder rb) { // Link rel='describedby' (Sec. 5.2.11) - rb.link("http://wiki.apache.org/marmotta/LDPImplementationReport", "describedby"); + rb.link(LDP_SERVER_CONSTRAINTS, "describedby"); return rb; }
