Create ElementProcessor - add unit test
Signed-off-by: Jacek Grzebyta <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/any23/repo Commit: http://git-wip-us.apache.org/repos/asf/any23/commit/f787e42e Tree: http://git-wip-us.apache.org/repos/asf/any23/tree/f787e42e Diff: http://git-wip-us.apache.org/repos/asf/any23/diff/f787e42e Branch: refs/heads/master Commit: f787e42e0357949b44408645b4546cd447242862 Parents: c7dd09e Author: Jacek Grzebyta <[email protected]> Authored: Fri Oct 20 17:41:40 2017 +0100 Committer: Jacek Grzebyta <[email protected]> Committed: Fri Oct 20 17:41:40 2017 +0100 ---------------------------------------------------------------------- .../any23/extractor/yaml/ElementsProcessor.java | 117 +++++++++++++++++++ .../extractor/yaml/ElementsProcessorTest.java | 68 +++++++++++ 2 files changed, 185 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/any23/blob/f787e42e/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 new file mode 100644 index 0000000..f69ca0c --- /dev/null +++ b/core/src/main/java/org/apache/any23/extractor/yaml/ElementsProcessor.java @@ -0,0 +1,117 @@ +/* + * Copyright 2017 The Apache Software Foundation. + * + * Licensed 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.any23.extractor.yaml; + +import java.util.AbstractMap; +import java.util.List; +import java.util.Map; +import org.apache.any23.rdf.RDFUtils; +import org.apache.any23.vocab.YAML; +import org.eclipse.rdf4j.model.IRI; +import org.eclipse.rdf4j.model.Literal; +import org.eclipse.rdf4j.model.Model; +import org.eclipse.rdf4j.model.ModelFactory; +import org.eclipse.rdf4j.model.Resource; +import org.eclipse.rdf4j.model.Value; +import org.eclipse.rdf4j.model.ValueFactory; +import org.eclipse.rdf4j.model.impl.LinkedHashModelFactory; +import org.eclipse.rdf4j.model.impl.SimpleValueFactory; +import org.eclipse.rdf4j.model.util.Literals; +import org.eclipse.rdf4j.model.vocabulary.RDF; +import org.eclipse.rdf4j.model.vocabulary.RDFS; + +/** + * + * @author Jacek Grzebyta (grzebyta.dev [at] gmail.com) + */ +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) { + 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. + * + * @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 + */ + 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); + } 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) { + // 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) -> { + /* 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(); + Map.Entry<Value, Model> valInst = asModel(ns, object.get(k), subGraphRoot); + // if asModel returns null than + if (valInst != null) { + /* + Subgraph root node is added always. If subgraph is null that root node is Literal. + Otherwise submodel in added to the current model. + */ + model.add(vf.createStatement((Resource) nodeURI, (IRI) predicate, valInst.getKey())); + if (valInst.getValue() != null) { + model.addAll(valInst.getValue()); + } + } + + }); + return asMapEntry(nodeURI, model); + } +} http://git-wip-us.apache.org/repos/asf/any23/blob/f787e42e/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 new file mode 100644 index 0000000..94cf64a --- /dev/null +++ b/core/src/test/java/org/apache/any23/extractor/yaml/ElementsProcessorTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2017 The Apache Software Foundation. + * + * Licensed 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.any23.extractor.yaml; + +import java.io.StringWriter; +import java.util.HashMap; +import java.util.Map; +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.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; +import org.slf4j.LoggerFactory; + +/** + * + * @author Jacek Grzebyta (jgrzebyta [at] apache [dot] org) + */ +public class ElementsProcessorTest { + + private Logger log = LoggerFactory.getLogger(getClass()); + + @Test + public void processMap() throws Exception { + Map<String, Object> simpleMap = new HashMap<String, Object>() { + { + put("key1", "value1"); + put("key2", "value2"); + put("key3", 3); + } + }; + + ElementsProcessor ep = new ElementsProcessor(); + 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"); + Assert.assertTrue(toTest.getValue().size() > 0); + log.debug("Model: \n{}\n", dumpModel(toTest.getValue(), RDFFormat.TURTLE)); + } + + private String dumpModel(Model m, RDFFormat format) { + StringWriter writer = new StringWriter(); + Rio.write(m, writer, format); + return writer.toString(); + } +}
