View Javadoc

1   /*
2   * The contents of this file are subject to the BT "ZEUS" Open Source 
3   * Licence (L77741), Version 1.0 (the "Licence"); you may not use this file 
4   * except in compliance with the Licence. You may obtain a copy of the Licence
5   * from $ZEUS_INSTALL/licence.html or alternatively from
6   * http://www.labs.bt.com/projects/agents/zeus/licence.htm
7   * 
8   * Except as stated in Clause 7 of the Licence, software distributed under the
9   * Licence is distributed WITHOUT WARRANTY OF ANY KIND, either express or 
10  * implied. See the Licence for the specific language governing rights and 
11  * limitations under the Licence.
12  * 
13  * The Original Code is within the package zeus.*.
14  * The Initial Developer of the Original Code is British Telecommunications
15  * public limited company, whose registered office is at 81 Newgate Street, 
16  * London, EC1A 7AJ, England. Portions created by British Telecommunications 
17  * public limited company are Copyright 1996-9. All Rights Reserved.
18  * 
19  * THIS NOTICE MUST BE INCLUDED ON ANY COPY OF THIS FILE
20  */
21  
22  
23  
24  /******************************************************************************
25  * SocietyModel.java
26  *
27  * The underlying model for the Summary Task Graph
28  *****************************************************************************/
29  
30  package zeus.generator;
31  
32  import java.util.*;
33  import java.awt.*;
34  import javax.swing.*;
35  import javax.swing.event.*;
36  
37  import zeus.util.*;
38  import zeus.concepts.*;
39  import zeus.gui.*;
40  import zeus.gui.graph.*;
41  import zeus.generator.event.*;
42  import zeus.generator.agent.AcquaintanceModel;
43  
44  public class SocietyModel extends AbstractGraphModel
45                            implements AgentListener {
46  
47    static final int SUPERIORS    = 0;
48    static final int SUBORDINATES = 1;
49    static final int PEERS        = 2;
50    static final int COWORKERS    = 3;
51  
52    protected boolean           isNodeEditable  = false;
53  
54    protected GeneratorModel    genmodel   = null;
55    protected Hashtable         nodeTable  = new Hashtable();
56    protected EventListenerList listeners  = new EventListenerList();
57    protected int               view       = 0;
58    protected BitSet            links      =
59       new BitSet(AcquaintanceModel.RELATIONS_LIST.size());
60  
61    public SocietyModel(GeneratorModel genmodel, boolean isNodeEditable) {
62       this(genmodel);
63       this.isNodeEditable = isNodeEditable;
64    }
65    public SocietyModel(GeneratorModel genmodel) {
66       this.genmodel = genmodel;
67       genmodel.addAgentListener(this);
68       reset();
69    }
70  
71    public void reset() {
72       nodeTable.clear();
73       for(int i = 0; i < links.size(); i++ )
74          links.set(i);
75  
76       Acquaintance[] others;
77       AgentDescription[] agents = genmodel.getAgents();
78       for(int i = 0; i < agents.length; i++ )
79          nodeTable.put(agents[i].getName(),new GraphNode(agents[i]));
80  
81       GraphNode node1, node2;
82       String relation;
83       for(int i = 0; i < agents.length; i++ ) {
84          // create parent-child relations between nodes
85          node1 = (GraphNode)nodeTable.get(agents[i].getName());
86          others = agents[i].getAcquaintances();
87          for(int j = 0; j < others.length; j++ ) {
88             node2 = (GraphNode)nodeTable.get(others[j].getName());
89             relation = others[j].getRelation();
90             switch(Misc.whichPosition(relation,
91                AcquaintanceModel.RELATIONS_LIST)) {
92                case SUPERIORS:
93                     node2.addChild(node1);
94                     node1.addParent(node2);
95                     break;
96                case SUBORDINATES:
97                     node1.addChild(node2);
98                     node2.addParent(node1);
99                     break;
100               default:
101                    node1.addSibling(node2);
102                    node2.addSibling(node1);
103                    break;
104            }
105         }
106      }
107      fireGraphStructureChanged();
108   }
109 
110   public Enumeration nodes() {
111      return nodeTable.elements();
112   }
113 
114   public void setValue(GraphNode node, Object user_object) {
115      AgentDescription agent = (AgentDescription)node.getUserObject();
116      String agentId = agent.getName();
117      genmodel.setAgentIcon(agentId,(String)user_object);
118      fireChanged();
119   }
120 
121   public boolean isNodeEditable(GraphNode node) {
122      return isNodeEditable;
123   }
124 
125   public Color getLinkColor(GraphNode from, GraphNode to) {
126      int type;
127      if ( (type = getLinkType(from,to)) != -1 )
128         return getColor(type);
129      return Color.black;
130   }
131   public boolean isLinkVisible(GraphNode from, GraphNode to) {
132      int type;
133      if ( (type = getLinkType(from,to)) != -1 )
134         return links.get(type);
135      return false;
136   }
137   public Vector getViewRelations(GraphNode node) {
138      Vector output = new Vector();
139      // first compute from me to others
140      AgentDescription agent = (AgentDescription)node.getUserObject();
141      String base = agent.getName();
142      Acquaintance[] others = agent.getAcquaintances();
143      for(int j = 0; j < others.length; j++ ) {
144         if ( Misc.whichPosition(others[j].getRelation(),
145                 AcquaintanceModel.RELATIONS_LIST) == view )
146            output.addElement(nodeTable.get(others[j].getName()));
147      }
148 
149      // next compute from others to me
150      Enumeration enum = nodeTable.elements();
151      GraphNode node1;
152      while( enum.hasMoreElements() ) {
153         node1 = (GraphNode)enum.nextElement();
154         if ( node1 != node && !output.contains(node1) ) {
155            agent = (AgentDescription)node1.getUserObject();
156            others = agent.getAcquaintances();
157            for(int j = 0; j < others.length; j++ ) {
158               if ( others[j].getName().equals(base) &&
159 	           Misc.whichPosition(others[j].getRelation(),
160                       AcquaintanceModel.RELATIONS_LIST) == view )
161               output.addElement(node1);
162            }
163         }
164      }
165 
166      return output;
167   }
168 
169   protected int getLinkType(GraphNode node1, GraphNode node2) {
170      AgentDescription agent1 = (AgentDescription)node1.getUserObject();
171      AgentDescription agent2 = (AgentDescription)node2.getUserObject();
172      String agentId = agent2.getName();
173      Acquaintance[] others = agent1.getAcquaintances();
174      for(int j = 0; j < others.length; j++ ) {
175         if ( others[j].getName().equals(agentId) ) {
176            return Misc.whichPosition(others[j].getRelation(),
177                                      AcquaintanceModel.RELATIONS_LIST);
178         }
179      }
180      return -1;
181   }
182 
183   public Color   getColor(int type)      { return ColorManager.getColor(type); }
184   public boolean isLinkVisible(int type) { return links.get(type); }
185   public void    setView(int type)       { this.view = type; }
186   public int     getView()               { return view; }
187 
188   public void showLinks(int type, boolean state) {
189      if ( state )
190         links.set(type);
191      else
192         links.clear(type);
193   }
194 
195   public void removeNodes(GraphNode[] input) {
196      AgentDescription agent;
197      String agentId;
198      for(int i = 0; i < input.length; i++ ) {
199         agent = (AgentDescription)input[i].getUserObject();
200         agentId = agent.getName();
201         genmodel.removeAgent(agentId);
202         // fireGraphNodeRemoved(input[i]);
203      }
204      fireChanged();
205   }
206 
207   public void addNewNode()  {
208      genmodel.createNewAgent();
209   }
210 
211   public void addNodes(GraphNode[] input) {
212      if ( input == null || input.length == 0 ) return;
213 
214      AgentDescription agent;
215      String agentId;
216      for(int i = 0; i < input.length; i++ ) {
217         agent = (AgentDescription)input[i].getUserObject();
218         agentId = agent.getName();
219         if ( genmodel.containsAgent(agentId) )
220            genmodel.cloneAgent(agentId);
221         else
222            genmodel.addAgent(agent);
223      }
224      fireChanged();
225   };
226 
227   public void agentStateChanged(AgentChangeEvent evt) {
228      AgentDescription agent = evt.getAgent();
229      String agentId = agent.getName();
230      Acquaintance[] others;
231      String relation;
232 
233      GraphNode node1, node2;
234      switch(evt.getEventType()) {
235         case AgentChangeEvent.ADD:
236              node1 = new GraphNode(agent);
237              nodeTable.put(agentId,node1);
238              others = agent.getAcquaintances();
239              for(int j = 0; j < others.length; j++ ) {
240                 node2 = (GraphNode)nodeTable.get(others[j].getName());
241                 if ( node2 != null ) {
242 		   relation = others[j].getRelation();
243                    int position = Misc.whichPosition(relation,
244                       AcquaintanceModel.RELATIONS_LIST);
245                    switch( position ) {
246                       case SUPERIORS:
247                            node2.addChild(node1);
248                            node1.addParent(node2);
249                            fireGraphNodeStateChanged(node2);
250                            break;
251                       case SUBORDINATES:
252                            node1.addChild(node2);
253                            node2.addParent(node1);
254                            fireGraphNodeStateChanged(node2);
255                            break;
256                       default:
257                            node1.addSibling(node2);
258                            node2.addSibling(node1);
259                            fireGraphNodeStateChanged(node2);
260                            break;
261                    }
262                 }
263              }
264              fireGraphNodeAdded(node1);
265              break;
266 
267         case AgentChangeEvent.DELETE:
268              node1 = (GraphNode)nodeTable.remove(agentId);
269              Enumeration enum = nodeTable.elements();
270              while( enum.hasMoreElements() ) {
271                 node2 = (GraphNode)enum.nextElement();
272                 if ( node2.hasChild(node1) )  {
273                    node2.removeChild(node1);
274                    fireGraphNodeStateChanged(node2);
275                 }
276                 else if ( node2.hasParent(node1) )  {
277                    node2.removeParent(node1);
278                    fireGraphNodeStateChanged(node2);
279                 }
280                 else if ( node2.hasSibling(node1) )  {
281                    node2.removeSibling(node1);
282                    fireGraphNodeStateChanged(node2);
283                 }
284              }
285              fireGraphNodeRemoved(node1);
286              break;
287 
288         case AgentChangeEvent.MODIFY:
289              node1 = (GraphNode)nodeTable.get(agentId);
290              // reset all of node1's internal state
291              node1.initialize();
292              node1.setUserObject(agent);
293              others = agent.getAcquaintances();
294              for(int j = 0; j < others.length; j++ ) {
295                 node2 = (GraphNode)nodeTable.get(others[j].getName());
296                 if ( node2 != null ) {
297                    relation = others[j].getRelation();
298                    int position = Misc.whichPosition(relation,
299                       AcquaintanceModel.RELATIONS_LIST);
300                    switch( position ) {
301                       case SUPERIORS:
302                            node2.addChild(node1);
303                            node1.addParent(node2);
304                            fireGraphNodeStateChanged(node2);
305                            break;
306                       case SUBORDINATES:
307                            node1.addChild(node2);
308                            node2.addParent(node1);
309                            fireGraphNodeStateChanged(node2);
310                            break;
311                       default:
312                            node1.addSibling(node2);
313                            node2.addSibling(node1);
314                            fireGraphNodeStateChanged(node2);
315                            break;
316                    }
317                 }
318              }
319              fireGraphNodeStateChanged(node1);
320              break;
321      }
322   }
323 
324   public void addChangeListener(ChangeListener x) {
325      listeners.add(ChangeListener.class, x);
326   }
327   public void removeChangeListener(ChangeListener x) {
328      listeners.remove(ChangeListener.class, x);
329   }
330 
331   protected void fireChanged() {
332      ChangeEvent c = new ChangeEvent(this);
333      Object[] list = listeners.getListenerList();
334      for(int i= list.length-2; i >= 0; i -=2) {
335         if (list[i] == ChangeListener.class) {
336            ChangeListener cl = (ChangeListener)list[i+1];
337            cl.stateChanged(c);
338         }
339      }
340   }
341 }