Repository: marmotta
Updated Branches:
  refs/heads/MARMOTTA-556 ec0b81967 -> 9f39e3283


MARMOTTA-556: moved ldf logic out of a RDFHandler to properly manage some errors


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

Branch: refs/heads/MARMOTTA-556
Commit: 157e44e2b884db874a08509edf2a801766099fc7
Parents: ec0b819
Author: Sergio Fernández <[email protected]>
Authored: Mon Oct 27 16:56:20 2014 +0100
Committer: Sergio Fernández <[email protected]>
Committed: Mon Oct 27 16:56:20 2014 +0100

----------------------------------------------------------------------
 .../marmotta/platform/ldf/api/LdfService.java   |  33 ++--
 .../platform/ldf/services/LdfServiceImpl.java   |  98 ++++++++--
 .../platform/ldf/sesame/LdfRDFHandler.java      | 185 -------------------
 .../platform/ldf/webservices/LdfWebService.java |  17 +-
 4 files changed, 106 insertions(+), 227 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/marmotta/blob/157e44e2/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/api/LdfService.java
----------------------------------------------------------------------
diff --git 
a/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/api/LdfService.java
 
b/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/api/LdfService.java
index c2d7dff..e8f84ce 100644
--- 
a/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/api/LdfService.java
+++ 
b/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/api/LdfService.java
@@ -17,14 +17,11 @@
  */
 package org.apache.marmotta.platform.ldf.api;
 
+import org.openrdf.model.Model;
 import org.openrdf.model.Resource;
 import org.openrdf.model.URI;
-import org.openrdf.rio.RDFFormat;
 import org.openrdf.model.Value;
 import org.openrdf.repository.RepositoryException;
-import org.openrdf.rio.RDFHandlerException;
-
-import java.io.OutputStream;
 
 /**
  * Linked Media Fragments service
@@ -36,33 +33,31 @@ public interface LdfService {
     final static int PAGE_SIZE = 100;
 
     /**
-     * Writes a fragment matching the specified triple fragment pattern
+     * Gets a fragment matching the specified triple fragment pattern
      * specified (null values are wildcards).
      *
      * @param subject fragment subject
      * @param predicate fragmnent predicate
      * @param object fragment object
      * @param page number of page (starting with 1)
-     * @param format RDF serialization
-     * @param out output stream where write the fragment
+     * @return fragment
      */
-    void writeFragment(String subject, String predicate, String object, int 
page, RDFFormat format, OutputStream out) throws RepositoryException, 
RDFHandlerException, IllegalArgumentException;
+    Model getFragment(String subject, String predicate, String object, int 
page) throws RepositoryException, IllegalArgumentException;
 
     /**
-     * Writes a fragment matching the specified triple fragment pattern
+     * Gets a fragment matching the specified triple fragment pattern
      * specified (null values are wildcards).
      *
      * @param subject fragment subject
      * @param predicate fragmnent predicate
      * @param object fragment object
      * @param page number of page (starting with 1)
-     * @param format RDF serialization
-     * @param out output stream where write the fragment
+     * @return fragment
      */
-    void writeFragment(URI subject, URI predicate, Value object, int page, 
RDFFormat format, OutputStream out) throws RepositoryException, 
RDFHandlerException, IllegalArgumentException;
+    Model getFragment(URI subject, URI predicate, Value object, int page) 
throws RepositoryException, IllegalArgumentException;
 
     /**
-     * Writes a fragment matching the specified quad fragment pattern
+     * Gets a fragment matching the specified quad fragment pattern
      * specified (null values are wildcards).
      *
      * @param subject fragment subject
@@ -70,13 +65,12 @@ public interface LdfService {
      * @param object fragment object
      * @param context named graph
      * @param page number of page (starting with 1)
-     * @param format RDF serialization
-     * @param out output stream where write the fragment
+     * @return fragment
      */
-    void writeFragment(String subject, String predicate, String object, String 
context, int page, RDFFormat format, OutputStream out) throws 
RepositoryException, RDFHandlerException, IllegalArgumentException;
+    Model getFragment(String subject, String predicate, String object, String 
context, int page) throws RepositoryException, IllegalArgumentException;
 
     /**
-     * Writes a fragment matching the specified quad fragment pattern
+     * Gets a fragment matching the specified quad fragment pattern
      * specified (null values are wildcards).
      *
      * @param subject fragment subject
@@ -84,9 +78,8 @@ public interface LdfService {
      * @param object fragment object
      * @param context named graph
      * @param page number of page (starting with 1)
-     * @param format RDF serialization
-     * @param out output stream where write the fragment
+     * @return fragment
      */
