[Mulgara-svn] r1044 - trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql
pag at mulgara.org
pag at mulgara.org
Wed Jul 2 21:38:52 UTC 2008
Author: pag
Date: 2008-07-02 14:38:52 -0700 (Wed, 02 Jul 2008)
New Revision: 1044
Added:
trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/IdentityTransformer.java
trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/SymbolicTransformationException.java
Log:
Transformation framework for constraints. Similar to Query transformations, but for ConstraintExpressions only
Added: trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/IdentityTransformer.java
===================================================================
--- trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/IdentityTransformer.java (rev 0)
+++ trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/IdentityTransformer.java 2008-07-02 21:38:52 UTC (rev 1044)
@@ -0,0 +1,325 @@
+/*
+ * 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.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jrdf.graph.URIReference;
+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.ConstraintHaving;
+import org.mulgara.query.ConstraintImpl;
+import org.mulgara.query.ConstraintIn;
+import org.mulgara.query.ConstraintIs;
+import org.mulgara.query.ConstraintNegation;
+import org.mulgara.query.ConstraintNotOccurs;
+import org.mulgara.query.ConstraintOccurs;
+import org.mulgara.query.ConstraintOccursLessThan;
+import org.mulgara.query.ConstraintOccursMoreThan;
+import org.mulgara.query.ConstraintOperation;
+import org.mulgara.query.ConstraintOptionalJoin;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.SingleTransitiveConstraint;
+import org.mulgara.query.TransitiveConstraint;
+import org.mulgara.query.WalkConstraint;
+import org.mulgara.resolver.relational.RelationalConstraint;
+import org.mulgara.resolver.test.TestConstraint;
+import org.mulgara.resolver.xsd.IntervalConstraint;
+
+/**
+ * Identity transformation on constraint expressions.
+ *
+ * @created July 1, 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 IdentityTransformer {
+
+ /** Maps constraint types to constructors */
+ protected Map<Class<? extends Constraint>, ConstraintTypeCons<? extends Constraint>> consMap = new HashMap<Class<? extends Constraint>, ConstraintTypeCons<? extends Constraint>>();
+
+ /**
+ * Builds a transformer, with identity constructors.
+ */
+ public IdentityTransformer() {
+ initialize(new ConsImpl(), new ConsInterval(), new ConsIs(), new ConsNegation(),
+ new ConsNotOccurs(), new ConsOccurs(), new ConsOccursLessThan(),
+ new ConsOccursMoreThan(), new ConsRelational(), new ConsSingleTransitive(),
+ new ConsTest(), new ConsTransitive(), new ConsWalk());
+ }
+
+ /**
+ * Builds a transformer, with given constructors.
+ * @param constructors The constructors to use.
+ */
+ public void initialize(ConstraintTypeCons<?>... constructors) {
+ for (ConstraintTypeCons<?> c: constructors) insert(c);
+ }
+
+ /**
+ * Gets a constructor for a give constraint type.
+ * @param c A constraint of the desired type.
+ * @return A constructor for the given constraint.
+ */
+ public ConstraintTypeCons<? extends Constraint> getCons(Constraint c) {
+ return consMap.get(c.getClass());
+ }
+
+ /**
+ * Maps a constraint type to its constructor. This will override existing mappings.
+ * @param cons The constraint constructor.
+ */
+ protected void insert(ConstraintTypeCons<? extends Constraint> cons) {
+ consMap.put(cons.getType(), cons);
+ }
+
+ /**
+ * Transforms a {@link ConstraintExpression}.
+ * @param expr The expression to transform.
+ * @return The transformed expression.
+ * @throws SymbolicTransformationException An error occurred in the transformation.
+ */
+ public ConstraintExpression transform(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;
+ }
+
+ /**
+ * Transforms a {@link ConstraintFilter}.
+ * @param expr The ConstraintFilter to transform.
+ * @return The transformed ConstraintFilter.
+ * @throws SymbolicTransformationException An error occurred in the transformation.
+ */
+ ConstraintFilter transformFilter(ConstraintExpression expr) throws SymbolicTransformationException {
+ ConstraintFilter filter = (ConstraintFilter)expr;
+ ConstraintExpression inner = filter.getUnfilteredConstraint();
+ ConstraintExpression tx = transform(inner);
+ return (tx == inner) ? filter : new ConstraintFilter(tx, filter.getFilter());
+ }
+
+ /**
+ * Transforms a {@link ConstraintIn}.
+ * @param expr The ConstraintIn to transform.
+ * @return The transformed ConstraintIn.
+ * @throws SymbolicTransformationException An error occurred in the transformation.
+ */
+ ConstraintIn transformIn(ConstraintExpression expr) throws SymbolicTransformationException {
+ ConstraintIn in = (ConstraintIn)expr;
+ ConstraintExpression inner = in.getConstraintParam();
+ ConstraintExpression tx = transform(inner);
+ return (tx == inner) ? in : new ConstraintIn(tx, in.getGraph());
+ }
+
+ /**
+ * Transforms a {@link ConstraintOperation}.
+ * @param expr The ConstraintOperation to transform.
+ * @return The transformed ConstraintOperation.
+ * @throws SymbolicTransformationException An error occurred in the transformation.
+ */
+ 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 = transform(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;
+ }
+
+ /**
+ * Transforms a {@link Constraint}. This method is usually replaced to modify instances
+ * of {@link ConstraintImpl}.
+ * @param expr The Constraint to transform.
+ * @return The transformed Constraint.
+ * @throws SymbolicTransformationException An error occurred in the transformation.
+ */
+ Constraint transformConstraint(ConstraintExpression expr) throws SymbolicTransformationException {
+ Constraint cnstr = (Constraint)expr;
+ try {
+ return getCons(cnstr).newConstraint(cnstr);
+ } catch (NullPointerException e) {
+ throw new SymbolicTransformationException("Unable to transform unknown Constraint type: " + cnstr);
+ }
+ }
+
+ /**
+ * 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);
+ }
+ }
+
+ /**
+ * Interface to describe a constructor along with the type the constructor applies to.
+ */
+ protected interface ConstraintTypeCons<T extends Constraint> {
+ /**
+ * Method to construct a new constraint of the expected type.
+ * @param c The old version of the constraint.
+ * @return A new Constraint with the same type as <var>c</var>.
+ * @throws SymbolicTransformationException There was an error in the data structure.
+ */
+ abstract T newConstraint(Constraint c) throws SymbolicTransformationException;
+ /** @return The class handled by this type. */
+ abstract Class<T> getType();
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // The following are classes for constructing each of the various types
+ ///////////////////////////////////////////////////////////////////////
+
+ protected abstract class ConsHaving<T extends ConstraintHaving> implements ConstraintTypeCons<T> {
+ public T newConstraint(Constraint c) {
+ ConstraintHaving h = (ConstraintHaving)c;
+ ConstraintElement[] ops = new ConstraintElement[4];
+ for (int i = 0; i < ops.length; i++) ops[i] = h.getElement(i);
+ return newHaving(ops);
+ }
+ protected abstract T newHaving(ConstraintElement[] ops);
+ }
+
+ protected class ConsNotOccurs extends ConsHaving<ConstraintNotOccurs> {
+ public ConstraintNotOccurs newHaving(ConstraintElement[] ops) { return new ConstraintNotOccurs(ops[0], ops[2], ops[3]); }
+ public Class<ConstraintNotOccurs> getType() { return ConstraintNotOccurs.class; }
+ }
+
+ protected class ConsOccurs extends ConsHaving<ConstraintOccurs> {
+ public ConstraintOccurs newHaving(ConstraintElement[] ops) { return new ConstraintOccurs(ops[0], ops[2], ops[3]); }
+ public Class<ConstraintOccurs> getType() { return ConstraintOccurs.class; }
+ }
+
+ protected class ConsOccursLessThan extends ConsHaving<ConstraintOccursLessThan> {
+ public ConstraintOccursLessThan newHaving(ConstraintElement[] ops) { return new ConstraintOccursLessThan(ops[0], ops[2], ops[3]); }
+ public Class<ConstraintOccursLessThan> getType() { return ConstraintOccursLessThan.class; }
+ }
+
+ protected class ConsOccursMoreThan extends ConsHaving<ConstraintOccursMoreThan> {
+ public ConstraintOccursMoreThan newHaving(ConstraintElement[] ops) { return new ConstraintOccursMoreThan(ops[0], ops[2], ops[3]); }
+ public Class<ConstraintOccursMoreThan> getType() { return ConstraintOccursMoreThan.class; }
+ }
+
+ protected class ConsImpl implements ConstraintTypeCons<ConstraintImpl> {
+ public ConstraintImpl newConstraint(Constraint c) {
+ return new ConstraintImpl(c.getElement(0), c.getElement(1), c.getElement(2), c.getElement(3));
+ }
+ public Class<ConstraintImpl> getType() { return ConstraintImpl.class; }
+ }
+
+ protected class ConsIs implements ConstraintTypeCons<ConstraintIs> {
+ public ConstraintIs newConstraint(Constraint c) {
+ return new ConstraintIs(c.getElement(0), c.getElement(2), c.getElement(3));
+ }
+ public Class<ConstraintIs> getType() { return ConstraintIs.class; }
+ }
+
+ protected class ConsNegation implements ConstraintTypeCons<ConstraintNegation> {
+ public ConstraintNegation newConstraint(Constraint c) { throw new IllegalStateException("Negations are no longer supported"); }
+ public Class<ConstraintNegation> getType() { return ConstraintNegation.class; }
+ }
+
+ protected class ConsInterval implements ConstraintTypeCons<IntervalConstraint> {
+ public IntervalConstraint newConstraint(Constraint c) {
+ IntervalConstraint i = (IntervalConstraint)c;
+ return i.mutateTo(i.getVariables().iterator().next(), (URIReference)i.getModel());
+ }
+ public Class<IntervalConstraint> getType() { return IntervalConstraint.class; }
+ }
+
+ protected class ConsRelational implements ConstraintTypeCons<RelationalConstraint> {
+ public RelationalConstraint newConstraint(Constraint c) { throw new UnsupportedOperationException("Cannot transform a relational constraint"); }
+ public Class<RelationalConstraint> getType() { return RelationalConstraint.class; }
+ }
+
+ protected class ConsSingleTransitive implements ConstraintTypeCons<SingleTransitiveConstraint> {
+ public SingleTransitiveConstraint newConstraint(Constraint c) throws SymbolicTransformationException {
+ SingleTransitiveConstraint s = (SingleTransitiveConstraint)c;
+ return new SingleTransitiveConstraint(transformConstraint(s.getTransConstraint()));
+ }
+ public Class<SingleTransitiveConstraint> getType() { return SingleTransitiveConstraint.class; }
+ }
+
+ protected class ConsTest implements ConstraintTypeCons<TestConstraint> {
+ public TestConstraint newConstraint(Constraint c) {
+ TestConstraint t = (TestConstraint)c;
+ return new TestConstraint(t.getVariable1(), t.getVariable2(), t.getTestSelection(), t.getTestParam());
+ }
+ public Class<TestConstraint> getType() { return TestConstraint.class; }
+ }
+
+ protected class ConsTransitive implements ConstraintTypeCons<TransitiveConstraint> {
+ public TransitiveConstraint newConstraint(Constraint c) throws SymbolicTransformationException {
+ TransitiveConstraint t = (TransitiveConstraint)c;
+ return new TransitiveConstraint(transformConstraint(t.getAnchoredConstraint()), transformConstraint(t.getUnanchoredConstraint()));
+ }
+ public Class<TransitiveConstraint> getType() { return TransitiveConstraint.class; }
+ }
+
+ protected class ConsWalk implements ConstraintTypeCons<WalkConstraint> {
+ public WalkConstraint newConstraint(Constraint c) throws SymbolicTransformationException {
+ WalkConstraint t = (WalkConstraint)c;
+ try {
+ return new WalkConstraint(transformConstraint(t.getAnchoredConstraint()), transformConstraint(t.getUnanchoredConstraint()));
+ } catch (QueryException e) {
+ throw new SymbolicTransformationException("Invalid Walk constraints being transformed", e);
+ }
+ }
+ public Class<WalkConstraint> getType() { return WalkConstraint.class; }
+ }
+
+}
Added: trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/SymbolicTransformationException.java
===================================================================
--- trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/SymbolicTransformationException.java (rev 0)
+++ trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/SymbolicTransformationException.java 2008-07-02 21:38:52 UTC (rev 1044)
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+/**
+ * Indicates an error performing a symbolic transformation.
+ *
+ * @created Jul 1, 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 class SymbolicTransformationException extends Exception {
+
+ /** Serialization ID */
+ private static final long serialVersionUID = -1791046260155844890L;
+
+ /**
+ * @param message The exception message.
+ */
+ public SymbolicTransformationException(String message) {
+ super(message);
+ }
+
+ /**
+ * @param message The exception message.
+ * @param cause The exception that caused the problem.
+ */
+ public SymbolicTransformationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
More information about the Mulgara-svn
mailing list