Project

General

Profile

Download (30.8 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.operations.AbstractOperation;
34
import org.eclipse.core.commands.operations.IOperationHistory;
35
import org.eclipse.core.runtime.IAdaptable;
36
import org.eclipse.core.runtime.ICoreRunnable;
37
import org.eclipse.core.runtime.IProgressMonitor;
38
import org.eclipse.core.runtime.IStatus;
39
import org.eclipse.core.runtime.NullProgressMonitor;
40
import org.eclipse.core.runtime.OperationCanceledException;
41
import org.eclipse.core.runtime.Status;
42
import org.eclipse.core.runtime.SubProgressMonitor;
43
import org.eclipse.core.runtime.jobs.Job;
44
import org.eclipse.e4.ui.di.UISynchronize;
45
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
46
import org.eclipse.e4.ui.workbench.modeling.EPartService;
47
import org.eclipse.jface.action.IStatusLineManager;
48
import org.eclipse.jface.viewers.IStructuredSelection;
49
import org.eclipse.jface.viewers.SelectionChangedEvent;
50
import org.eclipse.swt.graphics.Color;
51
import org.eclipse.swt.graphics.Font;
52
import org.eclipse.swt.widgets.Display;
53
import org.eclipse.swt.widgets.Shell;
54
import org.eclipse.ui.IWorkbench;
55
import org.eclipse.ui.PlatformUI;
56
import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
57
import org.eclipse.ui.progress.IProgressConstants;
58
import org.eclipse.ui.progress.IProgressService;
59
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
60

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

    
83
/**
84
 *
85
 * @author n.hoffmann
86
 * @created 11.05.2009
87
 * @version 1.0
88
 */
89
public abstract class AbstractUtility {
90

    
91
    private static final Logger logger = Logger.getLogger(AbstractUtility.class);
92

    
93
    /** Constant <code>statusLineManager</code> */
94
    protected static IStatusLineManager statusLineManager;
95
    /** Constant <code>DATE_FORMAT_NOW="yyyyMMddHHmm"</code> */
96
   	public static final String DATE_FORMAT_NOW = "yyyyMMddHHmm";
97

    
98
    public static Object getActivePart() {
99
        MPart activePart = EventUtility.getActivePart();
100
        if(activePart!=null){
101
            return activePart.getObject();
102
        }
103
        return null;
104
    }
105

    
106
    public static Shell getShell() {
107
        return EventUtility.getShell();
108
    }
109

    
110
    public static IWorkbench getWorkbench() {
111
        return TaxeditorStorePlugin.getDefault().getWorkbench();
112
    }
113

    
114
    public static Object getService(Class api) {
115
        return TaxeditorStorePlugin.getDefault().getWorkbench().getService(api);
116
    }
117

    
118
    public static Font getFont(String symbolicName) {
119
        return FontResources.getFont(symbolicName);
120
    }
121

    
122
    public static Color getColor(String symbolicName) {
123
        return ColorResources.getColor(symbolicName);
124
    }
125

    
126
    public static IStatus executeOperation(final AbstractPostOperation operation, UISynchronize sync) {
127
        if (getOperationHistory() == null) {
128
            throw new IllegalArgumentException(
129
                    "There is no operation history for this context");
130
        }
131

    
132
        final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
133
                .getUIInfoAdapter(getShell());
134

    
135
        Job job = Job.create(operation.getLabel(), (ICoreRunnable) monitor -> {
136
            sync.syncExec(() -> {
137
                String operationlabel = operation.getLabel();
138
                monitor.beginTask(operationlabel, 100);
139
                IStatus status = Status.CANCEL_STATUS;
140
                try {
141
                    operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
142
                    status = operation.execute(monitor, uiInfoAdapter);
143
                } catch (ExecutionException e) {
144

    
145
                    MessagingUtils.operationDialog(AbstractUtility.class, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
146

    
147
                } finally {
148
                    monitor.done();
149
                }
150

    
151
                String statusString = status.equals(Status.OK_STATUS) ? "completed"
152
                        : "cancelled";
153
                setStatusLine(operationlabel + " " + statusString + ".");
154
            });
155
        });
156

    
157
        try {
158
            job.setUser(true);
159
            job.schedule();
160
        } catch (Exception e) {
161
            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
162
        }
163

    
164
        IPostOperationEnabled postOperationEnabled = operation
165
                .getPostOperationEnabled();
166
        if (postOperationEnabled != null) {
167
            postOperationEnabled.onComplete();
168
        }
169
        return Status.OK_STATUS;
170
    }
171

    
172
    public static IStatus executeOperation(final AbstractOperation operation, final RemotingCdmHandlerE4 handler, UISynchronize sync) {
173
        return executeOperation_internal(operation, handler, sync);
174
    }
175

    
176
    public static IStatus executeOperation(final AbstractOperation operation, final RemotingCdmHandler handler, UISynchronize sync) {
177
        return executeOperation_internal(operation, handler, sync);
178
    }
179

    
180
    private static IStatus executeOperation_internal(final AbstractOperation operation, final Object handler,
181
            UISynchronize sync) {
182
        if (getOperationHistory() == null) {
183
            throw new IllegalArgumentException(
184
                    "There is no operation history for this context");
185
        }
186

    
187
        final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
188
                .getUIInfoAdapter(getShell());
189

    
190

    
191
        Job job = Job.create(operation.getLabel(), (ICoreRunnable) monitor -> {
192
            sync.syncExec(() -> {
193
                String operationlabel = operation.getLabel();
194
                monitor.beginTask(operationlabel, 100);
195
                IStatus status = Status.CANCEL_STATUS;
196
                try {
197
                    operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
198
                    status = operation.execute(monitor,
199
                            uiInfoAdapter);
200
                    if(handler instanceof RemotingCdmHandler) {
201
                        ((RemotingCdmHandler) handler).postOperation(status);
202
                    }
203
                    else if(handler instanceof RemotingCdmHandlerE4) {
204
                        ((RemotingCdmHandlerE4) handler).postOperation(status);
205
                    }
206
                } catch (ExecutionException e) {
207
                    MessagingUtils.operationDialog(AbstractUtility.class, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
208
                } finally {
209
                    monitor.done();
210
                }
211

    
212
                String statusString = status.equals(Status.OK_STATUS) ? "completed"
213
                        : "cancelled";
214
                setStatusLine(operationlabel + " " + statusString + ".");
215
            });
216
        });
217

    
218
        try {
219
            job.setUser(true);
220
            sync.syncExec(()->job.schedule());
221
        } catch (Exception e) {
222
            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
223
        }
224

    
225
        return Status.OK_STATUS;
226
    }
227

    
228
    /**
229
     * Executes a remoting monitored operation
230
     *
231
     * @param label for the operation
232
     * @param uuid of the remoting monitor already started on the server
233
     * @param pollInterval in milliseconds
234
     * @param cancelable flag which determines whether the operation can be cancelled
235
     * @param postOp callback for running post operation logic
236
     * @return
237
     */
238
    public static IStatus executeMoniteredExport(final String label,
239
            final UUID uuid,
240
            final int pollInterval,
241
            final boolean cancelable,
242
            final IPostMoniteredOperationEnabled postOp,
243
            final IFeedbackGenerator feedbackGenerator,
244
            String urlString,
245
            boolean createZip) {
246

    
247
        try {
248
            // get the remoting monitor the first time to make sure that the
249
            // operation is valid
250
            final IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
251
            final IRemotingProgressMonitor firstRemotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
252
            if(firstRemotingMonitor == null) {
253
                throw new IllegalStateException("Remoting progress monitor is null");
254
            }
255

    
256
            Job job = new Job(label) {
257

    
258

    
259
                @Override
260
                public IStatus run(IProgressMonitor monitor) {
261
                    // run the monitor until the operation is finished
262
                	monitor.beginTask("Start", 100);
263
                    IRemotingProgressMonitor remotingMonitor;
264
                    try {
265
                        remotingMonitor = CdmStore.getProgressMonitorClientManager().pollMonitor(label,
266
                                uuid,
267
                                pollInterval,
268
                                postOp,
269
                                feedbackGenerator,
270
                                monitor);
271
                    } catch (Exception ex) {
272
                        return new Status(Status.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
273
                    }
274
                    final StringBuilder reportSb = new StringBuilder();
275
                    if (remotingMonitor.getResult() instanceof ExportResult){
276
                    	ExportResult result = (ExportResult)remotingMonitor.getResult();
277

    
278
	                    reportSb.append(result.createReport());
279

    
280
	                    if(!StringUtils.isBlank(reportSb.toString())) {
281
	                        Display.getDefault().asyncExec(new Runnable() {
282
	                            @Override
283
	                            public void run() {
284
	                                // display reports with possibility to save
285
	                                ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
286
	                                dialog.setTitle(label + " Report");
287
	                                dialog.setReportText(reportSb.toString());
288
	                                dialog.open();
289
	                            }
290
	                        });
291
	                    }
292

    
293
	                    if (urlString != null){
294
	                    	 ExportDataWrapper data = result.getExportData();
295
	                         try{
296
	                             if (result.getExportData().getType().equals(ExportResultType.BYTE_ARRAY)){
297
	                                 byte[] exportData = (byte[])data.getExportData();
298
	                                 if(exportData != null){
299
	                                     File file = new File(urlString);
300
	                                     FileOutputStream stream = new FileOutputStream(file);
301
	                                     Writer out = new BufferedWriter(new OutputStreamWriter(
302
	                                 			stream, "UTF8"));
303

    
304
	                                 	stream.write(exportData);
305
	                                    out.flush();
306
	                                    stream.close();
307
	                                 }
308
	                             } else if (result.getExportData().getType().equals(ExportResultType.MAP_BYTE_ARRAY)){
309
	                                 Map<String, byte[]> resultMap = (Map<String, byte[]>)data.getExportData();
310
	                                 Set<String> keySet = resultMap.keySet();
311
	                                 SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
312
	                                 Calendar cal = Calendar.getInstance();
313
	                                 String fileEnding = ".csv";
314

    
315
	                                 if (createZip){
316
	                            		 File file = new File(urlString+File.separator +  sdf.format(cal.getTime())+ ".zip");
317
	                                     FileOutputStream stream = new FileOutputStream(file);
318
	                                     ZipOutputStream zos = new ZipOutputStream(stream);
319
	                                     for (String key: keySet){
320
	                                    	byte[] fileData = resultMap.get(key);
321
	                                    	ZipEntry entry = new ZipEntry( key + fileEnding);
322
	         								zos.putNextEntry(entry);
323
	         								zos.write(fileData);
324
	         								zos.closeEntry();
325
	                                     }
326
	                                     zos.close();
327
	                            	 }else{
328
	                            		if(result.getExportType().equals(ExportType.DWCA)){
329

    
330
	                                        File file = new File(urlString);
331
	                                        FileOutputStream stream = new FileOutputStream(file);
332
	                                        ZipOutputStream zos = new ZipOutputStream(stream);
333
	                                        for (String key: keySet){
334
             	                               	byte[] fileData = resultMap.get(key);
335
             	                               	ZipEntry entry = new ZipEntry( key + fileEnding);
336
             	    								zos.putNextEntry(entry);
337
             	    								zos.write(fileData);
338
             	    								zos.closeEntry();
339
	                                         }
340
	                                         zos.close();
341
	                                      }else{
342
		                            		 for (String key: keySet){
343
		                            			 byte[] fileData = resultMap.get(key);
344
		                            			 File file = new File(urlString+File.separator + key + fileEnding);
345
		                                         FileOutputStream stream = new FileOutputStream(file);
346
		                                         Writer out = new BufferedWriter(new OutputStreamWriter(
347
		                                     			stream, "UTF8"));
348
		                                         stream.write(fileData);
349
		                                         stream.close();
350
		                                     }
351
	                                      }
352
	                            	 }
353
	                            }else{
354
	                                 logger.error("This kind of result data is not supported yet." + result.getExportData().getType().toString());
355
	                             }
356
	                         } catch(Exception e){
357
	                             logger.error(e.getStackTrace());
358
	                         }
359
	                    }
360
                    }
361
                    return Status.OK_STATUS;
362
                }
363

    
364
                @Override
365
                protected void canceling() {
366
                    CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
367
                }
368
            };
369

    
370
            // configure the job
371
            job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
372
            job.setUser(true);
373
            // schedule job
374
            job.schedule();
375

    
376
        } catch (Exception e) {
377
            MessagingUtils.errorDialog("Error executing operation",
378
                    AbstractUtility.class,
379
                    "An error occured while executing " + label,
380
                    TaxeditorStorePlugin.PLUGIN_ID,
381
                    e,
382
                    true);
383
        }
384

    
385
        return Status.OK_STATUS;
386
    }
387

    
388
    public static IOperationHistory getOperationHistory() {
389
        return getWorkbench().getOperationSupport().getOperationHistory();
390
    }
391

    
392
    public static void setStatusLine(final String message) {
393
        Display.getDefault().asyncExec(new Runnable() {
394

    
395
            @Override
396
            public void run() {
397
                statusLineManager.setMessage(message);
398
            }
399

    
400
        });
401

    
402
    }
403

    
404
    public static IProgressMonitor getMonitor() {
405
        statusLineManager.setCancelEnabled(false);
406
        return statusLineManager.getProgressMonitor();
407
    }
408

    
409
    /**
410
     * Starts either the given {@link IProgressMonitor} if it's not
411
     * <code>null</code> or a new {@link NullProgressMonitor}.
412
     *
413
     * @param progressMonitor
414
     *            The {@link IProgressMonitor} or <code>null</code> if no
415
     *            progress should be reported.
416
     * @param taskName
417
     *            The name of the main task.
418
     * @param steps
419
     *            The number of steps this task is subdivided into.
420
     * @return The {@link IProgressMonitor}.
421
     */
422
    public static IProgressMonitor startMainMonitor(
423
            IProgressMonitor progressMonitor, String taskName, int steps) {
424
        IProgressMonitor newMonitor = progressMonitor;
425
        if (newMonitor == null) {
426
            newMonitor = new NullProgressMonitor();
427
        }
428
        newMonitor.beginTask(taskName == null ? "" : taskName, steps);
429
        newMonitor.subTask(" ");
430
        return newMonitor;
431
    }
432

    
433
    /**
434
     * Creates a {@link SubProgressMonitor} if the given
435
     * {@link IProgressMonitor} is not <code>null</code> and not a
436
     * {@link NullProgressMonitor}.
437
     *
438
     * @param progressMonitor
439
     *            The parent {@link IProgressMonitor} of the
440
     *            {@link SubProgressMonitor} to be created.
441
     * @param ticks
442
     *            The number of steps this subtask is subdivided into. Must be a
443
     *            positive number and must not be
444
     *            {@link IProgressMonitor#UNKNOWN}.
445
     * @return The {@link IProgressMonitor}.
446
     */
447
    public static IProgressMonitor getSubProgressMonitor(
448
            IProgressMonitor progressMonitor, int ticks) {
449
        if (progressMonitor == null) {
450
            return new NullProgressMonitor();
451
        }
452
        if (progressMonitor instanceof NullProgressMonitor) {
453
            return progressMonitor;
454
        }
455

    
456
        return new SubProgressMonitor(progressMonitor, ticks);
457
    }
458

    
459
    /**
460
     * Checks whether the user canceled this operation. If not canceled, the
461
     * given number of steps are declared as done.
462
     *
463
     * @param newMonitor
464
     *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
465
     * @param steps
466
     *            a int.
467
     */
468
    public static void workedChecked(IProgressMonitor newMonitor, int steps) {
469
        // In case the progress monitor was canceled throw an exception.
470
        if (newMonitor.isCanceled()) {
471
            throw new OperationCanceledException();
472
        }
473
        // Otherwise declare this step as done.
474
        newMonitor.worked(steps);
475
    }
476

    
477
    public static IProgressService getProgressService() {
478
        IWorkbench workbench = PlatformUI.getWorkbench();
479
        return workbench.getProgressService();
480
    }
481

    
482
    public static IWorkbenchSiteProgressService getProgressService2() {
483
        return (IWorkbenchSiteProgressService) getService(IWorkbenchSiteProgressService.class);
484
    }
485

    
486
    public static String getPluginId() {
487
        return "eu.taxeditor";
488
    }
489

    
490
    public static Object getActiveEditor() {
491
        MPart activePart = EventUtility.getActivePart();
492
        if(activePart!=null && activePart.getObject()!=null
493
                && activePart.getObject() instanceof IE4SavablePart){
494
            return activePart.getObject();
495
        }
496
        return null;
497
    }
498

    
499
    public static DetailsPartE4 getDetailsView(EPartService partService) {
500
        MPart part = partService.findPart("eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4");
501
        if(part!=null){
502
            return (DetailsPartE4) part.getObject();
503
        }
504
        return null;
505
    }
506

    
507
    public static void refreshDetailsViewer(EPartService partService) {
508
        if (getDetailsView(partService) != null) {
509
            ((AbstractCdmDataViewerE4) getDetailsView(partService).getViewer()).refresh();
510
        }
511
    }
512

    
513
    public static void reflowDetailsViewer(EPartService partService) {
514
        if (getDetailsView(partService) != null) {
515
            ((AbstractCdmDataViewerE4) getDetailsView(partService).getViewer()).reflow();
516
        }
517
    }
518

    
519

    
520
    /**
521
     * Orders a Collection of {@link IEnumTerm}s according to the term
522
     * hierarchy. <br>
523
     * <br>
524
     * The returned map will be be ordered primarily by root elements,
525
     * secondarily by the child elements and their children resp., both ascending alphabetically. <br>
526
     * @param terms
527
     *            A {@link Collection} of {@link IEnumTerm}s for which the term
528
     *            hierarchy should be created
529
     * @return a map which holds the terms as keys and their string
530
     *         representation via {@link IEnumTerm#getMessage()} as values
531
     */
532
    public static <T extends IEnumTerm<T>> LinkedHashMap<T, String> orderTerms(Collection<T> terms) {
533
        TreeSet<TermNode<T>> parentElements = new TreeSet<TermNode<T>>();
534
        parentElements.addAll(getTermHierarchy(terms));
535

    
536
        // create list according to the type hierarchy (root elements alphabetically with recursive children also alphabetically)
537
        LinkedHashMap<T, String> result = new LinkedHashMap<T, String>();
538
        parseTermTree(parentElements, result, -1);
539
        return result;
540
    }
541

    
542
    private static<T extends IEnumTerm<T>> void parseTermTree(Collection<TermNode<T>> children, LinkedHashMap<T, String> result, int depth){
543
        depth++;
544
        for(TermNode<T> node:children){
545
            String indentString = "";
546
            for(int i=0;i<depth;i++){
547
                indentString += "  ";
548
            }
549
            if(depth>0){
550
                indentString += "- ";
551
            }
552
            result.put(node.term, indentString + node.term.getMessage());
553
            parseTermTree(node.children, result, depth);
554
        }
555
    }
556

    
557
    private static<T extends IEnumTerm<T>> void addToParents(List<TermNode<T>> parents, Collection<T> terms){
558
        List<TermNode<T>> hasChildrenList = new ArrayList<TermNode<T>>();
559
        for(T term:terms){
560
            // only terms with parents
561
            if(term.getKindOf()!=null){
562
                TermNode<T> parentNode = new TermNode<T>(term.getKindOf());
563
                TermNode<T> childNode = new TermNode<T>(term);
564
                if(parents.contains(parentNode)){
565
                    // parent found in parent list -> add this term to parent's child list
566
                    parents.get(parents.indexOf(parentNode)).addChild(childNode);
567
                    if(!term.getGeneralizationOf().isEmpty()){
568
                        // has more children -> add to list which will be the parent for the next recursion
569
                        hasChildrenList.add(childNode);
570
                    }
571
                }
572
            }
573
        }
574
        if(!hasChildrenList.isEmpty()){
575
            addToParents(hasChildrenList, terms);
576
        }
577
    }
578

    
579
    private static<T extends IEnumTerm<T>> List<TermNode<T>> getTermHierarchy(Collection<T> terms){
580
        List<TermNode<T>> parents = new ArrayList<TermNode<T>>();
581
        // get root elements
582
        for(T term:terms){
583
            T parentTerm = term.getKindOf();
584
            if(parentTerm==null){
585
                // root element
586
                parents.add(new TermNode<T>(term));
587
            }
588
        }
589
        addToParents(parents, terms);
590
        return parents;
591
    }
592

    
593
    @SuppressWarnings("unchecked")
594
    /**
595
     * Recursively iterates over all term parents until no more parent is found i.e. the root node
596
     * @param term The term for which the parent should be found
597
     * @return the root terms of the term hierarchy
598
     */
599
    private static<T extends IEnumTerm<T>> T getParentFor(T term){
600
        // PP: cast should be safe. Why is Eclipse complaining??
601
        T parent = term.getKindOf();
602
        if(parent==null){
603
            return term;
604
        }
605
        else{
606
            return getParentFor(term.getKindOf());
607
        }
608
    }
609

    
610
    private static class TermNode<T extends IEnumTerm<T>> implements Comparable<TermNode<T>>{
611
        private final T term;
612
        private final TreeSet<TermNode<T>> children;
613

    
614
        public TermNode(T term) {
615
            super();
616
            this.term = term;
617
            this.children = new TreeSet<TermNode<T>>();
618
        }
619

    
620
        public void addChild(TermNode<T> child){
621
            this.children.add(child);
622
        }
623

    
624
        public TreeSet<TermNode<T>> getChildren() {
625
            return children;
626
        }
627

    
628
        public T getTerm() {
629
            return term;
630
        }
631

    
632
        @Override
633
        public int hashCode() {
634
            final int prime = 31;
635
            int result = 1;
636
            result = prime * result + ((term == null) ? 0 : term.hashCode());
637
            return result;
638
        }
639

    
640
        @Override
641
        public boolean equals(Object obj) {
642
            if (this == obj) {
643
                return true;
644
            }
645
            if (obj == null) {
646
                return false;
647
            }
648
            if (getClass() != obj.getClass()) {
649
                return false;
650
            }
651
            TermNode other = (TermNode) obj;
652
            if (term == null) {
653
                if (other.term != null) {
654
                    return false;
655
                }
656
            } else if (!term.equals(other.term)) {
657
                return false;
658
            }
659
            return true;
660
        }
661

    
662
        @Override
663
        public int compareTo(TermNode<T> that) {
664
            return this.term.getMessage().compareTo(that.term.getMessage());
665
        }
666
    }
667

    
668
    public static Object getElementsFromSelectionChangedEvent(SelectionChangedEvent event) {
669
        IStructuredSelection selection = (IStructuredSelection) event.getSelection();
670
        Object selectionToSet = selection;
671
        if(selection.size() == 1){
672
            selectionToSet = selection.getFirstElement();
673
        }
674
        else if(!selection.isEmpty()){
675
            selectionToSet = selection.toArray();
676
        }
677
        return selectionToSet;
678
    }
679

    
680
    /**
681
     * Executes a remoting monitored import
682
     *
683
     * @param label for the import
684
     * @param uuid of the remoting monitor already started on the server
685
     * @param pollInterval in milliseconds
686
     * @param cancelable flag which determines whether the operation can be cancelled
687
     * @param postOp callback for running post operation logic
688
     * @return
689
     */
690
    public static IStatus executeMoniteredOperation(final String label,
691
            final UUID uuid,
692
            final int pollInterval,
693
            final boolean cancelable,
694
            final IPostMoniteredOperationEnabled postOp,
695
            final IFeedbackGenerator feedbackGenerator) {
696

    
697
    	try{
698
    		// get the remoting monitor the first time to make sure that the
699
            // operation is valid
700
            final IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
701
            final IRemotingProgressMonitor firstRemotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
702
            if(firstRemotingMonitor == null) {
703
                throw new IllegalStateException("Remoting progress monitor is null");
704
            }
705

    
706
            Job job = new Job(label) {
707

    
708

    
709
                @Override
710
                public IStatus run(IProgressMonitor monitor) {
711
                    // run the monitor until the operation is finished
712
                	monitor.beginTask("Start", 100);
713
                    IRemotingProgressMonitor remotingMonitor;
714
                    try {
715
                        remotingMonitor = CdmStore.getProgressMonitorClientManager().pollMonitor(label,
716
                                uuid,
717
                                pollInterval,
718
                                postOp,
719
                                feedbackGenerator,
720
                                monitor);
721
                    } catch (Exception ex) {
722
                        return new Status(Status.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
723
                    }
724
                    final StringBuilder reportSb = new StringBuilder();
725
                    // collect reports
726
//	                    for(String report : remotingMonitor.getResult()) {
727
                        reportSb.append(((ExportResult)remotingMonitor.getResult()).createReport());
728
//	                    }
729
                    if(!StringUtils.isBlank(reportSb.toString())) {
730
                        Display.getDefault().asyncExec(new Runnable() {
731
                            @Override
732
                            public void run() {
733
                                // display reports with possibility to save
734
                                ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
735
                                dialog.setTitle(label + " Report");
736
                                dialog.setReportText(reportSb.toString());
737
                                dialog.open();
738
                            }
739
                        });
740
                    }
741
                    return Status.OK_STATUS;
742
                }
743

    
744
                @Override
745
                protected void canceling() {
746
                    CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
747
                }
748
            };
749

    
750
            // configure the job
751
            job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
752
            job.setUser(true);
753
            // schedule job
754
            job.schedule();
755

    
756
        } catch (Exception e) {
757
            MessagingUtils.errorDialog("Error executing operation",
758
                    AbstractUtility.class,
759
                    "An error occured while executing " + label,
760
                    TaxeditorStorePlugin.PLUGIN_ID,
761
                    e,
762
                    true);
763
        }
764

    
765
        return Status.OK_STATUS;
766
        }
767

    
768
}
(2-2/41)