/* * 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 org.apache.jena.arq.querybuilder.rewriters; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.jena.graph.Node ; import org.apache.jena.query.SortCondition ; import org.apache.jena.sparql.algebra.Op ; import org.apache.jena.sparql.algebra.OpVisitor ; import org.apache.jena.sparql.algebra.Table ; import org.apache.jena.sparql.algebra.op.* ; import org.apache.jena.sparql.algebra.table.TableN ; import org.apache.jena.sparql.core.* ; import org.apache.jena.sparql.engine.binding.Binding ; import org.apache.jena.sparql.expr.ExprAggregator ; import org.apache.jena.sparql.expr.ExprList ; import org.apache.jena.sparql.pfunction.PropFuncArg ; /** * A rewriter that implements OpVisitor. * */ class OpRewriter extends AbstractRewriter<Op> implements OpVisitor { /** * Constructor. * @param values The values to replace. */ OpRewriter(Map<Var, Node> values) { super(values); } private Quad rewrite(Quad q) { return new Quad(changeNode(q.getGraph()), changeNode(q.getSubject()), changeNode(q.getPredicate()), changeNode(q.getObject())); } private QuadPattern rewrite(QuadPattern pattern) { QuadPattern qp = new QuadPattern(); for (Quad q : pattern.getList()) { qp.add(rewrite(q)); } return qp; } private List<Op> rewriteOpList(List<Op> lst) { List<Op> retval = new ArrayList<Op>(); for (Op o : lst) { o.visit(this); retval.add(pop()); } return retval; } private BasicPattern rewrite(BasicPattern pattern) { return BasicPattern.wrap(rewrite(pattern.getList())); } @Override public void visit(OpBGP opBGP) { push(new OpBGP(rewrite(opBGP.getPattern()))); } @Override public void visit(OpQuadPattern quadPattern) { push(new OpQuadPattern(changeNode(quadPattern.getGraphNode()), rewrite(quadPattern.getBasicPattern()))); } @Override public void visit(OpQuadBlock quadBlock) { push(new OpQuadBlock(rewrite(quadBlock.getPattern()))); } @Override public void visit(OpTriple opTriple) { push(new OpTriple(rewrite(opTriple.getTriple()))); } @Override public void visit(OpQuad opQuad) { push(new OpQuad(rewrite(opQuad.getQuad()))); } @Override public void visit(OpPath opPath) { push(new OpPath(rewrite(opPath.getTriplePath()))); } @Override public void visit(OpTable opTable) { Table tbl = opTable.getTable(); boolean process = false; for (Var v : tbl.getVars()) { process = process | values.keySet().contains(v); } if (!process) { push(opTable); } else { TableN retTbl = new TableN(tbl.getVars()); Iterator<Binding> iter = tbl.rows(); while (iter.hasNext()) { retTbl.addBinding(rewrite(iter.next())); } push(OpTable.create(retTbl)); } } @Override public void visit(OpNull opNull) { push(opNull); } @Override public void visit(OpProcedure opProc) { opProc.getSubOp().visit(this); Op op = pop(); ExprList args = new ExprRewriter(values).rewrite(opProc.getArgs()); Node procId = changeNode(opProc.getProcId()); push(new OpProcedure(procId, args, op)); } private PropFuncArg rewrite(PropFuncArg arg) { if (arg.isList()) { List<Node> lst = changeNodes(arg.getArgList()); return new PropFuncArg(lst, null); } return new PropFuncArg(changeNode(arg.getArg())); } @Override public void visit(OpPropFunc opPropFunc) { opPropFunc.getSubOp().visit(this); Op op = pop(); Node uri = changeNode(opPropFunc.getProperty()); PropFuncArg args1 = rewrite(opPropFunc.getSubjectArgs()); PropFuncArg args2 = rewrite(opPropFunc.getObjectArgs()); push(new OpPropFunc(uri, args1, args2, op)); } @Override public void visit(OpFilter opFilter) { opFilter.getSubOp().visit(this); push(OpFilter.filterBy( new ExprRewriter(values).rewrite(opFilter.getExprs()), pop())); } @Override public void visit(OpGraph opGraph) { opGraph.getSubOp().visit(this); push(new OpGraph(changeNode(opGraph.getNode()), pop())); } @Override public void visit(OpService opService) { opService.getSubOp().visit(this); push(new OpService(changeNode(opService.getService()), pop(), opService.getSilent())); } @Override public void visit(OpDatasetNames dsNames) { push(new OpDatasetNames(changeNode(dsNames.getGraphNode()))); } @Override public void visit(OpLabel opLabel) { if (opLabel.hasSubOp()) { opLabel.getSubOp().visit(this); push(OpLabel.create(opLabel.getObject(), pop())); } else { push(opLabel); } } @Override public void visit(OpAssign opAssign) { opAssign.getSubOp().visit(this); push(OpAssign.assign(pop(), rewrite(opAssign.getVarExprList()))); } @Override public void visit(OpExtend opExtend) { opExtend.getSubOp().visit(this); push(OpExtend.extend(pop(), rewrite(opExtend.getVarExprList()))); } @Override public void visit(OpJoin opJoin) { opJoin.getRight().visit(this); opJoin.getLeft().visit(this); push(OpJoin.create(pop(), pop())); } @Override public void visit(OpLeftJoin opLeftJoin) { opLeftJoin.getRight().visit(this); opLeftJoin.getLeft().visit(this); push(OpLeftJoin.create(pop(), pop(), new ExprRewriter(values).rewrite(opLeftJoin.getExprs()))); } @Override public void visit(OpUnion opUnion) { opUnion.getRight().visit(this); opUnion.getLeft().visit(this); push(OpUnion.create(pop(), pop())); } @Override public void visit(OpDiff opDiff) { opDiff.getRight().visit(this); opDiff.getLeft().visit(this); push(OpDiff.create(pop(), pop())); } @Override public void visit(OpMinus opMinus) { opMinus.getRight().visit(this); opMinus.getLeft().visit(this); push(OpMinus.create(pop(), pop())); } @Override public void visit(OpConditional opCondition) { opCondition.getRight().visit(this); opCondition.getLeft().visit(this); push(new OpConditional(pop(), pop())); } @Override public void visit(OpSequence opSequence) { List<Op> lst = rewriteOpList(opSequence.getElements()); push(opSequence.copy(lst)); } @Override public void visit(OpDisjunction opDisjunction) { List<Op> lst = rewriteOpList(opDisjunction.getElements()); push(opDisjunction.copy(lst)); } @Override public void visit(OpExt opExt) { push(opExt); } @Override public void visit(OpList opList) { opList.getSubOp().visit(this); push(new OpList(pop())); } @Override public void visit(OpOrder opOrder) { List<SortCondition> lst = new ExprRewriter(values) .rewriteSortConditionList(opOrder.getConditions()); opOrder.getSubOp().visit(this); push(new OpOrder(pop(), lst)); } @Override public void visit(OpProject opProject) { opProject.getSubOp().visit(this); List<Var> vars = new ArrayList<Var>(); for (Var v : opProject.getVars()) { Node n = changeNode(v); vars.add(Var.alloc(n)); } push(new OpProject(pop(), vars)); } @Override public void visit(OpReduced opReduced) { opReduced.getSubOp().visit(this); push(opReduced.copy(pop())); } @Override public void visit(OpDistinct opDistinct) { opDistinct.getSubOp().visit(this); push(opDistinct.copy(pop())); } @Override public void visit(OpSlice opSlice) { opSlice.getSubOp().visit(this); push(opSlice.copy(pop())); } @Override public void visit(OpGroup opGroup) { opGroup.getSubOp().visit(this); ExprRewriter expRewriter = new ExprRewriter(values); VarExprList groupVars = rewrite(opGroup.getGroupVars()); List<ExprAggregator> aggregators = new ArrayList<ExprAggregator>(); for (ExprAggregator ea : opGroup.getAggregators()) { ea.visit(expRewriter); aggregators.add((ExprAggregator) expRewriter.pop()); } push(new OpGroup(pop(), groupVars, aggregators)); } @Override public void visit(OpTopN opTop) { opTop.getSubOp().visit(this); ExprRewriter expRewriter = new ExprRewriter(values); expRewriter.rewriteSortConditionList(opTop.getConditions()); push(new OpTopN(pop(), opTop.getLimit(), expRewriter.rewriteSortConditionList(opTop.getConditions()))); } }