You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2013/08/03 15:20:20 UTC
svn commit: r1509984 - /jena/Scratch/AFS/Jena-Dev/trunk/src/element/
Author: andy
Date: Sat Aug 3 13:20:20 2013
New Revision: 1509984
URL: http://svn.apache.org/r1509984
Log:
Rewrite query abstract syntax by transformation.
Added:
jena/Scratch/AFS/Jena-Dev/trunk/src/element/
jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransform.java
jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransformCopyBase.java
jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransformSubst.java
jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransformer.java
jena/Scratch/AFS/Jena-Dev/trunk/src/element/ExprTransformNodeElement.java
jena/Scratch/AFS/Jena-Dev/trunk/src/element/MainElt.java
jena/Scratch/AFS/Jena-Dev/trunk/src/element/NodeTransformSubst.java
jena/Scratch/AFS/Jena-Dev/trunk/src/element/QueryOps.java
jena/Scratch/AFS/Jena-Dev/trunk/src/element/TestQueryOps.java
jena/Scratch/AFS/Jena-Dev/trunk/src/element/TestSubstitution.java
jena/Scratch/AFS/Jena-Dev/trunk/src/element/TransEltLib.java
jena/Scratch/AFS/Jena-Dev/trunk/src/element/UpdateOps.java
Added: jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransform.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransform.java?rev=1509984&view=auto
==============================================================================
--- jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransform.java (added)
+++ jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransform.java Sat Aug 3 13:20:20 2013
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package element;
+
+import java.util.List ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.query.Query ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.expr.Expr ;
+import com.hp.hpl.jena.sparql.syntax.* ;
+
+/** Transformation function on an Element
+ * @see ElementTransformer
+ */
+public interface ElementTransform
+{
+ public Element transform(ElementTriplesBlock el) ;
+ public Element transform(ElementPathBlock el) ;
+ public Element transform(ElementFilter el, Expr expr2) ;
+ public Element transform(ElementAssign el, Var v, Expr expr2) ;
+ public Element transform(ElementBind el, Var v, Expr expr2) ;
+ public Element transform(ElementData el) ;
+ public Element transform(ElementUnion el, List<Element> elements) ;
+ public Element transform(ElementOptional el, Element opElt) ;
+ public Element transform(ElementGroup el, List<Element> members) ;
+ public Element transform(ElementDataset el, Element subElt) ;
+ public Element transform(ElementNamedGraph el, Node gn, Element subElt) ;
+ public Element transform(ElementExists el, Element subElt) ;
+ public Element transform(ElementNotExists el, Element subElt) ;
+ public Element transform(ElementMinus el, Element eltRHS) ;
+ public Element transform(ElementService el, Node service, Element subElt) ;
+ public Element transform(ElementSubQuery el, Query query) ;
+}
+
Added: jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransformCopyBase.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransformCopyBase.java?rev=1509984&view=auto
==============================================================================
--- jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransformCopyBase.java (added)
+++ jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransformCopyBase.java Sat Aug 3 13:20:20 2013
@@ -0,0 +1,142 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package element ;
+
+import java.util.List ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.query.Query ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.expr.Expr ;
+import com.hp.hpl.jena.sparql.syntax.* ;
+
+/** Create a copy if the Element(s) below have chanaged */
+public class ElementTransformCopyBase implements ElementTransform {
+ // Note the use of == as object pointer equality.
+
+ @Override
+ public Element transform(ElementTriplesBlock el) {
+ return el ;
+ }
+
+ @Override
+ public Element transform(ElementPathBlock el) {
+ return el ;
+ }
+
+ @Override
+ public Element transform(ElementFilter el, Expr expr2) {
+ if ( el.getExpr() == expr2 )
+ return el ;
+ return new ElementFilter(expr2) ;
+ }
+
+ @Override
+ public Element transform(ElementAssign el, Var v, Expr expr2) {
+ if ( el.getVar() == v && el.getExpr() == expr2 )
+ return el ;
+ return new ElementAssign(v, expr2) ;
+ }
+
+ @Override
+ public Element transform(ElementBind el, Var v, Expr expr2) {
+ if ( el.getVar() == v && el.getExpr() == expr2 )
+ return el ;
+ return new ElementAssign(v, expr2) ;
+ }
+
+ @Override
+ public Element transform(ElementData el) {
+ return el ;
+ }
+
+ @Override
+ public Element transform(ElementUnion el, List<Element> elts) {
+ if ( el.getElements() == elts )
+ return el ;
+ ElementUnion el2 = new ElementUnion() ;
+ el2.getElements().addAll(elts) ;
+ return el2 ;
+ }
+
+ @Override
+ public Element transform(ElementOptional el, Element elt1) {
+ if ( el.getOptionalElement() == elt1 )
+ return el ;
+ return new ElementOptional(elt1) ;
+ }
+
+ @Override
+ public Element transform(ElementGroup el, List<Element> elts) {
+ if ( el.getElements() == elts )
+ return el ;
+ ElementGroup el2 = new ElementGroup() ;
+ el2.getElements().addAll(elts) ;
+ return el2 ;
+ }
+
+ @Override
+ public Element transform(ElementDataset el, Element elt1) {
+ if ( el.getPatternElement() == elt1 )
+ return el ;
+ return new ElementDataset(el.getDataset(), elt1) ;
+ }
+
+ @Override
+ public Element transform(ElementNamedGraph el, Node gn, Element elt1) {
+ if ( el.getGraphNameNode() == gn && el.getElement() == elt1 )
+ return el ;
+ return new ElementNamedGraph(gn, elt1) ;
+ }
+
+ @Override
+ public Element transform(ElementExists el, Element elt1) {
+ if ( el.getElement() == elt1 )
+ return el ;
+ return new ElementExists(elt1) ;
+ }
+
+ @Override
+ public Element transform(ElementNotExists el, Element elt1) {
+ if ( el.getElement() == elt1 )
+ return el ;
+ return new ElementNotExists(elt1) ;
+ }
+
+ @Override
+ public Element transform(ElementMinus el, Element elt1) {
+ if ( el.getMinusElement() == elt1 )
+ return el ;
+ return new ElementMinus(elt1) ;
+ }
+
+ @Override
+ public Element transform(ElementService el, Node service, Element elt1) {
+ if ( el.getServiceNode() == service && el.getElement() == elt1 )
+ return el ;
+ return new ElementService(service, elt1, el.getSilent()) ;
+ }
+
+ @Override
+ public Element transform(ElementSubQuery el, Query query) {
+ if ( el.getQuery() == query )
+ return el ;
+ return new ElementSubQuery(query) ;
+ }
+}
Added: jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransformSubst.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransformSubst.java?rev=1509984&view=auto
==============================================================================
--- jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransformSubst.java (added)
+++ jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransformSubst.java Sat Aug 3 13:20:20 2013
@@ -0,0 +1,103 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package element ;
+
+import java.util.Map ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.graph.Triple ;
+import com.hp.hpl.jena.sparql.core.TriplePath ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.graph.NodeTransform ;
+import com.hp.hpl.jena.sparql.syntax.Element ;
+import com.hp.hpl.jena.sparql.syntax.ElementPathBlock ;
+import com.hp.hpl.jena.sparql.syntax.ElementTriplesBlock ;
+
+public class ElementTransformSubst extends ElementTransformCopyBase {
+ // NodeTransform
+
+ private final NodeTransform nodeTransform ;
+
+ public ElementTransformSubst(Map<Var, Node> mapping) {
+ this.nodeTransform = new NodeTransformSubst(mapping) ;
+ }
+
+ @Override
+ public Element transform(ElementTriplesBlock el) {
+ ElementTriplesBlock etb = new ElementTriplesBlock() ;
+ boolean changed = false ;
+ for (Triple t : el.getPattern()) {
+ Triple t2 = transform(t) ;
+ changed = changed || t != t2 ;
+ etb.addTriple(t2) ;
+ }
+ if ( changed )
+ return etb ;
+ return el ;
+ }
+
+ @Override
+ public Element transform(ElementPathBlock el) {
+ ElementPathBlock epb = new ElementPathBlock() ;
+ boolean changed = false ;
+ for (TriplePath p : el.getPattern()) {
+ TriplePath p2 = transform(p) ;
+ changed = changed || p != p2 ;
+ epb.addTriplePath(p2) ;
+ }
+ if ( changed )
+ return epb ;
+ return el ;
+ }
+
+ private TriplePath transform(TriplePath path) {
+ Node s = path.getSubject() ;
+ Node s1 = transform(s) ;
+ Node o = path.getObject() ;
+ Node o1 = transform(o) ;
+
+ if ( path.isTriple() ) {
+ Node p = path.getPredicate() ;
+ Node p1 = transform(p) ;
+ if ( s == s1 && p == p1 && o == o1 )
+ return path ;
+ return new TriplePath(Triple.create(s1, p1, o1)) ;
+ }
+ if ( s == s1 && o == o1 )
+ return path ;
+ return new TriplePath(s1, path.getPath(), o1) ;
+ }
+
+ private Triple transform(Triple triple) {
+ Node s = triple.getSubject() ;
+ Node s1 = transform(s) ;
+ Node p = triple.getPredicate() ;
+ Node p1 = transform(p) ;
+ Node o = triple.getObject() ;
+ Node o1 = transform(o) ;
+
+ if ( s == s1 && p == p1 && o == o1 )
+ return triple ;
+ return Triple.create(s1, p1, o1) ;
+ }
+
+ private Node transform(Node n) {
+ return nodeTransform.convert(n) ;
+ }
+}
Added: jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransformer.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransformer.java?rev=1509984&view=auto
==============================================================================
--- jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransformer.java (added)
+++ jena/Scratch/AFS/Jena-Dev/trunk/src/element/ElementTransformer.java Sat Aug 3 13:20:20 2013
@@ -0,0 +1,309 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package element ;
+
+import java.util.ArrayDeque ;
+import java.util.Deque ;
+import java.util.List ;
+
+import org.apache.jena.atlas.logging.Log ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.query.Query ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.expr.Expr ;
+import com.hp.hpl.jena.sparql.expr.ExprList ;
+import com.hp.hpl.jena.sparql.expr.ExprTransform ;
+import com.hp.hpl.jena.sparql.expr.ExprTransformer ;
+import com.hp.hpl.jena.sparql.syntax.* ;
+
+/** A bottom-top application of a transformation of SPARQL syntax */
+public class ElementTransformer {
+ private static ElementTransformer singleton = new ElementTransformer() ;
+
+ /** Get the current transformer */
+ public static ElementTransformer get() {
+ return singleton ;
+ }
+
+ /** Set the current transformer - use with care */
+ public static void set(ElementTransformer value) {
+ ElementTransformer.singleton = value ;
+ }
+
+ /** Transform an algebra expression */
+ public static Element transform(Element element, ElementTransform transform) {
+ return transform(element, transform, null, null, null) ;
+ }
+
+ /** Transformation with specific ElementTransform and ExprTransform */
+ public static Element transform(Element element, ElementTransform transform, ExprTransform exprTransform) {
+ return get().transformation(element, transform, exprTransform, null, null) ;
+ }
+
+ public static Element transform(Element element, ElementTransform transform, ExprTransform exprTransform,
+ ElementVisitor beforeVisitor, ElementVisitor afterVisitor) {
+ return get().transformation(element, transform, exprTransform, beforeVisitor, afterVisitor) ;
+ }
+
+ // To allow subclassing this class, we use a singleton pattern
+ // and these protected methods.
+ protected Element transformation(Element element, ElementTransform transform, ExprTransform exprTransform,
+ ElementVisitor beforeVisitor, ElementVisitor afterVisitor) {
+ ApplyTransformVisitor v = new ApplyTransformVisitor(transform, exprTransform) ;
+ return transformation(v, element, beforeVisitor, afterVisitor) ;
+ }
+
+ protected Element transformation(ApplyTransformVisitor transformApply, Element element,
+ ElementVisitor beforeVisitor, ElementVisitor afterVisitor) {
+ if ( element == null ) {
+ Log.warn(this, "Attempt to transform a null element - ignored") ;
+ return element ;
+ }
+ return applyTransformation(transformApply, element, beforeVisitor, afterVisitor) ;
+ }
+
+ /** The primitive operation to apply a transformation to an Op */
+ protected Element applyTransformation(ApplyTransformVisitor transformApply, Element element,
+ ElementVisitor beforeVisitor, ElementVisitor afterVisitor) {
+ ElementWalker.walk(element, transformApply) ; // , beforeVisitor,
+ // afterVisitor) ;
+ Element r = transformApply.result() ;
+ return r ;
+ }
+
+ protected ElementTransformer() {}
+
+ static class ApplyTransformVisitor implements ElementVisitor {
+ protected final ElementTransform transform ;
+ private final ExprTransform exprTransform ;
+
+ private final Deque<Element> stack = new ArrayDeque<Element>() ;
+
+ protected final Element pop() {
+ return stack.pop() ;
+ }
+
+ protected final void push(Element elt) {
+ stack.push(elt) ;
+ }
+
+ protected final void pushChanged(Element elt, Element elt2) {
+ if ( elt == elt2 )
+ stack.push(elt) ;
+ else
+ stack.push(elt2) ;
+ }
+
+ public ApplyTransformVisitor(ElementTransform transform, ExprTransform exprTransform) {
+ this.transform = transform ;
+ this.exprTransform = exprTransform ;
+ }
+
+ final Element result() {
+ if ( stack.size() != 1 )
+ Log.warn(this, "Stack is not aligned") ;
+ return pop() ;
+ }
+
+ @Override
+ public void visit(ElementTriplesBlock el) {
+ Element el2 = transform.transform(el) ;
+ pushChanged(el, el2) ;
+ }
+
+ @Override
+ public void visit(ElementPathBlock el) {
+ Element el2 = transform.transform(el) ;
+ pushChanged(el, el2) ;
+ }
+
+ @Override
+ public void visit(ElementFilter el) {
+ Expr expr = el.getExpr() ;
+ Expr expr2 = transform(expr, exprTransform) ;
+ Element el2 = transform.transform(el, expr2) ;
+ pushChanged(el, el2) ;
+ }
+
+ @Override
+ public void visit(ElementAssign el) {
+ Var v = el.getVar() ;
+ Var v1 = TransEltLib.applyVar(v, exprTransform) ;
+ Expr expr = el.getExpr() ;
+ Expr expr1 = ExprTransformer.transform(exprTransform, expr) ;
+ if ( v == v1 && expr == expr1 ) {
+ push(el) ;
+ return ;
+ }
+ push(new ElementAssign(v1, expr1)) ;
+ }
+
+ @Override
+ public void visit(ElementBind el) {
+ Var v = el.getVar() ;
+ Var v1 = TransEltLib.applyVar(v, exprTransform) ;
+ Expr expr = el.getExpr() ;
+ Expr expr1 = ExprTransformer.transform(exprTransform, expr) ;
+ if ( v == v1 && expr == expr1 ) {
+ push(el) ;
+ return ;
+ }
+ push(new ElementBind(v1, expr1)) ;
+ }
+
+ @Override
+ public void visit(ElementData el) {
+ push(el) ;
+ }
+
+ @Override
+ public void visit(ElementOptional el) {
+ Element elSub = el.getOptionalElement() ;
+ Element elSub2 = pop() ;
+ Element el2 = (elSub == elSub2) ? el : new ElementOptional(elSub2) ;
+ pushChanged(el, el2) ;
+ }
+
+ @Override
+ public void visit(ElementGroup el) {
+ ElementGroup newElt = new ElementGroup() ;
+ boolean b = transformFromTo(el.getElements(), newElt.getElements()) ;
+ if ( b )
+ push(newElt) ;
+ else
+ push(el) ;
+ }
+
+ @Override
+ public void visit(ElementUnion el) {
+ ElementUnion newElt = new ElementUnion() ;
+ boolean b = transformFromTo(el.getElements(), newElt.getElements()) ;
+ if ( b )
+ push(newElt) ;
+ else
+ push(el) ;
+ }
+
+ private boolean transformFromTo(List<Element> elts, List<Element> elts2) {
+ boolean changed = false ;
+ for (Element elt : elts) {
+ Element elt2 = pop() ;
+ changed = (changed || (elt != elt2)) ;
+ // Add reversed.
+ elts2.add(0, elt2) ;
+ }
+ return changed ;
+ }
+
+ @Override
+ public void visit(ElementDataset el) {
+ push(el) ;
+ // TODO
+ // el.getPatternElement() ;
+ }
+
+ @Override
+ public void visit(ElementNamedGraph el) {
+ Node n = el.getGraphNameNode() ;
+ Node n1 = TransEltLib.apply(n, exprTransform) ;
+ Element elt = el.getElement() ;
+ Element elt1 = pop() ;
+ if ( n == n1 && elt == elt1 )
+ push(el) ;
+ else
+ push(new ElementNamedGraph(n1, elt1)) ;
+ }
+
+ @Override
+ public void visit(ElementExists el) {
+ Element elt = el.getElement() ;
+ Element elt1 = subElement(elt) ;
+ if ( elt == elt1 )
+ push(el) ;
+ else
+ push(new ElementExists(elt1)) ;
+ }
+
+ @Override
+ public void visit(ElementNotExists el) {
+ Element elt = el.getElement() ;
+ Element elt1 = subElement(elt) ;
+ if ( elt == elt1 )
+ push(el) ;
+ else
+ push(new ElementNotExists(elt1)) ;
+ }
+
+ // When you need to force the walking of the tree ... EXISTS / NOT
+ // EXISTS
+ private Element subElement(Element elt) {
+ ElementWalker.walk(elt, this) ;
+ Element elt1 = pop() ;
+ return elt1 ;
+ }
+
+ @Override
+ public void visit(ElementMinus el) {
+ Element elt = el.getMinusElement() ;
+ Element elt1 = pop() ;
+ if ( elt == elt1 )
+ push(el) ;
+ else
+ push(new ElementMinus(elt1)) ;
+ }
+
+ @Override
+ public void visit(ElementService el) {
+ boolean b = el.getSilent() ;
+ Node n = el.getServiceNode() ;
+ Node n1 = TransEltLib.apply(n, exprTransform) ;
+ Element elt = el.getElement() ;
+ Element elt1 = pop() ;
+ if ( n == n1 && elt == elt1 )
+ push(el) ;
+ else
+ push(new ElementService(n1, elt1, b)) ;
+ }
+
+ @Override
+ public void visit(ElementSubQuery el) {
+ Query newQuery = QueryOps.transform(el.getQuery(), transform, exprTransform) ;
+ push(new ElementSubQuery(newQuery)) ;
+ }
+
+ // private Element transform(Element el)
+ // {
+ // el.visit(this) ;
+ // return pop() ;
+ // }
+
+ private ExprList transform(ExprList exprList, ExprTransform exprTransform) {
+ if ( exprList == null || exprTransform == null )
+ return exprList ;
+ return ExprTransformer.transform(exprTransform, exprList) ;
+ }
+
+ private Expr transform(Expr expr, ExprTransform exprTransform) {
+ if ( expr == null || exprTransform == null )
+ return expr ;
+ return ExprTransformer.transform(exprTransform, expr) ;
+ }
+ }
+}
Added: jena/Scratch/AFS/Jena-Dev/trunk/src/element/ExprTransformNodeElement.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Jena-Dev/trunk/src/element/ExprTransformNodeElement.java?rev=1509984&view=auto
==============================================================================
--- jena/Scratch/AFS/Jena-Dev/trunk/src/element/ExprTransformNodeElement.java (added)
+++ jena/Scratch/AFS/Jena-Dev/trunk/src/element/ExprTransformNodeElement.java Sat Aug 3 13:20:20 2013
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package element ;
+
+import org.apache.jena.atlas.lib.InternalErrorException ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.sparql.algebra.Op ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.expr.* ;
+import com.hp.hpl.jena.sparql.graph.NodeTransform ;
+import com.hp.hpl.jena.sparql.syntax.Element ;
+
+/**
+ * Special version of ExprTransform for applying a node transform on syntax
+ * (Elements) only
+ */
+public class ExprTransformNodeElement extends ExprTransformCopy {
+ private final NodeTransform nodeTransform ;
+ private final ElementTransform elementTransform ;
+
+ public ExprTransformNodeElement(NodeTransform nodeTransform, ElementTransform eltrans) {
+ this.nodeTransform = nodeTransform ;
+ this.elementTransform = eltrans ;
+ }
+
+ @Override
+ public Expr transform(ExprVar nv) {
+ Node n = nodeTransform.convert(nv.getAsNode()) ;
+ if ( n == nv.getAsNode() )
+ return nv ;
+ if ( n instanceof Var ) {
+ Var v = Var.alloc(n) ;
+ return new ExprVar(v) ;
+ }
+ return NodeValue.makeNode(n) ;
+ }
+
+ @Override
+ public Expr transform(NodeValue nv) {
+ Node n = nodeTransform.convert(nv.asNode()) ;
+ if ( n == nv.asNode() )
+ return nv ;
+ return NodeValue.makeNode(n) ;
+ }
+
+ @Override
+ public Expr transform(ExprFunctionOp funcOp, ExprList args, Op opArg) {
+ // Syntax phased only - ignore args and opArg
+ Element elt = funcOp.getElement() ;
+ Element elt1 = ElementTransformer.transform(elt, elementTransform) ;
+ if ( elt == elt1 )
+ return funcOp ;
+ else {
+ if ( funcOp instanceof E_Exists )
+ return new E_Exists(elt1) ;
+ if ( funcOp instanceof E_NotExists )
+ return new E_NotExists(elt1) ;
+ throw new InternalErrorException("Unknown ExprFunctionOp: " + funcOp.getFunctionSymbol()) ;
+ }
+ }
+}
Added: jena/Scratch/AFS/Jena-Dev/trunk/src/element/MainElt.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Jena-Dev/trunk/src/element/MainElt.java?rev=1509984&view=auto
==============================================================================
--- jena/Scratch/AFS/Jena-Dev/trunk/src/element/MainElt.java (added)
+++ jena/Scratch/AFS/Jena-Dev/trunk/src/element/MainElt.java Sat Aug 3 13:20:20 2013
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package element;
+
+
+import java.util.HashMap ;
+import java.util.Map ;
+
+import org.apache.jena.atlas.lib.StrUtils ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.graph.NodeFactory ;
+import com.hp.hpl.jena.query.Query ;
+import com.hp.hpl.jena.query.QueryFactory ;
+import com.hp.hpl.jena.query.Syntax ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.update.UpdateFactory ;
+import com.hp.hpl.jena.update.UpdateRequest ;
+
+public class MainElt
+{
+ public static void main(String[] args)
+ {
+ String x = StrUtils.strjoinNL
+ ( "PREFIX : <http://example/>"
+ //, "SELECT * { ?s :p ?x . NOT EXISTS { ?x :r ?x } FILTER NOT EXISTS { ?x :r ?x } FILTER ( ?x > ?y ) OPTIONAL { ?x :q ?y } }"
+ , "SELECT ?x { ?s :p ?x . FILTER NOT EXISTS { ?x :r ?x }} GROUP BY ?x ORDER BY ?x"
+ );
+
+ Query q = QueryFactory.create(x, Syntax.syntaxARQ) ;
+
+ Map<Var, Node> map = new HashMap<Var, Node>() ;
+ map.put(Var.alloc("x"), NodeFactory.createURI("X")) ;
+
+ Query q2 = QueryOps.transform(q, map) ;
+ System.out.print(q) ;
+ System.out.println("-------------");
+ System.out.print(q2) ;
+ System.out.println("-------------");
+
+ String z = StrUtils.strjoinNL
+ ( "PREFIX : <http://example/>"
+ , "DELETE { ?s :p ?x } WHERE {}"
+ );
+ UpdateRequest req = UpdateFactory.create(z) ;
+ UpdateRequest req2 = UpdateOps.transform(req, map) ;
+ System.out.print(req) ;
+ System.out.println("-------------");
+ System.out.print(req2) ;
+ System.out.println("-------------");
+
+
+ }
+
+}
+
Added: jena/Scratch/AFS/Jena-Dev/trunk/src/element/NodeTransformSubst.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Jena-Dev/trunk/src/element/NodeTransformSubst.java?rev=1509984&view=auto
==============================================================================
--- jena/Scratch/AFS/Jena-Dev/trunk/src/element/NodeTransformSubst.java (added)
+++ jena/Scratch/AFS/Jena-Dev/trunk/src/element/NodeTransformSubst.java Sat Aug 3 13:20:20 2013
@@ -0,0 +1,41 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package element ;
+
+import java.util.Map ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.graph.NodeTransform ;
+
+public class NodeTransformSubst implements NodeTransform {
+ private final Map<Var, Node> map ;
+
+ NodeTransformSubst(Map<Var, Node> map) {
+ this.map = map ;
+ }
+
+ @Override
+ public Node convert(Node node) {
+ Node n = map.get(node) ;
+ if ( n == null )
+ return node ;
+ return n ;
+ }
+}
Added: jena/Scratch/AFS/Jena-Dev/trunk/src/element/QueryOps.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Jena-Dev/trunk/src/element/QueryOps.java?rev=1509984&view=auto
==============================================================================
--- jena/Scratch/AFS/Jena-Dev/trunk/src/element/QueryOps.java (added)
+++ jena/Scratch/AFS/Jena-Dev/trunk/src/element/QueryOps.java Sat Aug 3 13:20:20 2013
@@ -0,0 +1,227 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package element ;
+
+import java.util.Map ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.query.Query ;
+import com.hp.hpl.jena.query.QueryVisitor ;
+import com.hp.hpl.jena.query.SortCondition ;
+import com.hp.hpl.jena.shared.PrefixMapping ;
+import com.hp.hpl.jena.shared.impl.PrefixMappingImpl ;
+import com.hp.hpl.jena.sparql.ARQException ;
+import com.hp.hpl.jena.sparql.core.* ;
+import com.hp.hpl.jena.sparql.expr.* ;
+import com.hp.hpl.jena.sparql.graph.NodeTransform ;
+import com.hp.hpl.jena.sparql.syntax.Element ;
+
+public class QueryOps {
+ public static Query transform(Query query, Map<Var, Node> substitutions) {
+ ElementTransform eltrans = new ElementTransformSubst(substitutions) ;
+ NodeTransform nodeTransform = new NodeTransformSubst(substitutions) ;
+ ExprTransform exprTrans = new ExprTransformNodeElement(nodeTransform, eltrans) ;
+ return transform(query, eltrans, exprTrans) ;
+ }
+
+ public static Query transform(Query query, ElementTransform transform, ExprTransform exprTransform) {
+ Query q2 = QueryOps.shallowCopy(query) ;
+
+ transformVarExprList(q2.getProject(), exprTransform) ;
+ transformVarExprList(q2.getGroupBy(), exprTransform) ;
+ // Nothing to do about ORDER BY - leave to sort by that variable.
+
+ Element el = q2.getQueryPattern() ;
+ Element el2 = ElementTransformer.transform(el, transform, exprTransform) ;
+ q2.setQueryPattern(el2) ;
+ return q2 ;
+ }
+
+ // Mutates the VarExprList
+ private static void transformVarExprList(VarExprList varExprList, ExprTransform exprTransform)
+ // , final Map<Var, Node> substitutions)
+ {
+ Map<Var, Expr> map = varExprList.getExprs() ;
+
+ for (Var v : varExprList.getVars()) {
+ Expr e = varExprList.getExpr(v) ;
+ ExprVar ev = new ExprVar(v) ;
+ Expr ev2 = exprTransform.transform(ev) ;
+ if ( ev != ev2 ) {
+ if ( e != null )
+ throw new ARQException("Can't substitute " + v + " because it's used as an AS variable") ;
+ if ( ev2 instanceof NodeValue ) {
+ // Convert to (substit value AS ?var)
+ map.put(v, ev2) ;
+ continue ;
+ } else
+ throw new ARQException("Can't substitute " + v + " because it's not a simple value: " + ev2) ;
+ }
+ if ( e == null )
+ continue ;
+
+ // Didn't change the variable.
+ Expr e2 = ExprTransformer.transform(exprTransform, e) ;
+ if ( e != e2 )
+ // replace
+ map.put(v, e2) ;
+ }
+ }
+
+ static class QueryShallowCopy implements QueryVisitor {
+ final Query newQuery = new Query() ;
+
+ QueryShallowCopy() {}
+
+ @Override
+ public void startVisit(Query query) {
+ newQuery.setSyntax(query.getSyntax()) ;
+
+ if ( query.explicitlySetBaseURI() )
+ newQuery.setBaseURI(query.getPrologue().getResolver()) ;
+
+ newQuery.setQueryResultStar(query.isQueryResultStar()) ;
+
+ if ( query.hasDatasetDescription() ) {
+ DatasetDescription desc = query.getDatasetDescription() ;
+ for (String x : desc.getDefaultGraphURIs())
+ newQuery.addGraphURI(x) ;
+ for (String x : desc.getDefaultGraphURIs())
+ newQuery.addNamedGraphURI(x) ;
+ }
+ // Not needed in a shallow copy?
+ // for ( ExprAggregator agg : query.getAggregators() )
+ // {
+ // // Hooks for
+ // //aggregatorsAllocated.put(key, v) ;
+ // //aggregatorsMap.put(v, aggExpr) ;
+ // //aggregators.add(aggExpr) ;
+ // }
+
+ }
+
+ @Override
+ public void visitPrologue(Prologue prologue) {
+ // newQuery.setBaseURI(prologue.getResolver()) ;
+ PrefixMapping pmap = new PrefixMappingImpl().setNsPrefixes(prologue.getPrefixMapping()) ;
+ newQuery.setPrefixMapping(pmap) ;
+ }
+
+ @Override
+ public void visitResultForm(Query q) {}
+
+ @Override
+ public void visitSelectResultForm(Query query) {
+ newQuery.setQuerySelectType() ;
+ newQuery.setDistinct(query.isDistinct()) ;
+ VarExprList x = query.getProject() ;
+ for (Var v : x.getVars()) {
+ Expr expr = x.getExpr(v) ;
+ if ( expr == null )
+ newQuery.addResultVar(v) ;
+ else
+ newQuery.addResultVar(v, expr) ;
+ }
+ }
+
+ @Override
+ public void visitConstructResultForm(Query query) {
+ newQuery.setQueryConstructType() ;
+ newQuery.setConstructTemplate(query.getConstructTemplate()) ;
+ }
+
+ @Override
+ public void visitDescribeResultForm(Query query) {
+ newQuery.setQueryDescribeType() ;
+ for (Node x : query.getResultURIs())
+ newQuery.addDescribeNode(x) ;
+ }
+
+ @Override
+ public void visitAskResultForm(Query query) {
+ newQuery.setQueryAskType() ;
+ }
+
+ @Override
+ public void visitDatasetDecl(Query query) {}
+
+ @Override
+ public void visitQueryPattern(Query query) {
+ newQuery.setQueryPattern(query.getQueryPattern()) ;
+ }
+
+ @Override
+ public void visitGroupBy(Query query) {
+ if ( query.hasGroupBy() ) {
+ VarExprList x = query.getGroupBy() ;
+
+ for (Var v : x.getVars()) {
+ Expr expr = x.getExpr(v) ;
+ if ( expr == null )
+ newQuery.addGroupBy(v) ;
+ else
+ newQuery.addGroupBy(v, expr) ;
+ }
+ }
+ }
+
+ @Override
+ public void visitHaving(Query query) {
+ if ( query.hasHaving() ) {
+ for (Expr expr : query.getHavingExprs())
+ newQuery.addHavingCondition(expr) ;
+ }
+ }
+
+ @Override
+ public void visitOrderBy(Query query) {
+ if ( query.hasOrderBy() ) {
+ for (SortCondition sc : query.getOrderBy())
+ newQuery.addOrderBy(sc) ;
+ }
+ }
+
+ @Override
+ public void visitLimit(Query query) {
+ newQuery.setLimit(query.getLimit()) ;
+ }
+
+ @Override
+ public void visitOffset(Query query) {
+ newQuery.setOffset(query.getOffset()) ;
+ }
+
+ @Override
+ public void visitValues(Query query) {
+ if ( query.hasValues() )
+ newQuery.setValuesDataBlock(query.getValuesVariables(), query.getValuesData()) ;
+ }
+
+ @Override
+ public void finishVisit(Query query) {}
+ }
+
+ public static Query shallowCopy(Query query) {
+ QueryShallowCopy copy = new QueryShallowCopy() ;
+ query.visit(copy) ;
+ Query q2 = copy.newQuery ;
+ return q2 ;
+ }
+
+}
Added: jena/Scratch/AFS/Jena-Dev/trunk/src/element/TestQueryOps.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Jena-Dev/trunk/src/element/TestQueryOps.java?rev=1509984&view=auto
==============================================================================
--- jena/Scratch/AFS/Jena-Dev/trunk/src/element/TestQueryOps.java (added)
+++ jena/Scratch/AFS/Jena-Dev/trunk/src/element/TestQueryOps.java Sat Aug 3 13:20:20 2013
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package element;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.junit.Test ;
+
+import com.hp.hpl.jena.query.Query ;
+import com.hp.hpl.jena.query.QueryFactory ;
+
+public class TestQueryOps extends BaseTest
+{
+ @Test public void queryOp_01() { testShallowCopy("SELECT * { }") ; }
+
+ @Test public void queryOp_02() { testShallowCopy("SELECT ?x { }") ; }
+
+ @Test public void queryOp_03() { testShallowCopy("SELECT * { ?s ?p ?o }") ; }
+
+ @Test public void queryOp_04() { testShallowCopy("SELECT ?x { ?s ?p ?o }") ; }
+
+ @Test public void queryOp_05() { testShallowCopy("SELECT (?x+1 AS ?z) ?y { }") ; }
+
+ @Test public void queryOp_06() { testShallowCopy("SELECT DISTINCT (?x+1 AS ?z) ?y { }") ; }
+
+ @Test public void queryOp_07() { testShallowCopy("SELECT REDUCED (?x+1 AS ?z) ?y { }") ; }
+
+ @Test public void queryOp_10() { testShallowCopy("SELECT ?s { ?s ?p ?o } GROUP BY ?s") ; }
+
+ @Test public void queryOp_11() { testShallowCopy("SELECT ?s { ?s ?p ?o } ORDER BY ?o") ; }
+
+ @Test public void queryOp_12() { testShallowCopy("SELECT ?s { ?s ?p ?o } LIMIT 10") ; }
+
+ @Test public void queryOp_13() { testShallowCopy("SELECT ?s { ?s ?p ?o } OFFSET 5 LIMIT 10") ; }
+
+ private static void testShallowCopy(String queryString)
+ {
+ Query q1 = QueryFactory.create(queryString) ;
+ Query q2 = QueryOps.shallowCopy(q1) ;
+ assertEquals(q1, q2) ;
+ }
+
+}
+
Added: jena/Scratch/AFS/Jena-Dev/trunk/src/element/TestSubstitution.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Jena-Dev/trunk/src/element/TestSubstitution.java?rev=1509984&view=auto
==============================================================================
--- jena/Scratch/AFS/Jena-Dev/trunk/src/element/TestSubstitution.java (added)
+++ jena/Scratch/AFS/Jena-Dev/trunk/src/element/TestSubstitution.java Sat Aug 3 13:20:20 2013
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package element;
+
+import java.util.HashMap ;
+import java.util.Map ;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.junit.Test ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.query.Query ;
+import com.hp.hpl.jena.query.QueryFactory ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.sse.SSE ;
+
+public class TestSubstitution extends BaseTest
+{
+ @Test public void subst_01() { testQuery("SELECT * { }", "SELECT * {}", "o", "1") ; }
+
+ @Test public void subst_02() { testQuery("SELECT ?x { }", "SELECT ?x {}", "o", "1") ; }
+
+ @Test public void subst_03() { testQuery("SELECT ?o { }", "SELECT (1 as ?o) {}", "o", "1") ; }
+
+ @Test public void subst_04() { testQuery("SELECT (?o AS ?z) { }", "SELECT (1 AS ?z) {}", "o", "1") ; }
+
+ @Test public void subst_05() { testQuery("SELECT (?o+2 AS ?z) { }", "SELECT (1+2 AS ?z) {}", "o", "1") ; }
+
+ @Test public void subst_09() { testQuery("SELECT * {?s ?p ?o}", "SELECT * {?s ?p 1}", "o", "1") ; }
+
+ @Test public void subst_10() { testQuery("SELECT * { SELECT ?o {} }", "SELECT * {SELECT (1 as ?o) {}}", "o", "1") ; }
+
+ //static final String PREFIX = "PREFIX : <http://example/>\n" ;
+ static final String PREFIX = "" ;
+
+ private void testQuery(String input, String output, String varStr, String valStr)
+ {
+ Query q1 = QueryFactory.create(PREFIX+input) ;
+ Query qExpected = QueryFactory.create(PREFIX+output) ;
+
+ Map<Var, Node> map = new HashMap<Var, Node>() ;
+ map.put(Var.alloc(varStr), SSE.parseNode(valStr)) ;
+
+ Query qTrans = QueryOps.transform(q1, map) ;
+ assertEquals(qExpected, qTrans) ;
+ }
+
+
+}
+
Added: jena/Scratch/AFS/Jena-Dev/trunk/src/element/TransEltLib.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Jena-Dev/trunk/src/element/TransEltLib.java?rev=1509984&view=auto
==============================================================================
--- jena/Scratch/AFS/Jena-Dev/trunk/src/element/TransEltLib.java (added)
+++ jena/Scratch/AFS/Jena-Dev/trunk/src/element/TransEltLib.java Sat Aug 3 13:20:20 2013
@@ -0,0 +1,57 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package element ;
+
+import org.apache.jena.atlas.lib.InternalErrorException ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.expr.Expr ;
+import com.hp.hpl.jena.sparql.expr.ExprTransform ;
+import com.hp.hpl.jena.sparql.expr.ExprVar ;
+import com.hp.hpl.jena.sparql.expr.NodeValue ;
+
+public class TransEltLib {
+ public static Var applyVar(Var v, ExprTransform exprTransform) {
+ ExprVar expr = new ExprVar(v) ;
+ Expr e = exprTransform.transform(expr) ;
+ if ( e instanceof ExprVar )
+ return ((ExprVar)e).asVar() ;
+ throw new InternalErrorException("Managed to turn a variable " + v + " into " + e) ;
+ }
+
+ public static Node apply(Node n, ExprTransform exprTransform) {
+ Expr e = null ;
+ if ( Var.isVar(n) ) {
+ Var v = Var.alloc(n) ;
+ ExprVar expr = new ExprVar(v) ;
+ e = exprTransform.transform(expr) ;
+ } else {
+ NodeValue nv = NodeValue.makeNode(n) ;
+ e = exprTransform.transform(nv) ;
+ }
+
+ if ( e instanceof ExprVar )
+ return ((ExprVar)e).asVar() ;
+ if ( e instanceof NodeValue )
+ return ((NodeValue)e).asNode() ;
+ throw new InternalErrorException("Managed to turn a node " + n + " into " + e) ;
+ }
+
+}
Added: jena/Scratch/AFS/Jena-Dev/trunk/src/element/UpdateOps.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Jena-Dev/trunk/src/element/UpdateOps.java?rev=1509984&view=auto
==============================================================================
--- jena/Scratch/AFS/Jena-Dev/trunk/src/element/UpdateOps.java (added)
+++ jena/Scratch/AFS/Jena-Dev/trunk/src/element/UpdateOps.java Sat Aug 3 13:20:20 2013
@@ -0,0 +1,206 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package element ;
+
+import java.util.ArrayList ;
+import java.util.List ;
+import java.util.Map ;
+
+import org.apache.jena.atlas.lib.Sink ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.sparql.core.Quad ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.expr.ExprTransform ;
+import com.hp.hpl.jena.sparql.graph.NodeTransform ;
+import com.hp.hpl.jena.sparql.modify.request.* ;
+import com.hp.hpl.jena.sparql.syntax.Element ;
+import com.hp.hpl.jena.update.Update ;
+import com.hp.hpl.jena.update.UpdateRequest ;
+
+public class UpdateOps {
+
+ public static Update transform(Update update, Map<Var, Node> substitutions) {
+ ElementTransform eltrans = new ElementTransformSubst(substitutions) ;
+ NodeTransform nodeTransform = new NodeTransformSubst(substitutions) ;
+ ExprTransform exprTrans = new ExprTransformNodeElement(nodeTransform, eltrans) ;
+ return transform(update, eltrans, exprTrans) ;
+ }
+
+ public static UpdateRequest transform(UpdateRequest update, Map<Var, Node> substitutions) {
+ ElementTransform eltrans = new ElementTransformSubst(substitutions) ;
+ NodeTransform nodeTransform = new NodeTransformSubst(substitutions) ;
+ ExprTransform exprTrans = new ExprTransformNodeElement(nodeTransform, eltrans) ;
+ return transform(update, eltrans, exprTrans) ;
+ }
+
+ public static Update transform(Update update, ElementTransform transform, ExprTransform exprTransform) {
+ UpdateTransform upParam = new UpdateTransform(transform, exprTransform) ;
+ update.visit(upParam) ;
+ Update update1 = upParam.result ;
+ return update1 ;
+ }
+
+ public static UpdateRequest transform(UpdateRequest update, ElementTransform transform, ExprTransform exprTransform) {
+ UpdateRequest req = new UpdateRequest() ;
+ for (Update up : update.getOperations()) {
+ up = transform(up, transform, exprTransform) ;
+ req.add(up) ;
+ }
+
+ return req ;
+ }
+
+ static class UpdateTransform implements UpdateVisitor {
+ ElementTransform elTransform ;
+ ExprTransform exprTransform ;
+ Update result = null ;
+
+ public UpdateTransform(ElementTransform transform, ExprTransform exprTransform) {
+ this.elTransform = transform ;
+ this.exprTransform = exprTransform ;
+ }
+
+ @Override
+ public void visit(UpdateDrop update) {
+ result = update ;
+ }
+
+ @Override
+ public void visit(UpdateClear update) {
+ result = update ;
+ }
+
+ @Override
+ public void visit(UpdateCreate update) {
+ result = update ;
+ }
+
+ @Override
+ public void visit(UpdateLoad update) {
+ result = update ;
+ }
+
+ @Override
+ public void visit(UpdateAdd update) {
+ result = update ;
+ }
+
+ @Override
+ public void visit(UpdateCopy update) {
+ result = update ;
+ }
+
+ @Override
+ public void visit(UpdateMove update) {
+ result = update ;
+ }
+
+ @Override
+ public void visit(UpdateDataInsert update) {
+ result = update ;
+ }
+
+ @Override
+ public void visit(UpdateDataDelete update) {
+ result = update ;
+ }
+
+ @Override
+ public void visit(UpdateDeleteWhere update) {
+ List<Quad> quads = update.getQuads() ;
+ List<Quad> quads2 = transform(quads) ;
+ if ( quads == quads2 )
+ result = update ;
+ else {
+ QuadAcc acc = new QuadAcc() ;
+ addAll(acc, quads2) ;
+ result = new UpdateDeleteWhere(acc) ;
+ }
+ }
+
+ @Override
+ public void visit(UpdateModify update) {
+ Element el = update.getWherePattern() ;
+ Element el2 = ElementTransformer.transform(el, elTransform, exprTransform) ;
+
+ List<Quad> del = update.getDeleteQuads() ;
+ List<Quad> del1 = transform(del) ;
+ List<Quad> ins = update.getInsertQuads() ;
+ List<Quad> ins1 = transform(ins) ;
+
+ UpdateModify mod = new UpdateModify() ;
+
+ addAll(mod.getDeleteAcc(), del1) ;
+ addAll(mod.getInsertAcc(), ins1) ;
+ result = mod ;
+ }
+
+ private void addAll(QuadAcc acc, List<Quad> quads) {
+ for (Quad q : quads)
+ acc.addQuad(q) ;
+ }
+
+ public List<Quad> transform(List<Quad> quads) {
+ List<Quad> x = new ArrayList<Quad>() ;
+ boolean changed = false ;
+ for (Quad q : quads) {
+ Quad q1 = transform(q) ;
+ changed = changed || q1 != q ;
+ x.add(q1) ;
+ }
+ if ( changed )
+ return x ;
+ return quads ;
+ }
+
+ private Quad transform(Quad q) {
+ Node g = q.getGraph() ;
+ Node g1 = transform(g) ;
+ Node s = q.getSubject() ;
+ Node s1 = transform(s) ;
+ Node p = q.getPredicate() ;
+ Node p1 = transform(p) ;
+ Node o = q.getObject() ;
+ Node o1 = transform(o) ;
+ if ( g == g1 && s == s1 && p == p1 && o == o1 )
+ return q ;
+ return Quad.create(g1, s1, p1, o1) ;
+ }
+
+ private Node transform(Node n) {
+ if ( Var.isVar(n) )
+ return TransEltLib.apply(Var.alloc(n), exprTransform) ;
+ else
+ return TransEltLib.apply(n, exprTransform) ;
+ }
+
+ @Override
+ public Sink<Quad> createInsertDataSink() {
+ return null ;
+ }
+
+ @Override
+ public Sink<Quad> createDeleteDataSink() {
+ return null ;
+ }
+
+ }
+
+}