[Mulgara-svn] r904 - trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql

pag at mulgara.org pag at mulgara.org
Wed May 7 14:26:05 UTC 2008


Author: pag
Date: 2008-05-07 07:26:04 -0700 (Wed, 07 May 2008)
New Revision: 904

Added:
   trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/PatternTransformer.java
Log:
Provides transformation operations, as per http://www.w3.org/TR/rdf-sparql-query/#convertGraphPattern

Added: trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/PatternTransformer.java
===================================================================
--- trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/PatternTransformer.java	                        (rev 0)
+++ trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/PatternTransformer.java	2008-05-07 14:26:04 UTC (rev 904)
@@ -0,0 +1,135 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.sparql;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.mulgara.parser.MulgaraParserException;
+import org.mulgara.query.ConstraintExpression;
+import org.mulgara.query.ConstraintFilter;
+import org.mulgara.query.ConstraintOptionalJoin;
+import org.mulgara.query.filter.And;
+import org.mulgara.query.filter.Filter;
+import org.mulgara.query.filter.value.Bool;
+
+/**
+ * This object transforms a {@link ConstraintExpression} into a minimized {@link ConstraintExpresion}.
+ *
+ * @created May 06, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class PatternTransformer {
+
+  /**
+   * Perform the mapping of the graph pattern and return the results as a {@link ConstraintExpression}.
+   * @return The mapped constraint expression.
+   */
+  static public ConstraintExpression transform(ConstraintExpression constraints) throws MulgaraParserException {
+    Transformer<? extends ConstraintExpression> tx = txMap.get(constraints);
+    if (tx == null) return constraints;
+    return tx.internalTx(constraints);
+  }
+
+  /** A mapping of constraint expressions to Transformers. */
+  private static Map<Class<? extends ConstraintExpression>,Transformer<? extends ConstraintExpression>> txMap =
+      new HashMap<Class<? extends ConstraintExpression>,Transformer<? extends ConstraintExpression>>();
+
+  /**
+   * The class for the mapping of {@link ConstraintExpression}s to {@link ConstraintExpression}s.
+   */
+  private static abstract class Transformer<T extends ConstraintExpression>  {
+    /** An entry point for the tx operation. This method handles casting to be compatible with the generic template. */
+    @SuppressWarnings("unchecked")
+    public ConstraintExpression internalTx(ConstraintExpression constraints) throws MulgaraParserException {
+      return tx((T)constraints);
+    }
+    public abstract ConstraintExpression tx(T constraints) throws MulgaraParserException;
+    /** Identify the class to be mapped by the extension. */
+    public abstract Class<T> getTxType();
+  }
+
+  /**
+   * Utility method to add a transformer to the map, keyed on the class it transforms.
+   * @param mapper The mapper to add to the map.
+   */
+  static void addToMap(Transformer<?> tx) {
+    txMap.put(tx.getTxType(), tx);
+  }
+
+  /**
+   * Initialize the mapping of patterns to the constraint builders.
+   */
+  static {
+    addToMap(new FilterTx());
+    addToMap(new LeftJoinTx());
+  }
+
+  /**
+   * Creates a conjunction of filters, skipping any TRUE values on the way.
+   * @param lhs The first filter to join
+   * @param rhs The second filter to join
+   * @return A new filter that represents the conjunction of the lhs and the rhs
+   */
+  private static Filter and(Filter lhs, Filter rhs) {
+    if (lhs == Bool.TRUE) return rhs;
+    if (rhs == Bool.TRUE) return lhs;
+    return new And(lhs, rhs);
+  }
+
+
+  /**
+   * Map filtered constraints to the flattening operation.
+   *   Filter(X1,Filter(X2,A)) => Filter(X2 && X1, A)
+   */
+  private static class FilterTx extends Transformer<ConstraintFilter> {
+    public Class<ConstraintFilter> getTxType() { return ConstraintFilter.class; }
+    public ConstraintExpression tx(ConstraintFilter constraint) throws MulgaraParserException {
+      ConstraintExpression subConstraint = constraint.getUnfilteredConstraint();
+      if (subConstraint instanceof ConstraintFilter) {
+        // found Filter(X1,Filter(X2,A))
+        ConstraintFilter subFilter = (ConstraintFilter)transform(subConstraint); // Filter(X2,A)
+        return new ConstraintFilter(subFilter.getUnfilteredConstraint(), and(subFilter.getFilter(), constraint.getFilter()));
+      }
+      return constraint;
+    }
+  }
+
+  /**
+   * Based on the syntactic (not algebraic) transformations:
+   *   LeftJoin(A, Filter(X1, B), X2) => LeftJoin(A, B, X1 && X2)
+   *   LeftJoin(A, LeftJoin(B, C, X1), X2) => LeftJoin(A, LeftJoin(B, C, true), X1 && X2)
+   */
+  private static class LeftJoinTx extends Transformer<ConstraintOptionalJoin> {
+    public Class<ConstraintOptionalJoin> getTxType() { return ConstraintOptionalJoin.class; }
+    public ConstraintExpression tx(ConstraintOptionalJoin leftJoin) throws MulgaraParserException {
+      ConstraintExpression op = leftJoin.getOptional();
+      if (op instanceof ConstraintFilter) {
+        // found LeftJoin(A, Filter(X1, B), X2)
+        ConstraintFilter filter = (ConstraintFilter)transform(op);  // Filter(X1, B)
+        Filter f = and(filter.getFilter(), leftJoin.getFilter());  // X1 && X2
+        return new ConstraintOptionalJoin(leftJoin.getMain(), filter.getUnfilteredConstraint(), f);
+      }
+      if (op instanceof ConstraintOptionalJoin) {
+        // found LeftJoin(A, LeftJoin(B, C, X1), X2)
+        ConstraintOptionalJoin subJoin = (ConstraintOptionalJoin)transform(op);  // LeftJoin(B, C, X1)
+        ConstraintOptionalJoin newSubJoin = new ConstraintOptionalJoin(subJoin.getMain(), subJoin.getOptional(), Bool.TRUE);
+        Filter newFilter = and(subJoin.getFilter(), leftJoin.getFilter());  // X1 && X2
+        return new ConstraintOptionalJoin(leftJoin.getMain(), newSubJoin, newFilter);
+      }
+      return leftJoin;
+    }
+  }
+
+}




More information about the Mulgara-svn mailing list