View Javadoc

1   /*
2    WSMO Studio - a Semantic Web Service Editor
3    Copyright (c) 2004-2006, Ontotext Lab. / SIRMA Group
4    
5    This library is free software; you can redistribute it and/or modify it under
6    the terms of the GNU Lesser General Public License as published by the Free
7    Software Foundation; either version 2.1 of the License, or (at your option)
8    any later version.
9    This library is distributed in the hope that it will be useful, but WITHOUT
10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   details.
13   You should have received a copy of the GNU Lesser General Public License along
14   with this library; if not, write to the Free Software Foundation, Inc.,
15   59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16   */
17  
18  package org.wsmostudio.bpmo.ui.editor.layout;
19  
20  import giny.model.RootGraph;
21  
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.HashMap;
25  import java.util.Map;
26  
27  import org.eclipse.draw2d.geometry.Dimension;
28  import org.eclipse.draw2d.geometry.Point;
29  import org.wsmostudio.bpmo.model.WorkflowEntitiesContainer;
30  import org.wsmostudio.bpmo.model.WorkflowEntityNode;
31  import org.wsmostudio.bpmo.model.blockpatterns.BlockPatternNode;
32  import org.wsmostudio.bpmo.model.connectors.GraphConnector;
33  
34  import phoebe.PNodeView;
35  
36  import cytoscape.giny.CytoscapeFingRootGraph;
37  import cytoscape.giny.FingCyNetwork;
38  import cytoscape.giny.PhoebeNetworkView;
39  import cytoscape.layout.AbstractLayout;
40  
41  
42  /***
43   *@author Luchesar Cekov
44   */
45  class EntityContainerLayouter {
46      private HashMap<WorkflowEntityNode, Integer> workflowEntity2nodeIndex = new HashMap<WorkflowEntityNode, Integer>();
47      private HashMap<Integer, WorkflowEntityNode> nodeIndex2workFlowEntity = new HashMap<Integer, WorkflowEntityNode>();    
48      private AbstractLayout layoutAlgoritm;
49      
50      EntityContainerLayouter(AbstractLayout aLayoutAlgoritm) {
51          layoutAlgoritm = aLayoutAlgoritm;
52      }
53      
54      @SuppressWarnings("deprecation")
55      public  void layout(WorkflowEntitiesContainer entityContainer) {
56          Collection<WorkflowEntityNode> workFlows = entityContainer.listWorkflows();
57          if (workFlows.size() == 0) {
58              entityContainer.setSize(entityContainer.getPreferredSize());
59              return;
60          }
61                         
62          for (WorkflowEntityNode entity : workFlows) {
63              if (entity instanceof WorkflowEntitiesContainer) {
64                  new EntityContainerLayouter(layoutAlgoritm).layout((WorkflowEntitiesContainer)entity);                
65              }
66          }
67                   
68          Collection<WorkflowEntityNode> layoutEntities = workFlows;
69          if (entityContainer instanceof BlockPatternNode) {
70              layoutEntities = new ArrayList<WorkflowEntityNode>(workFlows.size() + 2);
71              layoutEntities.addAll(workFlows);
72              layoutEntities.add(((BlockPatternNode)entityContainer).getStartNode());
73              layoutEntities.add(((BlockPatternNode)entityContainer).getEndNode());
74          } 
75          
76          final PhoebeNetworkView view = layout(layoutEntities);
77          
78          if (entityContainer instanceof BlockPatternNode) {        
79              layoutEntities.remove(((BlockPatternNode)entityContainer).getStartNode());
80              layoutEntities.remove(((BlockPatternNode)entityContainer).getEndNode());
81          }
82          
83          entityContainer.setSize(setEntitySize(layoutEntities, view));
84      }
85  
86      private PhoebeNetworkView layout(Collection<WorkflowEntityNode> workFlows) {
87          CytoscapeFingRootGraph root = new CytoscapeFingRootGraph();
88  
89          for (WorkflowEntityNode entity : workFlows) {
90              int conceptIndex = createNode(root, entity);
91              addSubConcepts(root, entity, conceptIndex);
92          }
93  
94          FingCyNetwork fingCyNetwork = new FingCyNetwork(root, new IntIteratorImpl(root
95                  .getNodeIndicesArray()), new IntIteratorImpl(root.getEdgeIndicesArray()));
96          final PhoebeNetworkView view = new PhoebeNetworkView(fingCyNetwork, "");
97          setNodeSize(view);
98          layoutAlgoritm.doLayout(view);
99          view.updateView();
100         return view;
101     }
102 
103     private Dimension setEntitySize(Collection<WorkflowEntityNode> workFlowEntries, final PhoebeNetworkView view) {
104         int maxX = 0;
105         int maxY = 0;
106         for (WorkflowEntityNode entrie : workFlowEntries) {
107             PNodeView nodeView = (PNodeView) view.getNodeView(workflowEntity2nodeIndex.get(entrie));            
108             int locationX = (int) Math.round(nodeView.getXPosition());
109             int locationY = (int) Math.round(nodeView.getYPosition());
110             
111             maxX = Math.max(maxX, locationY + (int)nodeView.getHeight());
112             maxY = Math.max(maxY, locationX + (int)nodeView.getWidth());
113             
114             entrie.setLocation(new Point(locationY, locationX));            
115         }
116         return new Dimension(maxX + 40, maxY + 40);
117     }
118 
119     private void setNodeSize(final PhoebeNetworkView view) {
120         for (Map.Entry<WorkflowEntityNode, Integer> entry : workflowEntity2nodeIndex.entrySet()) {
121             PNodeView nv = (PNodeView) view.getNodeView(entry.getValue());            
122             nv.setHeight(entry.getKey().getSize().width);
123             nv.setWidth(entry.getKey().getSize().height);
124         }
125     }
126     
127     private int createNode(RootGraph root, WorkflowEntityNode entity) {
128         Integer index = workflowEntity2nodeIndex.get(entity);
129         if (index != null) {
130             return index;
131         }
132         index = root.createNode();
133         workflowEntity2nodeIndex.put(entity, index);
134         nodeIndex2workFlowEntity.put(index, entity);
135         return index;
136     }
137 
138     private void addSubConcepts(RootGraph root, WorkflowEntityNode entity, int conceptIndex) {
139         for (GraphConnector connector : entity.listOutArcs()) {
140             Integer targetIndex = workflowEntity2nodeIndex.get(connector.getTarget());
141             if (targetIndex != null) {
142                 root.createEdge(conceptIndex, targetIndex);
143                 continue;
144             }
145             targetIndex = createNode(root, connector.getTarget());                        
146             root.createEdge(conceptIndex, targetIndex);
147             addSubConcepts(root, connector.getTarget(), targetIndex);
148         }
149     }
150 
151 }
152 
153 
154 /*$Log$
155  *Revision 1.3  2007/08/17 14:42:41  alex_simov
156  *gui model update
157  *
158 /*Revision 1.2  2007/08/01 15:47:25  alex_simov
159 /*ui model refactoring: classnames are suffixed by "Node" to avoid name
160 /*clashes with BPMO-API entities
161 /*
162 /*Revision 1.1  2007/06/26 13:34:29  lcekov
163 /*Add Layout functionality to imported from wsml BPMO models
164 /*
165 */