KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > commands > ws > WorkbenchCommandSupport


1 /*******************************************************************************
2  * Copyright (c) 2003, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.internal.commands.ws;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.Set JavaDoc;
20
21 import org.eclipse.swt.SWT;
22 import org.eclipse.swt.widgets.Event;
23 import org.eclipse.swt.widgets.Listener;
24 import org.eclipse.swt.widgets.Shell;
25 import org.eclipse.ui.IPageListener;
26 import org.eclipse.ui.IPartListener;
27 import org.eclipse.ui.IPerspectiveDescriptor;
28 import org.eclipse.ui.IPerspectiveListener;
29 import org.eclipse.ui.IWorkbenchPage;
30 import org.eclipse.ui.IWorkbenchPart;
31 import org.eclipse.ui.IWorkbenchSite;
32 import org.eclipse.ui.IWorkbenchWindow;
33 import org.eclipse.ui.commands.HandlerSubmission;
34 import org.eclipse.ui.commands.ICommandManager;
35 import org.eclipse.ui.commands.IWorkbenchCommandSupport;
36 import org.eclipse.ui.commands.Priority;
37 import org.eclipse.ui.contexts.IWorkbenchContextSupport;
38 import org.eclipse.ui.internal.Workbench;
39 import org.eclipse.ui.internal.commands.CommandManagerFactory;
40 import org.eclipse.ui.internal.commands.IMutableCommandManager;
41 import org.eclipse.ui.internal.commands.MutableCommandManager;
42 import org.eclipse.ui.internal.contexts.ws.WorkbenchContextSupport;
43 import org.eclipse.ui.internal.misc.Policy;
44 import org.eclipse.ui.internal.util.Util;
45 import org.eclipse.ui.keys.KeyFormatterFactory;
46 import org.eclipse.ui.keys.SWTKeySupport;
47
48 /**
49  * Provides command support in terms of the workbench.
50  *
51  * @since 3.0
52  */

