MARMOTTA-449: draft implementation for storing LDP-BRs (i.e., non LDP-RR)

Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo
Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/f59d008e
Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/f59d008e
Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/f59d008e

Branch: refs/heads/develop
Commit: f59d008e1abd408de900658a08b100c046f05cb5
Parents: 7b2de20
Author: Sergio Fernández <[email protected]>
Authored: Sun Mar 2 12:29:50 2014 +0100
Committer: Sergio Fernández <[email protected]>
Committed: Sun Mar 2 12:29:50 2014 +0100

----------------------------------------------------------------------
 .../platform/ldp/api/LdpBinaryStoreService.java |  40 +++++++
 .../ldp/services/LdpBinaryStoreServiceImpl.java | 108 +++++++++++++++++++
 .../platform/ldp/services/LdpServiceImpl.java   |  40 ++++---
 3 files changed, 167 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/marmotta/blob/f59d008e/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
new file mode 100644
index 0000000..8e5d67d
--- /dev/null
+++ 
b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/api/LdpBinaryStoreService.java
@@ -0,0 +1,40 @@
+/*
+ * 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.api;
+
+import org.openrdf.model.URI;
+
+import java.io.InputStream;
+import java.net.URISyntaxException;
+
+/**
+ *  LDP Store Service
+ *
+ *  @author Sergio Fernández
+ */
+public interface LdpBinaryStoreService {
+
+    boolean store(String resource, InputStream stream);
+
+    boolean store(URI resource, InputStream stream);
+
+    InputStream read(String resource);
+
+    InputStream read(URI resource);
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/f59d008e/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
new file mode 100644
index 0000000..7476336
--- /dev/null
+++ 
b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpBinaryStoreServiceImpl.java
@@ -0,0 +1,108 @@
+/*
+ * 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.services;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.marmotta.platform.core.api.config.ConfigurationService;
+import org.apache.marmotta.platform.core.events.SystemStartupEvent;
+import org.apache.marmotta.platform.ldp.api.LdpBinaryStoreService;
+import org.openrdf.model.URI;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.inject.Inject;
+import java.io.*;
+import java.net.URISyntaxException;
+
+/**
+ * Very basic disk-based implementation of the LDP Binary Store
+ *
+ * @author Sergio Fernández
+ */
+@ApplicationScoped
+public class LdpBinaryStoreServiceImpl implements LdpBinaryStoreService {
+
+    private static final Logger log = 
LoggerFactory.getLogger(LdpBinaryStoreServiceImpl.class);
+
+    @Inject
+    private ConfigurationService configurationService;
+
+    private File base;
+
+    public void init(@Observes SystemStartupEvent e) {
+        base = new File(configurationService.getHome(), "data");
+        if (!base.exists()) {
+            base.mkdir();
+        }
+        log.info("Initialized binary data store over {}", 
base.getAbsolutePath());
+    }
+
+    private File getFile(String resource) throws URISyntaxException {
+        java.net.URI uri = new java.net.URI(resource);
+        String schema = uri.getScheme();
+        if ("http".compareTo(schema) != 0) {
+            String msg = "Binary storage not supported for URIs with " + 
schema + " as schema";
+            log.error(msg);
+            throw new RuntimeException(msg);
+        }
+        return new File(base, StringUtils.removeStart(resource, "http://";));
+    }
+
+    @Override
+    public boolean store(String resource, InputStream stream)  {
+        try {
+            File file = getFile(resource);
+            File dir = file.getParentFile();
+            if (!dir.exists()) {
+                dir.mkdirs();
+            }
+
+            OutputStream bufferedOutputStream = new BufferedOutputStream(new 
FileOutputStream(file));
+            int token = -1;
+            while((token = stream.read()) != -1) {
+                bufferedOutputStream.write(token);
+            }
+            bufferedOutputStream.flush();
+            bufferedOutputStream.close();
+            stream.close();
+
+            return true;
+        } catch (URISyntaxException | IOException e) {
+            log.error("{} resource cannot be stored on disk: {}", resource, 
e.getMessage());
+            return false;
+        }
+    }
+
+    @Override
+    public boolean store(URI resource, InputStream stream) {
+        return store(resource.stringValue(), stream);
+    }
+
+    @Override
+    public InputStream read(String resource) {
+        return null;
+    }
+
+    @Override
+    public InputStream read(URI resource) {
+        return read(resource.stringValue());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/f59d008e/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 21989a3..70f1beb 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
@@ -23,6 +23,7 @@ import info.aduna.iteration.UnionIteration;
 import org.apache.marmotta.commons.vocabulary.DCTERMS;
 import org.apache.marmotta.commons.vocabulary.LDP;
 import org.apache.marmotta.platform.core.api.config.ConfigurationService;
+import org.apache.marmotta.platform.ldp.api.LdpBinaryStoreService;
 import org.apache.marmotta.platform.ldp.api.LdpService;
 import 
org.apache.marmotta.platform.ldp.exceptions.InvalidModificationException;
 import org.apache.marmotta.platform.ldp.patch.InvalidPatchDocumentException;
@@ -31,10 +32,7 @@ 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.openrdf.model.Literal;
-import org.openrdf.model.Statement;
-import org.openrdf.model.URI;
-import org.openrdf.model.Value;
+import org.openrdf.model.*;
 import org.openrdf.model.impl.ValueFactoryImpl;
 import org.openrdf.model.vocabulary.RDF;
 import org.openrdf.repository.RepositoryConnection;
@@ -68,6 +66,15 @@ public class LdpServiceImpl implements LdpService {
     @Inject
     private ConfigurationService configurationService;
 
+    @Inject
+    private LdpBinaryStoreService binaryStore;
+
+    private final URI ldpContext;
+
+    public LdpServiceImpl() {
+        ldpContext = ValueFactoryImpl.getInstance().createURI(LDP.NAMESPACE);
+    }
+
     private URI buildURI(String resource) {
         return ValueFactoryImpl.getInstance().createURI(resource);
     }
@@ -79,7 +86,6 @@ public class LdpServiceImpl implements LdpService {
 
     @Override
     public boolean exists(RepositoryConnection connection, URI resource) 
throws RepositoryException {
-        final URI ldpContext = 
connection.getValueFactory().createURI(LDP.NAMESPACE);
         return connection.hasStatement(resource, null, null, true, ldpContext);
     }
 
@@ -90,8 +96,7 @@ public class LdpServiceImpl implements LdpService {
 
     @Override
     public List<Statement> getLdpTypes(RepositoryConnection connection, URI 
resource) throws RepositoryException {
-            final URI ldp = 
connection.getValueFactory().createURI(LDP.NAMESPACE);
-            return Iterations.asList(new FilterIteration<Statement, 
RepositoryException>(connection.getStatements(resource, RDF.TYPE, null, false, 
ldp)) {
+            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();
@@ -107,7 +112,6 @@ public class LdpServiceImpl implements LdpService {
 
     @Override
     public void exportResource(RepositoryConnection connection, URI resource, 
OutputStream output, RDFFormat format) throws RepositoryException, 
RDFHandlerException {
-        URI ldpContext = connection.getValueFactory().createURI(LDP.NAMESPACE);
         // TODO: this should be a little more sophisticated...
         // TODO: non-membership triples flag / Prefer-header
         RDFWriter writer = Rio.createWriter(format, output);
@@ -129,12 +133,12 @@ public class LdpServiceImpl implements LdpService {
 
     @Override
     public boolean addResource(RepositoryConnection connection, URI container, 
URI resource, MediaType type, InputStream stream) throws RepositoryException, 
IOException, RDFParseException {
-        final URI ldpContext = 
connection.getValueFactory().createURI(LDP.NAMESPACE);
+        ValueFactory valueFactory = connection.getValueFactory();
 
         // Add container triples (Sec. 6.4.3)
         // container and meta triples!
 
-        Literal now = connection.getValueFactory().createLiteral(new Date());
+        Literal now = valueFactory.createLiteral(new Date());
 
         connection.add(container, RDF.TYPE, LDP.BasicContainer, ldpContext);
         connection.add(container, LDP.contains, resource, ldpContext);
@@ -145,15 +149,15 @@ public class LdpServiceImpl implements LdpService {
         connection.add(resource, DCTERMS.created, now, ldpContext);
         connection.add(resource, DCTERMS.modified, now, ldpContext);
 
-        // TODO: No LDP-BC for now!
-
         // Add the bodyContent
         log.trace("Content ({}) for new resource <{}>", type, resource);
         final RDFFormat rdfFormat = 
Rio.getParserFormatForMIMEType(type.toString(), RDFFormat.TURTLE);
         if (rdfFormat == null) {
-            log.debug("POST creates new LDP-BR with type {}", type);
-            log.warn("LDP-BR not (yet) supported!");
-            throw new UnsupportedRDFormatException("No available parser for " 
+ type.toString());
+            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 ?
+            //TODO: something else?
+            return binaryStore.store(resource, stream); //TODO: control 
exceptions
         } else {
             log.debug("POST creates new LDP-RR, data provided as {}", 
rdfFormat.getName());
 
@@ -171,7 +175,6 @@ public class LdpServiceImpl implements LdpService {
 
     @Override
     public EntityTag generateETag(RepositoryConnection connection, URI uri) 
throws RepositoryException {
-        final URI ldpContext = 
connection.getValueFactory().createURI(LDP.NAMESPACE);
         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.
@@ -202,7 +205,6 @@ public class LdpServiceImpl implements LdpService {
 
     @Override
     public Date getLastModified(RepositoryConnection connection, URI uri) 
throws RepositoryException {
-        final URI ldpContext = 
connection.getValueFactory().createURI(LDP.NAMESPACE);
         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.
@@ -229,11 +231,8 @@ public class LdpServiceImpl implements LdpService {
 
     @Override
     public void patchResource(RepositoryConnection connection, URI uri, 
InputStream patchData, boolean strict) throws RepositoryException, 
ParseException, InvalidModificationException, InvalidPatchDocumentException {
-        final URI ldpContext = 
connection.getValueFactory().createURI(LDP.NAMESPACE);
-
         final Literal now = connection.getValueFactory().createLiteral(new 
Date());
 
-
         log.trace("parsing patch");
         List<PatchLine> patch = new RdfPatchParserImpl(patchData).parsePatch();
 
@@ -262,7 +261,6 @@ public class LdpServiceImpl implements LdpService {
 
     @Override
     public boolean deleteResource(RepositoryConnection connection, URI 
resource) throws RepositoryException {
-        final URI ldpContext = 
connection.getValueFactory().createURI(LDP.NAMESPACE);
         final Literal now = connection.getValueFactory().createLiteral(new 
Date());
 
         // Delete corresponding containment and membership triples (Sec. 6.6.1)

Reply via email to