Class ValuesServiceQueryResolver

java.lang.Object
se.liu.ida.hefquin.engine.ValuesServiceQueryResolver

public class ValuesServiceQueryResolver extends Object
Queries with a WHERE clause of a form such as the following one need to be rewritten, which is what this class does.
 PREFIX ex: invalid input: '<'http://example.org/>

 SELECT * WHERE {
   VALUES (?s1 ?s2) {
     (ex:endpoint1 ex:endpoint2)
     (ex:endpoint1 ex:endpoint3)
   }
   SERVICE ?s1 { .. some pattern (that neither mentions ?s1 nor ?2) .. }
   SERVICE ?s2 { .. also some pattern (that also doesn't mention ?s1 or ?2) .. }
 }
 
The rewriting that is applied to such query patterns is to apply the solution mappings of the VALUES clause to the SERVICE clauses and, then remove the VALUES clause. If the VALUES clause contains multiple solution mappings (as in the example above), than the group of SERVICE clauses is copied for each of these solution mappings, and the resulting groups are combined via UNION. Additionally, in any of the two cases (just one solution mapping in the VALUES clause or multiple), BIND clauses are appended to still capture the bindings for the variables of the VALUES clause. For instance, the result of rewriting the example query above is given as follows.
 PREFIX ex: invalid input: '<'http://example.org/>

 SELECT * WHERE {
   {
     SERVICE ex:endpoint1 { .. some pattern (that neither mentions ?s1 nor ?2) .. }
     SERVICE ex:endpoint2 { .. also some pattern (that also doesn't mention ?s1 or ?2) .. }
     BIND (?s1 AS ex:endpoint1)
     BIND (?s2 AS ex:endpoint2)
   }
   UNION
   {
     SERVICE ex:endpoint1 { .. some pattern (that neither mentions ?s1 nor ?2) .. }
     SERVICE ex:endpoint3 { .. also some pattern (that also doesn't mention ?s1 or ?2) .. }
     BIND (?s1 AS ex:endpoint1)
     BIND (?s2 AS ex:endpoint3)
   }
 }
 
The VALUES clause may also be split up in the given queries, in order to avoid a combinatorial blow-up of possible combinations. For instance, the the initial example query above may also be provided in the following form (which results in the same rewritten query).
 PREFIX ex: invalid input: '<'http://example.org/>

 SELECT * WHERE {
   VALUES ?s1 { ex:endpoint1 }
   VALUES ?s2 { ex:endpoint2  ex:endpoint3 }
   SERVICE ?s1 { .. some pattern (that neither mentions ?s1 nor ?2) .. }
   SERVICE ?s2 { .. also some pattern (that also doesn't mention ?s1 or ?2) .. }
 }
 
When using multiple VALUES clauses, it is not even necessary to place all of them at the beginning of the WHERE clause. Instead, some of them may be moved closer to the SERVICE clause(s) in which the variables of a VALUES clause are used as the service variable. For instance, the initial example query above may also be provided in the following form (but, then, the rewritten version looks different, as discussed below).
 PREFIX ex: invalid input: '<'http://example.org/>

 SELECT * WHERE {
   VALUES ?s1 { ex:endpoint1 }
   SERVICE ?s1 { .. some pattern (that neither mentions ?s1 nor ?2) .. }
   VALUES ?s2 { ex:endpoint2  ex:endpoint3 }
   SERVICE ?s2 { .. also some pattern (that also doesn't mention ?s1 or ?2) .. }
 }
 
However, queries given in this form (with VALUES clauses in between other patterns) are treated slightly different by the rewriting algorithm in this class. That is, every VALUES clause that follows some other patterns (such as the VALUES clause with variable ?s2 in the previous example) is considered to end the scope of rewriting based on the previous VALUES clause(s) and to start a new rewriting scope. The rewritten parts from the different rewriting scopes are joined together in the resulting rewritten query. For instance, for the previous example query, the result looks as follows.
 PREFIX ex: invalid input: '<'http://example.org/>

 SELECT * WHERE {
   {
     SERVICE ex:endpoint1 { .. some pattern (that neither mentions ?s1 nor ?2) .. }
     BIND (?s1 AS ex:endpoint1)
   }
   {
     SERVICE ex:endpoint2 { .. also some pattern (that also doesn't mention ?s1 or ?2) .. }
     BIND (?s2 AS ex:endpoint2)
   }
   UNION
   {
     SERVICE ex:endpoint3 { .. also some pattern (that also doesn't mention ?s1 or ?2) .. }
     BIND (?s2 AS ex:endpoint3)
   }
 }
 
Notice that this resulting query differs from the one obtained for the cases in which the VALUES clauses are all at the beginning of the given query. Here, each rewriting scope results in its own UNION group (instead of just one big UNION group for everything together). Yet, since the input queries are semantically equivalent, the same also hold for the two resulting queries. The approach to consider different rewriting scopes introduces a limitation: It does not support SERVICE clauses with a variable that is not bound by the VALUES clause(s) that come closest before the SERVICE clause. Hence, HeFQUIN cannot support queries with such SERVICE clauses.
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    protected static class 
    Transforms all SERVICE clauses that have a service variable by replacing this variable with the URI that a given solution mapping assigns to the variable.
    protected static class 
    This exception is used internally by this class.
    protected static class 
    This exception is used internally by this class.
    protected static class 
    Collects all variables in a given Element except for variables that occur *only* as the variable of SERVICE clauses.
    protected static class 
    Checks for each visited SERVICE clause that has a service variable whether that variable is in a given list of permitted variables.
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    protected static List<org.apache.jena.sparql.syntax.Element>
    expandValuesPlusServicePattern(List<org.apache.jena.sparql.syntax.Element> elmts)
    Rewrites the given list of query elements (if needed).
    protected static List<org.apache.jena.sparql.syntax.Element>
    expandValuesPlusServicePattern(List<org.apache.jena.sparql.syntax.Element> elmts, org.apache.jena.sparql.syntax.ElementData valClause, int startPos)
    Rewrites the given list of query elements by using the solution mappings of the given VALUES clause as a basis, and starting only from the given position within the list (i.e., list elements that are at an earlier position in the list are ignored).
    static void
    expandValuesPlusServicePattern(org.apache.jena.query.Query q)
    If the WHERE clause of the given query is of a form that should be rewritten, then this method replaces the WHERE clause of the query by the rewritten one.
    protected static org.apache.jena.sparql.syntax.ElementData
    merge(org.apache.jena.sparql.syntax.ElementData valClause1, org.apache.jena.sparql.syntax.ElementData valClause2)
    Merges the two given VALUES clauses into a single one by creating a cross-product of their respective sets of solution mappings.
    protected static int
    positionOfNextVALUES(List<org.apache.jena.sparql.syntax.Element> elmts, int startPos)
    Determines the position of the next VALUES clause in the given list of query elements, starting from the given position (i.e., the first element that this function considers is the element at the given position).
    protected static org.apache.jena.sparql.syntax.Element
    rewrite(org.apache.jena.sparql.engine.binding.Binding solmap, List<org.apache.jena.sparql.syntax.Element> elmts, int startPos, int endPos, List<org.apache.jena.sparql.core.Var> varsForBind)
    Rewrites the query elements of the given list based on the given solution mapping, but considering only the list elements from the given start position until (and including) the given end position.
    protected static org.apache.jena.sparql.syntax.Element
    rewrite(org.apache.jena.sparql.syntax.ElementData valClause, List<org.apache.jena.sparql.syntax.Element> elmts, int startPos, int endPos)
    Rewrites the query elements of the given list based on the solution mappings of the given VALUES clause, but considering only the list elements from the given start position until (and including) the given end position.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • ValuesServiceQueryResolver

      public ValuesServiceQueryResolver()
  • Method Details

    • expandValuesPlusServicePattern

      public static void expandValuesPlusServicePattern(org.apache.jena.query.Query q) throws UnsupportedQueryException, IllegalQueryException
      If the WHERE clause of the given query is of a form that should be rewritten, then this method replaces the WHERE clause of the query by the rewritten one. Otherwise, the WHERE clause of the query is not changed. An UnsupportedQueryException is thrown if it is discovered that the WHERE clause of the given query uses VALUES clauses and SERVICE clauses in a way that is currently not supported. An IllegalQueryException is thrown if it is discovered that the WHERE clause of the given query uses VALUES clauses in an incorrect way.
      Throws:
      UnsupportedQueryException
      IllegalQueryException
    • expandValuesPlusServicePattern

      protected static List<org.apache.jena.sparql.syntax.Element> expandValuesPlusServicePattern(List<org.apache.jena.sparql.syntax.Element> elmts) throws ValuesServiceQueryResolver.MyUnsupportedQueryException, ValuesServiceQueryResolver.MyIllegalQueryException
      Rewrites the given list of query elements (if needed). Returns null if it turns out that nothing needs to be rewritten, which is the case if there is no VALUES clause in the given list or there is a VALUES clause but only as the very last element of the list. Throws an ValuesServiceQueryResolver.MyIllegalQueryException if it discovers two VALUES clauses whose sets of variables are not disjoint.
      Throws:
      ValuesServiceQueryResolver.MyUnsupportedQueryException
      ValuesServiceQueryResolver.MyIllegalQueryException
    • expandValuesPlusServicePattern

      protected static List<org.apache.jena.sparql.syntax.Element> expandValuesPlusServicePattern(List<org.apache.jena.sparql.syntax.Element> elmts, org.apache.jena.sparql.syntax.ElementData valClause, int startPos) throws ValuesServiceQueryResolver.MyUnsupportedQueryException, ValuesServiceQueryResolver.MyIllegalQueryException
      Rewrites the given list of query elements by using the solution mappings of the given VALUES clause as a basis, and starting only from the given position within the list (i.e., list elements that are at an earlier position in the list are ignored). May return null, namely in case that given position is the very last position of the list and there is another VALUES clause at that position. Throws an ValuesServiceQueryResolver.MyIllegalQueryException if it discovers two VALUES clauses whose sets of variables are not disjoint.
      Throws:
      ValuesServiceQueryResolver.MyUnsupportedQueryException
      ValuesServiceQueryResolver.MyIllegalQueryException
    • positionOfNextVALUES

      protected static int positionOfNextVALUES(List<org.apache.jena.sparql.syntax.Element> elmts, int startPos)
      Determines the position of the next VALUES clause in the given list of query elements, starting from the given position (i.e., the first element that this function considers is the element at the given position). If there is no VALUES clause in the given list from the given position until the end of the list, then this function returns -1.
    • merge

      protected static org.apache.jena.sparql.syntax.ElementData merge(org.apache.jena.sparql.syntax.ElementData valClause1, org.apache.jena.sparql.syntax.ElementData valClause2) throws ValuesServiceQueryResolver.MyIllegalQueryException
      Merges the two given VALUES clauses into a single one by creating a cross-product of their respective sets of solution mappings. Throws an ValuesServiceQueryResolver.MyIllegalQueryException if the sets of variables of the two given VALUES clauses are not disjoint.
      Throws:
      ValuesServiceQueryResolver.MyIllegalQueryException
    • rewrite

      protected static org.apache.jena.sparql.syntax.Element rewrite(org.apache.jena.sparql.syntax.ElementData valClause, List<org.apache.jena.sparql.syntax.Element> elmts, int startPos, int endPos)
      Rewrites the query elements of the given list based on the solution mappings of the given VALUES clause, but considering only the list elements from the given start position until (and including) the given end position. Assumes that none of these elements is a VALUES clause.
    • rewrite

      protected static org.apache.jena.sparql.syntax.Element rewrite(org.apache.jena.sparql.engine.binding.Binding solmap, List<org.apache.jena.sparql.syntax.Element> elmts, int startPos, int endPos, List<org.apache.jena.sparql.core.Var> varsForBind)
      Rewrites the query elements of the given list based on the given solution mapping, but considering only the list elements from the given start position until (and including) the given end position. Assumes that none of these elements is a VALUES clause. The given list of variables is used to add BIND clauses; in particular, for every variable in this list, if the given solution mapping covers the variable, then a BIND clause is added that assigns the variable to the corresponding RDF term of the solution mapping.