From a410b2f1fe3f6c35b79cd6f76836f1943645faed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Euzenat?= <Jerome.Euzenat@inria.fr> Date: Wed, 3 Jun 2015 11:22:38 +0000 Subject: [PATCH] - finished fully working SPARQL generator for link keys --- html/relnotes.html | 3 +- .../renderer/GraphPatternRendererVisitor.java | 177 +++++++++--------- .../SPARQLLinkkerRendererVisitor.java | 32 ++-- 3 files changed, 110 insertions(+), 102 deletions(-) diff --git a/html/relnotes.html b/html/relnotes.html index 167c8e68..0aba8a13 100644 --- a/html/relnotes.html +++ b/html/relnotes.html @@ -71,6 +71,7 @@ with a warning: <p><ul compact="1"> <li>Added interface <tt>AlignmentRepairer</tt> (api)</tt> <li>Added some more SPARQL renderers (impl)</li> +<li>Added <tt>SPARQLLinkkerRendererVisitor</tt> generating SPARQL from link keys(impl)</li> <li>Fixed a bug in pull aggregation (impl)</li> <li>Improved error reporting (err500) when ontology is unknown (serv)</li> <li>Implemented <tt>AbstractRepairer</tt> (impl)</tt> @@ -91,7 +92,7 @@ with a warning: <li>Fixed several bugs in <tt>GraphPatternRendererVisitor</tt> (impl)</li> <li>Fixed a bug in server updating (impl)</li> <li>Fixed the compareTo implementation in <tt>BasicCell</tt> (impl)</li> -<li>Implemented linkkeys in EDOAL (edoal)</li> +<li>Implemented link keys in EDOAL (edoal)</li> <li>Implemented (fully) extension parsing in RDFParser (parser)</li> <li>Reorganised AlignmentServices into transport (HTTP) and service (HTML/Web service) (serv)</li> <li>Enabled query translation in interface and web service (serv)</li> diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/GraphPatternRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/GraphPatternRendererVisitor.java index 2baf6c19..aa47ba4c 100644 --- a/src/fr/inrialpes/exmo/align/impl/renderer/GraphPatternRendererVisitor.java +++ b/src/fr/inrialpes/exmo/align/impl/renderer/GraphPatternRendererVisitor.java @@ -65,6 +65,7 @@ import fr.inrialpes.exmo.align.impl.edoal.RelationDomainRestriction; import fr.inrialpes.exmo.align.impl.edoal.RelationId; import fr.inrialpes.exmo.align.impl.edoal.Transformation; import fr.inrialpes.exmo.align.impl.edoal.Value; +import fr.inrialpes.exmo.align.impl.edoal.ValueExpression; import fr.inrialpes.exmo.align.parser.SyntaxElement.Constructor; import java.util.HashMap; import java.util.LinkedHashMap; @@ -197,14 +198,15 @@ public abstract class GraphPatternRendererVisitor extends IndentedRendererVisito return listBGP; } - public String registerPrefix(URI u) { - String prefix = getPrefixDomain(u); - String tag = getPrefixName(u); - String shortCut = getOrGenerateNSPrefix(prefix); - return shortCut + ":" + tag; + public String registerPrefix( URI u ) { + String str = u.toString(); + int index; + if ( str.contains("#") ) index = str.lastIndexOf("#"); + else index = str.lastIndexOf("/"); + return getOrGenerateNSPrefix(str.substring(0, index + 1)) + ":" + str.substring(index + 1); } - public String getPrefixDomain(URI u) { + public String getPrefixDomain( URI u ) { String str = u.toString(); int index; if (str.contains("#")) { @@ -215,7 +217,7 @@ public abstract class GraphPatternRendererVisitor extends IndentedRendererVisito return str.substring(0, index + 1); } - public String getPrefixName(URI u) { + public String getPrefixName(URI u) { // Would better be suffix String str = u.toString(); int index; if (str.contains("#")) { @@ -226,13 +228,11 @@ public abstract class GraphPatternRendererVisitor extends IndentedRendererVisito return str.substring(index + 1); } - public String getOrGenerateNSPrefix(String namespace) { - if (namespace.length() == 0) { - return ""; - } - String ns = prefixList.get(namespace); + public String getOrGenerateNSPrefix( String namespace ) { + if ( namespace.length() == 0 ) return ""; + String ns = prefixList.get( namespace ); if (ns == null) { - prefixList.put(namespace, ns = "ns" + numberNs++); + prefixList.put( namespace, ns = "ns" + numberNs++ ); } return ns; } @@ -315,7 +315,7 @@ public abstract class GraphPatternRendererVisitor extends IndentedRendererVisito } } - public void visit(final ClassConstruction e) throws AlignmentException { + public void visit( final ClassConstruction e ) throws AlignmentException { op = e.getOperator(); if (op == Constructor.OR) { int size = e.getComponents().size(); @@ -330,7 +330,7 @@ public abstract class GraphPatternRendererVisitor extends IndentedRendererVisito } } } else if (op == Constructor.NOT) { - strBGP += "FILTER (NOT EXISTS {" + NL; + strBGP += "FILTER (NOT EXISTS {"; for (final ClassExpression ce : e.getComponents()) { ce.accept(this); } @@ -346,54 +346,61 @@ public abstract class GraphPatternRendererVisitor extends IndentedRendererVisito } } - public void visit(final ClassValueRestriction c) throws AlignmentException { - String str = ""; - instance = ""; + private String valueToCompare( ValueExpression val, String var ) throws AlignmentException { value = ""; + uriType = ""; flagRestriction = true; - c.getValue().accept(this); + val.accept(this); flagRestriction = false; + return "xsd:"+uriType+"( "+var+" )"; + } - if (!instance.equals("")) { - valueRestriction = instance; - } else if (!value.equals("")) { - valueRestriction = value; - } - - if (c.getComparator().getURI().equals(Comparator.GREATER.getURI())) { - opOccurence = ">"; - inClassRestriction = true; - } - if (c.getComparator().getURI().equals(Comparator.LOWER.getURI())) { - opOccurence = "<"; - inClassRestriction = true; - } - flagRestriction = true; - c.getRestrictionPath().accept(this); - flagRestriction = false; - String temp = obj; - if (inClassRestriction && !objectsRestriction.isEmpty()) { - Iterator<String> listObj = objectsRestriction.iterator(); - if (op == Constructor.COMP) { - String tmp = ""; - while (listObj.hasNext()) { - tmp = listObj.next(); - } - str = "FILTER (" + tmp + opOccurence + valueRestriction + ")" + NL; - } else { - while (listObj.hasNext()) { - str += "FILTER (" + listObj.next() + opOccurence + valueRestriction + ")" + NL; - } - } - strBGP += str; - } - valueRestriction = null; - inClassRestriction = false; - obj = temp; - if (op == Constructor.AND) { - createVarName(); - } + public void visit(final ClassValueRestriction c) throws AlignmentException { + String str = ""; + instance = ""; + value = ""; + flagRestriction = true; + c.getValue().accept(this); + flagRestriction = false; + //String xxxx = valueToCompare( c.getValue() ); + + if (!instance.equals("")) { + valueRestriction = instance; + } else if (!value.equals("")) { + valueRestriction = value; + } + + opOccurence = c.getComparator().getSPARQLComparator(); + inClassRestriction = true; + + flagRestriction = true; + c.getRestrictionPath().accept(this); + flagRestriction = false; + + String temp = obj; + if (inClassRestriction && !objectsRestriction.isEmpty()) { + Iterator<String> listObj = objectsRestriction.iterator(); + if (op == Constructor.COMP) { + String tmp = ""; + while (listObj.hasNext()) { + tmp = listObj.next(); + } + str = "FILTER (" + tmp + opOccurence + valueRestriction + ")" + NL; + } else { + while (listObj.hasNext()) { + str += "FILTER (" + listObj.next() + opOccurence + valueRestriction + ")" + NL; + } + } + strBGP += str; + } + obj = temp; + valueRestriction = null; + inClassRestriction = false; + if (op == Constructor.AND) { + createVarName(); + } } + public void visit(final ClassTypeRestriction c) throws AlignmentException { String str = ""; @@ -440,32 +447,22 @@ public abstract class GraphPatternRendererVisitor extends IndentedRendererVisito public void visit(final ClassOccurenceRestriction c) throws AlignmentException { String str = ""; inClassRestriction = true; - if (c.getComparator().getURI().equals(Comparator.EQUAL.getURI())) { - nbCardinality = c.getOccurence(); - opOccurence = "="; - } - if (c.getComparator().getURI().equals(Comparator.GREATER.getURI())) { - nbCardinality = c.getOccurence(); - opOccurence = ">"; - } - if (c.getComparator().getURI().equals(Comparator.LOWER.getURI())) { - nbCardinality = c.getOccurence(); - opOccurence = "<"; - } + opOccurence = c.getComparator().getSPARQLComparator(); + nbCardinality = c.getOccurence(); flagRestriction = true; c.getRestrictionPath().accept(this); flagRestriction = false; if (!objectsRestriction.isEmpty()) { Iterator<String> listObj = objectsRestriction.iterator(); - if (op == Constructor.COMP) { + if ( op == Constructor.COMP ) { String tmp = ""; while (listObj.hasNext()) { tmp = listObj.next(); } - str += "FILTER(COUNT(" + tmp + ")" + opOccurence + nbCardinality + ")" + NL; + str += "FILTER( COUNT(" + tmp + ") " + opOccurence + " " + nbCardinality + ")" + NL; } else { while (listObj.hasNext()) { - str += "FILTER(COUNT(" + listObj.next() + ")" + opOccurence + nbCardinality + ")" + NL; + str += "FILTER( COUNT(" + listObj.next() + ") " + opOccurence + " " + nbCardinality + ")" + NL; } } @@ -517,12 +514,12 @@ public abstract class GraphPatternRendererVisitor extends IndentedRendererVisito } strBGP += "})" + NL; } else if (op == Constructor.COMP) { + int size = e.getComponents().size(); String tempSub = sub; - //if ( blanks && this.getClass() == SPARQLConstructRendererVisitor.class ) { + //if ( blanks && ( this.getClass() == SPARQLConstructRendererVisitor.class || this.getClass() == SPARQLLinkkerRendererVisitor.class ) ) { // obj = "_:o" + ++count; //} String tempObj = obj; - int size = e.getComponents().size(); for (final PathExpression re : e.getComponents()) { size--; // next object @@ -532,7 +529,7 @@ public abstract class GraphPatternRendererVisitor extends IndentedRendererVisito } else { obj = tempObj; } // otherwise, generating intermediate variables... - } else if (blanks && this.getClass() == SPARQLConstructRendererVisitor.class) { + } else if (blanks && (this.getClass() == SPARQLConstructRendererVisitor.class || this.getClass() == SPARQLLinkkerRendererVisitor.class )) { obj = "_:o" + ++varsIndexcount; } else { obj = "?o" + ++varsIndexcount; @@ -568,19 +565,18 @@ public abstract class GraphPatternRendererVisitor extends IndentedRendererVisito public void visit( final PropertyValueRestriction c ) throws AlignmentException { String str = ""; - value = ""; - uriType = ""; - flagRestriction = true; - c.getValue().accept(this); - flagRestriction = false; + String val = valueToCompare( c.getValue(), obj ); + /* if (c.getComparator().getURI().equals(Comparator.EQUAL.getURI())) { - str = "FILTER (xsd:" + uriType + "(" + obj + ") = "; + str = "FILTER (" + val + " = "; } else if (c.getComparator().getURI().equals(Comparator.GREATER.getURI())) { - str = "FILTER (xsd:" + uriType + "(" + obj + ") > "; + str = "FILTER (" + val + " > "; } else { - str = "FILTER (xsd:" + uriType + "(" + obj + ") < "; + str = "FILTER (" + val + " < "; } str += "\"" + value + "\")" + NL; + */ + str = "FILTER (" + val + " " + c.getComparator().getSPARQLComparator() + " \"" + value + "\")" + NL; strBGP += str; value = ""; @@ -670,7 +666,7 @@ public abstract class GraphPatternRendererVisitor extends IndentedRendererVisito } else if (op == Constructor.COMP) { int size = e.getComponents().size(); String temp = sub; - //if ( blanks && this.getClass() == SPARQLConstructRendererVisitor.class ) { + //if ( blanks && (this.getClass() == SPARQLConstructRendererVisitor.class || this.getClass() == SPARQLLinkkerRendererVisitor.class ) ) { //obj = "_:o" + ++count; createVarName(); //} @@ -682,7 +678,7 @@ public abstract class GraphPatternRendererVisitor extends IndentedRendererVisito if (size == 1 && valueRestriction != null && !inClassRestriction) { obj = valueRestriction.toString(); } else { - if (this.getClass() == SPARQLConstructRendererVisitor.class || this.getClass() == SPARQLSelectRendererVisitor.class) { + if (this.getClass() == SPARQLConstructRendererVisitor.class || this.getClass() == SPARQLSelectRendererVisitor.class || this.getClass() == SPARQLLinkkerRendererVisitor.class ) { createVarName(); } objectsRestriction.add(obj); @@ -757,10 +753,10 @@ public abstract class GraphPatternRendererVisitor extends IndentedRendererVisito flagRestriction = false; } - public void visit(final InstanceId e) throws AlignmentException { + public void visit( final InstanceId e ) throws AlignmentException { if (e.getURI() != null) { - String id = registerPrefix(e.getURI()); - if (flagRestriction) { + String id = registerPrefix( e.getURI() ); + if ( flagRestriction ) { instance = id; } else { strBGP += id + " ?p ?o1 ." + NL; @@ -770,7 +766,8 @@ public abstract class GraphPatternRendererVisitor extends IndentedRendererVisito public void visit( final Value e ) throws AlignmentException { value = e.getValue(); - if ( e.getType() != null ) uriType = decodeDatatype( e.getType().toString() ); + if ( e.getType() != null ) uriType = registerPrefix( e.getType() ); + //if ( e.getType() != null ) uriType = decodeDatatype( e.getType().toString() ); // JE2015: Not sure that this is really useful //if ( uriType != null && uriType.equals("") ) uriType = "xsd:string"; } diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/SPARQLLinkkerRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/SPARQLLinkkerRendererVisitor.java index 5ad1512f..f6d07b31 100644 --- a/src/fr/inrialpes/exmo/align/impl/renderer/SPARQLLinkkerRendererVisitor.java +++ b/src/fr/inrialpes/exmo/align/impl/renderer/SPARQLLinkkerRendererVisitor.java @@ -249,29 +249,39 @@ public class SPARQLLinkkerRendererVisitor extends GraphPatternRendererVisitor im } } + /** + * Generate the constraint corresponding to: + * MINUS SELECT ?x ?y WHERE { ?x pj ?wj . FILTER NOT EXISTS { ?y qj ?wj . } } + * MINUS SELECT ?x ?y WHERE { ?y qj ?wj . FILTER NOT EXISTS { ?x pj ?wj . } } + */ public void visit( final LinkkeyEquals linkkeyEquals ) throws AlignmentException { - String extravar1 = "x"; - String extravar2 = "y"; - initStructure(); //strBGP = ""; // congrats! - resetVariables( "?x", "?o" ); + // In the semantics of EQ-Linkkeys, the intersection must not be empty... + processInLinkKey( linkkeyEquals ); + String extravar1 = createVarName(); + String extravar2 = createVarName(); + initStructure(); //strBGP = ""; // congrats! Unsure + String o1 = createVarName(); + resetVariables( extravar1, o1 ); linkkeyEquals.getExpression1().accept( this ); String temp = obj; String GP1 = wrapInNamedGraph( onto1NamedGraph, getGP() ); // == resetS2( lkvar2 ); initStructure(); //strBGP = ""; // congrats! - resetVariables( "?y", "?o" ); + resetVariables( extravar2, o1 ); obj = temp; linkkeyEquals.getExpression2().accept( this ); String GP2 = wrapInNamedGraph( onto2NamedGraph, getGP() ); - lkpattern += "MINUS SELECT ?x ?y WHERE { " + GP1 + " FILTER NOT EXISTS { " + GP2 + " } }"; - lkpattern += "MINUS SELECT ?x ?y WHERE { " + GP2 + " FILTER NOT EXISTS { " + GP1 + " } }"; - //MINUS SELECT ?x ?y WHERE { ?x pj ?wj . FILTER NOT EXISTS { ?y qj ?wj . } } - //MINUS SELECT ?x ?y WHERE { ?y qj ?wj . FILTER NOT EXISTS { ?x pj ?wj . } } + lkpattern += "MINUS { SELECT "+extravar1+" "+extravar2+" WHERE { " + GP1 + " FILTER NOT EXISTS { " + GP2 + " } } }"+NL; + lkpattern += "MINUS { SELECT "+extravar1+" "+extravar2+" WHERE { " + GP2 + " FILTER NOT EXISTS { " + GP1 + " } } }"+NL; } + public void visit( final LinkkeyIntersects linkkeyIntersects ) throws AlignmentException { + processInLinkKey( linkkeyIntersects ); + } + // JE: I do not understand where the common variables are created... (by default obj is preserved) // JE: Is the GP reset??? The answer is no. Hence init... - public void visit( final LinkkeyIntersects linkkeyIntersects ) throws AlignmentException { + public void processInLinkKey( final LinkkeyBinding linkkeyIntersects ) throws AlignmentException { //?x p'i ?zi . ?y q'i ?zi . //= lkpattern += NL + lkvar1 + "p" + "newvar" + " . " + NL + lkvar2 + "q" + "samenewvar" + " . "; // == resetS1( lkvar1 ); @@ -288,7 +298,7 @@ public class SPARQLLinkkerRendererVisitor extends GraphPatternRendererVisitor im resetVariables( lkvar2, o2 ); linkkeyIntersects.getExpression2().accept( this ); lkpattern += wrapInNamedGraph( onto2NamedGraph, getGP() ); - lkpattern += "FILTER( lcase(str("+o1+")) = lcase(str("+o2+")) ) "; + lkpattern += "FILTER( lcase(str("+o1+")) = lcase(str("+o2+")) ) "+NL; } protected String wrapInNamedGraph( String namedGraph, String stuff ) { -- GitLab