You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ja...@apache.org on 2014/03/11 17:20:00 UTC
[3/4] git commit: MARMOTTA-440: Continued alignment with w3c ldp
working draft
MARMOTTA-440: Continued alignment with w3c ldp working draft
Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo
Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/da1e8827
Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/da1e8827
Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/da1e8827
Branch: refs/heads/ldp
Commit: da1e8827f78c8c0c24bd95f142146886a3e3df60
Parents: bb13208
Author: Jakob Frank <ja...@apache.org>
Authored: Tue Mar 11 17:03:17 2014 +0100
Committer: Jakob Frank <ja...@apache.org>
Committed: Tue Mar 11 17:03:17 2014 +0100
----------------------------------------------------------------------
.../apache/marmotta/commons/vocabulary/LDP.java | 31 ++----
.../platform/ldp/api/LdpBinaryStoreService.java | 3 +
.../marmotta/platform/ldp/api/LdpService.java | 11 ++
.../ldp/services/LdpBinaryStoreServiceImpl.java | 16 +++
.../platform/ldp/services/LdpServiceImpl.java | 106 ++++++++++++++-----
.../platform/ldp/webservices/LdpWebService.java | 50 +++++++--
6 files changed, 158 insertions(+), 59 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/marmotta/blob/da1e8827/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 7357b96..aa17814 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
@@ -30,17 +30,9 @@ public class LDP {
public static final String PREFIX = "ldp";
/**
- * A Linked Data Platform Container (LDPC) that also conforms to
- * additional patterns and conventions for managing members. It is distinguished from
- * CompositeContainer by the following behaviors:
- * <ol>
- * <li>Clients cannot assume that an AggregateContainer, when deleted, deletes its members.
- * </ol>
- * <p/>
- * While every attempt is made to be complete in this list, readers should also refer
- * to the specification defining this ontology.
+ * FIXME: Not yet part of the official vocab, but used in the Spec. (2014-03-11)
*/
- public static final URI AggregateContainer;
+ public static final URI DirectContainer;
/**
* FIXME: Not yet part of the official vocab, but used in the Spec. (2014-02-18)
@@ -48,17 +40,9 @@ public class LDP {
public static final URI BasicContainer;
/**
- * A Linked Data Platform Container (LDPC) that also conforms to
- * additional patterns and conventions for managing members. It is distinguished from
- * AggregateContainer by the following behaviors:
- * <ol>
- * <li>An CompositeContainer, when deleted, must delete all its members.
- * </ol>
- * <p/>
- * While every attempt is made to be complete in this list, readers should also
- * refer to the specification defining this ontology.
+ * FIXME: Not yet part of the official vocab, but used in the Spec. (2014-03-11)
*/
- public static final URI CompositeContainer;
+ public static final URI IndirectContainer;
/**
* A Linked Data Platform Resource (LDPR) that also conforms to
@@ -86,6 +70,7 @@ public class LDP {
/**
* 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;
@@ -127,9 +112,9 @@ public class LDP {
static {
ValueFactory factory = ValueFactoryImpl.getInstance();
- AggregateContainer = factory.createURI(LDP.NAMESPACE, "AggregateContainer");
- BasicContainer = factory.createURI(LDP.NAMESPACE, "BasicContainer");
- CompositeContainer = factory.createURI(LDP.NAMESPACE, "CompositeContainer");
+ DirectContainer = factory.createURI(LDP.NAMESPACE, "DirectContainer"); //TODO: missing term in the vocab
+ BasicContainer = factory.createURI(LDP.NAMESPACE, "BasicContainer"); //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");
http://git-wip-us.apache.org/repos/asf/marmotta/blob/da1e8827/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 34ec302..6e8f46a 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
@@ -38,4 +38,7 @@ public interface LdpBinaryStoreService {
InputStream read(URI resource) throws IOException;
+ String getHash(String resource);
+
+ String getHash(URI uri);
}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/da1e8827/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 f998028..4795512 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
@@ -111,7 +111,18 @@ public interface LdpService {
String getMimeType(RepositoryConnection connection, URI uri) throws RepositoryException;
+ boolean isNonRdfSourceResource(RepositoryConnection connection, String resource) throws RepositoryException;
+
+ boolean isNonRdfSourceResource(RepositoryConnection connection, URI uri) throws RepositoryException;
+
URI getRdfSourceForNonRdfSource(RepositoryConnection connection, URI uri) throws RepositoryException;
URI getRdfSourceForNonRdfSource(RepositoryConnection connection, String resource) throws RepositoryException;
+
+ boolean isRdfSourceResource(RepositoryConnection connection, String resource) throws RepositoryException;
+
+ boolean isRdfSourceResource(RepositoryConnection connection, URI uri) throws RepositoryException;
+
+ URI getNonRdfSourceForRdfSource(RepositoryConnection connection, String resource) throws RepositoryException;
+ URI getNonRdfSourceForRdfSource(RepositoryConnection connection, URI uri) throws RepositoryException;
}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/da1e8827/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 01a305f..09f34c6 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
@@ -19,6 +19,7 @@ package org.apache.marmotta.platform.ldp.services;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
+import org.apache.marmotta.commons.util.HashUtils;
import org.apache.marmotta.platform.core.api.config.ConfigurationService;
import org.apache.marmotta.platform.core.events.ConfigurationChangedEvent;
import org.apache.marmotta.platform.core.events.SystemStartupEvent;
@@ -113,4 +114,19 @@ public class LdpBinaryStoreServiceImpl implements LdpBinaryStoreService {
return read(resource.stringValue());
}
+
+ @Override
+ public String getHash(String resource) {
+ try(InputStream is = Files.newInputStream(getFile(resource))) {
+ return HashUtils.md5sum(is);
+ } catch (URISyntaxException | IOException e) {
+ log.error("Error calculating file-md5 of {}: {}", resource, e);
+ return null;
+ }
+ }
+
+ @Override
+ public String getHash(URI uri) {
+ return getHash(uri.stringValue());
+ }
}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/da1e8827/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 4818d19..54350d4 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
@@ -101,18 +101,38 @@ public class LdpServiceImpl implements LdpService {
@Override
public List<Statement> getLdpTypes(RepositoryConnection connection, URI resource) throws RepositoryException {
- return Iterations.asList(new FilterIteration<Statement, RepositoryException>(connection.getStatements(resource, RDF.TYPE, null, false, ldpContext)) {
- @Override
- protected boolean accept(Statement statement) {
- final Value object = statement.getObject();
- return object instanceof URI && object.stringValue().startsWith(LDP.NAMESPACE);
- }
- }); //FIXME
+ return Iterations.asList(new FilterIteration<Statement, RepositoryException>(connection.getStatements(resource, RDF.TYPE, null, false, ldpContext)) {
+ @Override
+ protected boolean accept(Statement statement) {
+ final Value object = statement.getObject();
+ return object instanceof URI && object.stringValue().startsWith(LDP.NAMESPACE);
+ }
+ }); //FIXME
+ }
+
+ @Override
+ public boolean isRdfSourceResource(RepositoryConnection connection, String resource) throws RepositoryException {
+ return isRdfSourceResource(connection, buildURI(resource));
+ }
+
+ @Override
+ public boolean isRdfSourceResource(RepositoryConnection connection, URI uri) throws RepositoryException {
+ return connection.hasStatement(uri, RDF.TYPE, LDP.RDFSource, true, ldpContext);
+ }
+
+ @Override
+ public boolean isNonRdfSourceResource(RepositoryConnection connection, String resource) throws RepositoryException {
+ return isRdfSourceResource(connection, buildURI(resource));
+ }
+
+ @Override
+ public boolean isNonRdfSourceResource(RepositoryConnection connection, URI uri) throws RepositoryException {
+ return connection.hasStatement(uri, RDF.TYPE, LDP.NonRdfResource, true, ldpContext);
}
+
@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
@@ -138,6 +158,32 @@ public class LdpServiceImpl implements LdpService {
}
@Override
+ public URI getNonRdfSourceForRdfSource(RepositoryConnection connection, String resource) throws RepositoryException {
+ return getNonRdfSourceForRdfSource(connection, buildURI(resource));
+ }
+
+ @Override
+ public URI getNonRdfSourceForRdfSource(final RepositoryConnection connection, URI uri) throws RepositoryException {
+ final FilterIteration<Statement, RepositoryException> it =
+ new FilterIteration<Statement, RepositoryException>(connection.getStatements(uri, DCTERMS.hasFormat, null, true, ldpContext)) {
+ @Override
+ protected boolean accept(Statement statement) throws RepositoryException {
+ return statement.getObject() instanceof URI
+ && connection.hasStatement((URI) statement.getObject(), RDF.TYPE, LDP.NonRdfResource, true, ldpContext);
+ }
+ };
+ try {
+ if (it.hasNext()) {
+ return (URI) it.next().getObject();
+ } else {
+ return null;
+ }
+ }finally {
+ it.close();
+ }
+ }
+
+ @Override
public void exportResource(RepositoryConnection connection, String resource, OutputStream output, RDFFormat format) throws RepositoryException, RDFHandlerException {
exportResource(connection, buildURI(resource), output, format);
}
@@ -209,6 +255,7 @@ public class LdpServiceImpl implements LdpService {
if (hasType(connection, container, LDP.BasicContainer)) {
connection.remove(container, DCTERMS.modified, null, ldpContext);
} else {
+ connection.add(container, RDF.TYPE, LDP.Container, ldpContext);
connection.add(container, RDF.TYPE, LDP.BasicContainer, ldpContext);
}
@@ -260,26 +307,35 @@ public class LdpServiceImpl implements LdpService {
@Override
public EntityTag generateETag(RepositoryConnection connection, URI uri) throws RepositoryException {
- final RepositoryResult<Statement> stmts = connection.getStatements(uri, DCTERMS.modified, null, true, ldpContext);
- try {
- // TODO: ETag is the last-modified date (explicitly managed) thus only weak.
- Date latest = null;
- while (stmts.hasNext()) {
- Value o = stmts.next().getObject();
- if (o instanceof Literal) {
- Date d = ((Literal)o).calendarValue().toGregorianCalendar().getTime();
- if (latest == null || d.after(latest)) {
- latest = d;
- }
- }
- }
- if (latest != null) {
- return new EntityTag(String.valueOf(latest.getTime()), true);
+ if (isNonRdfSourceResource(connection, uri)) {
+ final String hash = binaryStore.getHash(uri.stringValue());
+ if (hash != null) {
+ return new EntityTag(hash, false);
} else {
return null;
}
- } finally {
- stmts.close();
+ } else {
+ final RepositoryResult<Statement> stmts = connection.getStatements(uri, DCTERMS.modified, null, true, ldpContext);
+ try {
+ // TODO: ETag is the last-modified date (explicitly managed) thus only weak.
+ Date latest = null;
+ while (stmts.hasNext()) {
+ Value o = stmts.next().getObject();
+ if (o instanceof Literal) {
+ Date d = ((Literal)o).calendarValue().toGregorianCalendar().getTime();
+ if (latest == null || d.after(latest)) {
+ latest = d;
+ }
+ }
+ }
+ if (latest != null) {
+ return new EntityTag(String.valueOf(latest.getTime()), true);
+ } else {
+ return null;
+ }
+ } finally {
+ stmts.close();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/da1e8827/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 c4f68d3..8bf49b4 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
@@ -110,7 +110,17 @@ public class LdpWebService {
// TODO: Proper content negotiation
- final RDFFormat format = Rio.getWriterFormatForMIMEType(type.toString());
+ final RDFFormat format;
+ if (type.isWildcardType()) { // No explicit Accept Header
+ if (ldpService.isRdfSourceResource(conn, resource)) {
+ format = RDFFormat.TURTLE;
+ } else {
+ format = null;
+ }
+ } else {
+ format = Rio.getWriterFormatForMIMEType(LdpUtils.getMimeType(type), null);
+ }
+
if (format == null) {
log.debug("GET to <{}> with non-RDF format {}, so looking for a LDP-BR", resource, type);
final StreamingOutput entity = new StreamingOutput() {
@@ -208,6 +218,13 @@ public class LdpWebService {
conn.begin();
+ if (ldpService.isNonRdfSourceResource(conn, container)) {
+ log.info("POSTing to a NonRdfSource is not allowed ({})", container);
+ final Response.ResponseBuilder response = createResponse(conn, Response.Status.METHOD_NOT_ALLOWED, container).entity("POST to NonRdfSource is not allowed\n");
+ conn.commit();
+ return response.build();
+ }
+
log.trace("Checking possible name clash for new resource <{}>", newResource);
if (ldpService.exists(conn, newResource)) {
int i = 0;
@@ -229,7 +246,7 @@ public class LdpWebService {
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"); //FIXME: Sec. 6.2.3.12, see also http://www.w3.org/2012/ldp/track/issues/15
+ response.link(newResource, "describedby"); //FIXME: Sec. 5.2.3.12, see also http://www.w3.org/2012/ldp/track/issues/15
}
conn.commit();
return response.build();
@@ -414,14 +431,18 @@ public class LdpWebService {
Response.ResponseBuilder builder = createResponse(con, Response.Status.OK, resource);
- // Sec. 4.2.8.2
- builder.allow("GET", "HEAD", "POST", "PATCH", "OPTIONS");
-
- // Sec. 4.2.3 / Sec. ??
- builder.header("Accept-Post", "text/turtle, */*");
-
- // Sec. 4.2.7.1
- builder.header("Accept-Patch", RdfPatchParser.MIME_TYPE);
+ if (ldpService.isNonRdfSourceResource(con, resource)) {
+ // Sec. 4.2.8.2
+ builder.allow("GET", "HEAD", "OPTIONS");
+ } else if (ldpService.isRdfSourceResource(con, resource)) {
+ // Sec. 4.2.8.2
+ builder.allow("GET", "HEAD", "POST", "PATCH", "OPTIONS");
+ // Sec. 4.2.3 / Sec. ??
+ // TODO: LDP Interaction Model!
+ builder.header("Accept-Post", "text/turtle, */*");
+ // Sec. 4.2.7.1
+ builder.header("Accept-Patch", RdfPatchParser.MIME_TYPE);
+ }
con.commit();
return builder.build();
@@ -469,7 +490,14 @@ 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
+ // FIXME: Sec. 5.2.3.12, see also http://www.w3.org/2012/ldp/track/issues/15
+ rb.link(rdfSource.stringValue(), "meta");
+ rb.link(rdfSource.stringValue(), "describedby");
+ }
+ final URI nonRdfSource = ldpService.getNonRdfSourceForRdfSource(connection, resource);
+ if (nonRdfSource != null) {
+ // TODO: Propose to LDP-WG?
+ rb.link(nonRdfSource.stringValue(), "content");
}
// ETag (Sec. 5.2.7)