Browse Source

Temporary commit

Christophe Debruyne 8 years ago
parent
commit
c5e71a1b78

+ 3 - 0
src/r2rml/engine/RRF.java

@@ -23,4 +23,7 @@ public final class RRF {
 	public static final Property functionName = ResourceFactory.createProperty(NS + "functionName");
 	public static final Property functionName = ResourceFactory.createProperty(NS + "functionName");
 	public static final Property parameterBindings = ResourceFactory.createProperty(NS + "parameterBindings");
 	public static final Property parameterBindings = ResourceFactory.createProperty(NS + "parameterBindings");
 	
 	
+	// Properties for Containers and Collections
+	public static final Property gather = ResourceFactory.createProperty(NS + "gather");
+	
 }
 }

+ 25 - 0
src/r2rml/model/Gather.java

@@ -0,0 +1,25 @@
+package r2rml.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Gather Class.
+ * 
+ * @author Christophe Debruyne
+ * @version 0.1
+ *
+ */
+
+public class Gather {
+	
+	private List<TermMap> termMaps = new ArrayList<TermMap>();
+		
+	public List<TermMap> getTermMaps() {
+		return termMaps;
+	}
+
+	public void addTermMap(TermMap termMap) {
+		termMaps.add(termMap);
+	}
+}

+ 7 - 4
src/r2rml/model/ObjectMap.java

@@ -5,6 +5,7 @@ import java.util.List;
 import org.apache.jena.rdf.model.RDFNode;
 import org.apache.jena.rdf.model.RDFNode;
 import org.apache.jena.rdf.model.Resource;
 import org.apache.jena.rdf.model.Resource;
 import org.apache.jena.rdf.model.Statement;
 import org.apache.jena.rdf.model.Statement;
+import org.apache.jena.vocabulary.RDF;
 import org.apache.log4j.Logger;
 import org.apache.log4j.Logger;
 
 
 import r2rml.engine.R2RML;
 import r2rml.engine.R2RML;
@@ -89,8 +90,6 @@ public class ObjectMap extends TermMap {
 		return true;
 		return true;
 	}
 	}
 
 