53 public class WorkbenchCommandSupport implements IWorkbenchCommandSupport {
54
55     /**
56      * Whether the workbench command support should kick into debugging mode.
57      * This causes the unresolvable handler conflicts to be printed to the
58      * console.
59      */

60     private static final boolean DEBUG = Policy.DEBUG_HANDLERS;
61
62     /**
63      * Whether the workbench command support should kick into verbose debugging
64      * mode. This causes the resolvable handler conflicts to be printed to the
65      * console.
66      */

67     private static final boolean DEBUG_VERBOSE = Policy.DEBUG_HANDLERS
68             && Policy.DEBUG_HANDLERS_VERBOSE;
69
70     /**
71      * The command identifier to which the verbose output should be restricted.
72      */

73     private static final String JavaDoc DEBUG_VERBOSE_COMMAND_ID = Policy.DEBUG_HANDLERS_VERBOSE_COMMAND_ID;
74     
75     /**
76      * The least specific way in which a submissions may match another item.
77      * This means that the submissions will match any value.
78      */

79     private static final int MATCH_ANY = 0;
80
81     /**
82      * The submissions specifies a shell, and this shell is not the active
83      * shell. However, it is the active workbench window's shell. This is
84      * halfway between matching any and matching specifically.
85      */

86     private static final int MATCH_PARTIAL = 1;
87
88     /**
89      * The items match exactly.
90      */

91     private static final int MATCH_EXACT = 2;
92     
93     static {
94         MutableCommandManager.DEBUG_HANDLERS = Policy.DEBUG_HANDLERS
95                 && Policy.DEBUG_HANDLERS_VERBOSE;
96         MutableCommandManager.DEBUG_HANDLERS_COMMAND_ID = Policy.DEBUG_HANDLERS_VERBOSE_COMMAND_ID;
97         MutableCommandManager.DEBUG_COMMAND_EXECUTION = Policy.DEBUG_KEY_BINDINGS_VERBOSE;
98     }
99
100     /**
101      * Generates an integer value representing the quality of the match between
102      * <code>shellToMatch</code> and the active shell and workbench window's
103      * shell. It is assumed that <code>shellToMatch</code> is either
104      * <code>null</code>,<code>activeShell</code> or the active workbench
105      * window's shell.
106      *
107      * @param shellToMatch
108      * The shell to match; may be <code>null</code>.
109      * @param activeShell
110      * The active shell shell; may be <code>null</code>.
111      * @return One of <code>MATCH_ANY</code>,<code>MATCH_PARTIAL</code>,
112      * or <code>MATCH_EXACT</code>.
113      */

114     private static final int compareWindows(final Shell shellToMatch,
115             final Shell activeShell) {
116         if (shellToMatch == null) {
117             return MATCH_ANY;
118         } else if (shellToMatch == activeShell) { return MATCH_EXACT; }
119
120         return MATCH_PARTIAL;
121     }
122
123     /**
124      * Listens for shell activation events, and updates the list of enabled
125      * handlers appropriately. This is used to keep the enabled handlers
126      * synchronized with respect to the <code>activeShell</code> condition.
127      */

128     private Listener activationListener = new Listener() {
129
130         /*
131          * (non-Javadoc)
132          *
133          * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
134          */

135         public void handleEvent(Event event) {
136             processHandlerSubmissions(false, event.display.getActiveShell());
137         }
138     };
139
140     /**
141      * The currently active shell. This value is never <code>null</code>.
142      */

143     private Shell activeShell;
144
145     /**
146      * The active workbench site when the handler submissions were last
147      * processed. This value may be <code>null</code> if no workbench site is
148      * selected.
149      */

150     private IWorkbenchSite activeWorkbenchSite;
151
152     /**
153      * The active workbench window when the handler submissions were last
154      * processed. This value may be <code>null</code> if Eclipse is not the
155      * active application.
156      */

157     private IWorkbenchWindow activeWorkbenchWindow;
158
159     /**
160      * The map of the handler submissions indexed by command identifier. This
161      * value is never <code>null</code>, but may be empty. The command
162      * identifiers are strings, and the handler submissions are instances of
163      * <code>HandlerSubmission</code>.
164      */

165     private final Map JavaDoc handlerSubmissionsByCommandId = new HashMap JavaDoc();
166
167     /**
168      * The mutable command manager that should be notified of changes to the
169      * list of active handlers. This value is never <code>null</code>.
170      */

171     private final IMutableCommandManager mutableCommandManager;
172
173     /**
174      * A listener for changes in the active page. Changes to the active page
175      * causes the handler submissions to be reprocessed.
176      */

177     private final IPageListener pageListener = new IPageListener() {
178
179         public void pageActivated(IWorkbenchPage workbenchPage) {
180             processHandlerSubmissions(false);
181         }
182
183         public void pageClosed(IWorkbenchPage workbenchPage) {
184             processHandlerSubmissions(false);
185         }
186
187         public void pageOpened(IWorkbenchPage workbenchPage) {
188             processHandlerSubmissions(false);
189         }
190     };
191
192     /**
193      * A listener for changes in the active part. Changes to the active part
194      * causes the handler submissions to be reprocessed.
195      */

196     private final IPartListener partListener = new IPartListener() {
197
198         public void partActivated(IWorkbenchPart workbenchPart) {
199             processHandlerSubmissions(false);
200         }
201
202         public void partBroughtToTop(IWorkbenchPart workbenchPart) {
203             processHandlerSubmissions(false);
204         }
205
206         public void partClosed(IWorkbenchPart workbenchPart) {
207             processHandlerSubmissions(false);
208         }
209
210         public void partDeactivated(IWorkbenchPart workbenchPart) {
211             processHandlerSubmissions(false);
212         }
213
214         public void partOpened(IWorkbenchPart workbenchPart) {
215             processHandlerSubmissions(false);
216         }
217     };
218
219     /**
220      * A listener for changes in the active perspective. Changes to the active
221      * perspective causes the handler submissions to be reprocessed.
222      */

223     private final IPerspectiveListener perspectiveListener = new IPerspectiveListener() {
224
225         public void perspectiveActivated(IWorkbenchPage workbenchPage,
226                 IPerspectiveDescriptor perspectiveDescriptor) {
227             processHandlerSubmissions(false);
228         }
229
230         public void perspectiveChanged(IWorkbenchPage workbenchPage,
231                 IPerspectiveDescriptor perspectiveDescriptor, String JavaDoc changeId) {
232             processHandlerSubmissions(false);
233         }
234     };
235     
236     /**
237      * Whether the command support should process handler submissions. If it is
238      * not processing handler submissions, then it will update the listeners,
239      * but do no further work. This flag is used to avoid excessive updating
240      * when the workbench is performing some large change (e.g., opening an
241      * editor, starting up, shutting down, switching perspectives, etc.)
242      */

243     private boolean processing = true;
244
245     /**
246      * The workbench this class is supporting. This value should never be
247      * <code>null</code>.
248      */

249     private final Workbench workbench;
250
251     /**
252      * Constructs a new instance of <code>WorkbenchCommandSupport</code>
253      *
254      * @param workbenchToSupport
255      * The workbench for which the support should be created; must
256      * not be <code>null</code>.
257      */

258     public WorkbenchCommandSupport(final Workbench workbenchToSupport) {
259         workbench = workbenchToSupport;
260         mutableCommandManager = CommandManagerFactory
261                 .getMutableCommandManager();
262         KeyFormatterFactory.setDefault(SWTKeySupport
263                 .getKeyFormatterForPlatform());
264
265         // Attach a hook to latch on to the first workbench window to open.
266
workbenchToSupport.getDisplay().addFilter(SWT.Activate,
267                 activationListener);
268
269         final List JavaDoc submissions = new ArrayList JavaDoc();
270         final MutableCommandManager commandManager = (MutableCommandManager) mutableCommandManager;
271         final Set JavaDoc handlers = commandManager.getDefinedHandlers();
272         final Iterator JavaDoc handlerItr = handlers.iterator();
273
274         while (handlerItr.hasNext()) {
275             final HandlerProxy proxy = (HandlerProxy) handlerItr.next();
276             final String JavaDoc commandId = proxy.getCommandId();
277             final HandlerSubmission submission = new HandlerSubmission(null,
278                     null, null, commandId, proxy, Priority.LOW);
279             submissions.add(submission);
280         }
281
282         if (!submissions.isEmpty()) {
283             addHandlerSubmissions(submissions);
284         }
285         // TODO Should these be removed at shutdown? Is life cycle important?
286
}
287
288     public void addHandlerSubmission(HandlerSubmission handlerSubmission) {
289         addHandlerSubmissionReal(handlerSubmission);
290         processHandlerSubmissions(true);
291     }
292
293     /**
294      * Adds a single handler submission. This method is used by the two API
295      * methods to actually add a single handler submission.
296      *
297      * @param handlerSubmission
298      * The submission to be added; must not be <code>null</code>.
299      */

300     private final void addHandlerSubmissionReal(
301             final HandlerSubmission handlerSubmission) {
302         final String JavaDoc commandId = handlerSubmission.getCommandId();
303         List JavaDoc handlerSubmissions2 = (List JavaDoc) handlerSubmissionsByCommandId
304                 .get(commandId);
305
306         if (handlerSubmissions2 == null) {
307             handlerSubmissions2 = new ArrayList JavaDoc();
308             handlerSubmissionsByCommandId.put(commandId, handlerSubmissions2);
309         }
310
311         handlerSubmissions2.add(handlerSubmission);
312     }
313
314     public void addHandlerSubmissions(Collection JavaDoc handlerSubmissions) {
315         final Iterator JavaDoc submissionItr = handlerSubmissions.iterator();
316         while (submissionItr.hasNext()) {
317             addHandlerSubmissionReal((HandlerSubmission) submissionItr.next());
318         }
319
320         processHandlerSubmissions(true);
321     }
322
323     /**
324      * An accessor for the underlying command manager.
325      *
326      * @return The command manager used by this support class.
327      */

328     public ICommandManager getCommandManager() {
329         // TODO need to proxy this to prevent casts to IMutableCommandManager
330
return mutableCommandManager;
331     }
332
333     /**
334      * Processes incoming handler submissions, and decides which handlers should
335      * be active. If <code>force</code> is <code>false</code>, then it will
336      * only reconsider handlers if the state of the workbench has changed.
337      *
338      * @param force
339      * Whether to force reprocessing of the handlers -- regardless of
340      * whether the workbench has changed.
341      */

342     private void processHandlerSubmissions(boolean force) {
343         processHandlerSubmissions(force, workbench.getDisplay()
344                 .getActiveShell());
345     }
346
347     /**
348      * TODO See WorkbenchKeyboard. Switch to private when Bug 56231 is resolved.
349      *
350      * @param force
351      * Whether to force reprocessing of the handlers -- regardless of
352      * whether the workbench has changed.
353      * @param newActiveShell
354      * The shell that is now active. This could be the same as the
355      * current active shell, or it could indicate that a new shell
356      * has become active. This value can be <code>null</code> if
357      * there is no active shell currently (this can happen during
358      * shell transitions).
359      */

360     public void processHandlerSubmissions(boolean force,
361             final Shell newActiveShell) {
362
363         // We do not need to update the listeners until everything is done.
364
if (!processing) { return; }
365
366         IWorkbenchSite newWorkbenchSite = null;
367         IWorkbenchWindow newWorkbenchWindow = workbench
368                 .getActiveWorkbenchWindow();
369         boolean update = false;
370
371         // Update the active shell, and swap the listener.
372
if (activeShell != newActiveShell) {
373             activeShell = newActiveShell;
374             update = true;
375         }
376
377         if (activeWorkbenchWindow != newWorkbenchWindow) {
378             if (activeWorkbenchWindow != null) {
379                 activeWorkbenchWindow.removePageListener(pageListener);
380                 activeWorkbenchWindow
381                         .removePerspectiveListener(perspectiveListener);
382                 activeWorkbenchWindow.getPartService().removePartListener(
383                         partListener);
384             }
385
386             if (newWorkbenchWindow != null) {
387                 newWorkbenchWindow.addPageListener(pageListener);
388                 newWorkbenchWindow.addPerspectiveListener(perspectiveListener);
389                 newWorkbenchWindow.getPartService().addPartListener(
390                         partListener);
391             }
392
393             activeWorkbenchWindow = newWorkbenchWindow;
394
395             update = true;
396         }
397
398         if (newWorkbenchWindow != null) {
399             IWorkbenchPage activeWorkbenchPage = newWorkbenchWindow
400                     .getActivePage();
401
402             if (activeWorkbenchPage != null) {
403                 IWorkbenchPart activeWorkbenchPart = activeWorkbenchPage
404                         .getActivePart();
405
406                 if (activeWorkbenchPart != null) {
407                     newWorkbenchSite = activeWorkbenchPart.getSite();
408                 }
409             }
410         } else {
411             newWorkbenchSite = null;
412         }
413
414         if (force || update || (activeWorkbenchSite != newWorkbenchSite)) {
415             activeWorkbenchSite = newWorkbenchSite;
416             Map JavaDoc handlersByCommandId = new HashMap JavaDoc();
417             final WorkbenchContextSupport contextSupport = (WorkbenchContextSupport) workbench
418                     .getContextSupport();
419             final Map JavaDoc contextTree = contextSupport
420                         .createFilteredContextTreeFor(contextSupport
421                                 .getContextManager().getEnabledContextIds());
422             final boolean dialogOpen = contextTree
423                                 .containsKey(IWorkbenchContextSupport.CONTEXT_ID_DIALOG);
424
425             for (Iterator JavaDoc iterator = handlerSubmissionsByCommandId.entrySet()
426                     .iterator(); iterator.hasNext();) {
427                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
428                 String JavaDoc commandId = (String JavaDoc) entry.getKey();
429                 List JavaDoc handlerSubmissions = (List JavaDoc) entry.getValue();
430                 Iterator JavaDoc submissionItr = handlerSubmissions.iterator();
431                 HandlerSubmission bestHandlerSubmission = null;
432                 boolean conflict = false;
433
434                 while (submissionItr.hasNext()) {
435                     HandlerSubmission handlerSubmission = (HandlerSubmission) submissionItr
436                             .next();
437                     IWorkbenchSite activeWorkbenchSite2 = handlerSubmission
438                             .getActiveWorkbenchPartSite();
439
440                     if (activeWorkbenchSite2 != null
441                             && activeWorkbenchSite2 != newWorkbenchSite)
442                             continue;
443
444                     final Shell activeShell2 = handlerSubmission
445                             .getActiveShell();
446                     final Shell wbWinShell;
447                     if (activeWorkbenchWindow == null) {
448                         wbWinShell = null;
449                     } else {
450                         wbWinShell = activeWorkbenchWindow.getShell();
451                     }
452
453                     if ((activeShell2 != null) && (activeShell2 != activeShell)
454                             && ((activeShell2 != wbWinShell) || dialogOpen))
455                             continue;
456
457                     if (bestHandlerSubmission == null) {
458                         bestHandlerSubmission = handlerSubmission;
459                     } else {
460                         int compareTo = Util.compareIdentity(
461                                 activeWorkbenchSite2, bestHandlerSubmission
462                                         .getActiveWorkbenchPartSite());
463                         final int currentMatch = compareWindows(activeShell2,
464                                 activeShell);
465                         final Shell bestMatchingShell = bestHandlerSubmission
466                                 .getActiveShell();
467                         final int bestMatch = compareWindows(bestMatchingShell,
468                                 activeShell);
469
470                         if ((bestHandlerSubmission.getHandler() instanceof HandlerProxy)
471                                 && (currentMatch <= MATCH_PARTIAL)
472                                 && (dialogOpen)) {
473                             /*
474                              * TODO This is a workaround for the fact that there
475                              * is no API to specify the shell for handlers
476                              * contributed via XML. This would mean that these
477                              * handlers would always lose to the workbench
478                              * window fallback mechanism.
479                              *
480                              * This workaround assumes that the handler
481                              * submitted via XML is intended to match more
482                              * closely than the fallback mechanism.
483                              *
484                              * In the future, this XML-contributed handlers
485                              * should be allowed to specify the level at which
486                              * they are given priority: ANY, PARTIAL or EXACT.
487                              */

488                             compareTo = -1;
489                             
490                             if ((DEBUG_VERBOSE)
491                                     && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID
492                                             .equals(commandId)))) {
493                                 System.out
494                                         .println("HANDLERS >>> A handler contributed via XML will win over a less than exact match: " //$NON-NLS-1$
495
+ bestHandlerSubmission.getHandler());
496                             }
497                             
498                         } else if ((handlerSubmission.getHandler() instanceof HandlerProxy)
499                                 && (bestMatch <= MATCH_PARTIAL) && (dialogOpen)) {
500                             /*
501                              * TODO This is a workaround for the fact that there
502                              * is no API to specify the shell for handlers
503                              * contributed via XML. This would mean that these
504                              * handlers would always lose to the workbench
505                              * window fallback mechanism.
506                              *
507                              * This workaround assumes that the handler
508                              * submitted via XML is intended to match more
509                              * closely than the fallback mechanism.
510                              *
511                              * In the future, this XML-contributed handlers
512                              * should be allowed to specify the level at which
513                              * they are given priority: ANY, PARTIAL or EXACT.
514                              */

515                             compareTo = 1;
516                             if ((DEBUG_VERBOSE)
517                                     && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID
518                                             .equals(commandId)))) {
519                                 System.out
520                                         .println("HANDLERS >>> A handler contributed via XML will win over a less than exact match: " //$NON-NLS-1$
521
+ handlerSubmission.getHandler());
522                             }
523                             
524                         } else if ((currentMatch > bestMatch)
525                                 || (compareTo == 0)) {
526
527                             /*
528                              * Compare the two, to see if one is a better match.
529                              */

530                             compareTo = currentMatch - bestMatch;
531
532                             if (compareTo == 0)
533                                     compareTo = Util
534                                             .compare(handlerSubmission
535                                                     .getPriority(),
536                                                     bestHandlerSubmission
537                                                             .getPriority());
538                         }
539
540                         if (compareTo > 0) {
541                             if ((DEBUG_VERBOSE)
542                                     && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID
543                                             .equals(commandId)))) {
544                                 System.out
545                                         .println("HANDLERS >>> Resolved conflict detected between "); //$NON-NLS-1$
546
System.out.println("HANDLERS >>> win: " //$NON-NLS-1$
547
+ handlerSubmission);
548                                 System.out.println("HANDLERS >>> lose: " //$NON-NLS-1$
549
+ bestHandlerSubmission);
550                             }
551                             conflict = false;
552                             bestHandlerSubmission = handlerSubmission;
553                         } else if ((compareTo == 0)
554                                 && (bestHandlerSubmission.getHandler() != handlerSubmission
555                                         .getHandler())) {
556                             if (DEBUG) {
557                                 System.out
558                                         .println("HANDLERS >>> Unresolved conflict detected for " //$NON-NLS-1$
559
+ commandId);
560                             }
561                             conflict = true;
562                         } else if ((DEBUG_VERBOSE)
563                                 && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID
564                                         .equals(commandId)))) {
565                             System.out
566                                     .println("HANDLERS >>> Resolved conflict detected between "); //$NON-NLS-1$
567
System.out.println("HANDLERS >>> win: " //$NON-NLS-1$
568
+ bestHandlerSubmission);
569                             System.out.println("HANDLERS >>> lose: " //$NON-NLS-1$
570
+ handlerSubmission);
571                         }
572                     }
573                 }
574
575                 if (bestHandlerSubmission != null && !conflict)
576                         handlersByCommandId.put(commandId,
577                                 bestHandlerSubmission.getHandler());
578             }
579
580             mutableCommandManager.setHandlersByCommandId(handlersByCommandId);
581         }
582     }
583
584     public void removeHandlerSubmission(HandlerSubmission handlerSubmission) {
585         removeHandlerSubmissionReal(handlerSubmission);
586         processHandlerSubmissions(true);
587     }
588
589     /**
590      * Removes a single handler submission. This method is used by the two API
591      * methods to actually remove a single handler submission.
592      *
593      * @param handlerSubmission
594      * The submission to be removed; must not be <code>null</code>.
595      */

