| /* |
| * 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.sparql.algebra; |
| |
| import java.util.Deque ; |
| |
| import org.apache.jena.graph.Node ; |
| import org.apache.jena.sparql.algebra.AlgebraQuad.QuadSlot ; |
| import org.apache.jena.sparql.algebra.op.* ; |
| import org.apache.jena.sparql.core.Quad; |
| import org.apache.jena.sparql.core.Var ; |
| import org.apache.jena.sparql.expr.ExprVar ; |
| |
| /** |
| * Transform that rewrites an algebra into quad form |
| * |
| */ |
| public class TransformQuadGraph extends TransformCopy |
| { |
| private Deque<QuadSlot> tracker ; |
| private OpVisitor beforeVisitor ; |
| private OpVisitor afterVisitor ; |
| |
| public TransformQuadGraph(Deque<QuadSlot> tracker, OpVisitor before, OpVisitor after) { |
| this.tracker = tracker ; |
| this.beforeVisitor = before ; |
| this.afterVisitor = after ; |
| } |
| |
| protected Node getNode() { return tracker.peek().rewriteGraphName ; } |
| |
| @Override |
| public Op transform(OpGraph opGraph, Op op) { |
| // ?? Could just leave the (graph) in place always - just rewrite BGPs. |
| boolean noPattern = false ; |
| |
| /* One case to consider is when the pattern for the GRAPH |
| * statement includes uses the variable inside the GRAPH clause. |
| * In this case, we must rename away the inner variable |
| * to allow stream execution via index joins, |
| * and then put back the value via an assign. |
| * (This is what QueryIterGraph does using a streaming join |
| * for triples) |
| */ |
| |
| // Note: op is already quads by this point. |
| // Must test scoping by the subOp of GRAPH |
| |
| QuadSlot qSlot = tracker.peek() ; |
| Node actualName= qSlot.actualGraphName ; |
| Node rewriteName= qSlot.rewriteGraphName ; |
| |
| if ( OpBGP.isBGP(op) ) |
| { |
| // Empty BGP |
| if ( ((OpBGP)op).getPattern().isEmpty() ) |
| noPattern = true ; |
| } |
| else if ( op instanceof OpTable ) |
| { |
| // Empty BGP compiled to a unit table |
| if ( ((OpTable)op).isJoinIdentity() ) |
| noPattern = true ; |
| } |
| |
| if ( noPattern ) |
| { |
| // The case of something like: |
| // GRAPH ?g {} or GRAPH <v> {} |
| // which are ways of accessing the names in the dataset. |
| return new OpDatasetNames(opGraph.getNode()) ; |
| } |
| |
| if ( actualName != rewriteName ) |
| op = OpAssign.assign(op, Var.alloc(actualName), new ExprVar(rewriteName)) ; |
| |
| // Drop (graph...) because inside nodes |
| // have been converted to quads. |
| return op ; |
| } |
| |
| @Override |
| public Op transform(OpPropFunc opPropFunc, Op subOp) { |
| if ( opPropFunc.getSubOp() != subOp ) |
| opPropFunc = new OpPropFunc(opPropFunc.getProperty(), opPropFunc.getSubjectArgs(), opPropFunc.getObjectArgs(), subOp) ; |
| // Put the (graph) back round it so the property function works on the named graph. |
| return new OpGraph(getNode() , opPropFunc) ; |
| } |
| |
| @Override |
| public Op transform(OpFind opFind) { |
| // Put the (graph) back round it so FIND works on the named graph. |
| return new OpGraph(getNode() , opFind) ; |
| } |
| |
| @Override |
| public Op transform(OpPath opPath) { |
| return new OpGraph(getNode() , opPath) ; |
| // Does not get removed by transform above because this is |
| // not the OpGraph that gets walked by the transform. |
| } |
| |
| @Override |
| public Op transform(OpBGP opBGP) { |
| return new OpQuadPattern(getNode(), opBGP.getPattern()) ; |
| } |
| |
| @Override |
| public Op transform(OpTriple opTriple) { |
| return new OpQuad(Quad.create(getNode(), opTriple.getTriple())); |
| } |
| |
| @Override |
| public Op transform(OpExt opExt) { |
| return opExt.apply(this, beforeVisitor, afterVisitor) ; |
| } |
| } |