Merge branch 'develop' of wp5.e-taxonomy.eu:/var/git/taxeditor 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 handler.postOperation(status);
372 } catch (ExecutionException e) {
373 MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
374 } finally {
375 monitor.done();
376 }
377
378 String statusString = status.equals(Status.OK_STATUS) ? "completed"
379 : "cancelled";
380 setStatusLine(operationlabel + " " + statusString + ".");
381
382 }
383 };
384
385 try {
386 runInUI(runnable, null);
387 } catch (Exception e) {
388 MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
389 }
390
391 return Status.OK_STATUS;
392 }
393 /**
394 * <p>
395 * getOperationHistory
396 * </p>
397 *
398 * @return a {@link org.eclipse.core.commands.operations.IOperationHistory}
399 * object.
400 */
401 public static IOperationHistory getOperationHistory() {
402 return getWorkbench().getOperationSupport().getOperationHistory();
403 }
404
405 /**
406 * <p>
407 * setStatusLine
408 * </p>
409 *
410 * @param message
411 * a {@link java.lang.String} object.
412 */
413 public static void setStatusLine(final String message) {
414 Display.getDefault().asyncExec(new Runnable() {
415
416 @Override
417 public void run() {
418 statusLineManager.setMessage(message);
419 }
420
421 });
422
423 }
424
425 /**
426 * <p>
427 * getMonitor
428 * </p>
429 *
430 * @return a {@link org.eclipse.core.runtime.IProgressMonitor} object.
431 */
432 public static IProgressMonitor getMonitor() {
433 statusLineManager.setCancelEnabled(false);
434 return statusLineManager.getProgressMonitor();
435 }
436
437 /**
438 * Starts either the given {@link IProgressMonitor} if it's not
439 * <code>null</code> or a new {@link NullProgressMonitor}.
440 *
441 * @param progressMonitor
442 * The {@link IProgressMonitor} or <code>null</code> if no
443 * progress should be reported.
444 * @param taskName
445 * The name of the main task.
446 * @param steps
447 * The number of steps this task is subdivided into.
448 * @return The {@link IProgressMonitor}.
449 */
450 public static IProgressMonitor startMainMonitor(
451 IProgressMonitor progressMonitor, String taskName, int steps) {
452 IProgressMonitor newMonitor = progressMonitor;
453 if (newMonitor == null) {
454 newMonitor = new NullProgressMonitor();
455 }
456 newMonitor.beginTask(taskName == null ? "" : taskName, steps);
457 newMonitor.subTask(" ");
458 return newMonitor;
459 }
460
461 /**
462 * Creates a {@link SubProgressMonitor} if the given
463 * {@link IProgressMonitor} is not <code>null</code> and not a
464 * {@link NullProgressMonitor}.
465 *
466 * @param progressMonitor
467 * The parent {@link IProgressMonitor} of the
468 * {@link SubProgressMonitor} to be created.
469 * @param ticks
470 * The number of steps this subtask is subdivided into. Must be a
471 * positive number and must not be
472 * {@link IProgressMonitor#UNKNOWN}.
473 * @return The {@link IProgressMonitor}.
474 */
475 public static IProgressMonitor getSubProgressMonitor(
476 IProgressMonitor progressMonitor, int ticks) {
477 if (progressMonitor == null) {
478 return new NullProgressMonitor();
479 }
480 if (progressMonitor instanceof NullProgressMonitor) {
481 return progressMonitor;
482 }
483
484 return new SubProgressMonitor(progressMonitor, ticks);
485 }
486
487 /**
488 * Checks whether the user canceled this operation. If not canceled, the
489 * given number of steps are declared as done.
490 *
491 * @param newMonitor
492 * a {@link org.eclipse.core.runtime.IProgressMonitor} object.
493 * @param steps
494 * a int.
495 */
496 public static void workedChecked(IProgressMonitor newMonitor, int steps) {
497 // In case the progress monitor was canceled throw an exception.
498 if (newMonitor.isCanceled()) {
499 throw new OperationCanceledException();
500 }
501 // Otherwise declare this step as done.
502 newMonitor.worked(steps);
503 }
504
505 /**
506 * Present a progress dialog to the user. This dialog will block the UI
507 *
508 * @param runnable
509 * an implementation of {@link IRunnableWithProgress}
510 * @throws java.lang.InterruptedException
511 * if any.
512 * @throws java.lang.reflect.InvocationTargetException
513 * if any.
514 */
515 public static void busyCursorWhile(IRunnableWithProgress runnable)
516 throws InvocationTargetException, InterruptedException {
517 getProgressService().busyCursorWhile(runnable);
518 }
519
520 /**
521 * <p>
522 * runInUI
523 * </p>
524 *
525 * @see {@link IProgressService#runInUI(org.eclipse.jface.operation.IRunnableContext, IRunnableWithProgress, ISchedulingRule)}
526 * @param runnable
527 * a {@link org.eclipse.jface.operation.IRunnableWithProgress}
528 * object.
529 * @param rule
530 * a {@link org.eclipse.core.runtime.jobs.ISchedulingRule}
531 * object.
532 * @throws java.lang.reflect.InvocationTargetException
533 * if any.
534 * @throws java.lang.InterruptedException
535 * if any.
536 */
537 public static void runInUI(IRunnableWithProgress runnable,
538 ISchedulingRule rule) throws InvocationTargetException,
539 InterruptedException {
540 getProgressService().runInUI(getWorkbenchWindow(), runnable, rule);
541 }
542
543 /**
544 * <p>
545 * run
546 * </p>
547 *
548 * @param fork
549 * a boolean.
550 * @param cancelable
551 * a boolean.
552 * @param runnable
553 * a {@link org.eclipse.jface.operation.IRunnableWithProgress}
554 * object.
555 * @throws java.lang.reflect.InvocationTargetException
556 * if any.
557 * @throws java.lang.InterruptedException
558 * if any.
559 */
560 public static void run(boolean fork, boolean cancelable,
561 IRunnableWithProgress runnable) throws InvocationTargetException,
562 InterruptedException {
563 getProgressService().run(fork, cancelable, runnable);
564 }
565
566 /**
567 * <p>
568 * getProgressService
569 * </p>
570 *
571 * @return a {@link org.eclipse.ui.progress.IProgressService} object.
572 */
573 public static IProgressService getProgressService() {
574 IWorkbench workbench = PlatformUI.getWorkbench();
575 return workbench.getProgressService();
576 }
577
578 /**
579 * <p>
580 * getProgressService2
581 * </p>
582 *
583 * @return a {@link org.eclipse.ui.progress.IWorkbenchSiteProgressService}
584 * object.
585 */
586 public static IWorkbenchSiteProgressService getProgressService2() {
587 return (IWorkbenchSiteProgressService) getService(IWorkbenchSiteProgressService.class);
588 }
589
590 /**
591 * <p>
592 * getPluginId
593 * </p>
594 *
595 * @return a {@link java.lang.String} object.
596 */
597 public static String getPluginId() {
598 return "eu.taxeditor";
599 }
600
601 /**
602 * <p>
603 * getActiveEditor
604 * </p>
605 *
606 * @return a {@link org.eclipse.ui.IEditorPart} object.
607 */
608 public static IEditorPart getActiveEditor() {
609 return getActivePage() != null ? getActivePage().getActiveEditor()
610 : null;
611 }
612
613 /**
614 * <p>
615 * getDetailsView
616 * </p>
617 *
618 * @return a {@link eu.etaxonomy.taxeditor.view.detail.DetailsViewPart}
619 * object.
620 */
621 public static DetailsViewPart getDetailsView() {
622 return (DetailsViewPart) getView(DetailsViewPart.ID, false);
623 }
624
625 /**
626 * <p>
627 * refreshDetailsViewer
628 * </p>
629 */
630 public static void refreshDetailsViewer() {
631 if (getDetailsView() != null) {
632 ((AbstractCdmDataViewer) getDetailsView().getViewer()).refresh();
633 }
634 }
635
636 /**
637 * <p>
638 * reflowDetailsViewer
639 * </p>
640 */
641 public static void reflowDetailsViewer() {
642 if (getDetailsView() != null) {
643 ((AbstractCdmDataViewer) getDetailsView().getViewer()).reflow();
644 }
645 }
646
647 public static SupplementalDataViewPart getSupplementalDataView() {
648 return (SupplementalDataViewPart) getView(SupplementalDataViewPart.ID,
649 false);
650 }
651
652 public static void reflowSupplementalViewer() {
653 if (getSupplementalDataView() != null) {
654 ((AbstractCdmDataViewer) getSupplementalDataView().getViewer())
655 .reflow();
656 }
657 }
658
659
660 /**
661 * Orders a Collection of {@link IEnumTerm}s according to the term
662 * hierarchy. <br>
663 * <br>
664 * The returned map will be be ordered primarily by root elements,
665 * secondarily by the child elements and their children resp., both ascending alphabetically. <br>
666 * @param terms
667 * A {@link Collection} of {@link IEnumTerm}s for which the term
668 * hierarchy should be created
669 * @return a map which holds the terms as keys and their string
670 * representation via {@link IEnumTerm#getMessage()} as values
671 */
672 public static <T extends IEnumTerm<T>> LinkedHashMap<T, String> orderTerms(Collection<T> terms) {
673 TreeSet<TermNode<T>> parentElements = new TreeSet<TermNode<T>>();
674 parentElements.addAll(getTermHierarchy(terms));
675
676 // create list according to the type hierarchy (root elements alphabetically with recursive children also alphabetically)
677 LinkedHashMap<T, String> result = new LinkedHashMap<T, String>();
678 parseTermTree(parentElements, result, -1);
679 return result;
680 }
681
682 private static<T extends IEnumTerm<T>> void parseTermTree(Collection<TermNode<T>> children, LinkedHashMap<T, String> result, int depth){
683 depth++;
684 for(TermNode<T> node:children){
685 String indentString = "";
686 for(int i=0;i<depth;i++){
687 indentString += " ";
688 }
689 if(depth>0){
690 indentString += "- ";
691 }
692 result.put(node.term, indentString + node.term.getMessage());
693 parseTermTree(node.children, result, depth);
694 }
695 }
696
697 private static<T extends IEnumTerm<T>> void addToParents(List<TermNode<T>> parents, Collection<T> terms){
698 List<TermNode<T>> hasChildrenList = new ArrayList<TermNode<T>>();
699 for(T term:terms){
700 // only terms with parents
701 if(term.getKindOf()!=null){
702 TermNode<T> parentNode = new TermNode<T>(term.getKindOf());
703 TermNode<T> childNode = new TermNode<T>(term);
704 if(parents.contains(parentNode)){
705 // parent found in parent list -> add this term to parent's child list
706 parents.get(parents.indexOf(parentNode)).addChild(childNode);
707 if(!term.getGeneralizationOf().isEmpty()){
708 // has more children -> add to list which will be the parent for the next recursion
709 hasChildrenList.add(childNode);
710 }
711 }
712 }
713 }
714 if(!hasChildrenList.isEmpty()){
715 addToParents(hasChildrenList, terms);
716 }
717 }
718
719 private static<T extends IEnumTerm<T>> List<TermNode<T>> getTermHierarchy(Collection<T> terms){
720 List<TermNode<T>> parents = new ArrayList<TermNode<T>>();
721 // get root elements
722 for(T term:terms){
723 T parentTerm = term.getKindOf();
724 if(parentTerm==null){
725 // root element
726 parents.add(new TermNode<T>(term));
727 }
728 }
729 addToParents(parents, terms);
730 return parents;
731 }
732
733 @SuppressWarnings("unchecked")
734 /**
735 * Recursively iterates over all term parents until no more parent is found i.e. the root node
736 * @param term The term for which the parent should be found
737 * @return the root terms of the term hierarchy
738 */
739 private static<T extends IEnumTerm<T>> T getParentFor(T term){
740 // PP: cast should be safe. Why is Eclipse complaining??
741 T parent = term.getKindOf();
742 if(parent==null){
743 return term;
744 }
745 else{
746 return getParentFor(term.getKindOf());
747 }
748 }
749
750 private static class TermNode<T extends IEnumTerm<T>> implements Comparable<TermNode<T>>{
751 private final T term;
752 private final TreeSet<TermNode<T>> children;
753
754 /**
755 * @param term
756 * @param children
757 */
758 public TermNode(T term) {
759 super();
760 this.term = term;
761 this.children = new TreeSet<TermNode<T>>();
762 }
763
764 public void addChild(TermNode<T> child){
765 this.children.add(child);
766 }
767
768 /**
769 * @return the children
770 */
771 public TreeSet<TermNode<T>> getChildren() {
772 return children;
773 }
774
775 /**
776 * @return the term
777 */
778 public T getTerm() {
779 return term;
780 }
781
782 /* (non-Javadoc)
783 * @see java.lang.Object#hashCode()
784 */
785 @Override
786 public int hashCode() {
787 final int prime = 31;
788 int result = 1;
789 result = prime * result + ((term == null) ? 0 : term.hashCode());
790 return result;
791 }
792
793 /* (non-Javadoc)
794 * @see java.lang.Object#equals(java.lang.Object)
795 */
796 @Override
797 public boolean equals(Object obj) {
798 if (this == obj) {
799 return true;
800 }
801 if (obj == null) {
802 return false;
803 }
804 if (getClass() != obj.getClass()) {
805 return false;
806 }
807 TermNode other = (TermNode) obj;
808 if (term == null) {
809 if (other.term != null) {
810 return false;
811 }
812 } else if (!term.equals(other.term)) {
813 return false;
814 }
815 return true;
816 }
817
818 /* (non-Javadoc)
819 * @see java.lang.Comparable#compareTo(java.lang.Object)
820 */
821 @Override
822 public int compareTo(TermNode<T> that) {
823 return this.term.getMessage().compareTo(that.term.getMessage());
824 }
825 }
826
827
828 public static void executeCommand(String commandId, Object source, String pluginId) {
829 IHandlerService handlerService = (IHandlerService) AbstractUtility.getService(IHandlerService.class);
830 Exception exception = null;
831 try {
832 handlerService.executeCommand(commandId, null);
833 } catch (ExecutionException e) {
834 exception = e;
835 } catch (NotDefinedException e) {
836 exception = e;
837 } catch (NotEnabledException e) {
838 exception = e;
839 } catch (NotHandledException e) {
840 exception = e;
841 } finally {
842 if(exception != null) {
843 MessagingUtils.errorDialog("Error executing command",
844 source,
845 "Could not execute command with id " + commandId ,
846 pluginId,
847 exception,
848 true);
849 }
850 }
851 }
852 }