-    void writeFragment(URI subject, URI predicate, Value object, Resource 
context, int page, RDFFormat format, OutputStream out) throws 
RepositoryException, RDFHandlerException, IllegalArgumentException;
+    Model getFragment(URI subject, URI predicate, Value object, Resource 
context, int page) throws RepositoryException, IllegalArgumentException;
 
 }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/157e44e2/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/services/LdfServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/services/LdfServiceImpl.java
 
b/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/services/LdfServiceImpl.java
index 4ccdfeb..09a4dc8 100644
--- 
a/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/services/LdfServiceImpl.java
+++ 
b/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/services/LdfServiceImpl.java
@@ -17,23 +17,30 @@
  */
 package org.apache.marmotta.platform.ldf.services;
 
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.marmotta.commons.sesame.repository.ResultUtils;
+import org.apache.marmotta.commons.vocabulary.XSD;
 import org.apache.marmotta.platform.core.api.triplestore.SesameService;
 import org.apache.marmotta.platform.ldf.api.LdfService;
-import org.apache.marmotta.platform.ldf.sesame.LdfRDFHandler;
+import org.apache.marmotta.platform.ldf.vocab.HYDRA;
+import org.apache.marmotta.platform.ldf.vocab.VOID;
 import org.openrdf.model.*;
+import org.openrdf.model.impl.TreeModel;
 import org.openrdf.model.impl.ValueFactoryImpl;
+import org.openrdf.model.vocabulary.RDF;
 import org.openrdf.repository.RepositoryConnection;
 import org.openrdf.repository.RepositoryException;
 import org.openrdf.repository.RepositoryResult;