-
-
 	@Override
 	@Override
 	protected RDFNode distillConstant(RDFNode node) {
 	protected RDFNode distillConstant(RDFNode node) {
 		// If the constant-valued term map is an object map, then its 
 		// If the constant-valued term map is an object map, then its 
@@ -109,8 +108,8 @@ public class ObjectMap extends TermMap {
 	@Override
 	@Override
 	protected boolean isChosenTermTypeValid() {
 	protected boolean isChosenTermTypeValid() {
 		// Check if invalid URI was provided!
 		// Check if invalid URI was provided!
-		if(!(isTermTypeLiteral() || isTermTypeBlankNode() || isTermTypeIRI())) {
+		if(!(isTermTypeLiteral() || isTermTypeBlankNode() || isTermTypeIRI() || isTermTypeList() || isTermTypeContainer())) {
-			logger.error("TermType for ObjectMap must be rr:IRI, rr:Literal or rr:BlankNode.");
+			logger.error("TermType for ObjectMap must be rr:IRI, rr:Literal, rr:BlankNode, rdf:List, rdf:Bag, rdf:Alt, or rdf:Seq.");
 			logger.error(description);
 			logger.error(description);
 			return false;
 			return false;
 		}
 		}
@@ -132,6 +131,10 @@ public class ObjectMap extends TermMap {
 		/* We assume that functions are also by default literals */
 		/* We assume that functions are also by default literals */
 		if(isFunctionValuedTermMap())
 		if(isFunctionValuedTermMap())
 			return R2RML.LITERAL;
 			return R2RML.LITERAL;
+		
+		/* We assume that gathers are also by default collections */
+		if(isGatherTermMap())
+			return RDF.List;
 
 
 		return R2RML.IRI;
 		return R2RML.IRI;
 	}
 	}

+ 2 - 1
src/r2rml/model/PredicateObjectMap.java

@@ -119,7 +119,8 @@ public class PredicateObjectMap extends R2RMLResource {
 			boolean isOM = r.hasProperty(R2RML.column) 
 			boolean isOM = r.hasProperty(R2RML.column) 
 					|| r.hasProperty(R2RML.constant) 
 					|| r.hasProperty(R2RML.constant) 
 					|| r.hasProperty(R2RML.template)
 					|| r.hasProperty(R2RML.template)
-					|| r.hasProperty(RRF.functionCall);
+					|| r.hasProperty(RRF.functionCall)
+					|| r.hasProperty(RRF.gather);
 			boolean isROM = r.hasProperty(R2RML.joinCondition);
 			boolean isROM = r.hasProperty(R2RML.joinCondition);
 
 
 			// If it plays the roles of a OM, create OM
 			// If it plays the roles of a OM, create OM

+ 116 - 17
src/r2rml/model/TermMap.java

@@ -17,12 +17,15 @@ import org.apache.jena.datatypes.RDFDatatype;
 import org.apache.jena.enhanced.UnsupportedPolymorphismException;
 import org.apache.jena.enhanced.UnsupportedPolymorphismException;
 import org.apache.jena.iri.IRI;
 import org.apache.jena.iri.IRI;
 import org.apache.jena.iri.IRIFactory;
 import org.apache.jena.iri.IRIFactory;
+import org.apache.jena.rdf.model.Container;
+import org.apache.jena.rdf.model.ModelFactory;
 import org.apache.jena.rdf.model.RDFList;
 import org.apache.jena.rdf.model.RDFList;
 import org.apache.jena.rdf.model.RDFNode;
 import org.apache.jena.rdf.model.RDFNode;
 import org.apache.jena.rdf.model.Resource;
 import org.apache.jena.rdf.model.Resource;
 import org.apache.jena.rdf.model.ResourceFactory;
 import org.apache.jena.rdf.model.ResourceFactory;
 import org.apache.jena.rdf.model.Statement;
 import org.apache.jena.rdf.model.Statement;
 import org.apache.jena.util.iterator.ExtendedIterator;
 import org.apache.jena.util.iterator.ExtendedIterator;
+import org.apache.jena.vocabulary.RDF;
 import org.apache.jena.vocabulary.XSD;
 import org.apache.jena.vocabulary.XSD;
 import org.apache.log4j.Logger;
 import org.apache.log4j.Logger;
 
 
@@ -61,6 +64,7 @@ public abstract class TermMap extends R2RMLResource {
 	private RDFNode constant;
 	private RDFNode constant;
 	private String column;
 	private String column;
 	private FunctionCall functionCall;
 	private FunctionCall functionCall;
+	private Gather gather;
 
 
 	protected String language = null;
 	protected String language = null;
 	protected Resource datatype = null;
 	protected Resource datatype = null;
@@ -79,10 +83,11 @@ public abstract class TermMap extends R2RMLResource {
 		List<Statement> constants = description.listProperties(R2RML.constant).toList();
 		List<Statement> constants = description.listProperties(R2RML.constant).toList();
 		List<Statement> columns = description.listProperties(R2RML.column).toList();
 		List<Statement> columns = description.listProperties(R2RML.column).toList();
 		List<Statement> functions = description.listProperties(RRF.functionCall).toList();
 		List<Statement> functions = description.listProperties(RRF.functionCall).toList();
+		List<Statement> gathers = description.listProperties(RRF.gather).toList();
 
 
 		// Having exactly one of rr:constant, rr:column, rr:template
 		// Having exactly one of rr:constant, rr:column, rr:template
-		if(templates.size() + constants.size() + columns.size() + functions.size() != 1) {
+		if(templates.size() + constants.size() + columns.size() + functions.size() + gathers.size() != 1) {
-			logger.error("TermMap must have exactly one of rr:constant, rr:column, and rr:template.");
+			logger.error("TermMap must have exactly one of rr:constant, rr:column, rr:template, rrf:functionCall, and rrf:gather.");
 			logger.error(description);
 			logger.error(description);
 			return false;
 			return false;
 		}
 		}
@@ -122,7 +127,7 @@ public abstract class TermMap extends R2RMLResource {
 			functionCall = distillFunction(functions.get(0).getObject());
 			functionCall = distillFunction(functions.get(0).getObject());
 			if(functionCall == null)
 			if(functionCall == null)
 				return false;
 				return false;
-			
+
 			// Check whether the referenced column names are valid
 			// Check whether the referenced column names are valid
 			for(String columnName : getReferencedColumns()) {
 			for(String columnName : getReferencedColumns()) {
 				if(!R2RMLUtil.isValidColumnName(columnName)) {
 				if(!R2RMLUtil.isValidColumnName(columnName)) {
@@ -131,6 +136,19 @@ public abstract class TermMap extends R2RMLResource {
 					return false;
 					return false;
 				}
 				}
 			}
 			}
+		} else if(gathers.size() == 1) {
+			gather = distillGather(gathers.get(0).getObject());
+			if(gather == null)
+				return false;
+
+			// Check whether the referenced column names are valid
+			for(String columnName : getReferencedColumns()) {
+				if(!R2RMLUtil.isValidColumnName(columnName)) {
+					logger.error("Invalid column name in rrf:gather " + columnName);
+					logger.error(description);
+					return false;
+				}
+			}
 		}
 		}
 
 
 		// Validity of the termType is also local. 
 		// Validity of the termType is also local. 
@@ -160,20 +178,54 @@ public abstract class TermMap extends R2RMLResource {
 		return true;
 		return true;
 	}
 	}
 
 
-	private FunctionCall distillFunction(RDFNode node) {
+	private Gather distillGather(RDFNode node) {
-		if(node.isLiteral())
+		if(!node.canAs(RDFList.class)){
+			logger.error("rrf:gather should be used on a RDF collection.");
 			return null;
 			return null;
+		}
+
+		RDFList list = node.as(RDFList.class);
 		
 		
+		Gather gather = new Gather();
+
+		ExtendedIterator<RDFNode> iter = list.iterator();
+		while(iter.hasNext()) {
+			RDFNode param = iter.next();
+			if(!param.isResource()) {
+				logger.error("Nodes in rrf:gather have to be resources.");
+				logger.error(description);
+				return null;
+			}
+			
+			ObjectMap om = new ObjectMap(param.asResource(), baseIRI);
+			if(om.preProcessAndValidate()) {
+				gather.addTermMap(om);
+			} else {
+				logger.error("Something went wrong processing parameter.");
+				logger.error(description);
+				return null;
+			}
+		}
+
+		return gather;
+	}
+
+	private FunctionCall distillFunction(RDFNode node) {
+		if(node.isLiteral()) {
+			logger.error("FunctionCall cannot be a literal.");
+			return null;
+		}
+
 		// fcn stands for Function Call Node
 		// fcn stands for Function Call Node
 		Resource fcn = node.asResource();
 		Resource fcn = node.asResource();
-		
+
 		List<Statement> functions = fcn.listProperties(RRF.function).toList();
 		List<Statement> functions = fcn.listProperties(RRF.function).toList();
 		if(functions.size() != 1) {
 		if(functions.size() != 1) {
 			logger.error("Function valued TermMap must have exactly one rrf:function.");
 			logger.error("Function valued TermMap must have exactly one rrf:function.");
 			logger.error(description);
 			logger.error(description);
 			return null;
 			return null;
 		}
 		}
-		
+
 		// Process the function, get the function name and then the parameters
 		// Process the function, get the function name and then the parameters
 		RDFNode f = functions.get(0).getObject();
 		RDFNode f = functions.get(0).getObject();
 		String functionname = JSEnv.registerFunction(f);
 		String functionname = JSEnv.registerFunction(f);
@@ -181,14 +233,14 @@ public abstract class TermMap extends R2RMLResource {
 			// Something went wrong, reported by the function. 
 			// Something went wrong, reported by the function. 
 			return null;
 			return null;
 		}
 		}
-		
+
 		List<Statement> pbindings = fcn.listProperties(RRF.parameterBindings).toList();
 		List<Statement> pbindings = fcn.listProperties(RRF.parameterBindings).toList();
 		if(pbindings.size() != 1) {
 		if(pbindings.size() != 1) {
 			logger.error("Function valued TermMap must have exactly one rrf:parameterBindings.");
 			logger.error("Function valued TermMap must have exactly one rrf:parameterBindings.");
 			logger.error(description);
 			logger.error(description);
 			return null;
 			return null;
 		}
 		}
-		
+
 		RDFList list = null;
 		RDFList list = null;
 		try {
 		try {
 			list = pbindings.get(0).getObject().as(RDFList.class);
 			list = pbindings.get(0).getObject().as(RDFList.class);
@@ -197,9 +249,9 @@ public abstract class TermMap extends R2RMLResource {
 			logger.error(description);
 			logger.error(description);
 			return null;
 			return null;
 		}
 		}
-		
+
-		functionCall = new FunctionCall(functionname);
+		FunctionCall functionCall = new FunctionCall(functionname);
-		
+
 		ExtendedIterator<RDFNode> iter = list.iterator();
 		ExtendedIterator<RDFNode> iter = list.iterator();
 		while(iter.hasNext()) {
 		while(iter.hasNext()) {
 			RDFNode param = iter.next();
 			RDFNode param = iter.next();
@@ -217,7 +269,7 @@ public abstract class TermMap extends R2RMLResource {
 				return null;
 				return null;
 			}
 			}
 		}
 		}
-		
+
 		return functionCall;
 		return functionCall;
 	}
 	}
 
 
@@ -291,11 +343,15 @@ public abstract class TermMap extends R2RMLResource {
 	public boolean isConstantValuedTermMap() {
 	public boolean isConstantValuedTermMap() {
 		return constant != null;
 		return constant != null;
 	}
 	}
-	
+
 	public boolean isFunctionValuedTermMap() {
 	public boolean isFunctionValuedTermMap() {
 		return functionCall != null;
 		return functionCall != null;
 	}
 	}
 
 
+	public boolean isGatherTermMap() {
+		return gather != null;
+	}
+
 	public Resource getTermType() {
 	public Resource getTermType() {
 		return termType;
 		return termType;
 	}
 	}
@@ -311,6 +367,20 @@ public abstract class TermMap extends R2RMLResource {
 	public boolean isTermTypeLiteral() {
 	public boolean isTermTypeLiteral() {
 		return getTermType().getURI().equals(R2RML.LITERAL.getURI());
 		return getTermType().getURI().equals(R2RML.LITERAL.getURI());
 	}
 	}
+	
+	public boolean isTermTypeList() {
+		return getTermType().getURI().equals(RDF.List.getURI());
+	}
+	
+	public boolean isTermTypeContainer() {
+		if(getTermType().getURI().equals(RDF.Bag.getURI()))
+			return true;
+		if(getTermType().getURI().equals(RDF.Seq.getURI()))
+			return true;
+		if(getTermType().getURI().equals(RDF.Alt.getURI()))
+			return true;
+		return false;
+	}
 
 
 	public RDFNode generateRDFTerm(Row row) throws R2RMLException {
 	public RDFNode generateRDFTerm(Row row) throws R2RMLException {
 		Object value = getValueForRDFTerm(row);
 		Object value = getValueForRDFTerm(row);
@@ -331,13 +401,13 @@ public abstract class TermMap extends R2RMLResource {
 			IRI iri = IRIFactory.iriImplementation().create(value.toString());
 			IRI iri = IRIFactory.iriImplementation().create(value.toString());
 			if(iri.isAbsolute())
 			if(iri.isAbsolute())
 				return ResourceFactory.createResource(convertToIRISafeVersion(iri));
 				return ResourceFactory.createResource(convertToIRISafeVersion(iri));
-			
+
 			iri = IRIFactory.iriImplementation().create(baseIRI + value);
 			iri = IRIFactory.iriImplementation().create(baseIRI + value);
 			if(iri.isAbsolute())
 			if(iri.isAbsolute())
 				return ResourceFactory.createResource(convertToIRISafeVersion(iri));
 				return ResourceFactory.createResource(convertToIRISafeVersion(iri));
-			
+
 			throw new R2RMLException("Data error. " + baseIRI + value + " is not a valid absolute IRI", null);
 			throw new R2RMLException("Data error. " + baseIRI + value + " is not a valid absolute IRI", null);
-			
+
 		}
 		}
 		/*
 		/*
 		 * Otherwise, if the term type is rr:BlankNode: Return a blank node 
 		 * Otherwise, if the term type is rr:BlankNode: Return a blank node 
@@ -376,6 +446,8 @@ public abstract class TermMap extends R2RMLResource {
 			}
 			}
 			return ResourceFactory.createTypedLiteral(value);
 			return ResourceFactory.createTypedLiteral(value);
 		}
 		}
+		
+		
 		return null;
 		return null;
 	}
 	}
 
 
@@ -439,6 +511,33 @@ public abstract class TermMap extends R2RMLResource {
 			} catch (NoSuchMethodException | ScriptException e) {
 			} catch (NoSuchMethodException | ScriptException e) {
 				throw new R2RMLException("Error invoking function.", e);
 				throw new R2RMLException("Error invoking function.", e);
 			}
 			}
+		} else if (isGatherTermMap()) {
+			List<Object> items = new ArrayList<>();
+			for(TermMap tm : gather.getTermMaps()) {
+				Object item = tm.getValueForRDFTerm(row);
+				if(item != null)
+					items.add(item);
+			}
+			
+			if(isTermTypeContainer()) {
+				Container c = null;
+				if(getTermType().getURI().equals(RDF.Bag.getURI()))
+					c = ModelFactory.createDefaultModel().createBag();
+				if(getTermType().getURI().equals(RDF.Seq.getURI()))
+					c = ModelFactory.createDefaultModel().createSeq();
+				if(getTermType().getURI().equals(RDF.Alt.getURI()))
+					c = ModelFactory.createDefaultModel().createAlt();
+				
+				for(Object item : items)
+					c.add(item);
+				
+				return c;
+			} else if(isTermTypeList()) {
+				RDFList list = ModelFactory.createDefaultModel().createList();
+				for(Object item : items)
+					list.add((RDFNode) item);
+				return list;
+			}
 		}
 		}
 		return null;
 		return null;
 	}
 	}

+ 25 - 0
test/resources/COL01.mapping.ttl

@@ -0,0 +1,25 @@
+@prefix rr: <http://www.w3.org/ns/r2rml#> .
+@prefix ex: <http://example.com/ns#> .
+@prefix rrf: <http://kdeg.scss.tcd.ie/ns/rrf#>
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+
+<#TriplesMap1>
+    rr:logicalTable [ rr:tableName "PERSON" ];
+
+    rr:subjectMap [
+        rr:template "http://data.example.com/person/{ID}";
+    ];
+    
+    rr:predicateObjectMap [
+        rr:predicate ex:name;
+        rr:objectMap [ 
+        	rrf:gather (
+        		[ rr:column "TITLE" ]
+        		[ rr:column "FNAME" ] 
+        		[ rr:column "LNAME" ]  
+        	) ;
+        	rr:termType rdf:Bag ;
+        ];
+    ]
+    
+    .

+ 1 - 0
test/resources/PERSON.CSV

@@ -0,0 +1 @@
+ID,TITLE,FNAME,LNAME
1,Dr.,Christophe,Debruyne
2,,Lucy,McKenna
3,Prof.,Declan,O'Sullivan

+ 5 - 0
test/resources/PET.CSV

@@ -0,0 +1,5 @@
+ID,OWNER,NAME
+1,1,Victor
+2,1,Louis
+3,1,Bettina
+4,2,Snuggles

+ 44 - 0
test/test/TestR2RMLCOL.java

@@ -0,0 +1,44 @@
+package test;
+
+import org.apache.jena.rdf.model.Model;
+import org.apache.log4j.BasicConfigurator;
+import org.junit.BeforeClass;
+
+import junit.framework.TestCase;
+import r2rml.engine.Configuration;
+import r2rml.engine.R2RMLProcessor;
+
+/**
+ * Unit test for testing the functionality CSV to JDBC
+ * in memory database.
+ * 
+ * @author Christophe Debruyne
+ *
+ */
+public class TestR2RMLCOL extends TestCase {
+
+	//private static Logger logger = Logger.getLogger(TestR2RMLCSV.class.getName());
+	//private static String connectionURL = "jdbc:derby:memory:testing";
+
+	public TestR2RMLCOL(String testName) {
+		super(testName);
+	}
+
+	@BeforeClass
+	public static void init() throws Exception {
+		// Log4J junit configuration.
+		BasicConfigurator.configure();
+	}
+
+	public void testExampleCSV01() {
+		Configuration configuration = new Configuration();
+		configuration.setMappingFile("./test/resources/COL01.mapping.ttl");
+		configuration.getCSVFiles().add("./test/resources/PERSON.CSV");
+		configuration.getCSVFiles().add("./test/resources/PET.CSV");
+		R2RMLProcessor engine = new R2RMLProcessor(configuration);
+		engine.execute();
+		Model model = engine.getDataset().getDefaultModel();
+		model.write(System.out, "Turtle");
+	}
+
+}