Browse Source

preview methods added

Gavin Morris 5 years ago
parent
commit
ff556dfd0f

BIN
.DS_Store


BIN
src/.DS_Store


BIN
src/r2rml/.DS_Store


+ 34 - 5
src/r2rml/database/DB.java

@@ -7,6 +7,7 @@ import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.List;
 
+import r2rml.engine.Configuration;
 import r2rml.engine.R2RMLException;
 
 /**
@@ -17,21 +18,49 @@ import r2rml.engine.R2RMLException;
  *
  */
 public class DB {
+	public static final String MYSQL = "MySQL";
+	public static final String H2 = "H2";
 
 	private Connection connection = null;
 	private List<Statement> statements = new ArrayList<Statement>();
+	private Configuration configuration = null;
 
-	public DB(Connection connection) {
+	public DB(Connection connection, Configuration configuration) {
 		this.connection = connection;
+		this.configuration = configuration;
+	}
+
+	public Connection getConnection() {
+		return connection;
+	}
+
+	public void setConnection(Connection connection) {
+		this.connection = connection;
+	}
+
+	public Configuration getConfiguration() {
+		return configuration;
+	}
+
+	public void setConfiguration(Configuration configuration) {
+		this.configuration = configuration;
 	}
 
 	public Rows getRows(String query) throws R2RMLException {
-		try{
+		try {
 			Statement statement = connection.createStatement();
 			statements.add(statement);
+			if (configuration.isPreview()) {
+				if (connection.getMetaData().getDatabaseProductName().equals(MYSQL)
+						|| connection.getMetaData().getDatabaseProductName().equals(H2)) {
+					query += " LIMIT 1";
+				} else {
+					query += query.contains("WHERE") ? " AND ROWNUM < 2" : " WHERE ROWNUM < 2";
+				}
+			}
 			ResultSet resultset = statement.executeQuery(query);
 			return new Rows(resultset);
-		} catch(SQLException e) {
+		} catch (SQLException e) {
 			throw new R2RMLException(e.getMessage(), e);
 		}
 	}
@@ -39,7 +68,7 @@ public class DB {
 	public void close() throws R2RMLException {
 		if (!statements.isEmpty()) {
 			try {
-				for(Statement statement : statements) {
+				for (Statement statement : statements) {
 					statement.close();
 				}
 				statements.clear();
@@ -47,7 +76,7 @@ public class DB {
 				throw new R2RMLException(e.getMessage(), e);
 			}
 		}
-		
+
 	}
 
 }

+ 8 - 0
src/r2rml/database/Row.java

@@ -23,6 +23,14 @@ public class Row {
 		this.indexMap = indexMap;
 	}
 
+	public ResultSet getResultSet() {
+		return resultset;
+	}
+
+	public void setResultSet(ResultSet resultset) {
+		this.resultset = resultset;
+	}
+
 	public Object getObject(String column) throws R2RMLException {
 		try {
 			Integer index = indexMap.get(column);

+ 9 - 0
src/r2rml/engine/Configuration.java

@@ -31,6 +31,7 @@ public class Configuration {
 	private boolean filePerGraph = false;
 	private List<String> CSVFiles = new ArrayList<String>();
 	private String mapping;
+	private boolean preview = false;
 
 	public Configuration(String path) throws R2RMLException {
 		Properties properties = new Properties();
@@ -155,5 +156,13 @@ public class Configuration {
 	public void setMapping(String mapping) {
 		this.mapping = mapping;
 	}
+
+	public boolean isPreview() {
+		return preview;
+	}
+	
+	public void setPreview(boolean preview) {
+		this.preview = preview;
+	}
 	
 }

+ 2 - 2
src/r2rml/engine/R2RMLProcessor.java

@@ -52,7 +52,7 @@ public class R2RMLProcessor {
 			System.exit(-1);
 		}
 
-		DB database = new DB(connection);
+		DB database = new DB(connection, configuration);
 		
 		boolean abort = false;
 		
@@ -151,4 +151,4 @@ public class R2RMLProcessor {
 	public Dataset getDataset() {
 		return dataset;
 	}
-}
+}

BIN
src/r2rml/model/.DS_Store


+ 0 - 3
src/r2rml/model/ObjectMap.java

@@ -82,12 +82,9 @@ public class ObjectMap extends TermMap {
 					logger.error(description);
 					return false;
 				}
-
 				datatype = node.asResource();
 			}
-
 		}
-
 		return true;
 	}
 

+ 59 - 24
src/r2rml/model/R2RMLUtil.java

@@ -1,6 +1,11 @@
 package r2rml.model;
 
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.jena.rdf.model.RDFNode;
 import org.apache.log4j.Logger;
@@ -8,15 +13,17 @@ import org.apache.log4j.Logger;
 public class R2RMLUtil {
 
 	private static Logger logger = Logger.getLogger(R2RMLUtil.class.getName());
-	
+
 	public static boolean isValidLanguageTag(RDFNode node) {
-		if(!node.isLiteral()) return false;
+		if (!node.isLiteral())
+			return false;
 		// TODO: Implement language tag check
 		return true;
 	}
-	
+
 	/**
-	 * Utility function to check whether the string denoting a column name is valid
+	 * Utility function to check whether the string denoting a column name is
+	 * valid
 	 * 
 	 * @param columnName
 	 * @return True if a valid column name
@@ -27,33 +34,61 @@ public class R2RMLUtil {
 	}
 
 	public static String createJointQuery(TriplesMap child, TriplesMap parent, List<Join> joins) {
-		// If the child query and parent query of a referencing object 
-		// map are not identical, then the referencing object map must 
+		// If the child query and parent query of a referencing object
+		// map are not identical, then the referencing object map must
 		// have at least one join condition.
-		
+
 		String cquery = child.getLogicalTable().generateQuery();
 		String pquery = parent.getLogicalTable().generateQuery();
-		
-		if(!cquery.equals(pquery) && joins.isEmpty()) {
-			logger.error("If the child query and parent query of a referencing object map are not identical, then the referencing object map must have at least one join condition.");
+
+		if (!cquery.equals(pquery) && joins.isEmpty()) {
+			logger.error(
+					"If the child query and parent query of a referencing object map are not identical, then the referencing object map must have at least one join condition.");
 			return null;
 		}
-		
+
 		// If the referencing object map has no join condition
-		if(joins.isEmpty())
+		if (joins.isEmpty())
 			return "SELECT * FROM (" + cquery + ") AS tmp";
-		
+
 		String query = "SELECT * FROM (" + cquery + ") AS child, ";
-        query += "(" + pquery + ") AS parent WHERE ";
-        
-        for(Join join : joins) {
-        	query += "child." + join.getChild() + "=";
-        	query += "parent." + join.getParent() + " AND ";
-        }
-        
-        query += "TRUE";
-        
-        return query;
+		query += "(" + pquery + ") AS parent WHERE ";
+
+		for (Join join : joins) {
+			query += "child." + join.getChild() + "=";
+			query += "parent." + join.getParent() + " AND ";
+		}
+
+		query += "TRUE";
+
+		return query;
+	}
+
+	public static String createJointQueryPreview(TriplesMap triplesMap, TriplesMap ptm, List<Join> joins,
+			Map<String, Object> data) {
+		
+		String query = createJointQuery(triplesMap, ptm, joins);
+
+		for (Join join : joins) {
+			query += " AND child." + join.getChild() + "=" + data.get(join.getChild());
+		}
+		
+		return query;
+	}
+
+	public static Map<String, Object> getAttributeValueMap(ResultSet resultset) {
+		Map<String, Object> attributeValueMap = new HashMap<String, Object>();
+		try {
+			ResultSetMetaData rsmd = resultset.getMetaData();
+			int columnCount = rsmd.getColumnCount();
+			for (int i = 1; i <= columnCount; i++) {
+				String name = rsmd.getColumnName(i);
+				attributeValueMap.put(name, resultset.getObject(i));
+			}
+		} catch (SQLException e) {
+			logger.error("Error processing resultset metadata: " + e.getMessage());
+		}
+
+		return attributeValueMap;
 	}
-	
 }

+ 116 - 76
src/r2rml/model/TriplesMap.java

@@ -33,7 +33,7 @@ public class TriplesMap extends R2RMLResource {
 
 	private LogicalTable logicalTable = null;
 	private SubjectMap subjectMap = null;
-	private List<PredicateObjectMap> predicateObjectMaps = new ArrayList<PredicateObjectMap> ();
+	private List<PredicateObjectMap> predicateObjectMaps = new ArrayList<PredicateObjectMap>();
 	private String baseIRI = null;
 
 	private int count = 0;
@@ -73,14 +73,14 @@ public class TriplesMap extends R2RMLResource {
 
 		// TermMap must have an rr:logicalTable property (exactly one?)
 		List<Statement> list = description.listProperties(R2RML.logicalTable).toList();
-		if(list.size() != 1) {
+		if (list.size() != 1) {
 			logger.error("TriplesMap must have exactly one rr:logicalTable property.");
 			logger.error(description);
 			return false;
 		}
 
 		RDFNode node = list.get(0).getObject();
-		if(!node.isResource()) {
+		if (!node.isResource()) {
 			logger.error("LogicalTable of TriplesMap is not a resource.");
 			logger.error(description);
 			return false;
@@ -88,20 +88,21 @@ public class TriplesMap extends R2RMLResource {
 
 		// Pre-process and validate LogicalTable
 		logicalTable = new LogicalTable(node.asResource());
-		if(!logicalTable.preProcessAndValidate())
+		if (!logicalTable.preProcessAndValidate())
 			return false;
 
 		// TermMap must have exactly one of rr:subject and rr:subjectMap
-		// But we constructed rr:subjectMap from rr:subject, thus only check one!
-		list = description.listProperties(R2RML.subjectMap).toList();		
-		if(list.size() != 1) {
+		// But we constructed rr:subjectMap from rr:subject, thus only check
+		// one!
+		list = description.listProperties(R2RML.subjectMap).toList();
+		if (list.size() != 1) {
 			logger.error("TriplesMap must have exactly one one of rr:subject and rr:subjectMap.");
 			logger.error(description);
 			return false;
 		}
 
 		node = list.get(0).getObject();
-		if(!node.isResource()) {
+		if (!node.isResource()) {
 			logger.error("SubjectMap of TriplesMap is not a resource.");
 			logger.error(description);
 			return false;
@@ -109,23 +110,23 @@ public class TriplesMap extends R2RMLResource {
 
 		// Pre-process and validate SubjectMap
 		subjectMap = new SubjectMap(node.asResource(), baseIRI);
-		if(!subjectMap.preProcessAndValidate())
+		if (!subjectMap.preProcessAndValidate())
 			return false;
 
 		// Pre-process and validate PredicateObjectMaps
 		// TriplesMaps may have zero or more PredicateObjectMaps
 		// Just iterate over them.
 		list = description.listProperties(R2RML.predicateObjectMap).toList();
-		for(Statement s : list) {
+		for (Statement s : list) {
 			node = s.getObject();
-			if(!node.isResource()) {
+			if (!node.isResource()) {
 				logger.error("PredicateObjectMap is not a resource.");
 				logger.error(description);
 				return false;
 			}
 
 			PredicateObjectMap opm = new PredicateObjectMap(s.getObject().asResource(), baseIRI);
-			if(!opm.preProcessAndValidate())
+			if (!opm.preProcessAndValidate())
 				return false;
 			predicateObjectMaps.add(opm);
 		}
@@ -133,13 +134,28 @@ public class TriplesMap extends R2RMLResource {
 		return true;
 	}
 
-	public boolean generateTriples(
-			DB database, 
-			Dataset dataset, 
-			Map<Resource, TriplesMap> triplesMaps) {
-		
+	public boolean generateTriples(DB database, Dataset dataset, Map<Resource, TriplesMap> triplesMaps) {
+
 		try {
 			String query = getLogicalTable().generateQuery();
+			
+			// TODO maybe not necessary
+//			if (database.getConfiguration().isPreview()) {
+//				String previewSQL = ""; 
+//				for (PredicateObjectMap opm : getPredicateObjectMaps()) {
+//					for (RefObjectMap rof : opm.getRefObjectMaps()) {
+//						for(Join join : rof.getJoins()) {
+//							if(query.contains("WHERE") && previewSQL.contains("WHERE")) {
+//								previewSQL += " AND "+ join.getChild() + " IS NOT NULL ";					
+//							}else {
+//								previewSQL += " WHERE "+ join.getChild() + " IS NOT NULL ";					
+//							}
+//						}
+//					}
+//				}
+//				query = query + previewSQL + " UNION ALL " + query;
+//				System.out.println(query);
+//			}
 			Rows rows = database.getRows(query);
 
 			List<Resource> classes = getSubjectMap().getClasses();
@@ -149,137 +165,161 @@ public class TriplesMap extends R2RMLResource {
 
 			int child_column_count = rows.getColumnCount();
 
+			Map<String, Object> attributeValueMap = null;
+
 			Row row = null;
-			while((row = rows.nextRow()) != null) {
+			while ((row = rows.nextRow()) != null) {
+				if (database.getConfiguration().isPreview()) {
+					attributeValueMap = R2RMLUtil.getAttributeValueMap(row.getResultSet());
+				}
 				Resource subject = getSubjectMap().generateRDFTerm(row);
 
 				// According to term generation rules, if the value is null,
 				// then no RDFTerm is generated. If that is the case for the
 				// subject, then we do not generate RDF for that resource.
-				if(subject != null) {
+				if (subject != null) {
 
 					Set<String> subjectGraphs = new HashSet<String>();
-					for(GraphMap gm : sgm) {
+					for (GraphMap gm : sgm) {
 						Resource gmiri = gm.generateRDFTerm(row);
-						if(gmiri != null)
+						if (gmiri != null)
 							subjectGraphs.add(gmiri.getURI());
 					}
 
-					for(Resource c : classes) {
+					for (Resource c : classes) {
 						addTriplesToDataset(dataset, subject, RDF.type, c, subjectGraphs);
 					}
 
 					// Now process each predicate-object map of the triples map
-					for(PredicateObjectMap opm : getPredicateObjectMaps()) {
-						// Let predicates be the set of generated RDF terms that 
-						// result from applying each of the predicate-object 
+					for (PredicateObjectMap opm : getPredicateObjectMaps()) {
+						// Let predicates be the set of generated RDF terms that
+						// result from applying each of the predicate-object
 						// map's predicate maps to row
 						List<Property> predicates = new ArrayList<Property>();
-						for(PredicateMap pm : opm.getPredicateMaps()) {
+						for (PredicateMap pm : opm.getPredicateMaps()) {
 							Property p = pm.generateRDFTerm(row);
-							if(p != null)
+							if (p != null)
 								predicates.add(p);
 						}
 
-						// Let objects be the set of generated RDF terms that result 
-						// from applying each of the predicate-object map's object 
+						// Let objects be the set of generated RDF terms that
+						// result
+						// from applying each of the predicate-object map's
+						// object
 						// maps (but not referencing object maps) to row
 						List<RDFNode> objects = new ArrayList<RDFNode>();
-						for(ObjectMap om : opm.getObjectMaps()) {
-							RDFNode o = om.generateRDFTerm(row); 
-							if(o != null)
+						for (ObjectMap om : opm.getObjectMaps()) {
+							RDFNode o = om.generateRDFTerm(row);
+							if (o != null)
 								objects.add(o);
 						}
 
-						// Let pogm be the set of graph maps of the predicate-object 
-						// map. Let predicate-object_graphs be the set of generated 
-						// RDF terms that result from applying each graph map in pogm 
+						// Let pogm be the set of graph maps of the
+						// predicate-object
+						// map. Let predicate-object_graphs be the set of
+						// generated
+						// RDF terms that result from applying each graph map in
+						// pogm
 						// to row
 						Set<String> pogs = new HashSet<String>();
-						for(GraphMap gm : opm.getGraphMaps()) {
+						for (GraphMap gm : opm.getGraphMaps()) {
 							Resource gmiri = gm.generateRDFTerm(row);
-							if(gmiri != null)
+							if (gmiri != null)
 								pogs.add(gmiri.getURI());
 						}
 
-						// Target graphs: If sgm and pogm are empty: rr:defaultGraph; 
-						// otherwise: union of subject_graphs and predicate-object_graphs
+						// Target graphs: If sgm and pogm are empty:
+						// rr:defaultGraph;
+						// otherwise: union of subject_graphs and
+						// predicate-object_graphs
 						pogs.addAll(subjectGraphs);
-						for(Property p : predicates) {
-							for(RDFNode o : objects) {
+						for (Property p : predicates) {
+							for (RDFNode o : objects) {
 								addTriplesToDataset(dataset, subject, p, o, pogs);
 							}
 						}
 
-
 					}
 				}
 			} // end while
 
-			// For each referencing object map of a predicate-object map of 
+			// For each referencing object map of a predicate-object map of
 			// the triples map, apply the following steps:
-			for(PredicateObjectMap opm : getPredicateObjectMaps()) {
-				for(RefObjectMap rof : opm.getRefObjectMaps()) {
+			for (PredicateObjectMap opm : getPredicateObjectMaps()) {
+				for (RefObjectMap rof : opm.getRefObjectMaps()) {
 					TriplesMap ptm = triplesMaps.get(rof.getParentTriplesMap());
 					SubjectMap psm = ptm.getSubjectMap();
 					List<GraphMap> pogm = opm.getGraphMaps();
-					
-					String jointQuery = R2RMLUtil.createJointQuery(this, ptm, rof.getJoins());
-					if(jointQuery == null)
+
+					String jointQuery = null;
+					if (database.getConfiguration().isPreview()) {
+						jointQuery = R2RMLUtil.createJointQueryPreview(this, ptm, rof.getJoins(), attributeValueMap);
+					} else {
+						jointQuery = R2RMLUtil.createJointQuery(this, ptm, rof.getJoins());
+					}
+					if (jointQuery == null)
 						return false;
 
 					Rows rows2 = database.getRows(jointQuery);
 					int column_count = rows2.getColumnCount();
 					// For each row in rows2...
-					while(rows2.nextRow() != null) {
+					while (rows2.nextRow() != null) {
 						Row child_row = rows2.projectCurrentRow(1, child_column_count);
 						Row parent_row = rows2.projectCurrentRow(child_column_count + 1, column_count);
 
-						// Let subject be the generated RDF term that results 
+						// Let subject be the generated RDF term that results
 						// from applying sm to "child_row"
 						Resource subject = getSubjectMap().generateRDFTerm(child_row);
 
-						// Let object be the generated RDF term that results 
+						// Let object be the generated RDF term that results
 						// from applying psm to parent_row
 						Resource object = psm.generateRDFTerm(parent_row);
-						
+
 						// if subject or object is NULL, don't generate triples
-						if(subject != null || object != null) {
+						if (subject != null || object != null) {
 
-							// Let predicates be the set of generated RDF terms that result 
-							// from applying each of the predicate-object map's predicate 
+							// Let predicates be the set of generated RDF terms
+							// that result
+							// from applying each of the predicate-object map's
+							// predicate
 							// maps to child_row
 							List<Property> predicates = new ArrayList<Property>();
-							for(PredicateMap pm : opm.getPredicateMaps()) {
+							for (PredicateMap pm : opm.getPredicateMaps()) {
 								Property p = pm.generateRDFTerm(child_row);
-								if(p != null)
+								if (p != null)
 									predicates.add(p);
 							}
 
-							// Let subject_graphs be the set of generated RDF terms 
-							// that result from applying each graph map of sgm to 
+							// Let subject_graphs be the set of generated RDF
+							// terms
+							// that result from applying each graph map of sgm
+							// to
 							// child_row
 							Set<String> subjectGraphs = new HashSet<String>();
-							for(GraphMap gm : sgm) {
+							for (GraphMap gm : sgm) {
 								Resource gmiri = gm.generateRDFTerm(child_row);
-								if(gmiri != null)
+								if (gmiri != null)
 									subjectGraphs.add(gmiri.getURI());
 							}
 
-							// Let predicate-object_graphs be the set of generated 
-							// RDF terms that result from applying each graph map in 
+							// Let predicate-object_graphs be the set of
+							// generated
+							// RDF terms that result from applying each graph
+							// map in
 							// pogm to child_row
 							Set<String> pogs = new HashSet<String>();
-							for(GraphMap gm : pogm) {
+							for (GraphMap gm : pogm) {
 								Resource gmiri = gm.generateRDFTerm(child_row);
-								if(gmiri != null)
+								if (gmiri != null)
 									pogs.add(gmiri.getURI());
 							}
 
-							// Target graphs: If sgm and pogm are empty: rr:defaultGraph; 
-							// otherwise: union of subject_graphs and predicate-object_graphs
+							// Target graphs: If sgm and pogm are empty:
+							// rr:defaultGraph;
+							// otherwise: union of subject_graphs and
+							// predicate-object_graphs
 							pogs.addAll(subjectGraphs);
-							for(Property p : predicates) {
+							for (Property p : predicates) {
 								addTriplesToDataset(dataset, subject, p, object, pogs);
 							}
 						}
@@ -294,7 +334,7 @@ public class TriplesMap extends R2RMLResource {
 			logger.error(description);
 			return false;
 		} finally {
-			if(database != null) {
+			if (database != null) {
 				try {
 					database.close();
 				} catch (R2RMLException e) {
@@ -311,21 +351,21 @@ public class TriplesMap extends R2RMLResource {
 	 * Adding triples to the dataset. If the set of named graphs is empty, they
 	 * added to the default model.
 	 * 
-	 * @param ds The dataset
-	 * @param s The subject
-	 * @param p The predicate
-	 * @param o The object
+	 * @param ds  The dataset
+	 * @param s   The subject
+	 * @param p   The predicate
+	 * @param o   The object
 	 * @param ngs The set of named graphs
 	 */
 	private void addTriplesToDataset(Dataset ds, Resource s, Property p, RDFNode o, Set<String> ngs) {
-		if(ngs.isEmpty()) {
+		if (ngs.isEmpty()) {
 			ds.getDefaultModel().add(s, p, o);
 			count++;
 			return;
 		}
 
-		for(String ng : ngs) {
-			if(ng.equals(R2RML.defaultGraph.getURI())) {
+		for (String ng : ngs) {
+			if (ng.equals(R2RML.defaultGraph.getURI())) {
 				ds.getDefaultModel().add(s, p, o);
 				count++;
 			} else {