| /* |
| * 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.engine.main; |
| |
| import java.util.ArrayDeque ; |
| import java.util.Deque ; |
| |
| import org.apache.jena.atlas.logging.Log ; |
| import org.apache.jena.sparql.algebra.Op ; |
| import org.apache.jena.sparql.algebra.OpVisitor ; |
| import org.apache.jena.sparql.algebra.op.* ; |
| import org.apache.jena.sparql.engine.QueryIterator ; |
| |
| /** Class to provide type-safe execution dispatch using the visitor support of Op */ |
| |
| class ExecutionDispatch implements OpVisitor |
| { |
| private Deque<QueryIterator> stack = new ArrayDeque<>() ; |
| private OpExecutor opExecutor ; |
| |
| ExecutionDispatch(OpExecutor exec) |
| { |
| opExecutor = exec ; |
| } |
| |
| QueryIterator exec(Op op, QueryIterator input) |
| { |
| push(input) ; |
| int x = stack.size() ; |
| op.visit(this) ; |
| int y = stack.size() ; |
| if ( x != y ) |
| Log.warn(this, "Possible stack misalignment") ; |
| QueryIterator qIter = pop() ; |
| return qIter ; |
| } |
| |
| @Override |
| public void visit(OpBGP opBGP) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opBGP, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpQuadPattern quadPattern) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(quadPattern, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpQuadBlock quadBlock) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(quadBlock, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpTriple opTriple) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opTriple, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpQuad opQuad) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opQuad, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpPath opPath) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opPath, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpFind opFind) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opFind, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpProcedure opProc) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opProc, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpPropFunc opPropFunc) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opPropFunc, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpJoin opJoin) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opJoin, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpSequence opSequence) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opSequence, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpDisjunction opDisjunction) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opDisjunction, input) ; |
| push(qIter) ; |
| } |
| |
| |
| @Override |
| public void visit(OpLeftJoin opLeftJoin) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opLeftJoin, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpDiff opDiff) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opDiff, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpMinus opMinus) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opMinus, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpUnion opUnion) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opUnion, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpConditional opCondition) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opCondition, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpFilter opFilter) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opFilter, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpGraph opGraph) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opGraph, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpService opService) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opService, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpDatasetNames dsNames) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(dsNames, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpTable opTable) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opTable, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpExt opExt) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opExt, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpNull opNull) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opNull, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpLabel opLabel) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opLabel, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpList opList) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opList, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpOrder opOrder) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opOrder, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpProject opProject) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opProject, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpDistinct opDistinct) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opDistinct, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpReduced opReduced) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opReduced, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpAssign opAssign) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opAssign, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpExtend opExtend) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opExtend, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpSlice opSlice) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opSlice, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpGroup opGroup) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opGroup, input) ; |
| push(qIter) ; |
| } |
| |
| @Override |
| public void visit(OpTopN opTop) |
| { |
| QueryIterator input = pop() ; |
| QueryIterator qIter = opExecutor.execute(opTop, input) ; |
| push(qIter) ; |
| } |
| |
| private void push(QueryIterator qIter) { stack.push(qIter) ; } |
| private QueryIterator pop() |
| { |
| if ( stack.size() == 0 ) |
| Log.warn(this, "Warning: pop: empty stack") ; |
| return stack.pop() ; |
| } |
| } |