• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /barrelfish-2018-10-04/usr/eclipseclp/Visualisation/src/com/parctechnologies/eclipse/visualisation/
1// BEGIN LICENSE BLOCK
2// Version: CMPL 1.1
3//
4// The contents of this file are subject to the Cisco-style Mozilla Public
5// License Version 1.1 (the "License"); you may not use this file except
6// in compliance with the License.  You may obtain a copy of the License
7// at www.eclipse-clp.org/license.
8//
9// Software distributed under the License is distributed on an "AS IS"
10// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11// the License for the specific language governing rights and limitations
12// under the License.
13//
14// The Original Code is  The ECLiPSe Constraint Logic Programming System.
15// The Initial Developer of the Original Code is  Cisco Systems, Inc.
16// Portions created by the Initial Developer are
17// Copyright (C) 2006 Cisco Systems, Inc.  All Rights Reserved.
18//
19// Contributor(s):
20//
21// END LICENSE BLOCK
22
23package com.parctechnologies.eclipse.visualisation;
24import com.parctechnologies.eclipse.*;
25
26import java.util.*;
27import javax.swing.*;
28import java.awt.BorderLayout;
29import java.awt.Dimension;
30import java.awt.GridBagLayout;
31import java.awt.GridBagConstraints;
32import java.awt.Insets;
33import java.awt.Toolkit;
34import java.awt.event.ActionEvent;
35import javax.swing.event.*;
36
37/**
38 * The ViewerManager is the delegatee of the VisClient.
39
40
41 * The responsibilities of this class are all viewer-related and are grouped
42 * around each of the methods which are invoked by VisClient's processEvent
43 * method during the course of an event.<p>
44 * The graphical
45 * management of the viewers as well as the top level buttons and menus is
46 * delegated to ViewerManagerFrame.<p>
47 * The responsibilities are:
48 * <ul>
49 * <li> When setViewerBuildingPolicy is called for a create event, the
50 * ViewerManager must ask the user which viewers should be created OR if
51 * a suitable scenario already exists it should ask the user if they wish to
52 * use the viewerBuildingPolicy stored in the scenario.
53 * <li> When prepareForEvent is called for a create event, the ViewerManager must
54 * build and configure any viewers which are going to monitor the new viewable,
55 * according to its ViewerBuildingPolicy.
56 * <li> When prepareForEvent is called for any event, the ViewerManager must
57 * determine which viewers are participating in the event and then invoke the
58 * prepareForEvent method of each of those viewers.
59 * <li> For collectPreEventGoals, the viewerManager should collect the pre event
60 * goals of each of the participating viewers into a batch goal and return it.
61 * <li> For startEvent in the case of a createEvent, the viewerManager should
62 * add the new viewers to the ViewerManagerFrame.
63 * <li> For startEvent generally, the viewerManager should invoke the startEvent
64 * method of all participating viewers, distributing the results of each one's
65 * pre-event goals.
66 * <li> For shouldHold, the viewer should return true if any one of the
67 * participating viewers wants to hold.
68 * <li> For stopEvent, in the case of a DestroyEvent, the viewerManager should
69 * remove the viewers whose viewable has ceased to exist from the
70 * viewerManagerFrame.
71 * <li> For stopEvent generally, the viewerManager should invoke the stopEvent
72 * method of all participating viewers.
73 * <li> The ViewerManager must also provide access to the collection of current
74 * interest specs for any existent viewable.
75 * </ul>
76 *
77 * <p>
78 */
79class ViewerManager
80{
81  // in order to be able to efficiently determine which viewers are
82  // participating in each event, the ViewerManager maintains several map
83  // data structures.
84
85  // this allows us to work out the viewable which the event refers to, from its
86  // name.
87  private Map viewableNameToViewable;
88
89  // This is for update events, where we may need to determine which of several
90  // viewers monitoring the viewable is participating.
91  // we have exactly one interest per viewer
92  private Map interestSpecNameToViewer;
93
94  // maps viewable to all viewers monitoring it.
95  private Map viewableToViewers;
96
97  // required for implementation of getInterestSpecs()
98  private Map viewableToInterestSpecs;
99
100  private ViewerBuildingPolicy viewerBuildingPolicy;
101  // List of viewers which are participating in the current event
102  private List participatingViewers;
103  private Atom vcSupportAtom = new Atom("vc_support");
104  private ViewerManagerFrame viewerManagerFrame;
105  private VisEvent currentEvent;
106  private VisClientStateModel stateModel;
107
108
109  ViewerManager(VisClientStateModel stateModel)
110  {
111    this.stateModel = stateModel;
112    initialise();
113  }
114
115  private void initialise()
116  {
117    viewableNameToViewable = new HashMap();
118    interestSpecNameToViewer = new HashMap();
119    viewableToViewers = new HashMap();
120    viewableToInterestSpecs = new HashMap();
121    initialiseViewerBuildingPolicy();
122    initialiseViewerManagerFrame();
123  }
124
125  private void initialiseViewerManagerFrame()
126  {
127    viewerManagerFrame = new ViewerManagerFrame(stateModel);
128    if(DebuggingSupport.useGraphics)
129    {
130      viewerManagerFrame.setVisible(true);
131    }
132    viewerManagerFrame.pack();
133
134  }
135
136  public void initialiseViewerBuildingPolicy()
137  {
138    viewerBuildingPolicy = new DefaultViewerBuildingPolicy(stateModel);
139  }
140
141  public ViewerBuildingPolicy getViewerBuildingPolicy() {
142    return viewerBuildingPolicy;
143  }
144
145  public void configureViewerBuildingPolicy(String viewableName,
146                                            ViewableType viewableType)
147  {
148    if (!stateModel.getViewerBuildingPolicySelected()) {
149	// The user wishes to select new viewers
150	JDialog dialog = new SelectViewersDialog(viewableName,
151                                                 viewableType);
152	dialog.show();
153    }
154  }
155
156  private Viewable initialiseViewable(String viewableName,
157                                      ViewableType type)
158  {
159    Viewable viewable = new Viewable(viewableName, type);
160    viewableNameToViewable.put(viewableName, viewable);
161    return(viewable);
162  }
163
164
165  private java.util.List buildViewers(Viewable viewable)
166  {
167    java.util.List newViewers = viewerBuildingPolicy.buildViewers(viewable);
168    Iterator newViewersIterator = newViewers.iterator();
169    Viewer newViewer;
170
171    while(newViewersIterator.hasNext())
172    {
173        newViewer = (Viewer) newViewersIterator.next();
174        newViewer.setViewerManager(this);
175        if (DebuggingSupport.logMessages) {
176            DebuggingSupport.logMessage(this,
177                                        "built viewer=" + newViewer +
178                                        " interestSpec=" +
179                                        newViewer.getInterestSpec().getName() );
180        }
181        interestSpecNameToViewer.put(newViewer.getInterestSpec().getName(),
182                                     newViewer);
183    }
184    return(newViewers);
185  }
186
187  void closeViewer(Viewer viewer)
188  {
189    viewerManagerFrame.removeViewer(viewer);
190    Collection oldViewers =
191      (Collection) viewableToViewers.remove(viewer.getViewable());
192    Collection newViewers = new LinkedList(oldViewers);
193    newViewers.remove(viewer);
194    viewableToViewers.put(viewer.getViewable(), newViewers);
195    interestSpecNameToViewer.remove(viewer.getInterestSpec().getName());
196    DebuggingSupport.
197      logMessage(this, "viewer "+viewer.getDescription()+" removed");
198    // clean up memory used by the viewer
199    System.gc();
200  }
201
202  void prepareForEvent(VisEvent visEvent)
203  {
204    String viewableName = visEvent.getViewableName();
205    Viewable viewable;
206    Viewer currentViewer;
207
208    if(visEvent instanceof CreateEvent)
209    {
210      CreateEvent createEvent = (CreateEvent) visEvent;
211      viewable =
212        initialiseViewable(viewableName,
213                           createEvent.getViewableType());
214      java.util.List newViewers = buildViewers(viewable);
215      viewableToViewers.put(viewable, newViewers);
216      Collection interestSpecs = getAllInterestSpecs(newViewers);
217      viewableToInterestSpecs.put(viewable, interestSpecs);
218    }
219    else
220    {
221      viewable =
222      (Viewable) viewableNameToViewable.get(viewableName);
223    }
224
225    participatingViewers =
226      (java.util.List) determineParticipatingViewers(visEvent, viewable);
227
228    Iterator viewersIterator
229      = participatingViewers.iterator();
230    while(viewersIterator.hasNext())
231    {
232      currentViewer = (Viewer) viewersIterator.next();
233      currentViewer.prepareForEvent(visEvent);
234    }
235  }
236
237  private List determineParticipatingViewers(VisEvent event,
238                                             Viewable viewable)
239  {
240    if(event instanceof UpdateEvent)
241    {
242      UpdateEvent updateEvent = (UpdateEvent) event;
243      String interestSpecName = updateEvent.getInterestSpecName();
244      LinkedList result = new LinkedList();
245      Object viewer = interestSpecNameToViewer.get(interestSpecName);
246      if (DebuggingSupport.logMessages) {
247          DebuggingSupport.logMessage(this,
248                                      "interestSpecName=" +
249                                      interestSpecName + " viewer=" +
250                                      viewer);
251      }
252      if(viewer != null)
253      {
254        result.add(viewer);
255      }
256      return(result);
257    }
258    else
259    {
260      return((List) viewableToViewers.get(viewable));
261    }
262  }
263
264  BatchGoal collectPreEventGoals(VisEvent visEvent)
265  {
266    BatchGoal preEventGoals = new BatchGoal();
267    Viewer currentViewer;
268
269    Iterator viewersIterator
270      = participatingViewers.iterator();
271    while(viewersIterator.hasNext())
272    {
273      currentViewer = (Viewer) viewersIterator.next();
274      preEventGoals.add(currentViewer.collectPreEventGoals(visEvent));
275    }
276    return(preEventGoals);
277  }
278
279  void holdingEvent(VisEvent visEvent)
280  {
281    viewerManagerFrame.setLastEventString(visEvent.getDescription());
282  }
283
284  void startEvent(VisEvent visEvent, java.util.List goalResults)
285  {
286    viewerManagerFrame.setLastEventString("");
287
288    Viewer currentViewer;
289    Viewable viewable =
290      (Viewable) viewableNameToViewable.get(visEvent.getViewableName());
291    java.util.List currentGoalResults;
292
293    currentEvent = visEvent;
294
295    Iterator viewersIterator
296      = participatingViewers.iterator();
297    Iterator goalResultsIterator
298      = goalResults.iterator();
299
300    String viewableNameString = viewable.getNameString();
301
302
303    while(viewersIterator.hasNext())
304    {
305      currentViewer = (Viewer) viewersIterator.next();
306      currentGoalResults = (java.util.List) goalResultsIterator.next();
307      currentViewer.startEvent(visEvent, currentGoalResults);
308      if(visEvent instanceof CreateEvent)
309      {
310        viewerManagerFrame.addViewer(currentViewer, viewableNameString);
311      }
312    }
313  }
314
315
316
317  boolean shouldHold()
318  {
319    Viewer currentViewer;
320    Iterator viewersIterator
321      = participatingViewers.iterator();
322    while(viewersIterator.hasNext())
323    {
324      currentViewer = (Viewer) viewersIterator.next();
325      if(currentViewer.shouldHold())
326      {
327        return(true);
328      }
329    }
330    return(false);
331  }
332
333  void stopEvent()
334  {
335    Viewer currentViewer;
336    Iterator viewersIterator
337      = participatingViewers.iterator();
338    String viewableName = currentEvent.getViewableName();
339    Viewable viewable =
340      (Viewable) viewableNameToViewable.get(viewableName);
341
342
343    while(viewersIterator.hasNext())
344    {
345      currentViewer = (Viewer) viewersIterator.next();
346      currentViewer.stopEvent();
347      if(currentEvent instanceof DestroyEvent)
348      {
349        try
350        {
351          SwingUtilities.invokeAndWait(new ViewerCloser(currentViewer));
352        }
353        catch(Exception e)
354        {
355          throw new RuntimeException("Exception "+e+
356             " thrown during ViewerCloser.run()");
357        }
358      }
359    }
360    if(currentEvent instanceof DestroyEvent)
361    {
362      viewableToViewers.remove(viewable);
363      viewableToInterestSpecs.remove(viewable);
364      viewableNameToViewable.remove(viewableName);
365    }
366    currentEvent = null;
367    participatingViewers = null;
368  }
369
370  private class ViewerCloser implements Runnable {
371      private Viewer viewer;
372      ViewerCloser(Viewer viewer) {
373          this.viewer = viewer;
374      }
375      public void run() {
376          // closes the internal frame window and updates all book-keeping
377          viewerManagerFrame.removeViewer(viewer);
378      }
379  }
380
381  Collection getAllInterestSpecs(Collection viewers)
382  {
383    Collection interestSpecs = new LinkedList();
384    Viewer currentViewer;
385    Iterator viewersIterator
386      = viewers.iterator();
387    while(viewersIterator.hasNext())
388    {
389      currentViewer = (Viewer) viewersIterator.next();
390      interestSpecs.add(currentViewer.getInterestSpec());
391    }
392    return(interestSpecs);
393  }
394
395  Collection getInterestSpecs(String viewableName)
396  {
397    Viewable viewable = (Viewable) viewableNameToViewable.get(viewableName);
398    return((Collection) viewableToInterestSpecs.get(viewable));
399  }
400
401
402  void errorDialog(String message)
403  {
404    JOptionPane.showConfirmDialog(viewerManagerFrame, message,
405                                  "Error in visualisation client",
406                                  JOptionPane.DEFAULT_OPTION);
407  }
408
409  /**
410   * Dialog from which the user will select the viewers they wish to be
411   * created
412   */
413  private class SelectViewersDialog extends JDialog {
414    String viewableName;
415    ViewableType viewableType;
416
417    List buttons;
418    Set keys;
419
420    public SelectViewersDialog(String viewableName,
421                               ViewableType viewableType) {
422      super();
423      this.buttons = new LinkedList();
424      this.viewableName = viewableName ;
425      this.viewableType = viewableType ;
426      setModal(true);
427      this.setTitle("Select viewers for "+viewableName);
428      getContentPane().setLayout(new BorderLayout());
429      getContentPane().add(new JLabel("Which viewers would you like to create for viewable \""+viewableName+"\"?"),
430			   BorderLayout.NORTH);
431
432      getContentPane().add(viewerFactorySelectorPanel(),
433			   BorderLayout.CENTER);
434      JPanel buttonPanel = new JPanel();
435      buttonPanel.add(new ActionButton(new OkayAction()));
436      getContentPane().add(buttonPanel, BorderLayout.SOUTH);
437      pack();
438      // locate the window in the center for the screen
439      Dimension screenSize =
440	Toolkit.getDefaultToolkit().getScreenSize();
441      Dimension windowSize = getPreferredSize();
442      setLocation(screenSize.width/2 - (windowSize.width/2),
443		  screenSize.height/2 - (windowSize.height/2));
444    }
445
446    private JPanel viewerFactorySelectorPanel() {
447      JPanel panel = new JPanel();
448      BoxLayout layout = new BoxLayout(panel, BoxLayout.Y_AXIS);
449      panel.setLayout(layout);
450      keys = ((DefaultViewerBuildingPolicy)viewerBuildingPolicy).availableViewerFactories(viewableType);
451      Iterator it = keys.iterator();
452      for(int i = 0; it.hasNext(); i++)
453      {
454	Object name = it.next();
455	JCheckBox button = new JCheckBox(name.toString());
456	buttons.add(button);
457        panel.add(button);
458      }
459      return(panel);
460    }
461
462    private class OkayAction extends AbstractAction
463    {
464      OkayAction()
465      {
466        super("Okay");
467      }
468      public void actionPerformed(ActionEvent event)
469      {
470	List selected = new LinkedList();
471	Iterator keyIt = keys.iterator();
472	for(Iterator it = buttons.iterator(); it.hasNext(); ) {
473	    Object key = keyIt.next();
474	    if (((AbstractButton)it.next()).isSelected()) {
475		selected.add(key);
476	    }
477	}
478	(new PolicySelectedCommand(viewableName, selected)).issue();
479        dispose();
480      }
481    }
482
483  }
484}
485