diff --git a/pom.xml b/pom.xml index bd6de3e..3bef1e1 100644 --- a/pom.xml +++ b/pom.xml @@ -79,7 +79,7 @@ net.antidot db2triples - 1.0.2-SNAPSHOT + 1.0.2 com.sun.org.apache @@ -103,6 +103,11 @@ 2.0.1 jar + + net.sourceforge.jeval + jeval + 0.9.4 + diff --git a/src/main/java/be/ugent/mmlab/rml/core/RMLMappingFactory.java b/src/main/java/be/ugent/mmlab/rml/core/RMLMappingFactory.java index 3184c4e..f7224f1 100644 --- a/src/main/java/be/ugent/mmlab/rml/core/RMLMappingFactory.java +++ b/src/main/java/be/ugent/mmlab/rml/core/RMLMappingFactory.java @@ -209,7 +209,7 @@ private static Map extractTripleMapResources( // with referencing objects { triplesMapResources.put(s.getSubject(), new StdTriplesMap( - null, null, null, s.getSubject().stringValue())); + null, null, null, s.getSubject().stringValue(),null)); } } } @@ -281,6 +281,11 @@ private static void extractTriplesMap(SesameDataSet r2rmlMappingGraph, triplesMapResources); log.debug("[RMLMappingFactory:extractTriplesMap] Current number of created graphMaps : " + graphMaps.size()); + + + log.debug("[RMLMappingFactory:extractTriplesMap] Current number of created graphMaps : " + + graphMaps.size()); + // Fill triplesMap for (PredicateObjectMap predicateObjectMap : predicateObjectMaps) { result.addPredicateObjectMap(predicateObjectMap); @@ -507,13 +512,15 @@ private static Set extractJoinConditions( R2RMLTerm.CHILD); String parent = extractLiteralFromTermMap(r2rmlMappingGraph, jc, R2RMLTerm.PARENT); + String guard = extractLiteralFromTermMap(r2rmlMappingGraph, + jc, R2RMLTerm.GUARD); if (parent == null || child == null) { throw new InvalidR2RMLStructureException( "[RMLMappingFactory:extractReferencingObjectMap] " + object.stringValue() + " must have exactly two properties child and parent. "); } - result.add(new StdJoinCondition(child, parent)); + result.add(new StdJoinCondition(child, parent,guard)); } } catch (ClassCastException e) { throw new InvalidR2RMLStructureException( @@ -540,6 +547,8 @@ private static ObjectMap extractObjectMap(SesameDataSet r2rmlMappingGraph, object, R2RMLTerm.TEMPLATE); String languageTag = extractLiteralFromTermMap(r2rmlMappingGraph, object, R2RMLTerm.LANGUAGE); + String stringGuard = extractLiteralFromTermMap(r2rmlMappingGraph, + object, R2RMLTerm.GUARD); URI termType = (URI) extractValueFromTermMap(r2rmlMappingGraph, object, R2RMLTerm.TERM_TYPE); URI dataType = (URI) extractValueFromTermMap(r2rmlMappingGraph, object, @@ -551,8 +560,8 @@ private static ObjectMap extractObjectMap(SesameDataSet r2rmlMappingGraph, ReferenceIdentifier referenceValue = extractReferenceIdentifier(r2rmlMappingGraph, object); StdObjectMap result = new StdObjectMap(null, constantValue, dataType, - languageTag, stringTemplate, termType, inverseExpression, - referenceValue); + languageTag, stringTemplate, termType, stringGuard, + inverseExpression, referenceValue); log.debug("[RMLMappingFactory:extractObjectMap] Extract object map done."); return result; } @@ -587,6 +596,7 @@ private static PredicateMap extractPredicateMap( object, R2RMLTerm.CONSTANT); String stringTemplate = extractLiteralFromTermMap(r2rmlMappingGraph, object, R2RMLTerm.TEMPLATE); + String stringGuard = extractLiteralFromTermMap(r2rmlMappingGraph,object, R2RMLTerm.GUARD); URI termType = (URI) extractValueFromTermMap(r2rmlMappingGraph, object, R2RMLTerm.TERM_TYPE); @@ -597,7 +607,7 @@ private static PredicateMap extractPredicateMap( ReferenceIdentifier referenceValue = extractReferenceIdentifier(r2rmlMappingGraph, object); PredicateMap result = new StdPredicateMap(null, constantValue, - stringTemplate, inverseExpression, referenceValue, termType); + stringTemplate, stringGuard, inverseExpression, referenceValue, termType); log.debug("[RMLMappingFactory:extractPredicateMap] Extract predicate map done."); return result; } @@ -649,7 +659,8 @@ private static SubjectMap extractSubjectMap( subjectMap, R2RMLTerm.TERM_TYPE); String inverseExpression = extractLiteralFromTermMap(r2rmlMappingGraph, subjectMap, R2RMLTerm.INVERSE_EXPRESSION); - + String stringGuard = extractLiteralFromTermMap(r2rmlMappingGraph, + subjectMap, R2RMLTerm.GUARD); //MVS: Decide on ReferenceIdentifier ReferenceIdentifier referenceValue = extractReferenceIdentifier(r2rmlMappingGraph, subjectMap); Set classIRIs = extractURIsFromTermMap(r2rmlMappingGraph, @@ -678,7 +689,7 @@ private static SubjectMap extractSubjectMap( } } SubjectMap result = new StdSubjectMap(ownTriplesMap, constantValue, - stringTemplate, termType, inverseExpression, referenceValue, + stringTemplate, termType,stringGuard, inverseExpression, referenceValue, classIRIs, graphMaps); log.debug("[RMLMappingFactory:extractSubjectMap] Subject map extracted."); return result; @@ -696,6 +707,8 @@ private static GraphMap extractGraphMap(SesameDataSet r2rmlMappingGraph, graphMap, R2RMLTerm.CONSTANT); String stringTemplate = extractLiteralFromTermMap(r2rmlMappingGraph, graphMap, R2RMLTerm.TEMPLATE); + String stringGuard = extractLiteralFromTermMap(r2rmlMappingGraph, + graphMap, R2RMLTerm.GUARD); String inverseExpression = extractLiteralFromTermMap(r2rmlMappingGraph, graphMap, R2RMLTerm.INVERSE_EXPRESSION); @@ -706,7 +719,7 @@ private static GraphMap extractGraphMap(SesameDataSet r2rmlMappingGraph, graphMap, R2RMLTerm.TERM_TYPE); GraphMap result = new StdGraphMap(constantValue, stringTemplate, - inverseExpression, referenceValue, termType); + stringGuard, inverseExpression, referenceValue, termType); log.debug("[RMLMappingFactory:extractPredicateObjectMaps] Graph map extracted."); return result; } diff --git a/src/main/java/be/ugent/mmlab/rml/model/AbstractTermMap.java b/src/main/java/be/ugent/mmlab/rml/model/AbstractTermMap.java index cd28a52..3824eca 100644 --- a/src/main/java/be/ugent/mmlab/rml/model/AbstractTermMap.java +++ b/src/main/java/be/ugent/mmlab/rml/model/AbstractTermMap.java @@ -62,10 +62,11 @@ public abstract class AbstractTermMap implements TermMap { private String stringTemplate; private ReferenceIdentifier referenceValue; private String inverseExpression; + private String stringGuard; protected AbstractTermMap(Value constantValue, URI dataType, String languageTag, String stringTemplate, URI termType, - String inverseExpression, ReferenceIdentifier referenceValue) + String stringGuard, String inverseExpression, ReferenceIdentifier referenceValue) throws R2RMLDataError, InvalidR2RMLStructureException, InvalidR2RMLSyntaxException { @@ -73,6 +74,7 @@ protected AbstractTermMap(Value constantValue, URI dataType, setReferenceValue(referenceValue); setLanguageTag(languageTag); setStringTemplate(stringTemplate); + setStringGuard(stringGuard); setTermType(termType, dataType); setDataType(dataType); @@ -205,6 +207,14 @@ private void setStringTemplate(String stringTemplate) this.stringTemplate = stringTemplate; } + + private void setStringGuard(String stringGuard) + throws InvalidR2RMLSyntaxException, InvalidR2RMLStructureException { + // he value of the rr:template property MUST be a + // valid string template. + + this.stringGuard = stringGuard; + } /** * A string template is a format string that can be used to build @@ -358,6 +368,10 @@ public Set getReferencedSelectors() { public String getStringTemplate() { return stringTemplate; } + + public String getStringGuard() { + return stringGuard; + } public TermMapType getTermMapType() { if (constantValue != null) { diff --git a/src/main/java/be/ugent/mmlab/rml/model/JoinCondition.java b/src/main/java/be/ugent/mmlab/rml/model/JoinCondition.java index 37e7510..29c4660 100644 --- a/src/main/java/be/ugent/mmlab/rml/model/JoinCondition.java +++ b/src/main/java/be/ugent/mmlab/rml/model/JoinCondition.java @@ -41,5 +41,7 @@ public interface JoinCondition { * Parent reference must be a reference in the language defined by the parent triples map and exist there. */ public String getParent(); + + public String getGuard(); } diff --git a/src/main/java/be/ugent/mmlab/rml/model/PredicateObjectMap.java b/src/main/java/be/ugent/mmlab/rml/model/PredicateObjectMap.java index b6e2ed2..a3b2da2 100644 --- a/src/main/java/be/ugent/mmlab/rml/model/PredicateObjectMap.java +++ b/src/main/java/be/ugent/mmlab/rml/model/PredicateObjectMap.java @@ -77,6 +77,8 @@ public interface PredicateObjectMap { public Set getGraphMaps(); public void setGraphMaps(Set graphmaps); + public String getGuardMaps(); + public void setGuardMaps(String guardMaps); } diff --git a/src/main/java/be/ugent/mmlab/rml/model/StdGraphMap.java b/src/main/java/be/ugent/mmlab/rml/model/StdGraphMap.java index 97fbfa5..0bf2d9c 100644 --- a/src/main/java/be/ugent/mmlab/rml/model/StdGraphMap.java +++ b/src/main/java/be/ugent/mmlab/rml/model/StdGraphMap.java @@ -44,7 +44,7 @@ public class StdGraphMap extends AbstractTermMap implements GraphMap { public StdGraphMap(Value constantValue, - String stringTemplate, String inverseExpression, + String stringTemplate, String guard, String inverseExpression, ReferenceIdentifier referenceValue, URI termType) throws R2RMLDataError, InvalidR2RMLStructureException, InvalidR2RMLSyntaxException { // No Literal term type @@ -52,7 +52,7 @@ public StdGraphMap(Value constantValue, // ==> No specified language tag // Only termType possible : IRI => by default super(constantValue, null, null, stringTemplate, - termType, inverseExpression, referenceValue); + termType,guard, inverseExpression, referenceValue); } diff --git a/src/main/java/be/ugent/mmlab/rml/model/StdJoinCondition.java b/src/main/java/be/ugent/mmlab/rml/model/StdJoinCondition.java index 2064517..027d4c6 100644 --- a/src/main/java/be/ugent/mmlab/rml/model/StdJoinCondition.java +++ b/src/main/java/be/ugent/mmlab/rml/model/StdJoinCondition.java @@ -37,11 +37,13 @@ public class StdJoinCondition implements JoinCondition { private String child; private String parent; + private String guard; - public StdJoinCondition(String child, String parent) + public StdJoinCondition(String child, String parent,String guard) throws InvalidR2RMLStructureException, InvalidR2RMLSyntaxException { setChild(child); setParent(parent); + setGuard(guard); } private void setParent(String parent) @@ -86,5 +88,14 @@ public String getChild() { public String getParent() { return parent; } + + public String getGuard(){ + return guard; + } + + private void setGuard(String guard) { + if (guard != null) + this.guard=guard; + } } diff --git a/src/main/java/be/ugent/mmlab/rml/model/StdObjectMap.java b/src/main/java/be/ugent/mmlab/rml/model/StdObjectMap.java index 94d0cd2..32cc292 100644 --- a/src/main/java/be/ugent/mmlab/rml/model/StdObjectMap.java +++ b/src/main/java/be/ugent/mmlab/rml/model/StdObjectMap.java @@ -44,10 +44,10 @@ public class StdObjectMap extends AbstractTermMap implements TermMap, ObjectMap public StdObjectMap(PredicateObjectMap predicateObjectMap, Value constantValue, URI dataType, String languageTag, - String stringTemplate, URI termType, String inverseExpression, + String stringTemplate, URI termType, String stringGuard,String inverseExpression, ReferenceIdentifier referenceValue) throws R2RMLDataError, InvalidR2RMLStructureException, InvalidR2RMLSyntaxException { - super(constantValue, dataType, languageTag, stringTemplate, termType, + super(constantValue, dataType, languageTag, stringTemplate, termType, stringGuard, inverseExpression, referenceValue); setPredicateObjectMap(predicateObjectMap); } diff --git a/src/main/java/be/ugent/mmlab/rml/model/StdPredicateMap.java b/src/main/java/be/ugent/mmlab/rml/model/StdPredicateMap.java index 345c827..c9496eb 100644 --- a/src/main/java/be/ugent/mmlab/rml/model/StdPredicateMap.java +++ b/src/main/java/be/ugent/mmlab/rml/model/StdPredicateMap.java @@ -44,7 +44,7 @@ public class StdPredicateMap extends AbstractTermMap implements TermMap, private PredicateObjectMap predicateObjectMap; public StdPredicateMap(PredicateObjectMap predicateObjectMap, - Value constantValue, String stringTemplate, + Value constantValue, String stringTemplate, String guard, String inverseExpression, ReferenceIdentifier referenceValue, URI termType) throws R2RMLDataError, InvalidR2RMLStructureException, InvalidR2RMLSyntaxException { @@ -53,7 +53,7 @@ public StdPredicateMap(PredicateObjectMap predicateObjectMap, // ==> No specified language tag // No class IRI super(constantValue, null, null, stringTemplate, termType, - inverseExpression, referenceValue); + guard, inverseExpression, referenceValue); setPredicateObjectMap(predicateObjectMap); } diff --git a/src/main/java/be/ugent/mmlab/rml/model/StdPredicateObjectMap.java b/src/main/java/be/ugent/mmlab/rml/model/StdPredicateObjectMap.java index 38fcfb4..3ed62e6 100644 --- a/src/main/java/be/ugent/mmlab/rml/model/StdPredicateObjectMap.java +++ b/src/main/java/be/ugent/mmlab/rml/model/StdPredicateObjectMap.java @@ -35,6 +35,7 @@ public class StdPredicateObjectMap implements PredicateObjectMap { private Set objectMaps; private Set refObjectMaps; private Set predicateMaps; + private String guardMaps; protected TriplesMap ownTriplesMap; private HashSet graphMaps; @@ -126,5 +127,16 @@ public void setGraphMaps(Set graphMaps) { this.graphMaps = new HashSet(graphMaps); } + @Override + public String getGuardMaps() { + // TODO Auto-generated method stub + return guardMaps; + } + + @Override + public void setGuardMaps(String guard) { + this.guardMaps=guard; + + } } diff --git a/src/main/java/be/ugent/mmlab/rml/model/StdSubjectMap.java b/src/main/java/be/ugent/mmlab/rml/model/StdSubjectMap.java index a546665..a27416f 100644 --- a/src/main/java/be/ugent/mmlab/rml/model/StdSubjectMap.java +++ b/src/main/java/be/ugent/mmlab/rml/model/StdSubjectMap.java @@ -48,14 +48,14 @@ public class StdSubjectMap extends AbstractTermMap implements SubjectMap { protected TriplesMap ownTriplesMap; public StdSubjectMap(TriplesMap ownTriplesMap, Value constantValue, - String stringTemplate, URI termType, String inverseExpression, + String stringTemplate, URI termType, String guard, String inverseExpression, ReferenceIdentifier referenceValue, Set classIRIs, Set graphMaps) throws R2RMLDataError, InvalidR2RMLStructureException, InvalidR2RMLSyntaxException { // No Literal term type // ==> No datatype // ==> No specified language tag - super(constantValue, null, null, stringTemplate, termType, + super(constantValue, null, null, stringTemplate, termType,guard, inverseExpression, referenceValue); setClassIRIs(classIRIs); setGraphMaps(graphMaps); diff --git a/src/main/java/be/ugent/mmlab/rml/model/StdTriplesMap.java b/src/main/java/be/ugent/mmlab/rml/model/StdTriplesMap.java index 37e8393..e03ad13 100644 --- a/src/main/java/be/ugent/mmlab/rml/model/StdTriplesMap.java +++ b/src/main/java/be/ugent/mmlab/rml/model/StdTriplesMap.java @@ -36,14 +36,21 @@ public class StdTriplesMap implements TriplesMap { private SubjectMap subjectMap; private LogicalSource logicalSource; private String name; + private String guard; public StdTriplesMap(LogicalSource logicalSource, Set predicateObjectMaps, - StdSubjectMap subjectMap, String name) throws InvalidR2RMLStructureException { + StdSubjectMap subjectMap, String name,String guard) throws InvalidR2RMLStructureException { setSubjectMap(subjectMap); setLogicalSource(logicalSource); setPredicateObjectMap(predicateObjectMaps); setName(name); + setGuardObjectMap(guard); + } + + private void setGuardObjectMap(String guard) { + this.guard=guard; + } public void setLogicalSource(LogicalSource logicalTable) { @@ -106,4 +113,5 @@ public void setName(String name) { } + } diff --git a/src/main/java/be/ugent/mmlab/rml/model/TermMap.java b/src/main/java/be/ugent/mmlab/rml/model/TermMap.java index 493ced2..ebce9cf 100644 --- a/src/main/java/be/ugent/mmlab/rml/model/TermMap.java +++ b/src/main/java/be/ugent/mmlab/rml/model/TermMap.java @@ -80,6 +80,7 @@ public enum TermMapType { * curly braces. Only if TEMPLATE_VALUED type. */ public String getStringTemplate(); + public String getStringGuard(); /** * If the term map has an optional rr:termType property, then its term type diff --git a/src/main/java/be/ugent/mmlab/rml/processor/AbstractRMLProcessor.java b/src/main/java/be/ugent/mmlab/rml/processor/AbstractRMLProcessor.java index d61b92d..c456b9c 100644 --- a/src/main/java/be/ugent/mmlab/rml/processor/AbstractRMLProcessor.java +++ b/src/main/java/be/ugent/mmlab/rml/processor/AbstractRMLProcessor.java @@ -25,6 +25,9 @@ import net.antidot.semantic.rdf.model.impl.sesame.SesameDataSet; import net.antidot.semantic.rdf.rdb2rdf.r2rml.core.R2RMLEngine; import net.antidot.semantic.rdf.rdb2rdf.r2rml.tools.R2RMLToolkit; +import net.sourceforge.jeval.EvaluationException; +import net.sourceforge.jeval.Evaluator; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openrdf.model.Resource; @@ -38,277 +41,359 @@ /** * This class contains all generic functionality for executing an iteration and * processing the mapping - * + * * @author mielvandersande, andimou */ public abstract class AbstractRMLProcessor implements RMLProcessor { - /** - * Gets the globally defined identifier-to-path map - * - * @param ls the current LogicalSource - * @return the location of the file or table - */ - // Log - private static Log log = LogFactory.getLog(R2RMLEngine.class); - - protected String getIdentifier(LogicalSource ls) { - return RMLEngine.getFileMap().getProperty(ls.getIdentifier()); - } - - /** - * gets the expression specified in the logical source - * - * @param ls - * @return - */ - protected String getReference(LogicalSource ls) { - return ls.getReference(); - } - - /** - * - * Process the subject map - * - * @param dataset - * @param subjectMap - * @param node - * @return the created subject - */ - public Resource processSubjectMap(SesameDataSet dataset, SubjectMap subjectMap, Object node) { - //Get the uri - List values = processTermMap(subjectMap, node); - - if (values.isEmpty()) { - return null; - } - - //Since it is the subject, more than one value is not allowed. Only return the first one. Throw exception if not? - String value = values.get(0); - - if (value == null) { - return null; - } - - Resource subject = new URIImpl(value); - //Add the type triples - Set classIRIs = subjectMap.getClassIRIs(); - for (org.openrdf.model.URI classIRI : classIRIs) { - dataset.add(subject, RDF.TYPE, classIRI); - } - - return subject; - } - - /** - * Process any Term Map - * - * @param map current term map - * @param node current node in iteration - * @return the resulting value - */ - - private List processTermMap(TermMap map, Object node) { - List value = new ArrayList(); - - switch (map.getTermMapType()) { - case REFERENCE_VALUED: - //Get the expression and extract the value - ReferenceIdentifierImpl identifier = (ReferenceIdentifierImpl) map.getReferenceValue(); - return extractValueFromNode(node, identifier.toString()); - case CONSTANT_VALUED: - //Extract the value directly from the mapping - value.add(map.getConstantValue().stringValue()); - return value; - - case TEMPLATE_VALUED: - //Resolve the template - String template = map.getStringTemplate(); - Set tokens = R2RMLToolkit.extractColumnNamesFromStringTemplate(template); - - - for (String expression : tokens) { - List replacements = extractValueFromNode(node, expression); - - for (int i = 0; i < replacements.size(); i++) { - if (value.size() < (i + 1)) { - value.add(template); - } - - String replacement = replacements.get(i); - - //if (replacement == null || replacement.isEmpty()) { - if (replacement == null) { - //if the replacement value is null or empty, the reulting uri would be invalid, skip this. - //The placeholders remain which removes them in the end. - continue; - } - - String temp = value.get(i); - - if (expression.contains("[")) { - expression = expression.replaceAll("\\[", "").replaceAll("\\]", ""); - temp = temp.replaceAll("\\[", "").replaceAll("\\]", ""); - } - //JSONPath expression cause problems when replacing, remove the $ first - if (expression.contains("$")) { - expression = expression.replaceAll("\\$", ""); - temp = temp.replaceAll("\\$", ""); - } - - try { - //Use encoding UTF-8 explicit URL encode; other one is deprecated - temp = temp.replaceAll("\\{" + expression + "\\}", URLEncoder.encode(replacement,"UTF-8")); - } catch (UnsupportedEncodingException ex) { - log.error(ex); - } - - value.set(i, temp); - } - } - - //Check if there are any placeholders left in the templates and remove uris that are not - List validValues = new ArrayList(); - for (String uri : value){ - if (R2RMLToolkit.extractColumnNamesFromStringTemplate(uri).isEmpty()){ - validValues.add(uri); - } - } - - return validValues; - } - - return value; - } - - /** - * Process a predicate object map - * - * @param dataset - * @param subject the subject from the triple - * @param pom the predicate object map - * @param node the current node - */ - public void processPredicateObjectMap(SesameDataSet dataset, Resource subject, PredicateObjectMap pom, Object node) { - - Set predicateMaps = pom.getPredicateMaps(); - //Go over each predicate map - for (PredicateMap predicateMap : predicateMaps) { - //Get the predicate - List predicates = processPredicateMap(predicateMap, node); - - for (URI predicate : predicates) { - //Process the joins first - Set referencingObjectMaps = pom.getReferencingObjectMaps(); - for (ReferencingObjectMap referencingObjectMap : referencingObjectMaps) { - Set joinConditions = referencingObjectMap.getJoinConditions(); - - TriplesMap parentTriplesMap = referencingObjectMap.getParentTriplesMap(); - - //Create the processor based on the parent triples map to perform the join - RMLProcessorFactory factory = new ConcreteRMLProcessorFactory(); - QLTerm queryLanguage = parentTriplesMap.getLogicalSource().getQueryLanguage(); - RMLProcessor processor = factory.create(queryLanguage); - - RMLPerformer performer; - - if (joinConditions.isEmpty()) { - performer = new JoinRMLPerformer(processor, subject, predicate); - } else { - //Build a join map where - // key: the parent expression - // value: the value extracted from the child - HashMap joinMap = new HashMap(); - - for (JoinCondition joinCondition : joinConditions) { - List childValues = extractValueFromNode(node, joinCondition.getChild()); - - //MVS: Allow multiple values? - String childValue = childValues.get(0); - - log.debug("[AbstractRMLProcessorProcessor:processPredicateObjectMap]. joinCondition child: " + joinCondition.getChild()); - log.debug("[AbstractRMLProcessorProcessor:processPredicateObjectMap]. joinCondition parent: " + joinCondition.getParent()); - log.debug("[AbstractRMLProcessorProcessor:processPredicateObjectMap]. childValue: " + childValue); - - joinMap.put(joinCondition.getParent(), childValue); - } - - //Execute the join with candidate s, p - //Create a join performer to make the processor execute joins (Strategy pattern & composition) - performer = new ConditionalJoinRMLPerformer(processor, joinMap, subject, predicate); - } - processor.execute(dataset, parentTriplesMap, performer); - } - - //process the objectmaps - Set objectMaps = pom.getObjectMaps(); - for (ObjectMap objectMap : objectMaps) { - //Get the one or more objects returned by the object map - List objects = processObjectMap(objectMap, node); - for (Value object : objects) { - if (object != null && !object.toString().isEmpty()) { - dataset.add(subject, predicate, object); - } - } - } - } - - } - } - - /** - * process a predicate map - * - * @param predicateMap - * @param node - * @return the uri of the extracted predicate - */ - private List processPredicateMap(PredicateMap predicateMap, Object node) { - // Get the value - List values = processTermMap(predicateMap, node); - - List uris = new ArrayList(); - for (String value : values) { - uris.add(new URIImpl(value)); - } - //return the uri - return uris; - } - - /** - * process an object map - * - * @param objectMap - * @param node - * @return - */ - private List processObjectMap(ObjectMap objectMap, Object node) { - //A Term map returns one or more values (in case expression matches more) - List values = processTermMap(objectMap, node); - - List valueList = new ArrayList(); - for (String value : values) { - log.debug("[AbstractRMLProcessor:literal] value " + value); - switch (objectMap.getTermType()) { - case IRI: - valueList.add(new URIImpl(value)); - break; - case BLANK_NODE: - valueList.add(new BNodeImpl(value)); - break; - case LITERAL: - if (objectMap.getLanguageTag() != null && !value.equals("")) { - valueList.add(new LiteralImpl(value, objectMap.getLanguageTag())); - } else if (objectMap.getDataType() != null && !value.equals("")) { - valueList.add(new LiteralImpl(value, objectMap.getDataType())); - } else if (value != null && !value.equals("")) { - log.debug("[AbstractRMLProcessor:literal] Literal value " + value); - valueList.add(new LiteralImpl(value)); - } - //No reason to return null, is replaced by empty list. - } - - } - return valueList; - } + /** + * Gets the globally defined identifier-to-path map + * + * @param ls + * the current LogicalSource + * @return the location of the file or table + */ + // Log + private static Log log = LogFactory.getLog(R2RMLEngine.class); + + protected String getIdentifier(LogicalSource ls) { + return RMLEngine.getFileMap().getProperty(ls.getIdentifier()); + } + + /** + * gets the expression specified in the logical source + * + * @param ls + * @return + */ + protected String getReference(LogicalSource ls) { + return ls.getReference(); + } + + /** + * + * Process the subject map + * + * @param dataset + * @param subjectMap + * @param node + * @return the created subject + */ + public Resource processSubjectMap(SesameDataSet dataset, + SubjectMap subjectMap, Object node) { + // Get the uri + List values = processTermMap(subjectMap, node); + + if (values.isEmpty()) { + return null; + } + + // Since it is the subject, more than one value is not allowed. Only + // return the first one. Throw exception if not? + String value = values.get(0); + + if (value == null) { + return null; + } + + String guard = subjectMap.getStringGuard(); + boolean checkCondition = false; + if (guard != null) { + checkCondition = evaluateGuard(guard, node); + } + if (guard != null && !checkCondition) + return null; + Resource subject = new URIImpl(value); + // Add the type triples + Set classIRIs = subjectMap.getClassIRIs(); + for (org.openrdf.model.URI classIRI : classIRIs) { + dataset.add(subject, RDF.TYPE, classIRI); + } + + return subject; + } + + private boolean evaluateGuard(String guard, Object node) { + HashMap tmp = (HashMap) node; + Set columnNames = tmp.keySet(); + for (String columnName : columnNames) { + String cellValue = tmp.get(columnName); + guard = guard.replaceAll("\\$\\{" + columnName + "\\}", + cellValue); + if (!guard.contains("$")) + break; + } + Evaluator eval = new Evaluator(); + try { + boolean booleanResult = eval.getBooleanResult(guard); + return booleanResult; + } catch (EvaluationException e) { + e.printStackTrace(); + } + return false; + } + + /** + * Process any Term Map + * + * @param map + * current term map + * @param node + * current node in iteration + * @return the resulting value + */ + + private List processTermMap(TermMap map, Object node) { + List value = new ArrayList(); + + switch (map.getTermMapType()) { + case REFERENCE_VALUED: + // Get the expression and extract the value + ReferenceIdentifierImpl identifier = (ReferenceIdentifierImpl) map + .getReferenceValue(); + return extractValueFromNode(node, identifier.toString()); + case CONSTANT_VALUED: + // Extract the value directly from the mapping + value.add(map.getConstantValue().stringValue()); + return value; + + case TEMPLATE_VALUED: + // Resolve the template + String template = map.getStringTemplate(); + Set tokens = R2RMLToolkit + .extractColumnNamesFromStringTemplate(template); + + for (String expression : tokens) { + List replacements = extractValueFromNode(node, + expression); + + for (int i = 0; i < replacements.size(); i++) { + if (value.size() < (i + 1)) { + value.add(template); + } + + String replacement = replacements.get(i); + + // if (replacement == null || replacement.isEmpty()) { + if (replacement == null) { + // if the replacement value is null or empty, the + // reulting uri would be invalid, skip this. + // The placeholders remain which removes them in the + // end. + continue; + } + + String temp = value.get(i); + + if (expression.contains("[")) { + expression = expression.replaceAll("\\[", "") + .replaceAll("\\]", ""); + temp = temp.replaceAll("\\[", "").replaceAll("\\]", ""); + } + // JSONPath expression cause problems when replacing, remove + // the $ first + if (expression.contains("$")) { + expression = expression.replaceAll("\\$", ""); + temp = temp.replaceAll("\\$", ""); + } + + try { + // Use encoding UTF-8 explicit URL encode; other one is + // deprecated + temp = temp.replaceAll("\\{" + expression + "\\}", + URLEncoder.encode(replacement, "UTF-8")); + } catch (UnsupportedEncodingException ex) { + log.error(ex); + } + + value.set(i, temp); + } + } + + // Check if there are any placeholders left in the templates and + // remove uris that are not + List validValues = new ArrayList(); + for (String uri : value) { + if (R2RMLToolkit.extractColumnNamesFromStringTemplate(uri) + .isEmpty()) { + validValues.add(uri); + } + } + + return validValues; + } + + return value; + } + + /** + * Process a predicate object map + * + * @param dataset + * @param subject + * the subject from the triple + * @param pom + * the predicate object map + * @param node + * the current node + */ + public void processPredicateObjectMap(SesameDataSet dataset, + Resource subject, PredicateObjectMap pom, Object node) { + + Set predicateMaps = pom.getPredicateMaps(); +// boolean checkCondition = false; +// String guard = null; +// if (pom.getGuardMaps() != null) { +// guard = pom.getGuardMaps(); +// } + +// if (guard != null) { +// +// checkCondition = evaluateGuard(guard, node); +// } + +// if (checkCondition) { + // Go over each predicate map + for (PredicateMap predicateMap : predicateMaps) { + // Get the predicate + List predicates = processPredicateMap(predicateMap, node); + for (URI predicate : predicates) { + // Process the joins first + Set referencingObjectMaps = pom + .getReferencingObjectMaps(); + for (ReferencingObjectMap referencingObjectMap : referencingObjectMaps) { + Set joinConditions = referencingObjectMap + .getJoinConditions(); + + TriplesMap parentTriplesMap = referencingObjectMap + .getParentTriplesMap(); + + // Create the processor based on the parent triples map + // to perform the join + RMLProcessorFactory factory = new ConcreteRMLProcessorFactory(); + QLTerm queryLanguage = parentTriplesMap + .getLogicalSource().getQueryLanguage(); + RMLProcessor processor = factory.create(queryLanguage); + + RMLPerformer performer; + + if (joinConditions.isEmpty()) { + performer = new JoinRMLPerformer(processor, + subject, predicate); + } else { + // Build a join map where + // key: the parent expression + // value: the value extracted from the child + HashMap joinMap = new HashMap(); + + for (JoinCondition joinCondition : joinConditions) { + String guardString= joinCondition.getGuard(); + boolean checkCondition=false; + if(guardString!=null) + checkCondition =evaluateGuard(guardString, node); + + List childValues = extractValueFromNode( + node, joinCondition.getChild()); + + // MVS: Allow multiple values? + String childValue = childValues.get(0); + + log.debug("[AbstractRMLProcessorProcessor:processPredicateObjectMap]. joinCondition child: " + + joinCondition.getChild()); + log.debug("[AbstractRMLProcessorProcessor:processPredicateObjectMap]. joinCondition parent: " + + joinCondition.getParent()); + log.debug("[AbstractRMLProcessorProcessor:processPredicateObjectMap]. childValue: " + + childValue); + if(checkCondition) + joinMap.put(joinCondition.getParent(), + childValue); + } + + // Execute the join with candidate s, p + // Create a join performer to make the processor + // execute joins (Strategy pattern & composition) + performer = new ConditionalJoinRMLPerformer( + processor, joinMap, subject, predicate); + } + processor.execute(dataset, parentTriplesMap, performer); + } + + // process the objectmaps + Set objectMaps = pom.getObjectMaps(); + for (ObjectMap objectMap : objectMaps) { + // Get the one or more objects returned by the object + // map + List objects = processObjectMap(objectMap, node); + for (Value object : objects) { + if (object != null && !object.toString().isEmpty()) { + dataset.add(subject, predicate, object); + } + } + } + } + } +// } + } + + /** + * process a predicate map + * + * @param predicateMap + * @param node + * @return the uri of the extracted predicate + */ + private List processPredicateMap(PredicateMap predicateMap, Object node) { + // Get the value + List values = processTermMap(predicateMap, node); + + List uris = new ArrayList(); + for (String value : values) { + uris.add(new URIImpl(value)); + } + // return the uri + return uris; + } + + /** + * process an object map + * + * @param objectMap + * @param node + * @return + */ + private List processObjectMap(ObjectMap objectMap, Object node) { + // A Term map returns one or more values (in case expression matches + // more) + List values = processTermMap(objectMap, node); + + List valueList = new ArrayList(); + for (String value : values) { + if (value != null) { + log.debug("[AbstractRMLProcessor:literal] value " + value); + switch (objectMap.getTermType()) { + case IRI: + valueList.add(new URIImpl(value)); + break; + case BLANK_NODE: + valueList.add(new BNodeImpl(value)); + break; + case LITERAL: + if (objectMap.getLanguageTag() != null && !value.equals("")) { + valueList.add(new LiteralImpl(value, objectMap + .getLanguageTag())); + } else if (objectMap.getDataType() != null + && !value.equals("")) { + valueList.add(new LiteralImpl(value, objectMap + .getDataType())); + } else if (value != null && !value.equals("")) { + log.debug("[AbstractRMLProcessor:literal] Literal value " + + value); + valueList.add(new LiteralImpl(value)); + } + // No reason to return null, is replaced by empty list. + } + } + } + return valueList; + } } diff --git a/src/main/java/be/ugent/mmlab/rml/processor/concrete/JSONPathProcessor.java b/src/main/java/be/ugent/mmlab/rml/processor/concrete/JSONPathProcessor.java index 2eee3cc..0cfe453 100644 --- a/src/main/java/be/ugent/mmlab/rml/processor/concrete/JSONPathProcessor.java +++ b/src/main/java/be/ugent/mmlab/rml/processor/concrete/JSONPathProcessor.java @@ -6,6 +6,7 @@ import be.ugent.mmlab.rml.core.RMLMappingFactory; import be.ugent.mmlab.rml.core.RMLPerformer; +import be.ugent.mmlab.rml.model.PredicateObjectMap; import be.ugent.mmlab.rml.model.TriplesMap; import be.ugent.mmlab.rml.processor.AbstractRMLProcessor; import com.jayway.jsonpath.JsonPath; @@ -23,6 +24,7 @@ import net.minidev.json.JSONObject; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.openrdf.model.Resource; /** * @@ -101,4 +103,11 @@ public List extractValueFromNode(Object node, String expression) { } + @Override + public void processPredicateObjectMap(SesameDataSet dataset, + Resource subject, PredicateObjectMap pom, Object node) { + // TODO Auto-generated method stub + + } + } diff --git a/src/main/java/be/ugent/mmlab/rml/processor/concrete/XPathProcessor.java b/src/main/java/be/ugent/mmlab/rml/processor/concrete/XPathProcessor.java index 01cde33..c4b8c3c 100644 --- a/src/main/java/be/ugent/mmlab/rml/processor/concrete/XPathProcessor.java +++ b/src/main/java/be/ugent/mmlab/rml/processor/concrete/XPathProcessor.java @@ -2,6 +2,7 @@ import be.ugent.mmlab.rml.core.RMLMappingFactory; import be.ugent.mmlab.rml.core.RMLPerformer; +import be.ugent.mmlab.rml.model.PredicateObjectMap; import be.ugent.mmlab.rml.model.TriplesMap; import be.ugent.mmlab.rml.processor.AbstractRMLProcessor; import be.ugent.mmlab.rml.xml.XOMBuilder; @@ -25,6 +26,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jaxen.saxpath.SAXPathException; +import org.openrdf.model.Resource; import org.xml.sax.InputSource; /** @@ -134,4 +136,11 @@ private List extractValueFromNode(Node node, String expression) { public List extractValueFromNode(Object node, String expression) { return extractValueFromNode((Node) node, expression); } + + @Override + public void processPredicateObjectMap(SesameDataSet dataset, + Resource subject, PredicateObjectMap pom, Object node) { + // TODO Auto-generated method stub + + } } diff --git a/src/main/java/be/ugent/mmlab/rml/vocabulary/Vocab.java b/src/main/java/be/ugent/mmlab/rml/vocabulary/Vocab.java index 5315a1f..a9eb1f5 100644 --- a/src/main/java/be/ugent/mmlab/rml/vocabulary/Vocab.java +++ b/src/main/java/be/ugent/mmlab/rml/vocabulary/Vocab.java @@ -98,6 +98,7 @@ public enum R2RMLTerm { GRAPH_MAP("graphMap"), GRAPH_COLUMN("graphColumn"), GRAPH_TEMPLATE("graphTemplate"), + GUARD("guard"), INVERSE_EXPRESSION("inverseExpression"), JOIN_CONDITION("joinCondition"), LANGUAGE("language"),