View Javadoc

1   package org.molwind.graph;
2   
3   /*
4    * This file is part of Molwind.
5    *
6    * Molwind is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * Molwind is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with Molwind. If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  import java.util.HashMap;
21  import java.util.Iterator;
22  import java.util.Map;
23  import java.util.Collection;
24  import java.util.Vector;
25  import java.io.IOException;
26  import java.io.StringWriter;
27  import java.lang.Double;
28  import java.awt.geom.Point2D;
29  import java.awt.Color;
30  import java.awt.Paint;
31  
32  import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
33  
34  
35  
36  import org.molwind.model.Relationship;
37  import org.molwind.model.WorldEntity;
38  import org.molwind.model.PlacedWorldEntity;
39  
40  
41  import org.apache.commons.collections15.Transformer;
42  import org.apache.commons.collections15.TransformerUtils;
43  
44  import edu.uci.ics.jung.graph.SparseGraph;
45  import edu.uci.ics.jung.graph.DirectedSparseGraph;
46  import edu.uci.ics.jung.graph.DelegateTree;
47  import edu.uci.ics.jung.graph.DelegateForest;
48  import edu.uci.ics.jung.io.GraphMLWriter;
49  import edu.uci.ics.jung.graph.util.Pair;
50  import edu.uci.ics.jung.graph.util.EdgeType;
51  
52  import edu.uci.ics.jung.algorithms.layout.CircleLayout;
53  import edu.uci.ics.jung.algorithms.layout.StaticLayout;
54  import edu.uci.ics.jung.algorithms.layout.SpringLayout2;
55  import edu.uci.ics.jung.algorithms.layout.AggregateLayout;
56  import edu.uci.ics.jung.algorithms.layout.KKLayout;
57  import edu.uci.ics.jung.algorithms.layout.ISOMLayout;
58  import edu.uci.ics.jung.algorithms.layout.BalloonLayout ;
59  
60  import edu.uci.ics.jung.graph.Graph; 
61  import edu.uci.ics.jung.visualization.BasicVisualizationServer;
62  import javax.swing.JFrame;
63  import java.awt.Dimension;
64  
65  
66  
67  /**
68   * DefaultEntityGraph implements an EntityGraph using the JUNG graph lib.
69   *
70   * @author <a href="mailto:oliver.karch@molwind.org">Oliver Karch</a>
71   * @version 1.0
72   */
73  public class DefaultEntityGraph implements EntityGraph {
74  
75      private SparseGraph graph;
76      private HashMap entities;
77      private Vector<Vector<EntityVertex>> graphInLayers;
78      
79    
80  
81      
82  
83  
84      /**
85       * Get the Graph value.
86       * @return the Graph value.
87       */
88      public SparseGraph<EntityVertex,EntityEdge> getGraph() {
89  	//	graphInLayers = devideLayers();
90  	return graph;
91      }
92  
93      /**
94       * Set the Graph value.
95       * @param newGraph The new Graph value.
96       */
97      public void setGraph(SparseGraph newGraph) {
98  	this.graph = newGraph;
99  	
100     }
101 
102     
103 
104     /**
105      * Creates a new (empty) graph of entities.
106      */
107     public DefaultEntityGraph() {
108         graph = new SparseGraph<EntityVertex,EntityEdge>();
109         entities = new HashMap();
110 	
111     }
112 
113   
114 
115     /**
116      * Adds an entity i.e. vertex to graph. If the vertex id is existing
117      * already the vertex is replaced.
118      *
119      * @param vertexId
120      *      the vertex id
121      * @param entity
122      *      the entity to add
123      */
124     public void addEntity(final String vertexId, final WorldEntity entity) {
125         DefaultEntityVertex vertex =
126             (DefaultEntityVertex) entities.get(vertexId);
127 
128         if (vertex== null) {
129             vertex = new DefaultEntityVertex();
130             vertex.setId(vertexId);
131             entities.put(vertexId, vertex);
132             graph.addVertex((Object)vertex);
133         }
134 
135         vertex.setEntity(entity);
136     }
137 
138     /**
139      * Finds the given vertex id.
140      *
141      * @param vertexId
142      *      the vertex id
143      * @return
144      *      the entity if it was found, null otherwise
145      */
146     public WorldEntity findEntity(final String vertexId) {
147         EntityVertex vertex = (EntityVertex) entities.get(vertexId);
148 
149         if (vertex != null) {
150             return vertex.getEntity();
151         }
152 
153         return null;
154     }
155 
156     /**
157      * Adds a relationship edge between vertex vertexId1 and vertex vertexId2.
158      * For any non-existing vertex a new vertex is created.
159      *
160      * @param vertexId1
161      *      the first vertex id
162      * @param vertexId2
163      *      the second vertex id
164      * @param relation
165      *      the relationship represented by the edge
166      */
167     public void addEdge(final String vertexId1, final String vertexId2,
168 			final Relationship relation,int weight) {
169         DefaultEntityVertex vertex1 =
170             (DefaultEntityVertex) entities.get(vertexId1);
171 
172         if (vertex1 == null) {
173             vertex1 = new DefaultEntityVertex();
174             vertex1.setId(vertexId1);
175             entities.put(vertexId1, vertex1);
176             graph.addVertex(vertex1);
177         }
178 
179         DefaultEntityVertex vertex2 =
180             (DefaultEntityVertex) entities.get(vertexId2);
181 
182         if (vertex2 == null) {
183             vertex2 = new DefaultEntityVertex();
184             vertex2.setId(vertexId2);
185             entities.put(vertexId2, vertex2);
186             graph.addVertex(vertex2);
187         }
188 	Pair<EntityVertex> endpoints = new Pair<EntityVertex>(vertex1,vertex2);
189 	
190         DefaultEntityEdge edge = new DefaultEntityEdge(vertex1, vertex2);
191         edge.setRelationship(relation);
192 	edge.setEdgeWeight(weight);
193 	
194         graph.addEdge(edge,endpoints,EdgeType.DIRECTED);
195     }
196     
197 
198 
199     /**
200      * Analyzes the entity graph using the given analysis strategy.
201      *
202      * @param analyzer
203      *      the analysis strategy
204      */
205     public void analyze(final EntityGraphAnalyzer analyzer) {
206         Iterator it = entities.entrySet().iterator();
207 	
208         while (it.hasNext()) {
209             Map.Entry entry = (Map.Entry) it.next();
210             EntityVertex vertex = (EntityVertex) entry.getValue();
211 	    
212 
213             if (!analyzer.analyze(this, vertex)) {
214                 break;
215             }
216         }
217     }
218     
219     private boolean checkParent(EntityVertex entity,Vector<EntityVertex> vertexVector){
220 	for(EntityVertex tmp:vertexVector){
221 	    if(tmp.getEntity().getAttribute("Index").equals(entity.getEntity().getAttribute("Mother")))
222 		return true;
223 	}
224 	return false;
225     
226     }
227     
228     /**
229      * Gives the count of Layers for the allocation levels
230      *
231      * @return 
232      *      layer count
233      *
234      */
235     public int getLayerCount(){
236 	return graphInLayers.size();
237     
238     }
239     
240     
241     /**
242      * Get all vertices for the given layer
243      * @param 
244      *    the layer number
245      * @return
246      *    an array with the vertices belonging to the layer
247      */
248     public EntityVertex[] getLayer(int layer){
249    
250 	
251 	Vector<EntityVertex> result=graphInLayers.get(layer);
252 	
253 	EntityVertex[] resultArray = new EntityVertex[result.size()];
254 	int i = 0;
255 	for(EntityVertex vertex:result){
256 	    resultArray[i]= vertex;
257 	    i++;
258 	}
259 	
260 
261         return resultArray;
262     
263     }
264     
265   
266      /**
267      *
268      * Devides the graph into Layers
269      *
270      */
271     public void  devideLayers(){
272 	Vector<Vector<EntityVertex>> result = new Vector<Vector<EntityVertex>>();
273 	Vector<EntityVertex> notChecked = new Vector<EntityVertex>();
274 	Vector<EntityVertex> layer = new Vector<EntityVertex>();
275 	Vector<EntityVertex> nextLayer;
276 	Iterator it = iterator();
277 	while(it.hasNext()){
278 	    Map.Entry entry = (Map.Entry)it.next();
279 	    EntityVertex vertex =(EntityVertex)entry.getValue();
280 	    PlacedWorldEntity entity =(PlacedWorldEntity) vertex.getEntity();
281 	    
282 	    String parentId =(String) entity.getAttribute("Mother");
283 	    if(parentId.equals("0")){
284 		layer.add(vertex);
285 	    }
286 	    else
287 		notChecked.add(vertex);
288 	}
289 	result.add(layer);
290 	while(!notChecked.isEmpty()){
291 	    nextLayer = new Vector<EntityVertex>();
292 	    for(EntityVertex entity:notChecked){
293 		if(checkParent(entity,layer)){
294 		    nextLayer.add(entity);
295 		}
296 	    }
297 	    
298 	    for(EntityVertex entity:nextLayer){
299 		notChecked.remove(entity);
300 	    }
301 	    layer=nextLayer;
302 	    result.add(layer);
303 	
304 	    
305 	}
306 	for(int i = 0;i<result.size();i++){
307 	    for(EntityVertex v:result.get(i)){
308 		PlacedWorldEntity entity =(PlacedWorldEntity) v.getEntity();
309 	
310 		entity.setLayer(i);
311 	    }
312 	    
313 	}
314 	
315 	graphInLayers = result;
316 	
317 
318     
319        
320     
321     }
322     
323    
324 
325     /**
326      * Returns an iterator over a set of elements.
327      *
328      * @return
329      *      an Iterator
330      */
331     public Iterator iterator() {
332         return entities.entrySet().iterator();
333     }
334 
335     /**
336      * Writes a graph ml representation of this graph
337      *
338      * @return a human readable string
339      */
340     public String toString() {
341 	GraphMLWriter gml = new GraphMLWriter();
342 	StringWriter sw = new StringWriter();
343 	try {
344 	    gml.save( graph, sw );
345 	}
346 	catch( IOException ioe ) {
347 	    ioe.printStackTrace();
348 	}
349 	return sw.toString();
350     }
351     
352     
353 
354    
355     
356 
357    
358     
359     /**
360      *
361      * Visualizes the Graph
362      * 
363      * @param
364      *       the size of the Frame
365      */
366     public void viewGraph(int size){
367 
368 // 	Transformer<EntityEdge,Integer> transformer = new Transformer<EntityEdge,Integer>(){
369 	
370 // 	    public Integer transform(EntityEdge edge){
371 // 		return edge.getEdgeWeight();
372 // 	    }
373 // 	};
374 
375 // 	Transformer<EntityVertex,Point2D> tr = new Transformer<EntityVertex,Point2D>(){
376 // 	    public Point2D.Double transform(EntityVertex vertex){
377 // 		return vertex.getPosition();
378 // 	    }
379 	
380 // 	};
381 	
382 // 	Transformer<EntityVertex,Paint> vertexPaint = new Transformer<EntityVertex,Paint>() {
383 // 	    public Paint transform(EntityVertex vertex) {
384 // 		return Color.GREEN;
385 // 	    }
386 // 	};
387 	
388 // 	//TODO for testing the 2 layers below
389 // 	//later iteration over the whole graphInLayers vector
390 // 	EntityVertex[] pLayer = getLayer(0);
391 // 	EntityVertex[] chLayer =getLayer(1);
392 
393 // 	SparseGraph<EntityVertex,EntityEdge> parentGraph = new SparseGraph<EntityVertex,EntityEdge>();
394 
395 // 	for(int i = 0;i<pLayer.length;i++){
396 // 	    parentGraph.addVertex(pLayer[i]);
397 // 	    for(int j = i+1;j<pLayer.length;j++){
398 // 		Pair<EntityVertex> endpoints = new Pair<EntityVertex>(pLayer[i],pLayer[j]);
399 // 		int edgeWeight = pLayer[i].getEntity().getDimension()+ pLayer[j].getEntity().getDimension();
400 // 		DefaultEntityEdge edge = new DefaultEntityEdge(pLayer[i],pLayer[j],edgeWeight);
401 // 		parentGraph.addEdge(edge,endpoints,EdgeType.DIRECTED);
402 		
403 // 		    //parentGraph.addEdge(endpoints,EdgeType.DIRECTED);
404 // 	    }
405 		    
406 // 	}
407 // 	//Spring layout for the parent coordinates
408 
409 
410 // 	DelegateForest<EntityVertex,EntityEdge> forest = getForest(pLayer,chLayer);
411 // 	BalloonLayout<EntityVertex,EntityEdge> bLayout = new BalloonLayout<EntityVertex,EntityEdge>(forest);
412 	
413 // 	SpringLayout2<EntityVertex,EntityEdge> springLayout = new SpringLayout2<EntityVertex,EntityEdge>(parentGraph,transformer);
414 // 	//	springLayout.setStretch(0.05);
415 // 	springLayout.setRepulsionRange(200);
416 // 	springLayout.setSize(new Dimension(size,size));
417 // 	for(EntityVertex v:forest.getVertices())
418 // 	    v.setPosition((Point2D.Double)bLayout.transform(v));
419 // 	springLayout.initialize();
420 // 	BasicVisualizationServer basicVisualizationServer = new BasicVisualizationServer(springLayout);
421 // 	for(int i = 0;i<1000;i++)
422 // 	    springLayout.step();
423 // 	springLayout.done();
424 // 	springLayout.lock(true);
425 	
426 	
427 
428 	
429 
430 // 	for(EntityVertex v :pLayer){
431 // 	    Point2D.Double point = (Point2D.Double)springLayout.transform(v);
432 	 
433 // 	     v.setPosition(point);
434 // 	}
435 	
436 // // 	for(EntityVertex vertex:forest.getVertices()){
437 // // 	    PlacedWorldEntity entity = (PlacedWorldEntity)vertex.getEntity();
438 // // 	    entity.setDeltaX(100);
439 // // 	    entity.setDeltaY(-100);
440 // // 	}
441 	
442 		
443 	Transformer<EntityVertex,Paint> vertexPaint = new Transformer<EntityVertex,Paint>() {
444 	    public Paint transform(EntityVertex vertex) {
445 		return Color.GREEN;
446 	    }
447 	};
448 
449 
450 	Transformer<EntityVertex,Point2D> tr = new Transformer<EntityVertex,Point2D>(){
451 	    public Point2D.Double transform(EntityVertex vertex){
452 		return vertex.getPosition();
453 	    }
454 	
455 	};
456 
457 	StaticLayout<EntityVertex,EntityEdge> stLayout = new StaticLayout<EntityVertex,EntityEdge>(graph, tr);
458 	BasicVisualizationServer vv2 = new BasicVisualizationServer(stLayout);
459 	vv2.setPreferredSize(new Dimension(size, size)); //Sets the viewing area size
460 	vv2.getRenderContext().setVertexFillPaintTransformer(vertexPaint);
461 	vv2.setPreferredSize(new Dimension(size, size)); //Sets the viewing area size
462 	vv2.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<EntityVertex>());
463 	
464 	JFrame frame = new JFrame("Simple Graph View");
465 	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
466 	frame.getContentPane().add(vv2);
467 	frame.pack();
468 	frame.setVisible(true);
469 	
470     }
471     
472     
473     
474    
475   
476     
477     
478 
479 	
480     
481 }