[Mulgara-svn] r1395 - trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi
ronald at mulgara.org
ronald at mulgara.org
Wed Dec 3 09:26:01 UTC 2008
Author: ronald
Date: 2008-12-03 01:26:00 -0800 (Wed, 03 Dec 2008)
New Revision: 1395
Added:
trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/AbstractSymbolicTransformer.java
Modified:
trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/DuplicateVariableTransformer.java
Log:
Factored out generic constraint walking code into a common superclass for
symbolic transformers.
Added: trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/AbstractSymbolicTransformer.java
===================================================================
--- trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/AbstractSymbolicTransformer.java (rev 0)
+++ trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/AbstractSymbolicTransformer.java 2008-12-03 09:26:00 UTC (rev 1395)
@@ -0,0 +1,187 @@
+/*
+ * 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.resolver.spi;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import org.mulgara.query.Constraint;
+import org.mulgara.query.ConstraintConjunction;
+import org.mulgara.query.ConstraintDifference;
+import org.mulgara.query.ConstraintDisjunction;
+import org.mulgara.query.ConstraintExpression;
+import org.mulgara.query.ConstraintFilter;
+import org.mulgara.query.ConstraintIn;
+import org.mulgara.query.ConstraintOperation;
+import org.mulgara.query.ConstraintOptionalJoin;
+
+/**
+ * This provides some common processing for symbolic-transformers.
+ *
+ * @created Dec 2, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class AbstractSymbolicTransformer implements SymbolicTransformation {
+ private static final Logger logger = Logger.getLogger(AbstractSymbolicTransformer.class);
+
+ public void transform(SymbolicTransformationContext context, MutableLocalQuery mutableLocalQuery)
+ throws SymbolicTransformationException {
+ if (logger.isTraceEnabled()) logger.trace("Transforming query: " + mutableLocalQuery.getConstraintExpression());
+
+ ConstraintExpression expr = mutableLocalQuery.getConstraintExpression();
+ ConstraintExpression trans = transformExpr(context, expr);
+
+ if (logger.isTraceEnabled()) logger.trace("Transform result: " + (expr != trans ? trans : "-no-change-"));
+
+ if (expr != trans) {
+ mutableLocalQuery.setConstraintExpression(trans);
+ }
+ }
+
+ /**
+ * Transform the given constraint-expression. This is a dispatcher, invoking one of the other
+ * transformXYZ methods as applicable or returning the given expr if none are.
+ *
+ * @param context the current transformation context
+ * @param expr the constraint expression to transform
+ * @return a new expression is something was changed, or <var>expr</var> if nothing was changed.
+ * @throws SymbolicTransformationException If there is an error applying the transform
+ */
+ protected ConstraintExpression transformExpr(SymbolicTransformationContext context,
+ ConstraintExpression expr)
+ throws SymbolicTransformationException {
+ // explicitly handle all the recursive types
+ if (expr instanceof ConstraintFilter) return transformFilter(context, (ConstraintFilter)expr);
+ if (expr instanceof ConstraintIn) return transformIn(context, (ConstraintIn)expr);
+ if (expr instanceof ConstraintOperation) return transformOperation(context, (ConstraintOperation)expr);
+ // do the actual work of this transformer
+ if (expr instanceof Constraint) return transformConstraint(context, (Constraint)expr);
+ // By default we do not recognise the constraint type, so pass it unchanged.
+ return expr;
+ }
+
+ /**
+ * Transform the filtered constraint. This invokes {@link #transformExpr} on the inner constraint.
+ *
+ * @param context the current transformation context
+ * @param filter the constraint filter to transform
+ * @return a new expression is something was changed, or <var>filter</var> if nothing was changed.
+ * @throws SymbolicTransformationException If there is an error applying the transform
+ */
+ protected ConstraintExpression transformFilter(SymbolicTransformationContext context,
+ ConstraintFilter filter)
+ throws SymbolicTransformationException {
+ ConstraintExpression inner = filter.getUnfilteredConstraint();
+ ConstraintExpression tx = transformExpr(context, inner);
+ return (tx == inner) ? filter : new ConstraintFilter(tx, filter.getFilter());
+ }
+
+ /**
+ * Transform the in constraint. This invokes {@link #transformExpr} on the inner constraint.
+ *
+ * @param context the current transformation context
+ * @param in the in-constraint to transform
+ * @return a new expression is something was changed, or <var>in</var> if nothing was changed.
+ * @throws SymbolicTransformationException If there is an error applying the transform
+ */
+ protected ConstraintExpression transformIn(SymbolicTransformationContext context, ConstraintIn in)
+ throws SymbolicTransformationException {
+ ConstraintExpression inner = in.getConstraintParam();
+ ConstraintExpression tx = transformExpr(context, inner);
+ return (tx == inner) ? in : new ConstraintIn(tx, in.getGraph());
+ }
+
+ /**
+ * Transform the constraint-operation. This invokes {@link #transformExpr} on all the inner
+ * constraints.
+ *
+ * @param context the current transformation context
+ * @param oper the constraint-operation to transform
+ * @return a new expression is something was changed, or <var>oper</var> if nothing was changed.
+ * @throws SymbolicTransformationException If there is an error applying the transform
+ */
+ protected ConstraintExpression transformOperation(SymbolicTransformationContext context,
+ ConstraintOperation oper)
+ throws SymbolicTransformationException {
+ List<ConstraintExpression> ops = oper.getElements();
+ List<ConstraintExpression> newOps = new ArrayList<ConstraintExpression>(ops.size());
+ boolean changed = false;
+
+ for (ConstraintExpression op: ops) {
+ ConstraintExpression tx = transformExpr(context, op);
+ newOps.add(tx);
+ if (tx != op) changed = true;
+ }
+
+ if (changed) {
+ OpType operationType = OpType.getType(oper);
+ if (operationType == null) throw new SymbolicTransformationException("Encountered an unknown operation type: " + oper.getClass());
+ return operationType.newOp(newOps);
+ }
+
+ return oper;
+ }
+
+ /**
+ * Transform the given expression. The main work of this class is usually performed in this
+ * method.
+ *
+ * @param context the current transformation context
+ * @param c the constraint to transform.
+ * @return the original constraint, or a new constraint if something was changed.
+ * @throws SymbolicTransformationException If there is an error applying the transform
+ */
+ protected abstract ConstraintExpression transformConstraint(SymbolicTransformationContext context,
+ Constraint c)
+ throws SymbolicTransformationException;
+
+ /**
+ * This enum enumerates the ConstraintOperation types. It has been built to deal with
+ * the fact that constructors for the various types cannot be passed as a lambda.
+ * It also provides a map for the enumerated types to their enumerations, making it
+ * easy for an operation to get to an appropriate constructor.
+ */
+ protected static enum OpType {
+ difference {
+ public ConstraintOperation newOp(List<ConstraintExpression> ops) { return new ConstraintDifference(ops.get(0), ops.get(1)); }
+ },
+ optional {
+ public ConstraintOperation newOp(List<ConstraintExpression> ops) { return new ConstraintOptionalJoin(ops.get(0), ops.get(1)); }
+ },
+ conjunction {
+ public ConstraintOperation newOp(List<ConstraintExpression> ops) { return new ConstraintConjunction(ops); }
+ },
+ disjunction {
+ public ConstraintOperation newOp(List<ConstraintExpression> ops) { return new ConstraintDisjunction(ops); }
+ };
+
+ public abstract ConstraintOperation newOp(List<ConstraintExpression> ops);
+
+ private static Map<Class<? extends ConstraintOperation>, OpType> opMap = new HashMap<Class<? extends ConstraintOperation>, OpType>();
+
+ public static OpType getType(ConstraintOperation op) { return opMap.get(op.getClass()); }
+
+ static {
+ opMap.put(ConstraintDifference.class, difference);
+ opMap.put(ConstraintOptionalJoin.class, optional);
+ opMap.put(ConstraintConjunction.class, conjunction);
+ opMap.put(ConstraintDisjunction.class, disjunction);
+ }
+ }
+}
Property changes on: trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/AbstractSymbolicTransformer.java
___________________________________________________________________
Name: svn:keywords
+ Id HeadURL Revision
Name: svn:eol-style
+ native
Modified: trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/DuplicateVariableTransformer.java
===================================================================
--- trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/DuplicateVariableTransformer.java 2008-12-03 09:25:57 UTC (rev 1394)
+++ trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/DuplicateVariableTransformer.java 2008-12-03 09:26:00 UTC (rev 1395)
@@ -13,21 +13,13 @@
package org.mulgara.resolver.spi;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import org.mulgara.query.Constraint;
-import org.mulgara.query.ConstraintConjunction;
-import org.mulgara.query.ConstraintDifference;
-import org.mulgara.query.ConstraintDisjunction;
import org.mulgara.query.ConstraintElement;
import org.mulgara.query.ConstraintExpression;
import org.mulgara.query.ConstraintFilter;
import org.mulgara.query.ConstraintImpl;
-import org.mulgara.query.ConstraintIn;
-import org.mulgara.query.ConstraintOperation;
-import org.mulgara.query.ConstraintOptionalJoin;
import org.mulgara.query.Variable;
import org.mulgara.query.filter.And;
import org.mulgara.query.filter.Filter;
@@ -43,90 +35,35 @@
* @copyright © 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 DuplicateVariableTransformer implements SymbolicTransformation {
-
+public class DuplicateVariableTransformer extends AbstractSymbolicTransformer {
/**
- * @see org.mulgara.resolver.spi.SymbolicTransformation#transform(org.mulgara.resolver.spi.SymbolicTransformationContext, org.mulgara.resolver.spi.MutableLocalQuery)
- */
- public void transform(SymbolicTransformationContext context, MutableLocalQuery mutableLocalQuery)
- throws SymbolicTransformationException {
- ConstraintExpression expr = mutableLocalQuery.getConstraintExpression();
- ConstraintExpression trans = transformExpr(expr);
-
- if (expr != trans) {
- mutableLocalQuery.setConstraintExpression(trans);
- }
- }
-
- public ConstraintExpression transformExpr(ConstraintExpression expr) throws SymbolicTransformationException {
- // explicitly handle all the recursive types
- if (expr instanceof ConstraintFilter) return transformFilter(expr);
- if (expr instanceof ConstraintIn) return transformIn(expr);
- if (expr instanceof ConstraintOperation) return transformOperation(expr);
- // do the actual work of this transformer
- if (expr instanceof Constraint) return transformConstraint(expr);
- // By default we do not recognise the constraint type, so pass it unchanged.
- return expr;
- }
-
- ConstraintFilter transformFilter(ConstraintExpression expr) throws SymbolicTransformationException {
- ConstraintFilter filter = (ConstraintFilter)expr;
- ConstraintExpression inner = filter.getUnfilteredConstraint();
- ConstraintExpression tx = transformExpr(inner);
- return (tx == inner) ? filter : new ConstraintFilter(tx, filter.getFilter());
- }
-
- ConstraintIn transformIn(ConstraintExpression expr) throws SymbolicTransformationException {
- ConstraintIn in = (ConstraintIn)expr;
- ConstraintExpression inner = in.getConstraintParam();
- ConstraintExpression tx = transformExpr(inner);
- return (tx == inner) ? in : new ConstraintIn(tx, in.getGraph());
- }
-
- ConstraintOperation transformOperation(ConstraintExpression expr) throws SymbolicTransformationException {
- ConstraintOperation operation = (ConstraintOperation)expr;
- List<ConstraintExpression> ops = operation.getElements();
- List<ConstraintExpression> newOps = new ArrayList<ConstraintExpression>(ops.size());
- boolean changed = false;
- for (ConstraintExpression op: ops) {
- ConstraintExpression tx = transformExpr(op);
- newOps.add(tx);
- if (tx != op) changed = true;
- }
- if (changed) {
- OpType operationType = OpType.getType(operation);
- if (operationType == null) throw new SymbolicTransformationException("Encountered an unknown operation type: " + operation.getClass());
- return operationType.newOp(newOps);
- }
- return operation;
- }
-
- /**
* All the work of this class is performed in this method. It ignores general constraints,
* and converts a ConstraintImpls with repeated variables into a conjunction of terms
* which have non-repeating variables, joined in an equivalent way to the original constraint.
- * @param expr The expression to transform.
+ * @param c The constraint to transform.
* @return The original constraint, or else a new equivalent conjunction if expr contains
* a repeated variable.
* @throws SymbolicTransformationException If there is an error in the constraint structure.
*/
- ConstraintExpression transformConstraint(ConstraintExpression expr) throws SymbolicTransformationException {
- if (!((Constraint)expr).isRepeating()) return (Constraint)expr;
- ConstraintImpl cnstr = (ConstraintImpl)expr;
+ @Override
+ protected ConstraintExpression transformConstraint(SymbolicTransformationContext context, Constraint c)
+ throws SymbolicTransformationException {
+ if (!c.isRepeating()) return c;
+ ConstraintImpl cnstr = (ConstraintImpl)c;
VarFreq vf = new VarFreq(cnstr);
// build the equivalent term
ConstraintElement[] elements = buildElements(cnstr, vf);
- expr = new ConstraintImpl(elements[0], elements[1], elements[2], elements[3]);
+ c = new ConstraintImpl(elements[0], elements[1], elements[2], elements[3]);
// if there was only a pair then return it as a simple filter
- if (vf.frequency == 2) return new ConstraintFilter(expr, createSameTermPair(vf.repeatedVar, 1));
+ if (vf.frequency == 2) return new ConstraintFilter(c, createSameTermPair(vf.repeatedVar, 1));
// build a conjunction of filters
int matches = vf.frequency - 1;
Filter[] sameTerms = new Filter[matches];
for (int f = 0; f < matches; f++) sameTerms[f] = createSameTermPair(vf.repeatedVar, f + 1);
- return new ConstraintFilter(expr, new And(sameTerms));
+ return new ConstraintFilter(c, new And(sameTerms));
}
/**
@@ -223,34 +160,4 @@
this.repeatedVar = repeatedVar;
}
}
-
- /**
- * This enum enumerates the ConstraintOperation types. It has been built to deal with
- * the fact that constructors for the various types cannot be passed as a lambda.
- * It also provides a map for the enumerated types to their enumerations, making it
- * easy for an operation to get to an appropriate constructor.
- */
- private static enum OpType {
- difference {
- ConstraintOperation newOp(List<ConstraintExpression> ops) { return new ConstraintDifference(ops.get(0), ops.get(1)); }
- },
- optional {
- ConstraintOperation newOp(List<ConstraintExpression> ops) { return new ConstraintOptionalJoin(ops.get(0), ops.get(1)); }
- },
- conjunction {
- ConstraintOperation newOp(List<ConstraintExpression> ops) { return new ConstraintConjunction(ops); }
- },
- disjunction {
- ConstraintOperation newOp(List<ConstraintExpression> ops) { return new ConstraintDisjunction(ops); }
- };
- abstract ConstraintOperation newOp(List<ConstraintExpression> ops);
- private static Map<Class<? extends ConstraintOperation>, OpType> opMap = new HashMap<Class<? extends ConstraintOperation>, OpType>();
- public static OpType getType(ConstraintOperation op) { return opMap.get(op.getClass()); }
- static {
- opMap.put(ConstraintDifference.class, difference);
- opMap.put(ConstraintOptionalJoin.class, optional);
- opMap.put(ConstraintConjunction.class, conjunction);
- opMap.put(ConstraintDisjunction.class, disjunction);
- }
- }
}
More information about the Mulgara-svn
mailing list