    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  }