any23-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jgrzeb...@apache.org
Subject [05/17] any23 git commit: Create ElementProcessor - RDF-izer
Date Thu, 07 Dec 2017 12:28:08 GMT
Create ElementProcessor - RDF-izer

- Add RDF-iser based on types
- add unit tests

Signed-off-by: Jacek Grzebyta <grzebyta.dev@gmail.com>


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

Branch: refs/heads/master
Commit: 9f0cb636d51fee439310b1180685f48402431516
Parents: f787e42
Author: Jacek Grzebyta <grzebyta.dev@gmail.com>
Authored: Sat Oct 21 10:27:06 2017 +0100
Committer: Jacek Grzebyta <grzebyta.dev@gmail.com>
Committed: Sat Oct 21 10:35:32 2017 +0100

----------------------------------------------------------------------
 .../any23/extractor/yaml/ElementsProcessor.java | 94 +++++++++++++++-----
 .../extractor/yaml/ElementsProcessorTest.java   | 55 ++++++++++--
 2 files changed, 120 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/any23/blob/9f0cb636/core/src/main/java/org/apache/any23/extractor/yaml/ElementsProcessor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/any23/extractor/yaml/ElementsProcessor.java b/core/src/main/java/org/apache/any23/extractor/yaml/ElementsProcessor.java
index f69ca0c..58bc003 100644
--- a/core/src/main/java/org/apache/any23/extractor/yaml/ElementsProcessor.java
+++ b/core/src/main/java/org/apache/any23/extractor/yaml/ElementsProcessor.java
@@ -16,10 +16,13 @@
 package org.apache.any23.extractor.yaml;
 
 import java.util.AbstractMap;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Stream;
 import org.apache.any23.rdf.RDFUtils;
 import org.apache.any23.vocab.YAML;
+import org.eclipse.rdf4j.model.BNode;
 import org.eclipse.rdf4j.model.IRI;
 import org.eclipse.rdf4j.model.Literal;
 import org.eclipse.rdf4j.model.Model;
@@ -34,6 +37,16 @@ import org.eclipse.rdf4j.model.vocabulary.RDF;
 import org.eclipse.rdf4j.model.vocabulary.RDFS;
 
 /**
+ * Converts Object into RDF graph encoded to {@link Map.Entry}. Where key is a
+ * graph root node and value is a graph itself inside a {@link Model}.
+ *
+ * This parser performs conversion for three main types:
+ * <ul>
+ * <li> List - Creates RDF:List with bnode as root
+ * <li> Map - Creates simple graph where {key: value} is converted to
+ * predicate:object pair
+ * <li> Simple type - Crates RDF Literal
+ * </ul>
  *
  * @author Jacek Grzebyta (grzebyta.dev [at] gmail.com)
  */