-import org.openrdf.rio.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.inject.Inject;
-import java.io.OutputStream;
 import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
 
 /**
  * Linked Media Fragments service implementation
@@ -48,17 +55,17 @@ public class LdfServiceImpl implements LdfService {
     private SesameService sesameService;
 
     @Override
-    public void writeFragment(String subjectStr, String predicateStr, String 
objectStr, int page, RDFFormat format, OutputStream out) throws 
RepositoryException, RDFHandlerException, IllegalArgumentException {
-        writeFragment(subjectStr, predicateStr, objectStr, null, page, format, 
out);
+    public Model getFragment(String subjectStr, String predicateStr, String 
objectStr, int page) throws RepositoryException, IllegalArgumentException {
+        return getFragment(subjectStr, predicateStr, objectStr, null, page);
     }
 
     @Override
-    public void writeFragment(URI subject, URI predicate, Value object, int 
page, RDFFormat format, OutputStream out) throws RepositoryException, 
RDFHandlerException, IllegalArgumentException {
-        writeFragment(subject, predicate, object, null, page, format, out);
+    public Model getFragment(URI subject, URI predicate, Value object, int 
page) throws RepositoryException, IllegalArgumentException {
+        return getFragment(subject, predicate, object, null, page);
     }
 
     @Override
-    public void writeFragment(String subjectStr, String predicateStr, String 
objectStr, String contextStr, int page, RDFFormat format, OutputStream out) 
throws RepositoryException, RDFHandlerException, IllegalArgumentException {
+    public Model getFragment(String subjectStr, String predicateStr, String 
objectStr, String contextStr, int page) throws RepositoryException, 
IllegalArgumentException {
         final ValueFactoryImpl vf = new ValueFactoryImpl();
 
         URI subject = null;
@@ -101,22 +108,77 @@ public class LdfServiceImpl implements LdfService {
             }
         }
 
-        writeFragment(subject, predicate, object, context, page, format, out);
+        return getFragment(subject, predicate, object, context, page);
     }
 
     @Override
-    public void writeFragment(URI subject, URI predicate, Value object, 
Resource context, int page, RDFFormat format, OutputStream out) throws 
RepositoryException, RDFHandlerException, IllegalArgumentException {
+    public Model getFragment(URI subject, URI predicate, Value object, 
Resource context, int page) throws RepositoryException, 
IllegalArgumentException {
         final RepositoryConnection conn = sesameService.getConnection();
-        try {
-            conn.begin();
-            RepositoryResult<Statement> statements = 
conn.getStatements(subject, predicate, object, true, context);
-            RDFHandler handler = new LdfRDFHandler(Rio.createWriter(format, 
out), context, page);
-            Rio.write(ResultUtils.iterable(statements), handler);
-        } finally {
-            if (conn != null && conn.isOpen()) {
-                conn.close();
+        conn.begin();
+
+        //first get the triple fragment for ordering by a fixed criteria
+        //TODO: do this effectively
+        final RepositoryResult<Statement> results = 
conn.getStatements(subject, predicate, object, true, context);
+        final List<Statement> statements = 
FluentIterable.from(ResultUtils.iterable(results)).toSortedList(new 
Comparator<Statement>() {
+            @Override
+            public int compare(Statement s1, Statement s2) {
+                int subjectComparison = 
s1.getSubject().stringValue().compareTo(s2.getSubject().stringValue());
+                int predicatedComparison = 
s1.getPredicate().stringValue().compareTo(s2.getPredicate().stringValue());
+                if (subjectComparison != 0) {
+                    return subjectComparison;
+                } else if (predicatedComparison != 0) {
+                    return predicatedComparison;
+                } else if ((s1.getObject() instanceof Literal) && 
(s2.getObject() instanceof Resource)) {
+                    return 1;
+                } else if ((s1.getObject() instanceof Resource) && 
(s2.getObject() instanceof Literal)) {
+                    return -1;
+                } else {
+                    return 
s1.getObject().stringValue().compareTo(s2.getObject().stringValue());
+                }
             }
+        });
+        //ResultUtils takes care of closing the connection when consuming the 
RepositoryResult
+
+        //then filter
+        final int size = statements.size();
+        final int offset = LdfService.PAGE_SIZE * (page - 1);
+
+        if (offset > size) {
+            throw new IllegalArgumentException("page " + page + " can't be 
generated, empty fragment");
+        }
+
+        final Model model = new TreeModel();
+        final ValueFactoryImpl vf = new ValueFactoryImpl();
+
+        final int limit = LdfService.PAGE_SIZE < size - offset ? 
LdfService.PAGE_SIZE : size - offset;
+        List<Statement> filteredStatements = statements.subList(offset, limit);
+        if (filteredStatements.isEmpty()) {
+            throw new IllegalArgumentException("empty fragment");
         }
+
+        //add the fragment
+        model.addAll(filteredStatements);
+
+        //and add ldf metadata
+        Resource dataset = context != null ? context : vf.createBNode();
+        model.add(dataset, RDF.TYPE, VOID.Dataset);
+        model.add(dataset, RDF.TYPE, HYDRA.Collection);
+
+        Resource fragment = vf.createBNode(); //TODO
+        model.add(dataset, VOID.subset, fragment);
+        model.add(fragment, RDF.TYPE, HYDRA.Collection);
+        if (offset != 0 && limit != size) {
+            model.add(fragment, RDF.TYPE, HYDRA.PagedCollection);
+        }
+        model.add(fragment, VOID.triples, 
vf.createLiteral(Integer.toString(filteredStatements.size()), XSD.Integer));
+        model.add(fragment, HYDRA.totalItems, 
vf.createLiteral(Integer.toString(filteredStatements.size()), XSD.Integer));
+        model.add(fragment, HYDRA.itemsPerPage, 
vf.createLiteral(Integer.toString(LdfService.PAGE_SIZE), XSD.Integer));
+        //TODO: HYDRA_FIRSTPAGE, HYDRA_PREVIOUSPAGE, HYDRA_NEXTPAGE
+
+        //TODO: hydra controls
+
+        return model;
+
     }
 
 }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/157e44e2/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/sesame/LdfRDFHandler.java
----------------------------------------------------------------------
diff --git 
a/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/sesame/LdfRDFHandler.java
 
b/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/sesame/LdfRDFHandler.java
deleted file mode 100644
index 34ed85b..0000000
--- 
a/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/sesame/LdfRDFHandler.java
+++ /dev/null
@@ -1,185 +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.ldf.sesame;
-
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import org.apache.marmotta.commons.vocabulary.XSD;
-import org.apache.marmotta.platform.ldf.api.LdfService;
-import org.apache.marmotta.platform.ldf.vocab.HYDRA;
-import org.apache.marmotta.platform.ldf.vocab.VOID;
-import org.openrdf.model.Literal;
-import org.openrdf.model.Resource;
-import org.openrdf.model.Statement;
-import org.openrdf.model.impl.StatementImpl;
-import org.openrdf.model.impl.ValueFactoryImpl;
-import org.openrdf.model.vocabulary.RDF;
-import org.openrdf.model.vocabulary.RDFS;
-import org.openrdf.rio.RDFHandler;
-import org.openrdf.rio.RDFHandlerException;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * Specialized statements handler doing some LDF specific thing,
- * such as paging or metadata generation, before sending them to
- * the delegated RDFHandler.
- *
- * (TODO: find a more performance solution)
- *
- * @author Sergio Fernández
- */
-public class LdfRDFHandler implements RDFHandler {
-
-    private List<Statement> statements;
-    private final RDFHandler handler;
-    private final Resource context;
-    private final int page;
-
-    /**
-     * Constructs a PagedRDFHandler with a delegate handler
-     *
-     * @param handler The handler to delegate the calls to
-     */
-    public LdfRDFHandler(RDFHandler handler) {
-        this(handler, null, 1);
-    }
-
-    /**
-     * Constructs a PagedRDFHandler with a delegate handler
-     *
-     * @param handler The handler to delegate the calls to
-     * @param page number of page (starting with 1)
-     */
-    public LdfRDFHandler(RDFHandler handler, int page) {
-        this(handler, null, page);
-    }
-
-    /**
-     * Constructs a PagedRDFHandler with a delegate handler
-     *
-     * @param handler The handler to delegate the calls to
-     * @param context dataset
-     */
-    public LdfRDFHandler(RDFHandler handler, Resource context) {
-        this(handler, context, 1);
-    }
-
-    /**
-     * Constructs a PagedRDFHandler with a delegate handler
-     *
-     * @param handler The handler to delegate the calls to
-     * @param context dataset
-     * @param page number of page (starting with 1)
-     */
-    public LdfRDFHandler(RDFHandler handler, Resource context, int page) {
-        super();
-        this.statements = new ArrayList<>();
-        this.handler = handler;
-        this.context = context;
-        this.page = page;
-    }
-
-    @Override
-    public void startRDF() throws RDFHandlerException {
-        handler.startRDF();
-    }
-
-    @Override
-    public void endRDF() throws RDFHandlerException {
-        final ValueFactoryImpl vf = new ValueFactoryImpl();
-
-        //first order by a fixed criteria
-        Collections.sort(statements, new Comparator<Statement>() {
-            @Override
-            public int compare(Statement s1, Statement s2) {
-                int subjectComparison = 
s1.getSubject().stringValue().compareTo(s2.getSubject().stringValue());
-                int predicatedComparison = 
s1.getPredicate().stringValue().compareTo(s2.getPredicate().stringValue());
-                if (subjectComparison != 0) {
-                    return subjectComparison;
-                } else if (predicatedComparison != 0) {
-                    return predicatedComparison;
-                } else if((s1.getObject() instanceof Literal) && 
(s2.getObject() instanceof Resource)) {
-                    return 1;
-                } else if((s1.getObject() instanceof Resource) && 
(s2.getObject() instanceof Literal)) {
-                    return -1;
-                } else {
-                    return 
s1.getObject().stringValue().compareTo(s2.getObject().stringValue());
-                }
-            }
-        });
-
-        //then filter
-        final int size = statements.size();
-        final int offset = LdfService.PAGE_SIZE * (page - 1);
-        if (offset > size) {
-            //throw new RDFHandlerException("page " + page + " can't be 
generated");
-            Resource error = this.context != null ? this.context : 
vf.createBNode();
-            handler.handleStatement(new StatementImpl(error, RDF.TYPE, 
HYDRA.Error));
-            handler.handleStatement(new StatementImpl(error, RDFS.COMMENT, 
vf.createLiteral("page " + page + " can't be generated", "en")));
-        } else {
-            final int limit = LdfService.PAGE_SIZE < size - offset ? 
LdfService.PAGE_SIZE : size - offset;
-            List<Statement> filteredStatements = statements.subList(offset, 
limit);
-
-            //send statements to delegate writer
-            for (Statement statement : filteredStatements) {
-                handler.handleStatement(statement);
-            }
-
-            //add ldf metadata
-            Resource dataset = this.context != null ? this.context : 
vf.createBNode();
-            handler.handleStatement(new StatementImpl(dataset, RDF.TYPE, 
VOID.Dataset));
-            handler.handleStatement(new StatementImpl(dataset, RDF.TYPE, 
HYDRA.Collection));
-
-            Resource fragment = vf.createBNode(); //TODO
-            handler.handleStatement(new StatementImpl(dataset, VOID.subset, 
fragment));
-            handler.handleStatement(new StatementImpl(fragment, RDF.TYPE, 
HYDRA.Collection));
-            if (offset != 0 && limit != size) {
-                handler.handleStatement(new StatementImpl(fragment, RDF.TYPE, 
HYDRA.PagedCollection));
-            }
-            handler.handleStatement(new StatementImpl(fragment, VOID.triples, 
vf.createLiteral(Integer.toString(filteredStatements.size()), XSD.Integer)));
-            handler.handleStatement(new StatementImpl(fragment, 
HYDRA.totalItems, vf.createLiteral(Integer.toString(filteredStatements.size()), 
XSD.Integer)));
-            handler.handleStatement(new StatementImpl(fragment, 
HYDRA.itemsPerPage, vf.createLiteral(Integer.toString(LdfService.PAGE_SIZE), 
XSD.Integer)));
-            //TODO: HYDRA_FIRSTPAGE, HYDRA_PREVIOUSPAGE, HYDRA_NEXTPAGE
-
-            //TODO: hydra controls
-        }
-
-        //and actually end the rdf
-        handler.endRDF();
-    }
-
-    @Override
-    public void handleNamespace(String prefix, String uri) throws 
RDFHandlerException {
-        handler.handleNamespace(prefix, uri);
-    }
-
-    @Override
-    public void handleStatement(Statement statement) throws 
RDFHandlerException {
-        statements.add(statement);
-    }
-
-    @Override
-    public void handleComment(String comment) throws RDFHandlerException {
-        handler.handleComment(comment);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/157e44e2/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/webservices/LdfWebService.java
----------------------------------------------------------------------
diff --git 
a/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/webservices/LdfWebService.java
 
b/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/webservices/LdfWebService.java
index 0cc1f09..37b554c 100644
--- 
a/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/webservices/LdfWebService.java
+++ 
b/platform/marmotta-ldf/src/main/java/org/apache/marmotta/platform/ldf/webservices/LdfWebService.java
@@ -5,8 +5,8 @@ import org.apache.marmotta.commons.http.ContentType;
 import org.apache.marmotta.commons.http.MarmottaHttpUtils;
 import org.apache.marmotta.platform.core.api.config.ConfigurationService;
 import org.apache.marmotta.platform.core.api.exporter.ExportService;
-import org.apache.marmotta.platform.core.util.WebServiceUtil;
 import org.apache.marmotta.platform.ldf.api.LdfService;
+import org.openrdf.model.Model;
 import org.openrdf.repository.RepositoryException;
 import org.openrdf.rio.RDFFormat;
 import org.openrdf.rio.RDFHandlerException;
@@ -72,14 +72,23 @@ public class LdfWebService {
                                  final String context,
                                  final int page,
                                  final String accept) {
-        final RDFFormat format = getFormat(accept);
 
+        final Model fragment;
+        try {
+            fragment = ldfService.getFragment(subject, predicate, object, 
context, page);
+        } catch (RepositoryException e) {
+            return 
Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
+        } catch (IllegalArgumentException e) {
+            return 
Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
+        }
+
+        final RDFFormat format = getFormat(accept);
         StreamingOutput stream = new StreamingOutput() {
             @Override
             public void write(OutputStream outputStream) throws IOException, 
WebApplicationException {
                 try {
-                    ldfService.writeFragment(subject, predicate, object, 
context, page, format, outputStream);
-                } catch (RepositoryException | RDFHandlerException | 
IllegalArgumentException e) {
+                    Rio.write(fragment, outputStream, format);
+                } catch (RDFHandlerException e) {
                     throw new WebApplicationException(e);
                 }
             }

Reply via email to