KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > debugger > ActionsManager


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.api.debugger;
21
22 import java.beans.*;
23 import java.io.*;
24 import java.util.*;
25
26 import org.netbeans.spi.debugger.ActionsProvider;
27 import org.netbeans.spi.debugger.ActionsProviderListener;
28 import org.openide.util.Cancellable;
29 import org.openide.util.Task;
30
31 /**
32  * Manages some set of actions. Loads some set of ActionProviders registerred
33  * for some context, and allows to call isEnabled and doAction methods on them.
34  *
35  * @author Jan Jancura
36  */

37 public final class ActionsManager {
38
39
40     /** Action constant for Step Over Action. */
41     public static final Object JavaDoc ACTION_STEP_OVER = "stepOver";
42     
43     /** Action constant for breakpoint hit action. */
44     public static final Object JavaDoc ACTION_RUN_INTO_METHOD = "runIntoMethod";
45     
46     /** Action constant for Step Into Action. */
47     public static final Object JavaDoc ACTION_STEP_INTO = "stepInto";
48     
49     /** Action constant for Step Out Action. */
50     public static final Object JavaDoc ACTION_STEP_OUT = "stepOut";
51     
52     /** Action constant for Step Operation Action. */
53     public static final Object JavaDoc ACTION_STEP_OPERATION = "stepOperation";
54     
55     /** Action constant for Continue Action. */
56     public static final Object JavaDoc ACTION_CONTINUE = "continue";
57     
58     /** Action constant for Start Action. */
59     public static final Object JavaDoc ACTION_START = "start";
60     
61     /** Action constant for Kill Action. */
62     public static final Object JavaDoc ACTION_KILL= "kill";
63     
64     /** Action constant for Make Caller Current Action. */
65     public static final Object JavaDoc ACTION_MAKE_CALLER_CURRENT = "makeCallerCurrent";
66     
67     /** Action constant for Make Callee Current Action. */
68     public static final Object JavaDoc ACTION_MAKE_CALLEE_CURRENT = "makeCalleeCurrent";
69     
70     /** Action constant for Pause Action. */
71     public static final Object JavaDoc ACTION_PAUSE = "pause";
72     
73     /** Action constant for Run to Cursor Action. */
74     public static final Object JavaDoc ACTION_RUN_TO_CURSOR = "runToCursor";
75     
76     /** Action constant for Pop Topmost Call Action. */
77     public static final Object JavaDoc ACTION_POP_TOPMOST_CALL = "popTopmostCall";
78     
79     /** Action constant for Fix Action. */
80     public static final Object JavaDoc ACTION_FIX = "fix";
81     
82     /** Action constant for Restart Action. */
83     public static final Object JavaDoc ACTION_RESTART = "restart";
84
85     /** Action constant for Restart Action. */
86     public static final Object JavaDoc ACTION_TOGGLE_BREAKPOINT = "toggleBreakpoint";
87     
88     
89     // variables ...............................................................
90

91     private Vector listener = new Vector ();
92     private HashMap listeners = new HashMap ();
93     private HashMap actionProviders;
94     private Object JavaDoc actionProvidersLock = new Object JavaDoc();
95     private MyActionListener actionListener = new MyActionListener ();
96     private Lookup lookup;
97     private boolean doiingDo = false;
98     private boolean destroy = false;
99
100     
101     /**
102      * Create a new instance of ActionManager.
103      * This is called from synchronized blocks of other classes that need to have
104      * just one instance of this. Therefore do not put any foreign calls here.
105      */

106     ActionsManager (Lookup lookup) {
107         this.lookup = lookup;
108     }
109     
110     
111     // main public methods .....................................................
112

113     /**
114      * Performs action on this DebbuggerEngine.
115      *
116      * @param action action constant (default set of constanct are defined
117      * in this class with ACTION_ prefix)
118      * @return true if action has been performed
119      */

120     public final void doAction (final Object JavaDoc action) {
121         doiingDo = true;
122         ArrayList l;
123         synchronized (actionProvidersLock) {
124             if (actionProviders == null) initActionImpls ();
125             l = (ArrayList) actionProviders.get (action);
126             if (l != null) {
127                 l = (ArrayList) l.clone ();
128             }
129         }
130         boolean done = false;
131         if (l != null) {
132             int i, k = l.size ();
133             for (i = 0; i < k; i++) {
134                 if (((ActionsProvider) l.get (i)).isEnabled (action)) {
135                     done = true;
136                     ((ActionsProvider) l.get (i)).doAction (action);
137                 }
138             }
139         }
140         if (done) {
141             fireActionDone (action);
142         }
143         doiingDo = false;
144         if (destroy) destroyIn ();
145     }
146     
147     /**
148      * Post action on this DebbuggerEngine.
149      * This method does not block till the action is done,
150      * if {@link #canPostAsynchronously} returns true.
151      * Otherwise it behaves like {@link #doAction}.
152      * The returned taks, or
153      * {@link ActionsManagerListener} can be used to
154      * be notified when the action is done.
155      *
156      * @param action action constant (default set of constanct are defined
157      * in this class with ACTION_ prefix)
158      *
159      * @return a task, that can be checked for whether the action finished
160      * or not.
161      *
162      * @since 1.5
163      */

164     public final Task postAction(final Object JavaDoc action) {
165         doiingDo = true;
166         ArrayList l;
167         synchronized (actionProvidersLock) {
168             if (actionProviders == null) initActionImpls ();
169             l = (ArrayList) actionProviders.get (action);
170             if (l != null) {
171                 l = (ArrayList) l.clone ();
172             }
173         }
174         boolean posted = false;
175         int k;
176         if (l != null) {
177             k = l.size ();
178         } else {
179             k = 0;
180         }
181         List postedActions = new ArrayList(k);
182         final AsynchActionTask task = new AsynchActionTask(postedActions);
183         if (l != null) {
184             int i;
185             for (i = 0; i < k; i++) {
186                 ActionsProvider ap = (ActionsProvider) l.get (i);
187                 if (ap.isEnabled (action)) {
188                     postedActions.add(ap);
189                     posted = true;
190                 }
191             }
192             if (posted) {
193                 final int[] count = new int[] { 0 };
194                 Runnable JavaDoc notifier = new Runnable JavaDoc() {
195                     public void run() {
196                         synchronized (count) {
197                             if (--count[0] == 0) {
198                                 task.actionDone();
199                                 fireActionDone (action);
200                                 doiingDo = false;
201                                 if (destroy) destroyIn ();
202                             }
203                         }
204                     }
205                 };
206                 count[0] = k = postedActions.size();
207                 for (i = 0; i < k; i++) {
208                     ((ActionsProvider) postedActions.get (i)).postAction (
209                             action, notifier
210                     );
211                 }
212             }
213         }
214         if (!posted) {
215             doiingDo = false;
216             if (destroy) destroyIn ();
217             task.actionDone();
218         }
219         return task;
220     }
221                                                                                 
222     /**
223      * Returns true if given action can be performed on this DebuggerEngine.
224      *
225      * @param action action constant (default set of constanct are defined
226      * in this class with ACTION_ prefix)
227      * @return true if given action can be performed on this DebuggerEngine
228      */

229     public final boolean isEnabled (final Object JavaDoc action) {
230         ArrayList l;
231         synchronized (actionProvidersLock) {
232             if (actionProviders == null) initActionImpls ();
233             l = (ArrayList) actionProviders.get (action);
234             if (l != null) {
235                 l = (ArrayList) l.clone ();
236             }
237         }
238         if (l != null) {
239             int i, k = l.size ();
240             for (i = 0; i < k; i++)
241                 if (((ActionsProvider) l.get (i)).isEnabled (action))
242                     return true;
243         }
244         return false;
245     }
246     
247     /**
248      * Stops listening on all actions, stops firing events.
249      */

250     public void destroy () {
251         if (!doiingDo) destroyIn ();
252         destroy = true;
253     }
254
255     
256     // ActionsManagerListener support ..........................................
257

258     /**
259      * Add ActionsManagerListener.
260      *
261      * @param l listener instance
262      */

263     public void addActionsManagerListener (ActionsManagerListener l) {
264         listener.addElement (l);
265     }
266
267     /**
268      * Removes ActionsManagerListener.
269      *
270      * @param l listener instance
271      */

272     public void removeActionsManagerListener (ActionsManagerListener l) {
273         listener.removeElement (l);
274     }
275
276     /**
277      * Add ActionsManagerListener.
278      *
279      * @param propertyName a name of property to listen on
280      * @param l the ActionsManagerListener to add
281      */

282     public void addActionsManagerListener (
283         String JavaDoc propertyName,
284         ActionsManagerListener l
285     ) {
286         Vector listener = (Vector) listeners.get (propertyName);
287         if (listener == null) {
288             listener = new Vector ();
289             listeners.put (propertyName, listener);
290         }
291         listener.addElement (l);
292     }
293
294     /**
295      * Remove ActionsManagerListener.
296      *
297      * @param propertyName a name of property to listen on
298      * @param l the ActionsManagerListener to remove
299      */

300     public void removeActionsManagerListener (
301         String JavaDoc propertyName,
302         ActionsManagerListener l
303     ) {
304         Vector listener = (Vector) listeners.get (propertyName);
305         if (listener == null) return;
306         listener.removeElement (l);
307         if (listener.size () == 0)
308             listeners.remove (propertyName);
309     }
310
311     
312     // firing support ..........................................................
313

314     /**
315      * Notifies registered listeners about a change.
316      * Notifies {@link #listener registered listeners} that a breakpoint
317      * {@link DebuggerManagerListener#breakpointRemoved was removed}
318      * and {@link #pcs property change listeners} that its properties
319      * {@link PropertyChangeSupport#firePropertyChange(String, Object, Object)}
320      * were changed.
321      *
322      * @param breakpoint a breakpoint that was removed
323      */

324     private void fireActionDone (
325         final Object JavaDoc action
326     ) {
327         initListeners ();
328         Vector l = (Vector) listener.clone ();
329         Vector l1 = (Vector) listeners.get (
330             ActionsManagerListener.PROP_ACTION_PERFORMED
331         );
332         if (l1 != null)
333             l1 = (Vector) l1.clone ();
334         int i, k = l.size ();
335         for (i = 0; i < k; i++)
336             ((ActionsManagerListener) l.elementAt (i)).actionPerformed (
337                 action
338             );
339         if (l1 != null) {
340             k = l1.size ();
341             for (i = 0; i < k; i++)
342                 ((ActionsManagerListener) l1.elementAt (i)).actionPerformed
343                     (action);
344         }
345     }
346
347     /**
348      * Notifies registered listeners about a change.
349      * Notifies {@link #listener registered listeners} that a breakpoint
350      * {@link DebuggerManagerListener#breakpointRemoved was removed}
351      * and {@link #pcs property change listeners} that its properties
352      * {@link PropertyChangeSupport#firePropertyChange(String, Object, Object)}
353      * were changed.
354      *
355      * @param breakpoint a breakpoint that was removed
356      */

357     private void fireActionStateChanged (
358         final Object JavaDoc action
359     ) {
360         boolean enabled = isEnabled (action);
361         initListeners ();
362         Vector l = (Vector) listener.clone ();
363         Vector l1 = (Vector) listeners.get (
364             ActionsManagerListener.PROP_ACTION_STATE_CHANGED
365         );
366         if (l1 != null)
367             l1 = (Vector) l1.clone ();
368         int i, k = l.size ();
369         for (i = 0; i < k; i++)
370             ((ActionsManagerListener) l.elementAt (i)).actionStateChanged (
371                 action, enabled
372             );
373         if (l1 != null) {
374             k = l1.size ();
375             for (i = 0; i < k; i++)
376                 ((ActionsManagerListener) l1.elementAt (i)).actionStateChanged
377                     (action, enabled);
378         }
379     }
380     
381     
382     // private support .........................................................
383

384     private void registerActionsProvider (Object JavaDoc action, ActionsProvider p) {
385         synchronized (actionProvidersLock) {
386             ArrayList l = (ArrayList) actionProviders.get (action);
387             if (l == null) {
388                 l = new ArrayList ();
389                 actionProviders.put (action, l);
390             }
391             l.add (p);
392         }
393         fireActionStateChanged (action);
394         p.addActionsProviderListener (actionListener);
395     }
396     
397     private void initActionImpls () {
398         actionProviders = new HashMap ();
399         Iterator i = lookup.lookup (null, ActionsProvider.class).iterator ();
400         while (i.hasNext ()) {
401             ActionsProvider ap = (ActionsProvider) i.next ();
402             Iterator ii = ap.getActions ().iterator ();
403             while (ii.hasNext ())
404                 registerActionsProvider (ii.next (), ap);
405         }
406     }
407     
408     private boolean listerersLoaded = false;
409     private List lazyListeners;
410     
411     private void initListeners () {
412         if (listerersLoaded) return;
413         listerersLoaded = true;
414         lazyListeners = lookup.lookup (null, LazyActionsManagerListener.class);
415         int i, k = lazyListeners.size ();
416         for (i = 0; i < k; i++) {
417             LazyActionsManagerListener l = (LazyActionsManagerListener)
418                 lazyListeners.get (i);
419             String JavaDoc[] props = l.getProperties ();
420             if (props == null) {
421                 addActionsManagerListener (l);
422                 continue;
423             }
424             int j, jj = props.length;
425             for (j = 0; j < jj; j++) {
426                 addActionsManagerListener (props [j], l);
427             }
428         }
429     }
430     
431     private synchronized void destroyIn () {
432         int i, k = lazyListeners.size ();
433         for (i = 0; i < k; i++) {
434             LazyActionsManagerListener l = (LazyActionsManagerListener)
435                 lazyListeners.get (i);
436             String JavaDoc[] props = l.getProperties ();
437             if (props == null) {
438                 removeActionsManagerListener (l);
439                 continue;
440             }
441             int j, jj = props.length;
442             for (j = 0; j < jj; j++)
443                 removeActionsManagerListener (props [j], l);
444             l.destroy ();
445         }
446         lazyListeners = new ArrayList ();
447     }
448
449     
450     // innerclasses ............................................................
451

452     private static class AsynchActionTask extends Task implements Cancellable {
453         
454         private Collection postedActions;
455         
456         public AsynchActionTask(Collection postedActions) {
457             this.postedActions = postedActions;
458         }
459         
460         void actionDone() {
461             notifyFinished();
462         }
463
464         public boolean cancel() {
465             for (Iterator it = postedActions.iterator(); it.hasNext(); ) {
466                 Object JavaDoc action = it.next();
467                 if (action instanceof Cancellable) {
468                     if (!((Cancellable) action).cancel()) {
469                         return false;
470                     }
471                 } else {
472                     return false;
473                 }
474             }
475             return true;
476         }
477     }
478     
479     class MyActionListener implements ActionsProviderListener {
480         public void actionStateChange (Object JavaDoc action, boolean enabled) {
481             fireActionStateChanged (action);
482         }
483     }
484 }
485
486
Popular Tags