001/* 002 * Copyright (c) 2007-2016 Concurrent, Inc. All Rights Reserved. 003 * 004 * Project and contact information: http://www.cascading.org/ 005 * 006 * This file is part of the Cascading project. 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020 021package cascading.flow.planner.graph; 022 023import java.io.Serializable; 024import java.util.Collection; 025import java.util.Collections; 026import java.util.IdentityHashMap; 027import java.util.List; 028import java.util.Set; 029 030import cascading.flow.FlowElement; 031import cascading.flow.planner.Scope; 032import cascading.util.Util; 033import org.jgrapht.DirectedGraph; 034import org.jgrapht.Graphs; 035import org.jgrapht.graph.SimpleDirectedGraph; 036 037/** 038 * 039 */ 040public abstract class BaseElementGraph implements ElementGraph, Serializable 041 { 042 public static final ElementGraph NULL = new BaseElementGraph( new SimpleDirectedGraph<FlowElement, Scope>( Scope.class ) ) 043 { 044 @Override 045 public ElementGraph copyElementGraph() 046 { 047 return null; 048 } 049 }; 050 051 protected DirectedGraph<FlowElement, Scope> graph; 052 053 public BaseElementGraph() 054 { 055 } 056 057 public BaseElementGraph( DirectedGraph<FlowElement, Scope> graph ) 058 { 059 this.graph = graph; 060 } 061 062 protected void copyFrom( BaseElementGraph elementGraph ) 063 { 064 Graphs.addAllVertices( graph, elementGraph.vertexSet() ); 065 Graphs.addAllEdges( graph, elementGraph.graph, elementGraph.edgeSet() ); 066 } 067 068 public boolean containsEdge( FlowElement sourceVertex, FlowElement targetVertex ) 069 { 070 return graph.containsEdge( sourceVertex, targetVertex ); 071 } 072 073 public boolean removeAllEdges( Collection<? extends Scope> edges ) 074 { 075 return graph.removeAllEdges( edges ); 076 } 077 078 public Set<Scope> removeAllEdges( FlowElement sourceVertex, FlowElement targetVertex ) 079 { 080 return graph.removeAllEdges( sourceVertex, targetVertex ); 081 } 082 083 public boolean removeAllVertices( Collection<? extends FlowElement> vertices ) 084 { 085 return graph.removeAllVertices( vertices ); 086 } 087 088 public Set<Scope> getAllEdges( FlowElement sourceVertex, FlowElement targetVertex ) 089 { 090 return graph.getAllEdges( sourceVertex, targetVertex ); 091 } 092 093 public Scope getEdge( FlowElement sourceVertex, FlowElement targetVertex ) 094 { 095 return graph.getEdge( sourceVertex, targetVertex ); 096 } 097 098 public Scope addEdge( FlowElement sourceVertex, FlowElement targetVertex ) 099 { 100 return graph.addEdge( sourceVertex, targetVertex ); 101 } 102 103 public boolean addEdge( FlowElement sourceVertex, FlowElement targetVertex, Scope scope ) 104 { 105 return graph.addEdge( sourceVertex, targetVertex, scope ); 106 } 107 108 @Override 109 public boolean addHeadVertex( FlowElement flowElement ) 110 { 111 if( !graph.containsVertex( Extent.head ) ) 112 graph.addVertex( Extent.head ); 113 114 if( flowElement == Extent.head ) 115 return false; 116 117 boolean result = true; 118 119 if( !graph.containsVertex( flowElement ) ) 120 result = graph.addVertex( flowElement ); 121 122 return result && graph.addEdge( Extent.head, flowElement ) != null; 123 } 124 125 @Override 126 public boolean addTailVertex( FlowElement flowElement ) 127 { 128 if( !graph.containsVertex( Extent.tail ) ) 129 graph.addVertex( Extent.tail ); 130 131 if( flowElement == Extent.tail ) 132 return false; 133 134 boolean result = true; 135 136 if( !graph.containsVertex( flowElement ) ) 137 result = graph.addVertex( flowElement ); 138 139 return result && graph.addEdge( flowElement, Extent.tail ) != null; 140 } 141 142 public boolean addVertex( FlowElement flowElement ) 143 { 144 return graph.addVertex( flowElement ); 145 } 146 147 public FlowElement getEdgeSource( Scope scope ) 148 { 149 return graph.getEdgeSource( scope ); 150 } 151 152 public FlowElement getEdgeTarget( Scope scope ) 153 { 154 return graph.getEdgeTarget( scope ); 155 } 156 157 public boolean containsEdge( Scope scope ) 158 { 159 return graph.containsEdge( scope ); 160 } 161 162 public boolean containsVertex( FlowElement flowElement ) 163 { 164 return graph.containsVertex( flowElement ); 165 } 166 167 public Set<Scope> edgeSet() 168 { 169 return graph.edgeSet(); 170 } 171 172 public Set<Scope> edgesOf( FlowElement vertex ) 173 { 174 return graph.edgesOf( vertex ); 175 } 176 177 public int inDegreeOf( FlowElement vertex ) 178 { 179 return graph.inDegreeOf( vertex ); 180 } 181 182 public Set<Scope> incomingEdgesOf( FlowElement vertex ) 183 { 184 return graph.incomingEdgesOf( vertex ); 185 } 186 187 public int outDegreeOf( FlowElement vertex ) 188 { 189 return graph.outDegreeOf( vertex ); 190 } 191 192 public Set<Scope> outgoingEdgesOf( FlowElement vertex ) 193 { 194 return graph.outgoingEdgesOf( vertex ); 195 } 196 197 public Scope removeEdge( FlowElement sourceVertex, FlowElement targetVertex ) 198 { 199 return graph.removeEdge( sourceVertex, targetVertex ); 200 } 201 202 public boolean removeEdge( Scope scope ) 203 { 204 return graph.removeEdge( scope ); 205 } 206 207 public boolean removeVertex( FlowElement flowElement ) 208 { 209 return graph.removeVertex( flowElement ); 210 } 211 212 public Set<FlowElement> vertexSet() 213 { 214 return graph.vertexSet(); 215 } 216 217 @Override 218 public Set<FlowElement> vertexSetCopy() 219 { 220 Set<FlowElement> result = Collections.newSetFromMap( new IdentityHashMap<FlowElement, Boolean>() ); 221 222 result.addAll( vertexSet() ); 223 224 return result; 225 } 226 227 @Override 228 public List<FlowElement> predecessorListOf( FlowElement flowElement ) 229 { 230 return Graphs.predecessorListOf( graph, flowElement ); 231 } 232 233 @Override 234 public List<FlowElement> successorListOf( FlowElement flowElement ) 235 { 236 return Graphs.successorListOf( graph, flowElement ); 237 } 238 239 @Override 240 public void writeDOT( String filename ) 241 { 242 boolean success = ElementGraphs.printElementGraph( filename, this, null ); 243 244 if( success ) 245 Util.writePDF( filename ); 246 } 247 248 @Override 249 public boolean equals( Object object ) 250 { 251 return ElementGraphs.equals( this, (ElementGraph) object ); 252 } 253 254 @Override 255 public int hashCode() 256 { 257 int result = graph.hashCode(); 258 result = 31 * result; // parity with AnnotatedGraph types 259 return result; 260 } 261 }