@@ -42,59 +55,60 @@ public class ElementsProcessor {
     private final ModelFactory modelFactory = new LinkedHashModelFactory();
     private final YAML vocab = YAML.getInstance();
     protected ValueFactory vf = SimpleValueFactory.getInstance();
-    
-    private Map.Entry<Value,Model> asMapEntry(Value v, Model m) {
+
+    private Map.Entry<Value, Model> asMapEntry(Value v, Model m) {
         return new AbstractMap.SimpleEntry(v, m);
     }
 
     /**
-     * Converts a data structure to {@link Map.Entry<Value,Model>}. where value is
a 
-     * root node of the data structure and model is a content of the RDF graph.
-     * 
-     * If requested object is simple object (i.e. is neither List or Map) than 
-     * method returns map entry of relevant instance of {@link Literal} as key and
-     * null as value.
-     * 
+     * Converts a data structure to {@link Map.Entry<Value,Model>}. where value
+     * is a root node of the data structure and model is a content of the RDF
+     * graph.
+     *
+     * If requested object is simple object (i.e. is neither List or Map) than
+     * method returns map entry of relevant instance of {@link Literal} as key
+     * and null as value.
+     *
      * @param namespace Namespace for predicates
      * @param t Object (or data structure) converting to RDF graph
-     * @param rootNode root node of the graph. If not given then blank node is created.
-     * @return 
+     * @param rootNode root node of the graph. If not given then blank node is
+     * created.
+     * @return
      */
-    public Map.Entry<Value,Model> asModel(IRI namespace, final Object t, Value rootNode)
{
+    public Map.Entry<Value, Model> asModel(IRI namespace, final Object t, Value rootNode)
{
         if (t == null) {
             return null;
         }
 
         if (t instanceof List) {
-            //return processList(namespace, (List) t);
+            return processList(namespace, (List) t);
         } else if (t instanceof Map) {
             return processMap(namespace, (Map) t, rootNode);
         } else {
             return asMapEntry(Literals.createLiteral(vf, t), null);
         }
-         return null;
     }
-    
-    protected Map.Entry<Value,Model> processMap(IRI ns, Map<String, Object> object,
Value rootNode) {
+
+    protected Map.Entry<Value, Model> processMap(IRI ns, Map<String, Object>
object, Value rootNode) {
         // check if map is empty of contains only null values
         if (object.isEmpty() || (object.values().size() == 1 && object.values().contains(null)))
{
             return null;
         }
         assert ns != null : "Namespace value is null";
-        
+
         Model model = modelFactory.createEmptyModel();
         Value nodeURI = rootNode == null ? RDFUtils.makeIRI() : rootNode;
         model.add(vf.createStatement((Resource) nodeURI, RDF.TYPE, vocab.mapping));
-        object.keySet().forEach( (k) -> {
+        object.keySet().forEach((k) -> {
             /* False prevents adding _<int> to the predicate.
             Thus the predicate pattern is:
             "some string" ---> ns:someString
-            */
+             */
             Resource predicate = RDFUtils.makeIRI(k, ns, false);
             /* add map's key as statements:
             predicate rdf:type rdf:predicate .
             predicate rdfs:label predicate name
-            */
+             */
             model.add(vf.createStatement(predicate, RDF.TYPE, RDF.PREDICATE));
             model.add(vf.createStatement(predicate, RDFS.LABEL, RDFUtils.literal(k)));
             Value subGraphRoot = RDFUtils.makeIRI();
@@ -110,8 +124,46 @@ public class ElementsProcessor {
                     model.addAll(valInst.getValue());
                 }
             }
-            
+
         });
         return asMapEntry(nodeURI, model);
     }
+
+    protected Map.Entry<Value, Model> processList(IRI ns, List<Object> object)
{
+
+        if (object.isEmpty() || object.stream().noneMatch((i) -> {
+            return i != null;
+        })) {
+            return null;
+        }
+        assert ns != null : "Namespace value is null";
+
+        // revers order
+        Collections.reverse(object);
+
+        Stream<Map.Entry<Value, Model>> nodesStream = object
+                .stream()
+                .map((i) -> {
+                    return asModel(ns, i, vf.createBNode());
+                });
+        // add last element
+        Map.Entry<Value, Model> outcome = Stream.concat(Stream.of(asMapEntry(RDF.NIL,
modelFactory.createEmptyModel())), nodesStream)
+                .reduce((res, i) -> {
+                    BNode currentNode = vf.createBNode();
+                    Value val = res.getKey();
+                    Model mod = res.getValue();
+
+                    mod.add(vf.createStatement(currentNode, RDF.FIRST, i.getKey()));
+                    mod.add(vf.createStatement(currentNode, RDF.REST, val));
+
+                    if (i.getValue() != null) {
+                        mod.addAll(i.getValue());
+                    }
+
+                    return asMapEntry(currentNode, mod);
+                }).get();
+
+        outcome.getValue().add(vf.createStatement((Resource) outcome.getKey(), RDF.TYPE,
RDF.LIST));
+        return outcome;
+    }
 }

http://git-wip-us.apache.org/repos/asf/any23/blob/9f0cb636/core/src/test/java/org/apache/any23/extractor/yaml/ElementsProcessorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/any23/extractor/yaml/ElementsProcessorTest.java
b/core/src/test/java/org/apache/any23/extractor/yaml/ElementsProcessorTest.java
index 94cf64a..d800d9e 100644
--- a/core/src/test/java/org/apache/any23/extractor/yaml/ElementsProcessorTest.java
+++ b/core/src/test/java/org/apache/any23/extractor/yaml/ElementsProcessorTest.java
@@ -16,17 +16,16 @@
 package org.apache.any23.extractor.yaml;
 
 import java.io.StringWriter;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import org.eclipse.rdf4j.model.Literal;
 import org.eclipse.rdf4j.model.Model;
-import org.eclipse.rdf4j.model.Resource;
 import org.eclipse.rdf4j.model.Value;
-import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
-import org.eclipse.rdf4j.repository.sail.SailRepository;
-import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
 import org.eclipse.rdf4j.rio.RDFFormat;
 import org.eclipse.rdf4j.rio.Rio;
-import org.eclipse.rdf4j.sail.memory.MemoryStore;
 import org.junit.Assert;
 import org.junit.Test;
 import org.slf4j.Logger;
@@ -49,10 +48,10 @@ public class ElementsProcessorTest {
                 put("key3", 3);
             }
         };
-
+        
         ElementsProcessor ep = new ElementsProcessor();
-        Map.Entry<Value, Model> toTest = ep.processMap(ep.vf.createIRI("http://example.org/"),

-                simpleMap, 
+        Map.Entry<Value, Model> toTest = ep.processMap(ep.vf.createIRI("http://example.org/"),
+                simpleMap,
                 ep.vf.createIRI("http://example.org/node1"));
         
         Assert.assertEquals(toTest.getKey().stringValue(), "http://example.org/node1");
@@ -60,6 +59,46 @@ public class ElementsProcessorTest {
         log.debug("Model: \n{}\n", dumpModel(toTest.getValue(), RDFFormat.TURTLE));
     }
     
+    @Test
+    public void processList() throws Exception {
+        List<Object> simpleList = new ArrayList<Object>() {
+            {
+                add("Ala");
+                add(6);
+                add("ma");
+                add("k".getBytes()[0]);
+            }
+        };
+        
+        ElementsProcessor ep = new ElementsProcessor();
+        Map.Entry<Value, Model> toTest = ep.processList(ep.vf.createIRI("http://example.org/data"),
simpleList);
+        Assert.assertNotNull(toTest);
+        Assert.assertTrue(toTest.getValue().contains(null, RDF.FIRST, ep.vf.createLiteral("Ala"),
null));
+        Assert.assertTrue(toTest.getValue().contains(null, RDF.FIRST, ep.vf.createLiteral(6),
null));
+        Assert.assertTrue(toTest.getValue().contains(null, RDF.FIRST, ep.vf.createLiteral("ma"),
null));
+        Assert.assertTrue(toTest.getValue().contains(null, RDF.FIRST, ep.vf.createLiteral("k".getBytes()[0]),
null));
+        log.debug("Model: \n{}\n", dumpModel(toTest.getValue(), RDFFormat.TURTLE));
+    }
+    
+    @Test
+    public void processSimple() throws Exception {
+        List<Object> simpleList = new ArrayList<Object>() {
+            {
+                add("Ala");
+                add(6);
+                add("ma");
+                add("k".getBytes()[0]);
+            }
+        };
+        ElementsProcessor ep = new ElementsProcessor();
+        
+        simpleList.forEach((i) -> {
+            Map.Entry<Value, Model> out = ep.asModel(ep.vf.createIRI("urn:test/"),
i, null);
+            Assert.assertTrue(out.getKey() instanceof Literal);
+            Assert.assertNull(out.getValue());
+        });
+    }
+    
     private String dumpModel(Model m, RDFFormat format) {
         StringWriter writer = new StringWriter();
         Rio.write(m, writer, format);


Mime
View raw message