Project

General

Profile

Download (32.7 KB) Statistics
| Branch: | Tag: | Revision:
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.FontRegistry;
52
import org.eclipse.jface.viewers.IStructuredSelection;
53
import org.eclipse.jface.viewers.SelectionChangedEvent;
54
import org.eclipse.swt.graphics.Color;
55
import org.eclipse.swt.graphics.Font;
56
import org.eclipse.swt.widgets.Display;
57
import org.eclipse.swt.widgets.Shell;
58
import org.eclipse.ui.IWorkbench;
59
import org.eclipse.ui.PlatformUI;
60
import org.eclipse.ui.handlers.IHandlerService;
61
import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
62
import org.eclipse.ui.progress.IProgressConstants;
63
import org.eclipse.ui.progress.IProgressService;
64
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
65
import org.eclipse.ui.themes.ITheme;
66
import org.eclipse.ui.themes.IThemeManager;
67

    
68
import eu.etaxonomy.cdm.api.application.CdmApplicationState;
69
import eu.etaxonomy.cdm.api.service.IProgressMonitorService;
70
import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
71
import eu.etaxonomy.cdm.io.common.ExportDataWrapper;
72
import eu.etaxonomy.cdm.io.common.ExportResult;
73
import eu.etaxonomy.cdm.io.common.ExportResultType;
74
import eu.etaxonomy.cdm.io.common.ExportType;
75
import eu.etaxonomy.cdm.model.common.IEnumTerm;
76
import eu.etaxonomy.taxeditor.event.EventUtility;
77
import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
78
import eu.etaxonomy.taxeditor.operation.IFeedbackGenerator;
79
import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
80
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
81
import eu.etaxonomy.taxeditor.operation.RemotingCdmHandler;
82
import eu.etaxonomy.taxeditor.operation.e4.RemotingCdmHandlerE4;
83
import eu.etaxonomy.taxeditor.store.CdmStore;
84
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
85
import eu.etaxonomy.taxeditor.ui.dialog.ReportTextDialog;
86
import eu.etaxonomy.taxeditor.view.e4.AbstractCdmDataViewerE4;
87
import eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4;
88
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
89

    
90
/**
91
 *
92
 * @author n.hoffmann
93
 * @created 11.05.2009
94
 * @version 1.0
95
 */
