Merge branch 'develop' into remoting-4.0
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / model / AbstractUtility.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.taxeditor.model;
12
13 import java.lang.reflect.InvocationTargetException;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.LinkedHashMap;
17 import java.util.List;
18 import java.util.TreeSet;
19
20 import org.eclipse.core.commands.ExecutionException;
21 import org.eclipse.core.commands.NotEnabledException;
22 import org.eclipse.core.commands.NotHandledException;
23 import org.eclipse.core.commands.common.NotDefinedException;
24 import org.eclipse.core.commands.operations.AbstractOperation;
25 import org.eclipse.core.commands.operations.IOperationHistory;
26 import org.eclipse.core.runtime.IAdaptable;
27 import org.eclipse.core.runtime.IProgressMonitor;
28 import org.eclipse.core.runtime.IStatus;
29 import org.eclipse.core.runtime.NullProgressMonitor;
30 import org.eclipse.core.runtime.OperationCanceledException;
31 import org.eclipse.core.runtime.Status;
32 import org.eclipse.core.runtime.SubProgressMonitor;
33 import org.eclipse.core.runtime.jobs.ISchedulingRule;
34 import org.eclipse.jface.action.IStatusLineManager;
35 import org.eclipse.jface.operation.IRunnableWithProgress;
36 import org.eclipse.jface.resource.ColorRegistry;
37 import org.eclipse.jface.resource.FontRegistry;
38 import org.eclipse.jface.window.ApplicationWindow;
39 import org.eclipse.swt.graphics.Color;
40 import org.eclipse.swt.graphics.Font;
41 import org.eclipse.swt.widgets.Display;
42 import org.eclipse.swt.widgets.Shell;
43 import org.eclipse.ui.IEditorPart;
44 import org.eclipse.ui.IViewPart;
45 import org.eclipse.ui.IViewReference;
46 import org.eclipse.ui.IWorkbench;
47 import org.eclipse.ui.IWorkbenchPage;
48 import org.eclipse.ui.IWorkbenchPart;
49 import org.eclipse.ui.PartInitException;
50 import org.eclipse.ui.PlatformUI;
51 import org.eclipse.ui.handlers.IHandlerService;
52 import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
53 import org.eclipse.ui.part.EditorPart;
54 import org.eclipse.ui.progress.IProgressService;
55 import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
56 import org.eclipse.ui.themes.ITheme;
57 import org.eclipse.ui.themes.IThemeManager;
58
59 import eu.etaxonomy.cdm.model.common.IEnumTerm;
60 import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
61 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
62 import eu.etaxonomy.taxeditor.operation.RemotingCdmHandler;
63 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
64 import eu.etaxonomy.taxeditor.view.AbstractCdmDataViewer;
65 import eu.etaxonomy.taxeditor.view.detail.DetailsViewPart;
66 import eu.etaxonomy.taxeditor.view.supplementaldata.SupplementalDataViewPart;
67
68 /**
69 * <p>
70 * Abstract AbstractUtility class.
71 * </p>
72 *
73 * @author n.hoffmann
74 * @created 11.05.2009
75 * @version 1.0
76 */
77 public abstract class AbstractUtility {
78
79 /** Constant <code>statusLineManager</code> */
80 protected static IStatusLineManager statusLineManager;
81
82
83 /**
84 * <p>
85 * closeAll
86 * </p>
87 *
88 * @return a boolean.
89 */
90 public static boolean closeAll() {
91 return getActivePage().closeAllEditors(true);
92 }
93
94 /**
95 * Close the given editor.
96 *
97 * @param editor
98 * The <tt>MultipageTaxonEditor</tt> to close.
99 * @return <tt>true</tt> on success
100 */
101 public static boolean close(EditorPart editor) {
102 return getActivePage().closeEditor(editor, true);
103 }
104
105 /**
106 * <p>
107 * getShell
108 * </p>
109 *
110 * @return a {@link org.eclipse.swt.widgets.Shell} object.
111 */
112 public static Shell getShell() {
113
114 return TaxeditorStorePlugin.getDefault().getWorkbench()
115 .getActiveWorkbenchWindow().getShell();
116 }
117
118 /**
119 * <p>
120 * getActivePage
121 * </p>
122 *
123 * @return a {@link org.eclipse.ui.IWorkbenchPage} object.
124 */
125 public static IWorkbenchPage getActivePage() {
126
127 return TaxeditorStorePlugin.getDefault().getWorkbench()
128 .getActiveWorkbenchWindow().getActivePage();
129 }
130
131 /**
132 * <p>
133 * getActivePart
134 * </p>
135 *
136 * @return a {@link org.eclipse.ui.IWorkbenchPart} object.
137 */
138 public static IWorkbenchPart getActivePart() {
139 return getActivePage() != null ? getActivePage().getActivePart() : null;
140 }
141
142 public static IWorkbench getWorkbench() {
143 return TaxeditorStorePlugin.getDefault().getWorkbench();
144 }
145
146 /**
147 * <p>
148 * getWorkbenchWindow
149 * </p>
150 *
151 * @return a {@link org.eclipse.jface.window.ApplicationWindow} object.
152 */
153 public static ApplicationWindow getWorkbenchWindow() {
154 if (getWorkbench().getWorkbenchWindowCount() > 1) {
155 throw new IllegalStateException("More than one workbench window");
156 }
157 return (ApplicationWindow) getWorkbench().getWorkbenchWindows()[0];
158 }
159
160 /**
161 * <p>
162 * showView
163 * </p>
164 *
165 * @param id
166 * a {@link java.lang.String} object.
167 * @return a {@link org.eclipse.ui.IViewPart} object.
168 */
169 public static IViewPart showView(String id) {
170 try {
171 return PlatformUI.getWorkbench().getActiveWorkbenchWindow()
172 .getActivePage()
173 .showView(id, null, IWorkbenchPage.VIEW_VISIBLE);
174 } catch (PartInitException e) {
175 MessagingUtils.messageDialog("Error opening view", AbstractUtility.class, "Could not open view: " + id, e);
176 return null;
177 }
178 }
179
180 /**
181 * <p>
182 * hideView
183 * </p>
184 *
185 * @param view
186 * a {@link org.eclipse.ui.IViewPart} object.
187 */
188 public static void hideView(IViewPart view) {
189 PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
190 .hideView(view);
191 }
192
193 /**
194 * <p>
195 * getView
196 * </p>
197 *
198 * @param id
199 * a {@link java.lang.String} object.
200 * @param restore
201 * a boolean.
202 * @return a {@link org.eclipse.ui.IViewPart} object.
203 */
204 public static IViewPart getView(String id, boolean restore) {
205 IViewReference[] references = PlatformUI.getWorkbench()
206 .getActiveWorkbenchWindow().getActivePage().getViewReferences();
207 for (IViewReference reference : references) {
208 if (reference.getId().equals(id)) {
209 return reference.getView(restore);
210 }
211 }
212 return null;
213 }
214
215 /**
216 * <p>
217 * getService
218 * </p>
219 *
220 * @param api
221 * a {@link java.lang.Class} object.
222 * @return a {@link java.lang.Object} object.
223 */
224 public static Object getService(Class api) {
225 return TaxeditorStorePlugin.getDefault().getWorkbench().getService(api);
226 }
227
228 /**
229 * <p>
230 * getCurrentTheme
231 * </p>
232 *
233 * @return a {@link org.eclipse.ui.themes.ITheme} object.
234 */
235 public static ITheme getCurrentTheme() {
236 IThemeManager themeManager = TaxeditorStorePlugin.getDefault()
237 .getWorkbench().getThemeManager();
238 return themeManager.getCurrentTheme();
239 }
240
241 /**
242 * Fonts registered to the plugin may be obtained with the Eclipse themeing
243 * functionality. Thus fonts are chooseable by the user via
244 * Preferences->General->Appearance->Colors and Fonts
245 *
246 * @return the FontRegistry for the current theme
247 */
248 public static FontRegistry getFontRegistry() {
249 return getCurrentTheme().getFontRegistry();
250 }
251
252 /**
253 * <p>
254 * getFont
255 * </p>
256 *
257 * @param symbolicName
258 * a {@link java.lang.String} object.
259 * @return a {@link org.eclipse.swt.graphics.Font} object.
260 */
261 public static Font getFont(String symbolicName) {
262 return getFontRegistry().get(symbolicName);
263 }
264
265 /**
266 * Color registered to the plugin may be obtained with the Eclipse themeing
267 * functionality. Thus colors are editable by the user via
268 * Preferences->General->Appearance->Colors and Fonts
269 *
270 * @return the ColorRegistry for the current theme
271 */
272 public static ColorRegistry getColorRegistry() {
273 return getCurrentTheme().getColorRegistry();
274 }
275
276 /**
277 * <p>
278 * getColor
279 * </p>
280 *
281 * @param symbolicName
282 * a {@link java.lang.String} object.
283 * @return a {@link org.eclipse.swt.graphics.Color} object.
284 */
285 public static Color getColor(String symbolicName) {
286 return getColorRegistry().get(symbolicName);
287 }
288
289 /**
290 * <p>
291 * executeOperation
292 * </p>
293 *
294 * @param operation
295 * a
296 * {@link eu.etaxonomy.taxeditor.operation.AbstractPostTaxonOperation}
297 * object.
298 * @return a {@link org.eclipse.core.runtime.IStatus} object.
299 */
300 public static IStatus executeOperation(final AbstractPostOperation operation) {
301 if (getOperationHistory() == null) {
302 throw new IllegalArgumentException(
303 "There is no operation history for this context");
304 }
305
306 final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
307 .getUIInfoAdapter(getShell());
308
309 IRunnableWithProgress runnable = new IRunnableWithProgress() {
310
311 @Override
312 public void run(IProgressMonitor monitor)
313 throws InvocationTargetException, InterruptedException {
314 String operationlabel = operation.getLabel();
315 monitor.beginTask(operationlabel, 100);
316 IStatus status = Status.CANCEL_STATUS;
317 try {
318 operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
319 status = getOperationHistory().execute(operation, monitor,
320 uiInfoAdapter);
321 } catch (ExecutionException e) {
322
323 MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
324
325 } finally {
326 monitor.done();
327 }
328
329 String statusString = status.equals(Status.OK_STATUS) ? "completed"
330 : "cancelled";
331 setStatusLine(operationlabel + " " + statusString + ".");
332
333 }
334 };
335
336 try {
337 runInUI(runnable, null);
338 } catch (Exception e) {
339 MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
340 }
341
342 IPostOperationEnabled postOperationEnabled = operation
343 .getPostOperationEnabled();
344 if (postOperationEnabled != null) {
345 postOperationEnabled.onComplete();
346 }
347 return Status.OK_STATUS;
348 }
349
350 public static IStatus executeOperation(final AbstractOperation operation, final RemotingCdmHandler handler) {
351 if (getOperationHistory() == null) {
352 throw new IllegalArgumentException(
353 "There is no operation history for this context");
354 }
355
356 final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
357 .getUIInfoAdapter(getShell());
358
359 IRunnableWithProgress runnable = new IRunnableWithProgress() {
360
361 @Override
362 public void run(IProgressMonitor monitor)
363 throws InvocationTargetException, InterruptedException {
364 String operationlabel = operation.getLabel();
365 monitor.beginTask(operationlabel, 100);
366 IStatus status = Status.CANCEL_STATUS;
367 try {
368 operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
369 status = getOperationHistory().execute(operation, monitor,
370 uiInfoAdapter);
371 if(handler != null) {
372 handler.postOperation(status);
373 }
374 } catch (ExecutionException e) {
375 MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
376 } finally {
377 monitor.done();
378 }
379
380 String statusString = status.equals(Status.OK_STATUS) ? "completed"
381 : "cancelled";
382 setStatusLine(operationlabel + " " + statusString + ".");
383
384 }
385 };
386
387 try {
388 runInUI(runnable, null);
389 } catch (Exception e) {
390 MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
391 }
392
393 return Status.OK_STATUS;
394 }
395 /**
396 * <p>
397 * getOperationHistory
398 * </p>
399 *
400 * @return a {@link org.eclipse.core.commands.operations.IOperationHistory}
401 * object.
402 */
403 public static IOperationHistory getOperationHistory() {
404 return getWorkbench().getOperationSupport().getOperationHistory();
405 }
406
407 /**
408 * <p>
409 * setStatusLine
410 * </p>
411 *
412 * @param message
413 * a {@link java.lang.String} object.
414 */
415 public static void setStatusLine(final String message) {
416 Display.getDefault().asyncExec(new Runnable() {
417
418 @Override
419 public void run() {
420 statusLineManager.setMessage(message);
421 }
422
423 });
424
425 }
426
427 /**
428 * <p>
429 * getMonitor
430 * </p>
431 *
432 * @return a {@link org.eclipse.core.runtime.IProgressMonitor} object.
433 */
434 public static IProgressMonitor getMonitor() {
435 statusLineManager.setCancelEnabled(false);
436 return statusLineManager.getProgressMonitor();
437 }
438
439 /**
440 * Starts either the given {@link IProgressMonitor} if it's not
441 * <code>null</code> or a new {@link NullProgressMonitor}.
442 *
443 * @param progressMonitor
444 * The {@link IProgressMonitor} or <code>null</code> if no
445 * progress should be reported.
446 * @param taskName
447 * The name of the main task.
448 * @param steps
449 * The number of steps this task is subdivided into.
450 * @return The {@link IProgressMonitor}.
451 */
452 public static IProgressMonitor startMainMonitor(
453 IProgressMonitor progressMonitor, String taskName, int steps) {
454 IProgressMonitor newMonitor = progressMonitor;
455 if (newMonitor == null) {
456 newMonitor = new NullProgressMonitor();
457 }
458 newMonitor.beginTask(taskName == null ? "" : taskName, steps);
459 newMonitor.subTask(" ");
460 return newMonitor;
461 }
462
463 /**
464 * Creates a {@link SubProgressMonitor} if the given
465 * {@link IProgressMonitor} is not <code>null</code> and not a
466 * {@link NullProgressMonitor}.
467 *
468 * @param progressMonitor
469 * The parent {@link IProgressMonitor} of the
470 * {@link SubProgressMonitor} to be created.
471 * @param ticks
472 * The number of steps this subtask is subdivided into. Must be a
473 * positive number and must not be
474 * {@link IProgressMonitor#UNKNOWN}.
475 * @return The {@link IProgressMonitor}.
476 */
477 public static IProgressMonitor getSubProgressMonitor(
478 IProgressMonitor progressMonitor, int ticks) {
479 if (progressMonitor == null) {
480 return new NullProgressMonitor();
481 }
482 if (progressMonitor instanceof NullProgressMonitor) {
483 return progressMonitor;
484 }
485
486 return new SubProgressMonitor(progressMonitor, ticks);
487 }
488
489 /**
490 * Checks whether the user canceled this operation. If not canceled, the
491 * given number of steps are declared as done.
492 *
493 * @param newMonitor
494 * a {@link org.eclipse.core.runtime.IProgressMonitor} object.
495 * @param steps
496 * a int.
497 */
498 public static void workedChecked(IProgressMonitor newMonitor, int steps) {
499 // In case the progress monitor was canceled throw an exception.
500 if (newMonitor.isCanceled()) {
501 throw new OperationCanceledException();
502 }
503 // Otherwise declare this step as done.
504 newMonitor.worked(steps);
505 }
506
507 /**
508 * Present a progress dialog to the user. This dialog will block the UI
509 *
510 * @param runnable
511 * an implementation of {@link IRunnableWithProgress}
512 * @throws java.lang.InterruptedException
513 * if any.
514 * @throws java.lang.reflect.InvocationTargetException
515 * if any.
516 */
517 public static void busyCursorWhile(IRunnableWithProgress runnable)
518 throws InvocationTargetException, InterruptedException {
519 getProgressService().busyCursorWhile(runnable);
520 }
521
522 /**
523 * <p>
524 * runInUI
525 * </p>
526 *
527 * @see {@link IProgressService#runInUI(org.eclipse.jface.operation.IRunnableContext, IRunnableWithProgress, ISchedulingRule)}
528 * @param runnable
529 * a {@link org.eclipse.jface.operation.IRunnableWithProgress}
530 * object.
531 * @param rule
532 * a {@link org.eclipse.core.runtime.jobs.ISchedulingRule}
533 * object.
534 * @throws java.lang.reflect.InvocationTargetException
535 * if any.
536 * @throws java.lang.InterruptedException
537 * if any.
538 */
539 public static void runInUI(IRunnableWithProgress runnable,
540 ISchedulingRule rule) throws InvocationTargetException,
541 InterruptedException {
542 getProgressService().runInUI(getWorkbenchWindow(), runnable, rule);
543 }
544
545 /**
546 * <p>
547 * run
548 * </p>
549 *
550 * @param fork
551 * a boolean.
552 * @param cancelable
553 * a boolean.
554 * @param runnable
555 * a {@link org.eclipse.jface.operation.IRunnableWithProgress}
556 * object.
557 * @throws java.lang.reflect.InvocationTargetException
558 * if any.
559 * @throws java.lang.InterruptedException
560 * if any.
561 */
562 public static void run(boolean fork, boolean cancelable,
563 IRunnableWithProgress runnable) throws InvocationTargetException,
564 InterruptedException {
565 getProgressService().run(fork, cancelable, runnable);
566 }
567
568 /**
569 * <p>
570 * getProgressService
571 * </p>
572 *
573 * @return a {@link org.eclipse.ui.progress.IProgressService} object.
574 */
575 public static IProgressService getProgressService() {
576 IWorkbench workbench = PlatformUI.getWorkbench();
577 return workbench.getProgressService();
578 }
579
580 /**
581 * <p>
582 * getProgressService2
583 * </p>
584 *
585 * @return a {@link org.eclipse.ui.progress.IWorkbenchSiteProgressService}
586 * object.
587 */
588 public static IWorkbenchSiteProgressService getProgressService2() {
589 return (IWorkbenchSiteProgressService) getService(IWorkbenchSiteProgressService.class);
590 }
591
592 /**
593 * <p>
594 * getPluginId
595 * </p>
596 *
597 * @return a {@link java.lang.String} object.
598 */
599 public static String getPluginId() {
600 return "eu.taxeditor";
601 }
602
603 /**
604 * <p>
605 * getActiveEditor
606 * </p>
607 *
608 * @return a {@link org.eclipse.ui.IEditorPart} object.
609 */
610 public static IEditorPart getActiveEditor() {
611 return getActivePage() != null ? getActivePage().getActiveEditor()
612 : null;
613 }
614
615 /**
616 * <p>
617 * getDetailsView
618 * </p>
619 *
620 * @return a {@link eu.etaxonomy.taxeditor.view.detail.DetailsViewPart}
621 * object.
622 */
623 public static DetailsViewPart getDetailsView() {
624 return (DetailsViewPart) getView(DetailsViewPart.ID, false);
625 }
626
627 /**
628 * <p>
629 * refreshDetailsViewer
630 * </p>
631 */
632 public static void refreshDetailsViewer() {
633 if (getDetailsView() != null) {
634 ((AbstractCdmDataViewer) getDetailsView().getViewer()).refresh();
635 }
636 }
637
638 /**
639 * <p>
640 * reflowDetailsViewer
641 * </p>
642 */
643 public static void reflowDetailsViewer() {
644 if (getDetailsView() != null) {
645 ((AbstractCdmDataViewer) getDetailsView().getViewer()).reflow();
646 }
647 }
648
649 public static SupplementalDataViewPart getSupplementalDataView() {
650 return (SupplementalDataViewPart) getView(SupplementalDataViewPart.ID,
651 false);
652 }
653
654 public static void reflowSupplementalViewer() {
655 if (getSupplementalDataView() != null) {
656 ((AbstractCdmDataViewer) getSupplementalDataView().getViewer())
657 .reflow();
658 }
659 }
660
661
662 /**
663 * Orders a Collection of {@link IEnumTerm}s according to the term
664 * hierarchy. <br>
665 * <br>
666 * The returned map will be be ordered primarily by root elements,
667 * secondarily by the child elements and their children resp., both ascending alphabetically. <br>
668 * @param terms
669 * A {@link Collection} of {@link IEnumTerm}s for which the term
670 * hierarchy should be created
671 * @return a map which holds the terms as keys and their string
672 * representation via {@link IEnumTerm#getMessage()} as values
673 */
674 public static <T extends IEnumTerm<T>> LinkedHashMap<T, String> orderTerms(Collection<T> terms) {
675 TreeSet<TermNode<T>> parentElements = new TreeSet<TermNode<T>>();
676 parentElements.addAll(getTermHierarchy(terms));
677
678 // create list according to the type hierarchy (root elements alphabetically with recursive children also alphabetically)
679 LinkedHashMap<T, String> result = new LinkedHashMap<T, String>();
680 parseTermTree(parentElements, result, -1);
681 return result;
682 }
683
684 private static<T extends IEnumTerm<T>> void parseTermTree(Collection<TermNode<T>> children, LinkedHashMap<T, String> result, int depth){
685 depth++;
686 for(TermNode<T> node:children){
687 String indentString = "";
688 for(int i=0;i<depth;i++){
689 indentString += " ";
690 }
691 if(depth>0){
692 indentString += "- ";
693 }
694 result.put(node.term, indentString + node.term.getMessage());
695 parseTermTree(node.children, result, depth);
696 }
697 }
698
699 private static<T extends IEnumTerm<T>> void addToParents(List<TermNode<T>> parents, Collection<T> terms){
700 List<TermNode<T>> hasChildrenList = new ArrayList<TermNode<T>>();
701 for(T term:terms){
702 // only terms with parents
703 if(term.getKindOf()!=null){
704 TermNode<T> parentNode = new TermNode<T>(term.getKindOf());
705 TermNode<T> childNode = new TermNode<T>(term);
706 if(parents.contains(parentNode)){
707 // parent found in parent list -> add this term to parent's child list
708 parents.get(parents.indexOf(parentNode)).addChild(childNode);
709 if(!term.getGeneralizationOf().isEmpty()){
710 // has more children -> add to list which will be the parent for the next recursion
711 hasChildrenList.add(childNode);
712 }
713 }
714 }
715 }
716 if(!hasChildrenList.isEmpty()){
717 addToParents(hasChildrenList, terms);
718 }
719 }
720
721 private static<T extends IEnumTerm<T>> List<TermNode<T>> getTermHierarchy(Collection<T> terms){
722 List<TermNode<T>> parents = new ArrayList<TermNode<T>>();
723 // get root elements
724 for(T term:terms){
725 T parentTerm = term.getKindOf();
726 if(parentTerm==null){
727 // root element
728 parents.add(new TermNode<T>(term));
729 }
730 }
731 addToParents(parents, terms);
732 return parents;
733 }
734
735 @SuppressWarnings("unchecked")
736 /**
737 * Recursively iterates over all term parents until no more parent is found i.e. the root node
738 * @param term The term for which the parent should be found
739 * @return the root terms of the term hierarchy
740 */
741 private static<T extends IEnumTerm<T>> T getParentFor(T term){
742 // PP: cast should be safe. Why is Eclipse complaining??
743 T parent = term.getKindOf();
744 if(parent==null){
745 return term;
746 }
747 else{
748 return getParentFor(term.getKindOf());
749 }
750 }
751
752 private static class TermNode<T extends IEnumTerm<T>> implements Comparable<TermNode<T>>{
753 private final T term;
754 private final TreeSet<TermNode<T>> children;
755
756 /**
757 * @param term
758 * @param children
759 */
760 public TermNode(T term) {
761 super();
762 this.term = term;
763 this.children = new TreeSet<TermNode<T>>();
764 }
765
766 public void addChild(TermNode<T> child){
767 this.children.add(child);
768 }
769
770 /**
771 * @return the children
772 */
773 public TreeSet<TermNode<T>> getChildren() {
774 return children;
775 }
776
777 /**
778 * @return the term
779 */
780 public T getTerm() {
781 return term;
782 }
783
784 /* (non-Javadoc)
785 * @see java.lang.Object#hashCode()
786 */
787 @Override
788 public int hashCode() {
789 final int prime = 31;
790 int result = 1;
791 result = prime * result + ((term == null) ? 0 : term.hashCode());
792 return result;
793 }
794
795 /* (non-Javadoc)
796 * @see java.lang.Object#equals(java.lang.Object)
797 */
798 @Override
799 public boolean equals(Object obj) {
800 if (this == obj) {
801 return true;
802 }
803 if (obj == null) {
804 return false;
805 }
806 if (getClass() != obj.getClass()) {
807 return false;
808 }
809 TermNode other = (TermNode) obj;
810 if (term == null) {
811 if (other.term != null) {
812 return false;
813 }
814 } else if (!term.equals(other.term)) {
815 return false;
816 }
817 return true;
818 }
819
820 /* (non-Javadoc)
821 * @see java.lang.Comparable#compareTo(java.lang.Object)
822 */
823 @Override
824 public int compareTo(TermNode<T> that) {
825 return this.term.getMessage().compareTo(that.term.getMessage());
826 }
827 }
828
829
830 public static void executeCommand(String commandId, Object source, String pluginId) {
831 IHandlerService handlerService = (IHandlerService) AbstractUtility.getService(IHandlerService.class);
832 Exception exception = null;
833 try {
834 handlerService.executeCommand(commandId, null);
835 } catch (ExecutionException e) {
836 exception = e;
837 } catch (NotDefinedException e) {
838 exception = e;
839 } catch (NotEnabledException e) {
840 exception = e;
841 } catch (NotHandledException e) {
842 exception = e;
843 } finally {
844 if(exception != null) {
845 MessagingUtils.errorDialog("Error executing command",
846 source,
847 "Could not execute command with id " + commandId ,
848 pluginId,
849 exception,
850 true);
851 }
852 }
853 }
854 }