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  * SummaryTaskModel.java
26  *
27  * The underlying model for the Summary Task Graph
28  *****************************************************************************/
29  
30  package zeus.generator.task;
31  
32  import java.util.*;
33  import javax.swing.*;
34  import javax.swing.event.*;
35  
36  import zeus.util.*;
37  import zeus.concepts.*;
38  import zeus.gui.graph.*;
39  import zeus.generator.event.*;
40  
41  public class SummaryTaskModel extends AbstractGraphModel
42                         implements ChangeListener {
43  
44    static final int PRECONDITION  = 0;
45    static final int POSTCONDITION = 1;
46  
47    static final int BASIC_NODE = 0;
48    static final int GUARD_NODE = 1;
49  
50    protected static final boolean ERROR = true;
51    protected static final boolean NO_ERROR = false;
52  
53    protected static int count  = 0;
54  
55    protected OntologyDb        ontologyDb = null;
56    protected Hashtable         nodeTable  = new Hashtable();
57    protected Hashtable         linkTable  = new Hashtable();
58    protected EventListenerList listeners  = new EventListenerList();
59  
60    public SummaryTaskModel(OntologyDb ontologyDb,
61                            TaskNode[] node, TaskLink[] link) {
62       this.ontologyDb = ontologyDb;
63       ontologyDb.addChangeListener(this);
64       reset(node,link);
65    }
66  
67    public void reset(TaskNode[] node, TaskLink[] link) {
68       nodeTable.clear();
69       linkTable.clear();
70       for(int i = 0; i < node.length; i++ )
71          nodeTable.put(node[i].getName(),new GraphNode(node[i]));
72  
73       GraphNode node1, node2;
74       for(int i = 0; i < link.length; i++ ) {
75          linkTable.put(link[i].getId(),link[i]);
76          // create parent-child relations between nodes
77          node1 = (GraphNode)nodeTable.get(link[i].getLeftNode());
78          node2 = (GraphNode)nodeTable.get(link[i].getRightNode());
79          node1.addParent(node2);
80          node2.addChild(node1);
81       }
82       fireGraphStructureChanged();
83    }
84  
85    Fact[] getConditions(int type) {
86       Fact[] out;
87       GraphNode gnode;
88       TaskNode node;
89  
90       switch(type) {
91          case PRECONDITION:
92               gnode = (GraphNode)nodeTable.get(TaskNode.BEGIN);
93               node = (TaskNode)gnode.getUserObject();
94               return node.getPostconditions();
95  
96          case POSTCONDITION:
97               gnode = (GraphNode)nodeTable.get(TaskNode.END);
98               node = (TaskNode)gnode.getUserObject();
99               return node.getPreconditions();
100      }
101      Core.ERROR(null,1,this); // should never get here
102      return null;
103   }
104 
105   public TaskNode[] getNodes() {
106      TaskNode[] output = new TaskNode[nodeTable.size()];
107      Enumeration enum = nodeTable.elements();
108      GraphNode node;
109      for(int i = 0; enum.hasMoreElements(); i++ ) {
110         node = (GraphNode)enum.nextElement();
111         output[i] = (TaskNode)node.getUserObject();
112      }
113      return output;
114   }
115   public TaskLink[] getLinks() {
116      TaskLink[] output = new TaskLink[linkTable.size()];
117      Enumeration enum = linkTable.elements();
118      for(int i = 0; enum.hasMoreElements(); i++ )
119         output[i] = (TaskLink)enum.nextElement();
120      return output;
121   }
122 
123   public boolean isLinkVisible(GraphNode from, GraphNode to) {
124      TaskNode node1 = (TaskNode)from.getUserObject();
125      TaskNode node2 = (TaskNode)to.getUserObject();
126      String name1 = node1.getName();
127      String name2 = node2.getName();
128      TaskLink link;
129      Enumeration enum = linkTable.elements();
130      while( enum.hasMoreElements() ) {
131         link = (TaskLink)enum.nextElement();
132         if ( link.getLeftNode().equals(name1) &&
133              link.getRightNode().equals(name2) )
134            return true;
135      }
136      return false;
137   }
138 
139 
140   public Enumeration nodes() {
141      return nodeTable.elements();
142   }
143   public void setValue(GraphNode gnode, Object user_object) {
144      Vector input = (Vector)user_object;
145      TaskNode input_node = (TaskNode)input.elementAt(0);
146      TaskLink[] input_links = (TaskLink[])input.elementAt(1);
147      Hashtable nameTable = (Hashtable)input.elementAt(2);
148 
149      TaskNode node0 = (TaskNode)gnode.getUserObject();
150      String name0 = node0.getName();
151      nodeTable.remove(name0);
152 
153      gnode.setUserObject(input_node);
154      nodeTable.put(input_node.getName(),gnode);
155 
156      // Remove all previous links relating to the original node (name0)
157      Enumeration enum = linkTable.keys();
158      String linkId;
159      TaskLink link;
160      while( enum.hasMoreElements() ) {
161         linkId = (String)enum.nextElement();
162         link = (TaskLink)linkTable.get(linkId);
163         if ( link.referencesNode(name0) )
164            linkTable.remove(linkId);
165      }
166 
167      // initialise all graph  nodes
168      enum = nodeTable.elements();
169      while( enum.hasMoreElements() )
170         ((GraphNode)enum.nextElement()).initialize();
171 
172      // add new links to linkTable
173      for(int i = 0; i < input_links.length; i++ )
174         linkTable.put(input_links[i].getId(),input_links[i]);
175 
176      GraphNode node1, node2;
177      enum = linkTable.keys();
178      while( enum.hasMoreElements() ) {
179         linkId = (String)enum.nextElement();
180         link = (TaskLink)linkTable.get(linkId);
181         // create parent-child relations between nodes
182         node1 = (GraphNode)nodeTable.get(link.getLeftNode());
183         node2 = (GraphNode)nodeTable.get(link.getRightNode());
184         node1.addParent(node2);
185         node2.addChild(node1);
186      }
187      fireGraphStructureChanged();
188      fireChanged();
189   }
190   public boolean isNodeEditable(GraphNode node) {
191      return true;
192   }
193 
194   public void removeNodes(GraphNode[] input) {
195      TaskNode node;
196      GraphNode node1, node2;
197      TaskLink link;
198      Enumeration enum;
199      String name;
200      for(int i = 0; i < input.length; i++ ) {
201         node = (TaskNode)input[i].getUserObject();
202         name = node.getName();
203         if ( name.equals(TaskNode.BEGIN) || name.equals(TaskNode.END) ) {
204            JOptionPane.showMessageDialog(null,
205               "Cannot delete the BEGIN or END nodes",
206               "Error", JOptionPane.ERROR_MESSAGE);
207         }
208         else {
209            nodeTable.remove(node.getName());
210            // remove links between node[i] and all other nodes in nodeTable
211            enum = linkTable.elements();
212            while( enum.hasMoreElements() ) {
213               link = (TaskLink)enum.nextElement();
214               if ( link.referencesNode(node.getName()) ) {
215                  node1 = (GraphNode)nodeTable.get(link.getLeftNode());
216                  node2 = (GraphNode)nodeTable.get(link.getRightNode());
217                  if ( node1 != null && node2 != null ) {
218                     node1.removeParent(node2);
219                     node2.removeChild(node1);
220                  }
221               }
222            }
223            fireGraphNodeRemoved(input[i]);
224         }
225      }
226      fireChanged();
227   }
228 
229   public void addNewNode(int type)  {
230      GraphNode[] node = new GraphNode[1];
231      String name = "node" + (count++);
232      while( contains(name,NO_ERROR) )
233         name = "node" + (count++);
234      switch(type) {
235         case BASIC_NODE:
236              node[0] = new GraphNode(new TaskNode(name));
237              break;
238         case GUARD_NODE:
239              node[0] = new GraphNode(new ConditionalNode(name));
240              break;
241         default:
242              Core.ERROR(null,1001,this);
243              break;
244      }
245      addNodes(node);
246   }
247 
248   public void addNodes(GraphNode[] input) {
249      if ( input == null || input.length == 0 ) return;
250 
251      TaskNode node;
252      String name;
253      for(int i = 0; i < input.length; i++ ) {
254         node = (TaskNode)input[i].getUserObject();
255         if ( node.isConditionalNode() )
256            node = new ConditionalNode((ConditionalNode)node);
257         else
258            node = new TaskNode(node);
259         name = node.getName();
260         while( contains(name,NO_ERROR) )
261            name += "$" + (count++);
262         node.setName(name);
263         GraphNode gnode = new GraphNode(node);
264         nodeTable.put(name,gnode);
265         fireGraphNodeAdded(gnode);
266      }
267      fireChanged();
268   }
269 
270   protected boolean contains(String name, boolean error) {
271      if ( nodeTable.containsKey(name) ) {
272         if ( error )
273            JOptionPane.showMessageDialog(null,
274               "Attempting to rename node to an already\nexisting name",
275               "Error", JOptionPane.ERROR_MESSAGE);
276         return true;
277      }
278      return false;
279   }
280 
281   public void stateChanged(ChangeEvent e) {
282      // Underlying ontology has changed!!
283      // NEED to verify all facts!!
284   }
285 
286   public void addChangeListener(ChangeListener x) {
287      listeners.add(ChangeListener.class, x);
288   }
289   public void removeChangeListener(ChangeListener x) {
290      listeners.remove(ChangeListener.class, x);
291   }
292   public void addRenameListener(RenameListener x) {
293      listeners.add(RenameListener.class, x);
294   }
295   public void removeRenameListener(RenameListener x) {
296      listeners.remove(RenameListener.class, x);
297   }
298 
299   protected void fireChanged() {
300      ChangeEvent c = new ChangeEvent(this);
301      Object[] list = listeners.getListenerList();
302      for(int i= list.length-2; i >= 0; i -=2) {
303         if (list[i] == ChangeListener.class) {
304            ChangeListener cl = (ChangeListener)list[i+1];
305            cl.stateChanged(c);
306         }
307      }
308   }
309 
310   protected void fireNameChanged(Object object, Object previous,
311                                  Object current) {
312      RenameEvent c = new RenameEvent(this,object,previous,current);
313      Object[] list = listeners.getListenerList();
314      for(int i= list.length-2; i >= 0; i -=2) {
315         if (list[i] == RenameListener.class) {
316            RenameListener cl = (RenameListener)list[i+1];
317            cl.nameChanged(c);
318         }
319      }
320   }
321 }