96
public abstract class AbstractUtility {
97

    
98
    private static final Logger logger = Logger.getLogger(AbstractUtility.class);
99

    
100
    /** Constant <code>statusLineManager</code> */
101
    protected static IStatusLineManager statusLineManager;
102
    /** Constant <code>DATE_FORMAT_NOW="yyyyMMddHHmm"</code> */
103
   	public static final String DATE_FORMAT_NOW = "yyyyMMddHHmm";
104

    
105
    public static Object getActivePart() {
106
        MPart activePart = EventUtility.getActivePart();
107
        if(activePart!=null){
108
            return activePart.getObject();
109
        }
110
        return null;
111
    }
112

    
113
    public static Shell getShell() {
114
        return EventUtility.getShell();
115
    }
116

    
117
    public static IWorkbench getWorkbench() {
118
        return TaxeditorStorePlugin.getDefault().getWorkbench();
119
    }
120

    
121
    public static Object getService(Class api) {
122
        return TaxeditorStorePlugin.getDefault().getWorkbench().getService(api);
123
    }
124

    
125
    public static ITheme getCurrentTheme() {
126
        IThemeManager themeManager = TaxeditorStorePlugin.getDefault()
127
                .getWorkbench().getThemeManager();
128
        return themeManager.getCurrentTheme();
129
    }
130

    
131
    /**
132
     * Fonts registered to the plugin may be obtained with the Eclipse themeing
133
     * functionality. Thus fonts are chooseable by the user via
134
     * Preferences->General->Appearance->Colors and Fonts
135
     *
136
     * @return the FontRegistry for the current theme
137
     */
138
    public static FontRegistry getFontRegistry() {
139
        return getCurrentTheme().getFontRegistry();
140
    }
141

    
142
    public static Font getFont(String symbolicName) {
143
        return getFontRegistry().get(symbolicName);
144
    }
145

    
146
    public static Color getColor(String symbolicName) {
147
        return ColorResources.getColor(symbolicName);
148
    }
149

    
150
    public static IStatus executeOperation(final AbstractPostOperation operation, UISynchronize sync) {
151
        if (getOperationHistory() == null) {
152
            throw new IllegalArgumentException(
153
                    "There is no operation history for this context");
154
        }
155

    
156
        final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
157
                .getUIInfoAdapter(getShell());
158

    
159
        Job job = Job.create(operation.getLabel(), (ICoreRunnable) monitor -> {
160
            sync.syncExec(() -> {
161
                String operationlabel = operation.getLabel();
162
                monitor.beginTask(operationlabel, 100);
163
                IStatus status = Status.CANCEL_STATUS;
164
                try {
165
                    operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
166
                    status = operation.execute(monitor, uiInfoAdapter);
167
                } catch (ExecutionException e) {
168

    
169
                    MessagingUtils.operationDialog(AbstractUtility.class, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
170

    
171
                } finally {
172
                    monitor.done();
173
                }
174

    
175
                String statusString = status.equals(Status.OK_STATUS) ? "completed"
176
                        : "cancelled";
177
                setStatusLine(operationlabel + " " + statusString + ".");
178
            });
179
        });
180

    
181
        try {
182
            job.setUser(true);
183
            job.schedule();
184
        } catch (Exception e) {
185
            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
186
        }
187

    
188
        IPostOperationEnabled postOperationEnabled = operation
189
                .getPostOperationEnabled();
190
        if (postOperationEnabled != null) {
191
            postOperationEnabled.onComplete();
192
        }
193
        return Status.OK_STATUS;
194
    }
195

    
196
    public static IStatus executeOperation(final AbstractOperation operation, final RemotingCdmHandlerE4 handler, UISynchronize sync) {
197
        return executeOperation_internal(operation, handler, sync);
198
    }
199

    
200
    public static IStatus executeOperation(final AbstractOperation operation, final RemotingCdmHandler handler, UISynchronize sync) {
201
        return executeOperation_internal(operation, handler, sync);
202
    }
203

    
204
    private static IStatus executeOperation_internal(final AbstractOperation operation, final Object handler,
205
            UISynchronize sync) {
206
        if (getOperationHistory() == null) {
207
            throw new IllegalArgumentException(
208
                    "There is no operation history for this context");
209
        }
210

    
211
        final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
212
                .getUIInfoAdapter(getShell());
213

    
214

    
215
        Job job = Job.create(operation.getLabel(), (ICoreRunnable) monitor -> {
216
            sync.syncExec(() -> {
217
                String operationlabel = operation.getLabel();
218
                monitor.beginTask(operationlabel, 100);
219
                IStatus status = Status.CANCEL_STATUS;
220
                try {
221
                    operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
222
                    status = operation.execute(monitor,
223
                            uiInfoAdapter);
224
                    if(handler instanceof RemotingCdmHandler) {
225
                        ((RemotingCdmHandler) handler).postOperation(status);
226
                    }
227
                    else if(handler instanceof RemotingCdmHandlerE4) {
228
                        ((RemotingCdmHandlerE4) handler).postOperation(status);
229
                    }
230
                } catch (ExecutionException e) {
231
                    MessagingUtils.operationDialog(AbstractUtility.class, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
232
                } finally {
233
                    monitor.done();
234
                }
235

    
236
                String statusString = status.equals(Status.OK_STATUS) ? "completed"
237
                        : "cancelled";
238
                setStatusLine(operationlabel + " " + statusString + ".");
239
            });
240
        });
241

    
242
        try {
243
            job.setUser(true);
244
            sync.syncExec(()->job.schedule());
245
        } catch (Exception e) {
246
            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
247
        }
248

    
249
        return Status.OK_STATUS;
250
    }
251

    
252
    /**
253
     * Executes a remoting monitored operation
254
     *
255
     * @param label for the operation
256
     * @param uuid of the remoting monitor already started on the server
257
     * @param pollInterval in milliseconds
258
     * @param cancelable flag which determines whether the operation can be cancelled
259
     * @param postOp callback for running post operation logic
260
     * @return
261
     */
262
    public static IStatus executeMoniteredExport(final String label,
263
            final UUID uuid,
264
            final int pollInterval,
265
            final boolean cancelable,
266
            final IPostMoniteredOperationEnabled postOp,
267
            final IFeedbackGenerator feedbackGenerator,
268
            String urlString,
269
            boolean createZip) {
270

    
271
        try {
272
            // get the remoting monitor the first time to make sure that the
273
            // operation is valid
274
            final IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
275
            final IRemotingProgressMonitor firstRemotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
276
            if(firstRemotingMonitor == null) {
277
                throw new IllegalStateException("Remoting progress monitor is null");
278
            }
279

    
280
            Job job = new Job(label) {
281

    
282

    
283
                @Override
284
                public IStatus run(IProgressMonitor monitor) {
285
                    // run the monitor until the operation is finished
286
                	monitor.beginTask("Start", 100);
287
                    IRemotingProgressMonitor remotingMonitor;
288
                    try {
289
                        remotingMonitor = CdmStore.getProgressMonitorClientManager().pollMonitor(label,
290
                                uuid,
291
                                pollInterval,
292
                                postOp,
293
                                feedbackGenerator,
294
                                monitor);
295
                    } catch (Exception ex) {
296
                        return new Status(Status.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
297
                    }
298
                    final StringBuilder reportSb = new StringBuilder();
299
                    if (remotingMonitor.getResult() instanceof ExportResult){
300
                    	ExportResult result = (ExportResult)remotingMonitor.getResult();
301

    
302
	                    reportSb.append(result.createReport());
303

    
304
	                    if(!StringUtils.isBlank(reportSb.toString())) {
305
	                        Display.getDefault().asyncExec(new Runnable() {
306
	                            @Override
307
	                            public void run() {
308
	                                // display reports with possibility to save
309
	                                ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
310
	                                dialog.setTitle(label + " Report");
311
	                                dialog.setReportText(reportSb.toString());
312
	                                dialog.open();
313
	                            }
314
	                        });
315
	                    }
316

    
317
	                    if (urlString != null){
318
	                    	 ExportDataWrapper data = result.getExportData();
319
	                         try{
320
	                             if (result.getExportData().getType().equals(ExportResultType.BYTE_ARRAY)){
321
	                                 byte[] exportData = (byte[])data.getExportData();
322
	                                 if(exportData != null){
323
	                                     File file = new File(urlString);
324
	                                     FileOutputStream stream = new FileOutputStream(file);
325
	                                     Writer out = new BufferedWriter(new OutputStreamWriter(
326
	                                 			stream, "UTF8"));
327

    
328
	                                 	stream.write(exportData);
329
	                                    out.flush();
330
	                                    stream.close();
331
	                                 }
332
	                             } else if (result.getExportData().getType().equals(ExportResultType.MAP_BYTE_ARRAY)){
333
	                                 Map<String, byte[]> resultMap = (Map<String, byte[]>)data.getExportData();
334
	                                 Set<String> keySet = resultMap.keySet();
335
	                                 SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
336
	                                 Calendar cal = Calendar.getInstance();
337
	                                 String fileEnding = ".csv";
338

    
339
	                                 if (createZip){
340
	                            		 File file = new File(urlString+File.separator +  sdf.format(cal.getTime())+ ".zip");
341
	                                     FileOutputStream stream = new FileOutputStream(file);
342
	                                     ZipOutputStream zos = new ZipOutputStream(stream);
343
	                                     for (String key: keySet){
344
	                                    	byte[] fileData = resultMap.get(key);
345
	                                    	ZipEntry entry = new ZipEntry( key + fileEnding);
346
	         								zos.putNextEntry(entry);
347
	         								zos.write(fileData);
348
	         								zos.closeEntry();
349
	                                     }
350
	                                     zos.close();
351
	                            	 }else{
352
	                            		if(result.getExportType().equals(ExportType.DWCA)){
353

    
354
	                                        File file = new File(urlString);
355
	                                        FileOutputStream stream = new FileOutputStream(file);
356
	                                        ZipOutputStream zos = new ZipOutputStream(stream);
357
	                                        for (String key: keySet){
358
             	                               	byte[] fileData = resultMap.get(key);
359
             	                               	ZipEntry entry = new ZipEntry( key + fileEnding);
360
             	    								zos.putNextEntry(entry);
361
             	    								zos.write(fileData);
362
             	    								zos.closeEntry();
363
	                                         }
364
	                                         zos.close();
365
	                                      }else{
366
		                            		 for (String key: keySet){
367
		                            			 byte[] fileData = resultMap.get(key);
368
		                            			 File file = new File(urlString+File.separator + key + fileEnding);
369
		                                         FileOutputStream stream = new FileOutputStream(file);
370
		                                         Writer out = new BufferedWriter(new OutputStreamWriter(
371
		                                     			stream, "UTF8"));
372
		                                         stream.write(fileData);
373
		                                         stream.close();
374
		                                     }
375
	                                      }
376
	                            	 }
377
	                            }else{
378
	                                 logger.error("This kind of result data is not supported yet." + result.getExportData().getType().toString());
379
	                             }
380
	                         } catch(Exception e){
381
	                             logger.error(e.getStackTrace());
382
	                         }
383
	                    }
384
                    }
385
                    return Status.OK_STATUS;
386
                }
387

    
388
                @Override
389
                protected void canceling() {
390
                    CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
391
                }
392
            };
393

    
394
            // configure the job
395
            job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
396
            job.setUser(true);
397
            // schedule job
398
            job.schedule();
399

    
400
        } catch (Exception e) {
401
            MessagingUtils.errorDialog("Error executing operation",
402
                    AbstractUtility.class,
403
                    "An error occured while executing " + label,
404
                    TaxeditorStorePlugin.PLUGIN_ID,
405
                    e,
406
                    true);
407
        }
408

    
409
        return Status.OK_STATUS;
410
    }
411

    
412
    public static IOperationHistory getOperationHistory() {
413
        return getWorkbench().getOperationSupport().getOperationHistory();
414
    }
415

    
416
    public static void setStatusLine(final String message) {
417
        Display.getDefault().asyncExec(new Runnable() {
418

    
419
            @Override
420
            public void run() {
421
                statusLineManager.setMessage(message);
422
            }
423

    
424
        });
425

    
426
    }
427

    
428
    public static IProgressMonitor getMonitor() {
429
        statusLineManager.setCancelEnabled(false);
430
        return statusLineManager.getProgressMonitor();
431
    }
432

    
433
    /**
434
     * Starts either the given {@link IProgressMonitor} if it's not
435
     * <code>null</code> or a new {@link NullProgressMonitor}.
436
     *
437
     * @param progressMonitor
438
     *            The {@link IProgressMonitor} or <code>null</code> if no
439
     *            progress should be reported.
440
     * @param taskName
441
     *            The name of the main task.
442
     * @param steps
443
     *            The number of steps this task is subdivided into.
444
     * @return The {@link IProgressMonitor}.
445
     */
446
    public static IProgressMonitor startMainMonitor(
447
            IProgressMonitor progressMonitor, String taskName, int steps) {
448
        IProgressMonitor newMonitor = progressMonitor;
449
        if (newMonitor == null) {
450
            newMonitor = new NullProgressMonitor();
451
        }
452
        newMonitor.beginTask(taskName == null ? "" : taskName, steps);
453
        newMonitor.subTask(" ");
454
        return newMonitor;
455
    }
456

    
457
    /**
458
     * Creates a {@link SubProgressMonitor} if the given
459
     * {@link IProgressMonitor} is not <code>null</code> and not a
460
     * {@link NullProgressMonitor}.
461
     *
462
     * @param progressMonitor
463
     *            The parent {@link IProgressMonitor} of the
464
     *            {@link SubProgressMonitor} to be created.
465
     * @param ticks
466
     *            The number of steps this subtask is subdivided into. Must be a
467
     *            positive number and must not be
468
     *            {@link IProgressMonitor#UNKNOWN}.
469
     * @return The {@link IProgressMonitor}.
470
     */
471
    public static IProgressMonitor getSubProgressMonitor(
472
            IProgressMonitor progressMonitor, int ticks) {
473
        if (progressMonitor == null) {
474
            return new NullProgressMonitor();
475
        }
476
        if (progressMonitor instanceof NullProgressMonitor) {
477
            return progressMonitor;
478
        }
479

    
480
        return new SubProgressMonitor(progressMonitor, ticks);
481
    }
482

    
483
    /**
484
     * Checks whether the user canceled this operation. If not canceled, the
485
     * given number of steps are declared as done.
486
     *
487
     * @param newMonitor
488
     *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
489
     * @param steps
490
     *            a int.
491
     */
492
    public static void workedChecked(IProgressMonitor newMonitor, int steps) {
493
        // In case the progress monitor was canceled throw an exception.
494
        if (newMonitor.isCanceled()) {
495
            throw new OperationCanceledException();
496
        }
497
        // Otherwise declare this step as done.
498
        newMonitor.worked(steps);
499
    }
500

    
501
    public static IProgressService getProgressService() {
502
        IWorkbench workbench = PlatformUI.getWorkbench();
503
        return workbench.getProgressService();
504
    }
505

    
506
    public static IWorkbenchSiteProgressService getProgressService2() {
507
        return (IWorkbenchSiteProgressService) getService(IWorkbenchSiteProgressService.class);
508
    }
509

    
510
    public static String getPluginId() {
511
        return "eu.taxeditor";
512
    }
513

    
514
    public static Object getActiveEditor() {
515
        MPart activePart = EventUtility.getActivePart();
516
        if(activePart!=null && activePart.getObject()!=null
517
                && activePart.getObject() instanceof IE4SavablePart){
518
            return activePart.getObject();
519
        }
520
        return null;
521
    }
522

    
523
    public static DetailsPartE4 getDetailsView(EPartService partService) {
524
        MPart part = partService.findPart("eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4");
525
        if(part!=null){
526
            return (DetailsPartE4) part.getObject();
527
        }
528
        return null;
529
    }
530

    
531
    public static void refreshDetailsViewer(EPartService partService) {
532
        if (getDetailsView(partService) != null) {
533
            ((AbstractCdmDataViewerE4) getDetailsView(partService).getViewer()).refresh();
534
        }
535
    }
536

    
537
    public static void reflowDetailsViewer(EPartService partService) {
538
        if (getDetailsView(partService) != null) {
539
            ((AbstractCdmDataViewerE4) getDetailsView(partService).getViewer()).reflow();
540
        }
541
    }
542

    
543

    
544
    /**
545
     * Orders a Collection of {@link IEnumTerm}s according to the term
546
     * hierarchy. <br>
547
     * <br>
548
     * The returned map will be be ordered primarily by root elements,
549
     * secondarily by the child elements and their children resp., both ascending alphabetically. <br>
550
     * @param terms
551
     *            A {@link Collection} of {@link IEnumTerm}s for which the term
552
     *            hierarchy should be created
553
     * @return a map which holds the terms as keys and their string
554
     *         representation via {@link IEnumTerm#getMessage()} as values
555
     */
556
    public static <T extends IEnumTerm<T>> LinkedHashMap<T, String> orderTerms(Collection<T> terms) {
557
        TreeSet<TermNode<T>> parentElements = new TreeSet<TermNode<T>>();
558
        parentElements.addAll(getTermHierarchy(terms));
559

    
560
        // create list according to the type hierarchy (root elements alphabetically with recursive children also alphabetically)
561
        LinkedHashMap<T, String> result = new LinkedHashMap<T, String>();
562
        parseTermTree(parentElements, result, -1);
563
        return result;
564
    }
565

    
566
    private static<T extends IEnumTerm<T>> void parseTermTree(Collection<TermNode<T>> children, LinkedHashMap<T, String> result, int depth){
567
        depth++;
568
        for(TermNode<T> node:children){
569
            String indentString = "";
570
            for(int i=0;i<depth;i++){
571
                indentString += "  ";
572
            }
573
            if(depth>0){
574
                indentString += "- ";
575
            }
576
            result.put(node.term, indentString + node.term.getMessage());
577
            parseTermTree(node.children, result, depth);
578
        }
579
    }
580

    
581
    private static<T extends IEnumTerm<T>> void addToParents(List<TermNode<T>> parents, Collection<T> terms){
582
        List<TermNode<T>> hasChildrenList = new ArrayList<TermNode<T>>();
583
        for(T term:terms){
584
            // only terms with parents
585
            if(term.getKindOf()!=null){
586
                TermNode<T> parentNode = new TermNode<T>(term.getKindOf());
587
                TermNode<T> childNode = new TermNode<T>(term);
588
                if(parents.contains(parentNode)){
589
                    // parent found in parent list -> add this term to parent's child list
590
                    parents.get(parents.indexOf(parentNode)).addChild(childNode);
591
                    if(!term.getGeneralizationOf().isEmpty()){
592
                        // has more children -> add to list which will be the parent for the next recursion
593
                        hasChildrenList.add(childNode);
594
                    }
595
                }
596
            }
597
        }
598
        if(!hasChildrenList.isEmpty()){
599
            addToParents(hasChildrenList, terms);
600
        }
601
    }
602

    
603
    private static<T extends IEnumTerm<T>> List<TermNode<T>> getTermHierarchy(Collection<T> terms){
604
        List<TermNode<T>> parents = new ArrayList<TermNode<T>>();
605
        // get root elements
606
        for(T term:terms){
607
            T parentTerm = term.getKindOf();
608
            if(parentTerm==null){
609
                // root element
610
                parents.add(new TermNode<T>(term));
611
            }
612
        }
613
        addToParents(parents, terms);
614
        return parents;
615
    }
616

    
617
    @SuppressWarnings("unchecked")
618
    /**
619
     * Recursively iterates over all term parents until no more parent is found i.e. the root node
620
     * @param term The term for which the parent should be found
621
     * @return the root terms of the term hierarchy
622
     */
623
    private static<T extends IEnumTerm<T>> T getParentFor(T term){
624
        // PP: cast should be safe. Why is Eclipse complaining??
625
        T parent = term.getKindOf();
626
        if(parent==null){
627
            return term;
628
        }
629
        else{
630
            return getParentFor(term.getKindOf());
631
        }
632
    }
633

    
634
    private static class TermNode<T extends IEnumTerm<T>> implements Comparable<TermNode<T>>{
635
        private final T term;
636
        private final TreeSet<TermNode<T>> children;
637

    
638
        public TermNode(T term) {
639
            super();
640
            this.term = term;
641
            this.children = new TreeSet<TermNode<T>>();
642
        }
643

    
644
        public void addChild(TermNode<T> child){
645
            this.children.add(child);
646
        }
647

    
648
        public TreeSet<TermNode<T>> getChildren() {
649
            return children;
650
        }
651

    
652
        public T getTerm() {
653
            return term;
654
        }
655

    
656
        @Override
657
        public int hashCode() {
658
            final int prime = 31;
659
            int result = 1;
660
            result = prime * result + ((term == null) ? 0 : term.hashCode());
661
            return result;
662
        }
663

    
664
        @Override
665
        public boolean equals(Object obj) {
666
            if (this == obj) {
667
                return true;
668
            }
669
            if (obj == null) {
670
                return false;
671
            }
672
            if (getClass() != obj.getClass()) {
673
                return false;
674
            }
675
            TermNode other = (TermNode) obj;
676
            if (term == null) {
677
                if (other.term != null) {
678
                    return false;
679
                }
680
            } else if (!term.equals(other.term)) {
681
                return false;
682
            }
683
            return true;
684
        }
685

    
686
        @Override
687
        public int compareTo(TermNode<T> that) {
688
            return this.term.getMessage().compareTo(that.term.getMessage());
689
        }
690
    }
691

    
692

    
693
    public static void executeCommand(String commandId, Object source, String pluginId) {
694
        IHandlerService handlerService = (IHandlerService) AbstractUtility.getService(IHandlerService.class);
695
        Exception exception = null;
696
        try {
697
            handlerService.executeCommand(commandId, null);
698
        } catch (ExecutionException e) {
699
            exception = e;
700
        } catch (NotDefinedException e) {
701
            exception = e;
702
        } catch (NotEnabledException e) {
703
            exception = e;
704
        } catch (NotHandledException e) {
705
            exception = e;
706
        } finally {
707
            if(exception != null) {
708
                MessagingUtils.errorDialog("Error executing command",
709
                        source,
710
                        "Could not execute command with id " + commandId ,
711
                        pluginId,
712
                        exception,
713
                        true);
714
            }
715
        }
716
    }
717

    
718
    public static Object getElementsFromSelectionChangedEvent(SelectionChangedEvent event) {
719
        IStructuredSelection selection = (IStructuredSelection) event.getSelection();
720
        Object selectionToSet = selection;
721
        if(selection.size() == 1){
722
            selectionToSet = selection.getFirstElement();
723
        }
724
        else if(!selection.isEmpty()){
725
            selectionToSet = selection.toArray();
726
        }
727
        return selectionToSet;
728
    }
729

    
730
    /**
731
     * Executes a remoting monitored import
732
     *
733
     * @param label for the import
734
     * @param uuid of the remoting monitor already started on the server
735
     * @param pollInterval in milliseconds
736
     * @param cancelable flag which determines whether the operation can be cancelled
737
     * @param postOp callback for running post operation logic
738
     * @return
739
     */
740
    public static IStatus executeMoniteredOperation(final String label,
741
            final UUID uuid,
742
            final int pollInterval,
743
            final boolean cancelable,
744
            final IPostMoniteredOperationEnabled postOp,
745
            final IFeedbackGenerator feedbackGenerator) {
746

    
747
    	try{
748
    		// get the remoting monitor the first time to make sure that the
749
            // operation is valid
750
            final IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
751
            final IRemotingProgressMonitor firstRemotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
752
            if(firstRemotingMonitor == null) {
753
                throw new IllegalStateException("Remoting progress monitor is null");
754
            }
755

    
756
            Job job = new Job(label) {
757

    
758

    
759
                @Override
760
                public IStatus run(IProgressMonitor monitor) {
761
                    // run the monitor until the operation is finished
762
                	monitor.beginTask("Start", 100);
763
                    IRemotingProgressMonitor remotingMonitor;
764
                    try {
765
                        remotingMonitor = CdmStore.getProgressMonitorClientManager().pollMonitor(label,
766
                                uuid,
767
                                pollInterval,
768
                                postOp,
769
                                feedbackGenerator,
770
                                monitor);
771
                    } catch (Exception ex) {
772
                        return new Status(Status.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
773
                    }
774
                    final StringBuilder reportSb = new StringBuilder();
775
                    // collect reports
776
//	                    for(String report : remotingMonitor.getResult()) {
777
                        reportSb.append(((ExportResult)remotingMonitor.getResult()).createReport());
778
//	                    }
779
                    if(!StringUtils.isBlank(reportSb.toString())) {
780
                        Display.getDefault().asyncExec(new Runnable() {
781
                            @Override
782
                            public void run() {
783
                                // display reports with possibility to save
784
                                ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
785
                                dialog.setTitle(label + " Report");
786
                                dialog.setReportText(reportSb.toString());
787
                                dialog.open();
788
                            }
789
                        });
790
                    }
791
                    return Status.OK_STATUS;
792
                }
793

    
794
                @Override
795
                protected void canceling() {
796
                    CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
797
                }
798
            };
799

    
800
            // configure the job
801
            job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
802
            job.setUser(true);
803
            // schedule job
804
            job.schedule();
805

    
806
        } catch (Exception e) {
807
            MessagingUtils.errorDialog("Error executing operation",
808
                    AbstractUtility.class,
809
                    "An error occured while executing " + label,
810
                    TaxeditorStorePlugin.PLUGIN_ID,
811
                    e,
812
                    true);
813
        }
814

    
815
        return Status.OK_STATUS;
816
        }
817

    
818
}
(2-2/40)