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