You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by wi...@apache.org on 2014/03/03 14:25:35 UTC
[2/2] git commit: MARMOTTA-449: implemented LDP-NR accroding the last
spec (sec. 6.2.3.12)
MARMOTTA-449: implemented LDP-NR accroding the last spec (sec. 6.2.3.12)
Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo
Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/3c1962b6
Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/3c1962b6
Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/3c1962b6
Branch: refs/heads/ldp
Commit: 3c1962b6cfe05b6162751b9a8cb90ec6969ceef2
Parents: 20d8794
Author: Sergio Fernández <wi...@apache.org>
Authored: Mon Mar 3 14:23:52 2014 +0100
Committer: Sergio Fernández <wi...@apache.org>
Committed: Mon Mar 3 14:23:52 2014 +0100
----------------------------------------------------------------------
.../marmotta/platform/ldp/api/LdpService.java | 35 +++++++-
.../platform/ldp/services/LdpServiceImpl.java | 48 +++++++---
.../marmotta/platform/ldp/util/LdpUtils.java | 95 ++++++++++++++++++++
.../platform/ldp/util/LdpWebServiceUtils.java | 74 ---------------
.../platform/ldp/webservices/LdpWebService.java | 39 ++++----
5 files changed, 183 insertions(+), 108 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/marmotta/blob/3c1962b6/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 7978273..8f49e82 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
@@ -40,6 +40,7 @@ import java.util.List;
* LDP Service
*
* @author Sergio Fernández
+ * @author Jakob Frank
*/
public interface LdpService {
@@ -47,9 +48,37 @@ public interface LdpService {
boolean exists(RepositoryConnection connection, URI resource) throws RepositoryException;
- boolean addResource(RepositoryConnection connection, String container, String resource, MediaType type, InputStream stream) throws RepositoryException, IOException, RDFParseException;
-
- boolean addResource(RepositoryConnection connection, URI container, URI resource, MediaType type, InputStream stream) throws RepositoryException, IOException, RDFParseException;
+ boolean exists(RepositoryConnection connection, URI resource, URI type) throws RepositoryException;
+
+ /**
+ * Add a LDP resource
+ *
+ * @param connection repository connection
+ * @param container container where add the resource
+ * @param resource resource to add
+ * @param type mimetype of the posted resource
+ * @param stream stream from where read the resource representation
+ * @return resource location
+ * @throws RepositoryException
+ * @throws IOException
+ * @throws RDFParseException
+ */
+ String addResource(RepositoryConnection connection, String container, String resource, MediaType type, InputStream stream) throws RepositoryException, IOException, RDFParseException;
+
+ /**
+ * Add a LDP resource
+ *
+ * @param connection repository connection
+ * @param container container where add the resource
+ * @param resource resource to add
+ * @param type mimetype of the posted resource
+ * @param stream stream from where read the resource representation
+ * @return resource location
+ * @throws RepositoryException
+ * @throws IOException
+ * @throws RDFParseException
+ */
+ String addResource(RepositoryConnection connection, URI container, URI resource, MediaType type, InputStream stream) throws RepositoryException, IOException, RDFParseException;
List<Statement> getLdpTypes(RepositoryConnection connection, String resource) throws RepositoryException;
http://git-wip-us.apache.org/repos/asf/marmotta/blob/3c1962b6/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 2cd4fc3..e5eea4e 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
@@ -32,7 +32,7 @@ import org.apache.marmotta.platform.ldp.patch.RdfPatchUtil;
import org.apache.marmotta.platform.ldp.patch.model.PatchLine;
import org.apache.marmotta.platform.ldp.patch.parser.ParseException;
import org.apache.marmotta.platform.ldp.patch.parser.RdfPatchParserImpl;
-import org.apache.marmotta.platform.ldp.util.LdpWebServiceUtils;
+import org.apache.marmotta.platform.ldp.util.LdpUtils;
import org.openrdf.model.*;
import org.openrdf.model.impl.ValueFactoryImpl;
import org.openrdf.model.vocabulary.RDF;
@@ -91,6 +91,11 @@ public class LdpServiceImpl implements LdpService {
}
@Override
+ public boolean exists(RepositoryConnection connection, URI resource, URI type) throws RepositoryException {
+ return connection.hasStatement(resource, RDF.TYPE, type, true, ldpContext);
+ }
+
+ @Override
public List<Statement> getLdpTypes(RepositoryConnection connection, String resource) throws RepositoryException {
return getLdpTypes(connection, buildURI(resource));
}
@@ -121,7 +126,7 @@ public class LdpServiceImpl implements LdpService {
connection.getStatements(resource, null, null, false, ldpContext)
);
try {
- LdpWebServiceUtils.exportIteration(writer, resource, union);
+ LdpUtils.exportIteration(writer, resource, union);
} finally {
union.close();
}
@@ -145,12 +150,12 @@ public class LdpServiceImpl implements LdpService {
}
@Override
- public boolean addResource(RepositoryConnection connection, String container, String resource, MediaType type, InputStream stream) throws RepositoryException, IOException, RDFParseException {
+ public String addResource(RepositoryConnection connection, String container, String resource, MediaType type, InputStream stream) throws RepositoryException, IOException, RDFParseException {
return addResource(connection, buildURI(container), buildURI(resource), type, stream);
}
@Override
- public boolean addResource(RepositoryConnection connection, URI container, URI resource, MediaType type, InputStream stream) throws RepositoryException, IOException, RDFParseException {
+ public String addResource(RepositoryConnection connection, URI container, URI resource, MediaType type, InputStream stream) throws RepositoryException, IOException, RDFParseException {
ValueFactory valueFactory = connection.getValueFactory();
// Add container triples (Sec. 6.4.3)
@@ -158,31 +163,48 @@ public class LdpServiceImpl implements LdpService {
Literal now = valueFactory.createLiteral(new Date());
- connection.add(container, RDF.TYPE, LDP.BasicContainer, ldpContext);
+ if (exists(connection, container, LDP.BasicContainer)) {
+ connection.remove(container, DCTERMS.modified, null, ldpContext);
+ } else {
+ 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);
- connection.add(resource, RDF.TYPE, LDP.Resource, ldpContext);
- connection.add(resource, DCTERMS.created, now, ldpContext);
- connection.add(resource, DCTERMS.modified, now, ldpContext);
-
// Add the bodyContent
log.trace("Content ({}) for new resource <{}>", type, resource);
final RDFFormat rdfFormat = Rio.getParserFormatForMIMEType(type.toString());
if (rdfFormat == null) {
log.debug("POST creates new LDP-BR, because no RDF parser found for type {}", type);
Literal format = valueFactory.createLiteral(type.toString());
- connection.add(resource, DCTERMS.format, format, ldpContext); //nie:mimeType ?
+ URI binaryResource = valueFactory.createURI(resource.stringValue() + LdpUtils.getExtension(type.toString()));
+
+ //connection.add(resource, RDF.TYPE, LDP.NonRdfResource, ldpContext); //TODO:
+ connection.add(binaryResource, DCTERMS.created, now, ldpContext);
+ connection.add(binaryResource, DCTERMS.modified, now, ldpContext);
+
+ //extra triples
+ //TODO: check conformance with 6.2.3.12
+ connection.add(binaryResource, DCTERMS.format, format, ldpContext); //nie:mimeType ?
+ connection.add(binaryResource, DCTERMS.isFormatOf, resource, ldpContext);
+
//TODO: something else?
- return binaryStore.store(resource, stream); //TODO: control exceptions
+
+ binaryStore.store(binaryResource, stream);//TODO: exceptions control
+
+ return binaryResource.stringValue();
} else {
log.debug("POST creates new LDP-RR, data provided as {}", rdfFormat.getName());
+ connection.add(resource, RDF.TYPE, LDP.Resource, ldpContext);
+ connection.add(resource, DCTERMS.created, now, ldpContext);
+ connection.add(resource, DCTERMS.modified, now, ldpContext);
+
// FIXME: We are (are we?) allowed to filter out server-managed properties here
connection.add(stream, resource.stringValue(), rdfFormat, resource);
- return true;
+ return resource.stringValue();
}
}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/3c1962b6/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
new file mode 100644
index 0000000..dc565b4
--- /dev/null
+++ b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/util/LdpUtils.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.marmotta.platform.ldp.util;
+
+import info.aduna.iteration.CloseableIteration;
+import org.apache.marmotta.commons.vocabulary.LDP;
+import org.apache.marmotta.commons.vocabulary.XSD;
+import org.apache.tika.mime.MimeType;
+import org.apache.tika.mime.MimeTypeException;
+import org.apache.tika.mime.MimeTypes;
+import org.openrdf.model.Statement;
+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.RDFHandlerException;
+import org.openrdf.rio.RDFWriter;
+
+/**
+ * Various Util-Methods for the {@link org.apache.marmotta.platform.ldp.api.LdpService}.
+ */
+public class LdpUtils {
+
+ /**
+ * Urify the Slug: header value, i.e. replace all non-url chars with a single dash.
+ *
+ * @param slugHeaderValue the client-provided Slug-header
+ * @return the slugHeaderValue "urified"
+ */
+ public static String urify(String slugHeaderValue) {
+ return slugHeaderValue.trim()
+ // Replace non-url chars with '-'
+ .replaceAll("[^\\w]+", "-");
+ }
+
+ /**
+ * Get the preferred file extension for the content type
+ *
+ * @param contentType content type
+ * @return file extension (already including '.')
+ * @throws MimeTypeException
+ */
+ public static String getExtension(String contentType) {
+ MimeTypes allTypes = MimeTypes.getDefaultMimeTypes();
+ try {
+ MimeType mimeType = allTypes.forName(contentType);
+ return mimeType.getExtension();
+ } catch (MimeTypeException e) {
+ return null; //FIXME
+ }
+
+ }
+
+ /**
+ * LDP-Style to serialize a resource.
+ *
+ * @param writer the writer to serialize to
+ * @param subject the resource to serialize
+ * @param iteration the Iteration containing the data
+ * @throws RDFHandlerException
+ * @throws RepositoryException
+ */
+ public static void exportIteration(RDFWriter writer, URI subject, CloseableIteration<Statement, RepositoryException> iteration) throws RDFHandlerException, RepositoryException {
+ writer.startRDF();
+
+ writer.handleNamespace(LDP.PREFIX, LDP.NAMESPACE);
+ writer.handleNamespace(RDF.PREFIX, RDF.NAMESPACE);
+ writer.handleNamespace(XSD.PREFIX, XSD.NAMESPACE);
+ writer.handleNamespace(DCTERMS.PREFIX, DCTERMS.NAMESPACE);
+
+ writer.handleNamespace("", subject.stringValue());
+
+ while (iteration.hasNext()) {
+ writer.handleStatement(iteration.next());
+ }
+
+ writer.endRDF();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/3c1962b6/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/util/LdpWebServiceUtils.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/util/LdpWebServiceUtils.java b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/util/LdpWebServiceUtils.java
deleted file mode 100644
index 1116879..0000000
--- a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/util/LdpWebServiceUtils.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.marmotta.platform.ldp.util;
-
-import info.aduna.iteration.CloseableIteration;
-import info.aduna.iteration.Iteration;
-import info.aduna.iteration.UnionIteration;
-import org.apache.marmotta.commons.vocabulary.LDP;
-import org.apache.marmotta.commons.vocabulary.XSD;
-import org.openrdf.model.Statement;
-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.RDFHandlerException;
-import org.openrdf.rio.RDFWriter;
-
-/**
- * Various Util-Methods for the {@link org.apache.marmotta.platform.ldp.webservices.LdpWebService}.
- */
-public class LdpWebServiceUtils {
-
- /**
- * Urify the Slug: header value, i.e. replace all non-url chars with a single dash.
- *
- * @param slugHeaderValue the client-provided Slug-header
- * @return the slugHeaderValue "urified"
- */
- public static String urify(String slugHeaderValue) {
- return slugHeaderValue
- // Replace non-url chars with '-'
- .replaceAll("[^\\w]+", "-");
- }
-
- /**
- * LDP-Style to serialize a resource.
- * @param writer the writer to serialize to
- * @param subject the resource to serialize
- * @param iteration the Iteration containing the data
- * @throws RDFHandlerException
- * @throws RepositoryException
- */
- public static void exportIteration(RDFWriter writer, URI subject, CloseableIteration<Statement, RepositoryException> iteration) throws RDFHandlerException, RepositoryException {
- writer.startRDF();
-
- writer.handleNamespace(LDP.PREFIX, LDP.NAMESPACE);
- writer.handleNamespace(RDF.PREFIX, RDF.NAMESPACE);
- writer.handleNamespace(XSD.PREFIX, XSD.NAMESPACE);
- writer.handleNamespace(DCTERMS.PREFIX, DCTERMS.NAMESPACE);
-
- writer.handleNamespace("", subject.stringValue());
-
- while (iteration.hasNext()) {
- writer.handleStatement(iteration.next());
- }
-
- writer.endRDF();
- }
-}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/3c1962b6/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 88da2e3..f10da48 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
@@ -27,7 +27,7 @@ import org.apache.marmotta.platform.ldp.patch.InvalidPatchDocumentException;
import org.apache.marmotta.platform.ldp.patch.parser.ParseException;
import org.apache.marmotta.platform.ldp.patch.parser.RdfPatchParser;
import org.apache.marmotta.platform.ldp.util.EntityTagUtils;
-import org.apache.marmotta.platform.ldp.util.LdpWebServiceUtils;
+import org.apache.marmotta.platform.ldp.util.LdpUtils;
import org.jboss.resteasy.spi.NoLogWebApplicationException;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
@@ -178,11 +178,8 @@ public class LdpWebService {
final String container = getResourceUri(uriInfo);
log.debug("POST to LDPC <{}>", container);
- final RepositoryConnection con = sesameService.getConnection();
+ final RepositoryConnection conn = sesameService.getConnection();
try {
- con.begin();
- // TODO: Check if resource (container) exists
- log.warn("NOT CHECKING EXISTENCE OF <{}>", container);
final String localName;
if (StringUtils.isBlank(slug)) {
@@ -193,21 +190,23 @@ public class LdpWebService {
// Honor client wishes from Slug-header (Sec. 6.4.11)
// http://www.ietf.org/rfc/rfc5023.txt
log.trace("Slug-Header is '{}'", slug);
- localName = LdpWebServiceUtils.urify(slug);
+ localName = LdpUtils.urify(slug);
log.trace("Slug-Header urified: {}", localName);
}
String newResource = uriInfo.getRequestUriBuilder().path(localName).build().toString();
+ conn.begin();
+
log.trace("Checking possible name clash for new resource <{}>", newResource);
- if (ldpService.exists(con, newResource)) {
+ if (ldpService.exists(conn, newResource)) {
int i = 0;
final String base = newResource;
do {
final String candidate = base + "-" + (++i);
log.trace("<{}> already exists, trying <{}>", newResource, candidate);
newResource = candidate;
- } while (ldpService.exists(con, newResource));
+ } while (ldpService.exists(conn, newResource));
log.debug("resolved name clash, new resource will be <{}>", newResource);
} else {
log.debug("no name clash for <{}>", newResource);
@@ -215,25 +214,29 @@ public class LdpWebService {
log.debug("POST to <{}> will create new LDP-R <{}>", container, newResource);
+ //checking if resource (container) exists is done later in the service
try {
- ldpService.addResource(con, container, newResource, type, postBody);
- final Response.ResponseBuilder resp = createResponse(con, Response.Status.CREATED, container).location(java.net.URI.create(newResource));
- con.commit();
- return resp.build();
+ String location = ldpService.addResource(conn, container, newResource, type, 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
+ }
+ conn.commit();
+ return response.build();
} catch (IOException | RDFParseException e) {
- final Response.ResponseBuilder resp = createResponse(con, Response.Status.BAD_REQUEST, container).entity(e.getClass().getSimpleName() + ": " + e.getMessage());
- con.rollback();
+ final Response.ResponseBuilder resp = createResponse(conn, Response.Status.BAD_REQUEST, container).entity(e.getClass().getSimpleName() + ": " + e.getMessage());
+ conn.rollback();
return resp.build();
} catch (UnsupportedRDFormatException e) {
- final Response.ResponseBuilder resp = createResponse(con, Response.Status.UNSUPPORTED_MEDIA_TYPE, container).entity(e);
- con.rollback();
+ final Response.ResponseBuilder resp = createResponse(conn, Response.Status.UNSUPPORTED_MEDIA_TYPE, container).entity(e);
+ conn.rollback();
return resp.build();
}
} catch (final Throwable t) {
- con.rollback();
+ conn.rollback();
throw t;
} finally {
- con.close();
+ conn.close();
}
}