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  }