Initial opendaylight infrastructure commit!!
[controller.git] / third-party / net.sf.jung2 / src / main / java / edu / uci / ics / jung / algorithms / layout / AggregateLayout.java
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/AggregateLayout.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/AggregateLayout.java
new file mode 100644 (file)
index 0000000..3805837
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ * 
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ * 
+ * 
+ * 
+ */
+package edu.uci.ics.jung.algorithms.layout;
+
+import java.awt.Dimension;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.algorithms.util.IterativeContext;
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * A {@code Layout} implementation that combines 
+ * multiple other layouts so that they may be manipulated
+ * as one layout. The relaxer thread will step each layout
+ * in sequence.
+ * 
+ * @author Tom Nelson - tomnelson@dev.java.net
+ *
+ * @param <V> the vertex type
+ * @param <E> the edge type
+ */
+public class AggregateLayout<V, E> implements Layout<V,E>, IterativeContext {
+
+       protected Layout<V,E> delegate;
+       protected Map<Layout<V,E>,Point2D> layouts = new HashMap<Layout<V,E>,Point2D>();
+
+       /**
+        * Creates an instance backed by the specified {@code delegate}.
+        * @param delegate
+        */
+       public AggregateLayout(Layout<V, E> delegate) {
+               this.delegate = delegate;
+       }
+
+       /**
+        * @return the delegate
+        */
+       public Layout<V, E> getDelegate() {
+               return delegate;
+       }
+
+       /**
+        * @param delegate the delegate to set
+        */
+       public void setDelegate(Layout<V, E> delegate) {
+               this.delegate = delegate;
+       }
+
+       /**
+        * adds the passed layout as a sublayout, also specifying
+        * the center of where this sublayout should appear
+        * @param layout
+        * @param center
+        */
+       public void put(Layout<V,E> layout, Point2D center) {
+               layouts.put(layout,center);
+       }
+       
+       /**
+        * Returns the center of the passed layout.
+        * @param layout
+        * @return the center of the passed layout
+        */
+       public Point2D get(Layout<V,E> layout) {
+               return layouts.get(layout);
+       }
+       
+       /**
+        * Removes {@code layout} from this instance.
+        */
+       public void remove(Layout<V,E> layout) {
+               layouts.remove(layout);
+       }
+       
+       /**
+        * Removes all layouts from this instance.
+        */
+       public void removeAll() {
+               layouts.clear();
+       }
+       
+       /**
+        * Returns the graph for which this layout is defined.
+        * @return the graph for which this layout is defined
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#getGraph()
+        */
+       public Graph<V, E> getGraph() {
+               return delegate.getGraph();
+       }
+
+       /**
+        * Returns the size of the underlying layout.
+        * @return the size of the underlying layout
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#getSize()
+        */
+       public Dimension getSize() {
+               return delegate.getSize();
+       }
+
+       /**
+        * 
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#initialize()
+        */
+       public void initialize() {
+               delegate.initialize();
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       layout.initialize();
+               }
+       }
+
+       /**
+        * Override to test if the passed vertex is locked in
+        * any of the layouts.
+        * @param v
+        * @return true if v is locked in any of the layouts, and false otherwise
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#isLocked(java.lang.Object)
+        */
+       public boolean isLocked(V v) {
+               boolean locked = false;
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       locked |= layout.isLocked(v);
+               }
+               locked |= delegate.isLocked(v);
+               return locked;
+       }
+
+       /**
+        * override to lock or unlock this vertex in any layout with
+        * a subgraph containing it
+        * @param v
+        * @param state
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#lock(java.lang.Object, boolean)
+        */
+       public void lock(V v, boolean state) {
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       if(layout.getGraph().getVertices().contains(v)) {
+                               layout.lock(v, state);
+                       }
+               }
+               delegate.lock(v, state);
+       }
+
+       /**
+        * 
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#reset()
+        */
+       public void reset() {
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       layout.reset();
+               }
+               delegate.reset();
+       }
+
+       /**
+        * @param graph
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#setGraph(edu.uci.ics.jung.graph.Graph)
+        */
+       public void setGraph(Graph<V, E> graph) {
+               delegate.setGraph(graph);
+       }
+
+       /**
+        * @param initializer
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#setInitializer(org.apache.commons.collections15.Transformer)
+        */
+       public void setInitializer(Transformer<V, Point2D> initializer) {
+               delegate.setInitializer(initializer);
+       }
+
+       /**
+        * @param v
+        * @param location
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#setLocation(java.lang.Object, java.awt.geom.Point2D)
+        */
+       public void setLocation(V v, Point2D location) {
+               boolean wasInSublayout = false;
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       if(layout.getGraph().getVertices().contains(v)) {
+                               Point2D center = layouts.get(layout);
+                               // transform by the layout itself, but offset to the
+                               // center of the sublayout
+                               Dimension d = layout.getSize();
+
+                               AffineTransform at = 
+                                       AffineTransform.getTranslateInstance(-center.getX()+d.width/2,-center.getY()+d.height/2);
+                               Point2D localLocation = at.transform(location, null);
+                               layout.setLocation(v, localLocation);
+                               wasInSublayout = true;
+                       }
+               }
+               if(wasInSublayout == false && getGraph().getVertices().contains(v)) {
+                       delegate.setLocation(v, location);
+               }
+       }
+
+       /**
+        * @param d
+        * @see edu.uci.ics.jung.algorithms.layout.Layout#setSize(java.awt.Dimension)
+        */
+       public void setSize(Dimension d) {
+               delegate.setSize(d);
+       }
+       
+       /**
+        * Returns a map from each {@code Layout} instance to its center point.
+        */
+       public Map<Layout<V,E>,Point2D> getLayouts() {
+               return layouts;
+       }
+
+       /**
+        * Returns the location of the vertex.  The location is specified first
+        * by the sublayouts, and then by the base layout if no sublayouts operate
+        * on this vertex.
+        * @return the location of the vertex
+        * @see org.apache.commons.collections15.Transformer#transform(java.lang.Object)
+        */
+       public Point2D transform(V v) {
+               boolean wasInSublayout = false;
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       if(layout.getGraph().getVertices().contains(v)) {
+                               wasInSublayout = true;
+                               Point2D center = layouts.get(layout);
+                               // transform by the layout itself, but offset to the
+                               // center of the sublayout
+                               Dimension d = layout.getSize();
+                               AffineTransform at = 
+                                       AffineTransform.getTranslateInstance(center.getX()-d.width/2,
+                                                       center.getY()-d.height/2);
+                               return at.transform(layout.transform(v),null);
+                       }
+               }
+               if(wasInSublayout == false) {
+                       return delegate.transform(v);
+               }
+               return null;
+       
+       }
+
+       /**
+        * Check all sublayouts.keySet() and the delegate layout, returning
+        * done == true iff all are done.
+        */
+       public boolean done() {
+               boolean done = true;
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       if(layout instanceof IterativeContext) {
+                               done &= ((IterativeContext)layout).done();
+                       }
+               }
+               if(delegate instanceof IterativeContext) {
+                       done &= ((IterativeContext)delegate).done();
+               }
+               return done;
+       }
+
+       /**
+        * call step on any sublayout that is also an IterativeContext
+        * and is not done
+        */
+       public void step() {
+               for(Layout<V,E> layout : layouts.keySet()) {
+                       if(layout instanceof IterativeContext) {
+                               IterativeContext context = (IterativeContext)layout;
+                               if(context.done() == false) {
+                                       context.step();
+                               }
+                       }
+               }
+               if(delegate instanceof IterativeContext) {
+                       IterativeContext context = (IterativeContext)delegate;
+                       if(context.done() == false) {
+                               context.step();
+                       }
+               }
+       }
+       
+}