596     private final void removeHandlerSubmissionReal(
597             final HandlerSubmission handlerSubmission) {
598         final String JavaDoc commandId = handlerSubmission.getCommandId();
599         final List JavaDoc handlerSubmissions2 = (List JavaDoc) handlerSubmissionsByCommandId
600                 .get(commandId);
601
602         if (handlerSubmissions2 != null) {
603             handlerSubmissions2.remove(handlerSubmission);
604
605             if (handlerSubmissions2.isEmpty()) {
606                 handlerSubmissionsByCommandId.remove(commandId);
607             }
608         }
609     }
610
611     public void removeHandlerSubmissions(Collection JavaDoc handlerSubmissions) {
612         final Iterator JavaDoc submissionItr = handlerSubmissions.iterator();
613         while (submissionItr.hasNext()) {
614             removeHandlerSubmissionReal((HandlerSubmission) submissionItr.next());
615         }
616
617         processHandlerSubmissions(true);
618     }
619
620     /**
621      * Sets the active context identifiers on the mutable command manager this
622      * class interacts with.
623      *
624      * @param activeContextIds
625      * The new map of active context identifiers -- representing the
626      * hierarchy of active contexts. This should be a map of string
627      * values. It may be empty, but it should never be
628      * <code>null</code>.
629      */

630     public void setActiveContextIds(Map JavaDoc activeContextIds) {
631         mutableCommandManager.setActiveContextIds(activeContextIds);
632     }
633     
634     /**
635      * Sets whether the workbench's command support should process handler
636      * submissions. The workbench should not allow the event loop to spin unless
637      * this value is set to <code>true</code>. If the value changes from
638      * <code>false</code> to <code>true</code>, this automatically triggers
639      * a re-processing of the handler submissions.
640      *
641      * @param processing
642      * Whether to process handler submissions
643      */

644     public final void setProcessing(final boolean processing) {
645         final boolean reprocess = !this.processing && processing;
646         this.processing = processing;
647         if (reprocess) {
648             processHandlerSubmissions(true);
649         }
650     }
651 }
652
Popular Tags