| /* |
| * 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.pig.test.utils.dotGraph; |
| |
| import org.apache.pig.impl.plan.*; |
| |
| import java.io.ByteArrayInputStream; |
| import java.util.Map; |
| import java.util.HashMap; |
| |
| public abstract class OperatorPlanLoader<E extends Operator, |
| P extends OperatorPlan<E>> { |
| |
| /*** |
| * This method is used for loading an operator plan encoded in Dot format |
| * @param dotContent the dot content |
| * @param clazz the plan type to be created |
| * @return |
| */ |
| public P load(String dotContent, Class<P> clazz) { |
| DotGraphReader dotReader = new DotGraphReader() ; |
| DotGraph graph = dotReader.load(dotContent) ; |
| return constructPlan(graph, clazz) ; |
| } |
| |
| /*** |
| * Convenient method for loading directly from file |
| * @param file |
| * @param clazz |
| * @return |
| */ |
| public P loadFromFile(String file, Class<P> clazz) { |
| DotGraphReader dotReader = new DotGraphReader() ; |
| DotGraph graph = dotReader.loadFromFile(file) ; |
| return constructPlan(graph, clazz) ; |
| } |
| |
| public PlanAndGraphEntry loadFromFileWithGraph(String file, |
| Class<P> clazz) { |
| DotGraphReader dotReader = new DotGraphReader() ; |
| DotGraph graph = dotReader.loadFromFile(file) ; |
| P plan = constructPlan(graph, clazz) ; |
| return new PlanAndGraphEntry(plan, graph) ; |
| } |
| |
| public class PlanAndGraphEntry { |
| public PlanAndGraphEntry(P plan, DotGraph dotGraph) { |
| this.plan = plan ; |
| this.dotGraph = dotGraph ; |
| } |
| public P plan ; |
| public DotGraph dotGraph ; |
| } |
| |
| /*** |
| * This method has be overridden to instantiate the correct vertex type |
| * |
| * @param node |
| * @param plan |
| * @return |
| */ |
| protected abstract E createOperator(DotNode node, P plan) ; |
| |
| //////////////// Helpers ////////////////// |
| |
| /*** |
| * Construct the plan based on the given Dot graph |
| * |
| * @param graph |
| * @return |
| */ |
| |
| P constructPlan(DotGraph graph, Class<P> clazz) { |
| |
| P plan ; |
| Map<String, E> nameMap = new HashMap<String, E>() ; |
| |
| try { |
| plan = clazz.newInstance() ; |
| } |
| catch (IllegalAccessException iae) { |
| throw new AssertionError("Cannot instantiate a plan") ; |
| } |
| catch (InstantiationException ie) { |
| throw new AssertionError("Cannot instantiate a plan") ; |
| } |
| |
| for(DotNode node: graph.nodes) { |
| E op = createOperator(node, plan) ; |
| nameMap.put(node.name, op) ; |
| plan.add(op); |
| } |
| |
| for(DotEdge edge: graph.edges) { |
| E fromOp = nameMap.get(edge.fromNode) ; |
| E toOp = nameMap.get(edge.toNode) ; |
| try { |
| plan.connect(fromOp, toOp); |
| } |
| catch (PlanException pe) { |
| throw new RuntimeException("Invalid Dot file") ; |
| } |
| } |
| |
| return plan ; |
| } |
| |
| |
| /*** |
| * Helper for retrieving operator key from encoded attributes. |
| * By default, it will look for "key" in attributes. |
| * If no key is found, an arbitrary one will be generated. |
| * @param attributes |
| * @return |
| */ |
| protected OperatorKey getKey(Map<String,String> attributes) { |
| String key = attributes.get("key") ; |
| if (key != null) { |
| return new OperatorKey("scope", Long.parseLong(key)) ; |
| } |
| else { |
| long newId = NodeIdGenerator.getGenerator().getNextNodeId("scope") ; |
| return new OperatorKey("scope", newId) ; |
| } |
| } |
| |
| } |