Project

General

Profile

Download (36.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.lang.reflect.InvocationTargetException;
18
import java.text.SimpleDateFormat;
19
import java.util.ArrayList;
20
import java.util.Calendar;
21
import java.util.Collection;
22
import java.util.LinkedHashMap;
23
import java.util.List;
24
import java.util.Map;
25
import java.util.Set;
26
import java.util.TreeSet;
27
import java.util.UUID;
28
import java.util.zip.ZipEntry;
29
import java.util.zip.ZipOutputStream;
30

    
31
import org.apache.commons.lang.StringUtils;
32
import org.apache.log4j.Logger;
33
import org.eclipse.core.commands.ExecutionException;
34
import org.eclipse.core.commands.NotEnabledException;
35
import org.eclipse.core.commands.NotHandledException;
36
import org.eclipse.core.commands.common.NotDefinedException;
37
import org.eclipse.core.commands.operations.AbstractOperation;
38
import org.eclipse.core.commands.operations.IOperationHistory;
39
import org.eclipse.core.runtime.IAdaptable;
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.ISchedulingRule;
47
import org.eclipse.core.runtime.jobs.Job;
48
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
49
import org.eclipse.jface.action.IStatusLineManager;
50
import org.eclipse.jface.operation.IRunnableWithProgress;
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.IViewPart;
60
import org.eclipse.ui.IViewReference;
61
import org.eclipse.ui.IWorkbench;
62
import org.eclipse.ui.IWorkbenchPage;
63
import org.eclipse.ui.IWorkbenchWindow;
64
import org.eclipse.ui.PartInitException;
65
import org.eclipse.ui.PlatformUI;
66
import org.eclipse.ui.handlers.IHandlerService;
67
import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
68
import org.eclipse.ui.progress.IProgressConstants;
69
import org.eclipse.ui.progress.IProgressService;
70
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
71
import org.eclipse.ui.themes.ITheme;
72
import org.eclipse.ui.themes.IThemeManager;
73

    
74
import eu.etaxonomy.cdm.api.application.CdmApplicationState;
75
import eu.etaxonomy.cdm.api.service.IProgressMonitorService;
76
import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
77
import eu.etaxonomy.cdm.io.common.ExportDataWrapper;
78
import eu.etaxonomy.cdm.io.common.ExportResult;
79
import eu.etaxonomy.cdm.io.common.ExportResultType;
80
import eu.etaxonomy.cdm.io.common.ExportType;
81
import eu.etaxonomy.cdm.model.common.IEnumTerm;
82
import eu.etaxonomy.taxeditor.event.EventUtility;
83
import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
84
import eu.etaxonomy.taxeditor.operation.IFeedbackGenerator;
85
import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
86
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
87
import eu.etaxonomy.taxeditor.operation.RemotingCdmHandler;
88
import eu.etaxonomy.taxeditor.operation.e4.RemotingCdmHandlerE4;
89
import eu.etaxonomy.taxeditor.store.CdmStore;
90
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
91
import eu.etaxonomy.taxeditor.ui.dialog.ReportTextDialog;
92
import eu.etaxonomy.taxeditor.view.AbstractCdmDataViewer;
93
import eu.etaxonomy.taxeditor.view.detail.DetailsViewPart;
94
import eu.etaxonomy.taxeditor.view.supplementaldata.SupplementalDataViewPart;
95
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
96

    
97
/**
98
 *
99
 * @author n.hoffmann
100
 * @created 11.05.2009
101
 * @version 1.0
102
 */
103
public abstract class AbstractUtility {
104

    
105
    private static final Logger logger = Logger.getLogger(AbstractUtility.class);
106

    
107
    /** Constant <code>statusLineManager</code> */
108
    protected static IStatusLineManager statusLineManager;
109
    /** Constant <code>DATE_FORMAT_NOW="yyyyMMddHHmm"</code> */
110
   	public static final String DATE_FORMAT_NOW = "yyyyMMddHHmm";
111

    
112
    public static Object getActivePart() {
113
        MPart activePart = EventUtility.getActivePart();
114
        if(activePart!=null){
115
            return activePart.getObject();
116
        }
117
        return null;
118
    }
119

    
120
    public static boolean closeAll() {
121
        if(getActivePage()!=null){
122
            return getActivePage().closeAllEditors(true);
123
        }
124
        return false;
125
    }
126

    
127
    public static Shell getShell() {
128

    
129
        return TaxeditorStorePlugin.getDefault().getWorkbench()
130
                .getActiveWorkbenchWindow().getShell();
131
    }
132

    
133
    public static IWorkbenchPage getActivePage() {
134
        try{
135
            return TaxeditorStorePlugin.getDefault().getWorkbench()
136
                    .getActiveWorkbenchWindow().getActivePage();
137
        } catch(NullPointerException npe){
138
            return null;
139
        }
140
    }
141

    
142
    public static IWorkbench getWorkbench() {
143
        return TaxeditorStorePlugin.getDefault().getWorkbench();
144
    }
145

    
146
    public static IWorkbenchWindow getWorkbenchWindow() {
147
        if (getWorkbench().getWorkbenchWindowCount() > 1) {
148
            throw new IllegalStateException("More than one workbench window");
149
        }
150
        return getWorkbench().getWorkbenchWindows()[0];
151
    }
152

    
153
    public static IViewPart showView(String id) {
154
        try {
155
            return PlatformUI.getWorkbench().getActiveWorkbenchWindow()
156
                    .getActivePage()
157
                    .showView(id, null, IWorkbenchPage.VIEW_VISIBLE);
158
        } catch (PartInitException e) {
159
            MessagingUtils.messageDialog("Error opening view", AbstractUtility.class, "Could not open view: " + id, e);
160
            return null;
161
        }
162
    }
163

    
164
    public static void hideView(IViewPart view) {
165
        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
166
        .hideView(view);
167
    }
168

    
169
    public static IViewPart getView(String id, boolean restore) {
170
    	IWorkbench workbench = PlatformUI.getWorkbench();
171
        IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
172
    	IViewReference[] references = null;
173
    	if(activeWorkbenchWindow!=null && activeWorkbenchWindow.getActivePage()!=null){
174
    	    references = activeWorkbenchWindow.getActivePage().getViewReferences();
175
    	}
176
    	else if(workbench.getWorkbenchWindows().length>0 && workbench.getWorkbenchWindows()[0].getActivePage()!=null){
177
    		references = workbench.getWorkbenchWindows()[0].getActivePage().getViewReferences();
178
    	}
179
    	if(references!=null){
180
    		for (IViewReference reference : references) {
181
    			if (reference.getId().equals(id)) {
182
    				return reference.getView(restore);
183
    			}
184
    		}
185
    	}
186
        return null;
187
    }
188

    
189
    public static Object getService(Class api) {
190
        return TaxeditorStorePlugin.getDefault().getWorkbench().getService(api);
191
    }
192

    
193
    public static ITheme getCurrentTheme() {
194
        IThemeManager themeManager = TaxeditorStorePlugin.getDefault()
195
                .getWorkbench().getThemeManager();
196
        return themeManager.getCurrentTheme();
197
    }
198

    
199
    /**
200
     * Fonts registered to the plugin may be obtained with the Eclipse themeing
201
     * functionality. Thus fonts are chooseable by the user via
202
     * Preferences->General->Appearance->Colors and Fonts
203
     *
204
     * @return the FontRegistry for the current theme
205
     */
206
    public static FontRegistry getFontRegistry() {
207
        return getCurrentTheme().getFontRegistry();
208
    }
209

    
210
    public static Font getFont(String symbolicName) {
211
        return getFontRegistry().get(symbolicName);
212
    }
213

    
214
    /**
215
     * Color registered to the plugin may be obtained with the Eclipse themeing
216
     * functionality. Thus colors are editable by the user via
217
     * Preferences->General->Appearance->Colors and Fonts
218
     *
219
     * @return the ColorRegistry for the current theme
220
     */
221
    public static ColorRegistry getColorRegistry() {
222
        return getCurrentTheme().getColorRegistry();
223
    }
224

    
225
    public static Color getColor(String symbolicName) {
226
        return getColorRegistry().get(symbolicName);
227
    }
228

    
229
    public static IStatus executeOperation(final AbstractPostOperation operation) {
230
        if (getOperationHistory() == null) {
231
            throw new IllegalArgumentException(
232
                    "There is no operation history for this context");
233
        }
234

    
235
        final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
236
                .getUIInfoAdapter(getShell());
237

    
238
        IRunnableWithProgress runnable = new IRunnableWithProgress() {
239

    
240
            @Override
241
            public void run(IProgressMonitor monitor)
242
                    throws InvocationTargetException, InterruptedException {
243
                String operationlabel = operation.getLabel();
244
                monitor.beginTask(operationlabel, 100);
245
                IStatus status = Status.CANCEL_STATUS;
246
                try {
247
                    operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
248
                    status = getOperationHistory().execute(operation, monitor,
249
                            uiInfoAdapter);
250
                } catch (ExecutionException e) {
251

    
252
                    MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
253

    
254
                } finally {
255
                    monitor.done();
256
                }
257

    
258
                String statusString = status.equals(Status.OK_STATUS) ? "completed"
259
                        : "cancelled";
260
                setStatusLine(operationlabel + " " + statusString + ".");
261

    
262
            }
263
        };
264

    
265
        try {
266
            runInUI(runnable, null);
267
        } catch (Exception e) {
268
            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
269
        }
270

    
271
        IPostOperationEnabled postOperationEnabled = operation
272
                .getPostOperationEnabled();
273
        if (postOperationEnabled != null) {
274
            postOperationEnabled.onComplete();
275
        }
276
        return Status.OK_STATUS;
277
    }
278

    
279
    public static IStatus executeOperation(final AbstractOperation operation, final RemotingCdmHandlerE4 handler) {
280
        return executeOperation_internal(operation, handler);
281
    }
282

    
283
    public static IStatus executeOperation(final AbstractOperation operation, final RemotingCdmHandler handler) {
284
        return executeOperation_internal(operation, handler);
285
    }
286

    
287
    private static IStatus executeOperation_internal(final AbstractOperation operation, final Object handler) {
288
        if (getOperationHistory() == null) {
289
            throw new IllegalArgumentException(
290
                    "There is no operation history for this context");
291
        }
292

    
293
        final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
294
                .getUIInfoAdapter(getShell());
295

    
296
        IRunnableWithProgress runnable = new IRunnableWithProgress() {
297

    
298
            @Override
299
            public void run(IProgressMonitor monitor)
300
                    throws InvocationTargetException, InterruptedException {
301
                String operationlabel = operation.getLabel();
302
                monitor.beginTask(operationlabel, 100);
303
                IStatus status = Status.CANCEL_STATUS;
304
                try {
305
                    operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
306
                    status = getOperationHistory().execute(operation, monitor,
307
                            uiInfoAdapter);
308
                    if(handler instanceof RemotingCdmHandler) {
309
                        ((RemotingCdmHandler) handler).postOperation(status);
310
                    }
311
                    else if(handler instanceof RemotingCdmHandlerE4) {
312
                        ((RemotingCdmHandlerE4) handler).postOperation(status);
313
                    }
314
                } catch (ExecutionException e) {
315
                    MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
316
                } finally {
317
                    monitor.done();
318
                }
319

    
320
                String statusString = status.equals(Status.OK_STATUS) ? "completed"
321
                        : "cancelled";
322
                setStatusLine(operationlabel + " " + statusString + ".");
323

    
324
            }
325
        };
326

    
327
        try {
328
            runInUI(runnable, null);
329
        } catch (Exception e) {
330
            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
331
        }
332

    
333
        return Status.OK_STATUS;
334
    }
335

    
336
    /**
337
     * Executes a remoting monitored operation
338
     *
339
     * @param label for the operation
340
     * @param uuid of the remoting monitor already started on the server
341
     * @param pollInterval in milliseconds
342
     * @param cancelable flag which determines whether the operation can be cancelled
343
     * @param postOp callback for running post operation logic
344
     * @return
345
     */
346
    public static IStatus executeMoniteredExport(final String label,
347
            final UUID uuid,
348
            final int pollInterval,
349
            final boolean cancelable,
350
            final IPostMoniteredOperationEnabled postOp,
351
            final IFeedbackGenerator feedbackGenerator,
352
            String urlString,
353
            boolean createZip) {
354

    
355
        try {
356
            // get the remoting monitor the first time to make sure that the
357
            // operation is valid
358
            final IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
359
            final IRemotingProgressMonitor firstRemotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
360
            if(firstRemotingMonitor == null) {
361
                throw new IllegalStateException("Remoting progress monitor is null");
362
            }
363

    
364
            Job job = new Job(label) {
365

    
366

    
367
                @Override
368
                public IStatus run(IProgressMonitor monitor) {
369
                    // run the monitor until the operation is finished
370
                	monitor.beginTask("Start", 100);
371
                    IRemotingProgressMonitor remotingMonitor;
372
                    try {
373
                        remotingMonitor = CdmStore.getProgressMonitorClientManager().pollMonitor(label,
374
                                uuid,
375
                                pollInterval,
376
                                postOp,
377
                                feedbackGenerator,
378
                                monitor);
379
                    } catch (Exception ex) {
380
                        return new Status(Status.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
381
                    }
382
                    final StringBuilder reportSb = new StringBuilder();
383
                    if (remotingMonitor.getResult() instanceof ExportResult){
384
                    	ExportResult result = (ExportResult)remotingMonitor.getResult();
385

    
386
	                    reportSb.append(result.createReport());
387

    
388
	                    if(!StringUtils.isBlank(reportSb.toString())) {
389
	                        Display.getDefault().asyncExec(new Runnable() {
390
	                            @Override
391
	                            public void run() {
392
	                                // display reports with possibility to save
393
	                                ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
394
	                                dialog.setTitle(label + " Report");
395
	                                dialog.setReportText(reportSb.toString());
396
	                                dialog.open();
397
	                            }
398
	                        });
399
	                    }
400

    
401
	                    if (urlString != null){
402
	                    	 ExportDataWrapper data = result.getExportData();
403
	                         try{
404
	                             if (result.getExportData().getType().equals(ExportResultType.BYTE_ARRAY)){
405
	                                 byte[] exportData = (byte[])data.getExportData();
406
	                                 if(exportData != null){
407
	                                     File file = new File(urlString);
408
	                                     FileOutputStream stream = new FileOutputStream(file);
409
	                                     Writer out = new BufferedWriter(new OutputStreamWriter(
410
	                                 			stream, "UTF8"));
411

    
412
	                                 	stream.write(exportData);
413
	                                    out.flush();
414
	                                    stream.close();
415
	                                 }
416
	                             } else if (result.getExportData().getType().equals(ExportResultType.MAP_BYTE_ARRAY)){
417
	                                 Map<String, byte[]> resultMap = (Map<String, byte[]>)data.getExportData();
418
	                                 Set<String> keySet = resultMap.keySet();
419
	                                 SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
420
	                                 Calendar cal = Calendar.getInstance();
421
	                                 String fileEnding = ".csv";
422

    
423
	                                 if (createZip){
424
	                            		 File file = new File(urlString+File.separator +  sdf.format(cal.getTime())+ ".zip");
425
	                                     FileOutputStream stream = new FileOutputStream(file);
426
	                                     ZipOutputStream zos = new ZipOutputStream(stream);
427
	                                     for (String key: keySet){
428
	                                    	byte[] fileData = resultMap.get(key);
429
	                                    	ZipEntry entry = new ZipEntry( key + fileEnding);
430
	         								zos.putNextEntry(entry);
431
	         								zos.write(fileData);
432
	         								zos.closeEntry();
433
	                                     }
434
	                                     zos.close();
435
	                            	 }else{
436
	                            		if(result.getExportType().equals(ExportType.DWCA)){
437

    
438
	                                        File file = new File(urlString);
439
	                                        FileOutputStream stream = new FileOutputStream(file);
440
	                                        ZipOutputStream zos = new ZipOutputStream(stream);
441
	                                        for (String key: keySet){
442
             	                               	byte[] fileData = resultMap.get(key);
443
             	                               	ZipEntry entry = new ZipEntry( key + fileEnding);
444
             	    								zos.putNextEntry(entry);
445
             	    								zos.write(fileData);
446
             	    								zos.closeEntry();
447
	                                         }
448
	                                         zos.close();
449
	                                      }else{
450
		                            		 for (String key: keySet){
451
		                            			 byte[] fileData = resultMap.get(key);
452
		                            			 File file = new File(urlString+File.separator + key + fileEnding);
453
		                                         FileOutputStream stream = new FileOutputStream(file);
454
		                                         Writer out = new BufferedWriter(new OutputStreamWriter(
455
		                                     			stream, "UTF8"));
456
		                                         stream.write(fileData);
457
		                                         stream.close();
458
		                                     }
459
	                                      }
460
	                            	 }
461
	                            }else{
462
	                                 logger.error("This kind of result data is not supported yet." + result.getExportData().getType().toString());
463
	                             }
464
	                         } catch(Exception e){
465
	                             logger.error(e.getStackTrace());
466
	                         }
467
	                    }
468
                    }
469
                    return Status.OK_STATUS;
470
                }
471

    
472
                @Override
473
                protected void canceling() {
474
                    CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
475
                }
476
            };
477

    
478
            // configure the job
479
            job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
480
            job.setUser(true);
481
            // schedule job
482
            job.schedule();
483

    
484
        } catch (Exception e) {
485
            MessagingUtils.errorDialog("Error executing operation",
486
                    AbstractUtility.class,
487
                    "An error occured while executing " + label,
488
                    TaxeditorStorePlugin.PLUGIN_ID,
489
                    e,
490
                    true);
491
        }
492

    
493
        return Status.OK_STATUS;
494
    }
495

    
496
    public static IOperationHistory getOperationHistory() {
497
        return getWorkbench().getOperationSupport().getOperationHistory();
498
    }
499

    
500
    public static void setStatusLine(final String message) {
501
        Display.getDefault().asyncExec(new Runnable() {
502

    
503
            @Override
504
            public void run() {
505
                statusLineManager.setMessage(message);
506
            }
507

    
508
        });
509

    
510
    }
511

    
512
    public static IProgressMonitor getMonitor() {
513
        statusLineManager.setCancelEnabled(false);
514
        return statusLineManager.getProgressMonitor();
515
    }
516

    
517
    /**
518
     * Starts either the given {@link IProgressMonitor} if it's not
519
     * <code>null</code> or a new {@link NullProgressMonitor}.
520
     *
521
     * @param progressMonitor
522
     *            The {@link IProgressMonitor} or <code>null</code> if no
523
     *            progress should be reported.
524
     * @param taskName
525
     *            The name of the main task.
526
     * @param steps
527
     *            The number of steps this task is subdivided into.
528
     * @return The {@link IProgressMonitor}.
529
     */
530
    public static IProgressMonitor startMainMonitor(
531
            IProgressMonitor progressMonitor, String taskName, int steps) {
532
        IProgressMonitor newMonitor = progressMonitor;
533
        if (newMonitor == null) {
534
            newMonitor = new NullProgressMonitor();
535
        }
536
        newMonitor.beginTask(taskName == null ? "" : taskName, steps);
537
        newMonitor.subTask(" ");
538
        return newMonitor;
539
    }
540

    
541
    /**
542
     * Creates a {@link SubProgressMonitor} if the given
543
     * {@link IProgressMonitor} is not <code>null</code> and not a
544
     * {@link NullProgressMonitor}.
545
     *
546
     * @param progressMonitor
547
     *            The parent {@link IProgressMonitor} of the
548
     *            {@link SubProgressMonitor} to be created.
549
     * @param ticks
550
     *            The number of steps this subtask is subdivided into. Must be a
551
     *            positive number and must not be
552
     *            {@link IProgressMonitor#UNKNOWN}.
553
     * @return The {@link IProgressMonitor}.
554
     */
555
    public static IProgressMonitor getSubProgressMonitor(
556
            IProgressMonitor progressMonitor, int ticks) {
557
        if (progressMonitor == null) {
558
            return new NullProgressMonitor();
559
        }
560
        if (progressMonitor instanceof NullProgressMonitor) {
561
            return progressMonitor;
562
        }
563

    
564
        return new SubProgressMonitor(progressMonitor, ticks);
565
    }
566

    
567
    /**
568
     * Checks whether the user canceled this operation. If not canceled, the
569
     * given number of steps are declared as done.
570
     *
571
     * @param newMonitor
572
     *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
573
     * @param steps
574
     *            a int.
575
     */
576
    public static void workedChecked(IProgressMonitor newMonitor, int steps) {
577
        // In case the progress monitor was canceled throw an exception.
578
        if (newMonitor.isCanceled()) {
579
            throw new OperationCanceledException();
580
        }
581
        // Otherwise declare this step as done.
582
        newMonitor.worked(steps);
583
    }
584

    
585
    /**
586
     * Present a progress dialog to the user. This dialog will block the UI
587
     *
588
     * @param runnable
589
     *            an implementation of {@link IRunnableWithProgress}
590
     * @throws java.lang.InterruptedException
591
     *             if any.
592
     * @throws java.lang.reflect.InvocationTargetException
593
     *             if any.
594
     */
595
    public static void busyCursorWhile(IRunnableWithProgress runnable)
596
            throws InvocationTargetException, InterruptedException {
597
        getProgressService().busyCursorWhile(runnable);
598
    }
599

    
600
    public static void runInUI(IRunnableWithProgress runnable,
601
            ISchedulingRule rule) throws InvocationTargetException,
602
            InterruptedException {
603
        getProgressService().runInUI(getWorkbenchWindow(), runnable, rule);
604
    }
605

    
606
    public static void run(boolean fork, boolean cancelable,
607
            IRunnableWithProgress runnable) throws InvocationTargetException,
608
            InterruptedException {
609
        getProgressService().run(fork, cancelable, runnable);
610
    }
611

    
612
    public static IProgressService getProgressService() {
613
        IWorkbench workbench = PlatformUI.getWorkbench();
614
        return workbench.getProgressService();
615
    }
616

    
617
    public static IWorkbenchSiteProgressService getProgressService2() {
618
        return (IWorkbenchSiteProgressService) getService(IWorkbenchSiteProgressService.class);
619
    }
620

    
621
    public static String getPluginId() {
622
        return "eu.taxeditor";
623
    }
624

    
625
    public static Object getActiveE4Editor() {
626
        MPart activePart = EventUtility.getActivePart();
627
        if(activePart!=null && activePart.getObject()!=null
628
                && activePart.getObject() instanceof IE4SavablePart){
629
            return activePart.getObject();
630
        }
631
        return null;
632
    }
633

    
634
    public static DetailsViewPart getDetailsView() {
635
        return (DetailsViewPart) getView(DetailsViewPart.ID, false);
636
    }
637

    
638
    public static void refreshDetailsViewer() {
639
        if (getDetailsView() != null) {
640
            ((AbstractCdmDataViewer) getDetailsView().getViewer()).refresh();
641
        }
642
    }
643

    
644
    public static void reflowDetailsViewer() {
645
        if (getDetailsView() != null) {
646
            ((AbstractCdmDataViewer) getDetailsView().getViewer()).reflow();
647
        }
648
    }
649

    
650
    public static SupplementalDataViewPart getSupplementalDataView() {
651
        return (SupplementalDataViewPart) getView(SupplementalDataViewPart.ID,
652
                false);
653
    }
654

    
655
    public static void reflowSupplementalViewer() {
656
        if (getSupplementalDataView() != null) {
657
            ((AbstractCdmDataViewer) getSupplementalDataView().getViewer())
658
            .reflow();
659
        }
660
    }
661

    
662

    
663
    /**
664
     * Orders a Collection of {@link IEnumTerm}s according to the term
665
     * hierarchy. <br>
666
     * <br>
667
     * The returned map will be be ordered primarily by root elements,
668
     * secondarily by the child elements and their children resp., both ascending alphabetically. <br>
669
     * @param terms
670
     *            A {@link Collection} of {@link IEnumTerm}s for which the term
671
     *            hierarchy should be created
672
     * @return a map which holds the terms as keys and their string
673
     *         representation via {@link IEnumTerm#getMessage()} as values
674
     */
675
    public static <T extends IEnumTerm<T>> LinkedHashMap<T, String> orderTerms(Collection<T> terms) {
676
        TreeSet<TermNode<T>> parentElements = new TreeSet<TermNode<T>>();
677
        parentElements.addAll(getTermHierarchy(terms));
678

    
679
        // create list according to the type hierarchy (root elements alphabetically with recursive children also alphabetically)
680
        LinkedHashMap<T, String> result = new LinkedHashMap<T, String>();
681
        parseTermTree(parentElements, result, -1);
682
        return result;
683
    }
684

    
685
    private static<T extends IEnumTerm<T>> void parseTermTree(Collection<TermNode<T>> children, LinkedHashMap<T, String> result, int depth){
686
        depth++;
687
        for(TermNode<T> node:children){
688
            String indentString = "";
689
            for(int i=0;i<depth;i++){
690
                indentString += "  ";
691
            }
692
            if(depth>0){
693
                indentString += "- ";
694
            }
695
            result.put(node.term, indentString + node.term.getMessage());
696
            parseTermTree(node.children, result, depth);
697
        }
698
    }
699

    
700
    private static<T extends IEnumTerm<T>> void addToParents(List<TermNode<T>> parents, Collection<T> terms){
701
        List<TermNode<T>> hasChildrenList = new ArrayList<TermNode<T>>();
702
        for(T term:terms){
703
            // only terms with parents
704
            if(term.getKindOf()!=null){
705
                TermNode<T> parentNode = new TermNode<T>(term.getKindOf());
706
                TermNode<T> childNode = new TermNode<T>(term);
707
                if(parents.contains(parentNode)){
708
                    // parent found in parent list -> add this term to parent's child list
709
                    parents.get(parents.indexOf(parentNode)).addChild(childNode);
710
                    if(!term.getGeneralizationOf().isEmpty()){
711
                        // has more children -> add to list which will be the parent for the next recursion
712
                        hasChildrenList.add(childNode);
713
                    }
714
                }
715
            }
716
        }
717
        if(!hasChildrenList.isEmpty()){
718
            addToParents(hasChildrenList, terms);
719
        }
720
    }
721

    
722
    private static<T extends IEnumTerm<T>> List<TermNode<T>> getTermHierarchy(Collection<T> terms){
723
        List<TermNode<T>> parents = new ArrayList<TermNode<T>>();
724
        // get root elements
725
        for(T term:terms){
726
            T parentTerm = term.getKindOf();
727
            if(parentTerm==null){
728
                // root element
729
                parents.add(new TermNode<T>(term));
730
            }
731
        }
732
        addToParents(parents, terms);
733
        return parents;
734
    }
735

    
736
    @SuppressWarnings("unchecked")
737
    /**
738
     * Recursively iterates over all term parents until no more parent is found i.e. the root node
739
     * @param term The term for which the parent should be found
740
     * @return the root terms of the term hierarchy
741
     */
742
    private static<T extends IEnumTerm<T>> T getParentFor(T term){
743
        // PP: cast should be safe. Why is Eclipse complaining??
744
        T parent = term.getKindOf();
745
        if(parent==null){
746
            return term;
747
        }
748
        else{
749
            return getParentFor(term.getKindOf());
750
        }
751
    }
752

    
753
    private static class TermNode<T extends IEnumTerm<T>> implements Comparable<TermNode<T>>{
754
        private final T term;
755
        private final TreeSet<TermNode<T>> children;
756

    
757
        public TermNode(T term) {
758
            super();
759
            this.term = term;
760
            this.children = new TreeSet<TermNode<T>>();
761
        }
762

    
763
        public void addChild(TermNode<T> child){
764
            this.children.add(child);
765
        }
766

    
767
        public TreeSet<TermNode<T>> getChildren() {
768
            return children;
769
        }
770

    
771
        public T getTerm() {
772
            return term;
773
        }
774

    
775
        @Override
776
        public int hashCode() {
777
            final int prime = 31;
778
            int result = 1;
779
            result = prime * result + ((term == null) ? 0 : term.hashCode());
780
            return result;
781
        }
782

    
783
        @Override
784
        public boolean equals(Object obj) {
785
            if (this == obj) {
786
                return true;
787
            }
788
            if (obj == null) {
789
                return false;
790
            }
791
            if (getClass() != obj.getClass()) {
792
                return false;
793
            }
794
            TermNode other = (TermNode) obj;
795
            if (term == null) {
796
                if (other.term != null) {
797
                    return false;
798
                }
799
            } else if (!term.equals(other.term)) {
800
                return false;
801
            }
802
            return true;
803
        }
804

    
805
        @Override
806
        public int compareTo(TermNode<T> that) {
807
            return this.term.getMessage().compareTo(that.term.getMessage());
808
        }
809
    }
810

    
811

    
812
    public static void executeCommand(String commandId, Object source, String pluginId) {
813
        IHandlerService handlerService = (IHandlerService) AbstractUtility.getService(IHandlerService.class);
814
        Exception exception = null;
815
        try {
816
            handlerService.executeCommand(commandId, null);
817
        } catch (ExecutionException e) {
818
            exception = e;
819
        } catch (NotDefinedException e) {
820
            exception = e;
821
        } catch (NotEnabledException e) {
822
            exception = e;
823
        } catch (NotHandledException e) {
824
            exception = e;
825
        } finally {
826
            if(exception != null) {
827
                MessagingUtils.errorDialog("Error executing command",
828
                        source,
829
                        "Could not execute command with id " + commandId ,
830
                        pluginId,
831
                        exception,
832
                        true);
833
            }
834
        }
835
    }
836

    
837
    public static Object getElementsFromSelectionChangedEvent(SelectionChangedEvent event) {
838
        IStructuredSelection selection = (IStructuredSelection) event.getSelection();
839
        Object selectionToSet = selection;
840
        if(selection.size() == 1){
841
            selectionToSet = selection.getFirstElement();
842
        }
843
        else if(!selection.isEmpty()){
844
            selectionToSet = selection.toArray();
845
        }
846
        return selectionToSet;
847
    }
848

    
849
    /**
850
     * Executes a remoting monitored import
851
     *
852
     * @param label for the import
853
     * @param uuid of the remoting monitor already started on the server
854
     * @param pollInterval in milliseconds
855
     * @param cancelable flag which determines whether the operation can be cancelled
856
     * @param postOp callback for running post operation logic
857
     * @return
858
     */
859
    public static IStatus executeMoniteredOperation(final String label,
860
            final UUID uuid,
861
            final int pollInterval,
862
            final boolean cancelable,
863
            final IPostMoniteredOperationEnabled postOp,
864
            final IFeedbackGenerator feedbackGenerator) {
865

    
866
    	try{
867
    		// get the remoting monitor the first time to make sure that the
868
            // operation is valid
869
            final IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
870
            final IRemotingProgressMonitor firstRemotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
871
            if(firstRemotingMonitor == null) {
872
                throw new IllegalStateException("Remoting progress monitor is null");
873
            }
874

    
875
            Job job = new Job(label) {
876

    
877

    
878
                @Override
879
                public IStatus run(IProgressMonitor monitor) {
880
                    // run the monitor until the operation is finished
881
                	monitor.beginTask("Start", 100);
882
                    IRemotingProgressMonitor remotingMonitor;
883
                    try {
884
                        remotingMonitor = CdmStore.getProgressMonitorClientManager().pollMonitor(label,
885
                                uuid,
886
                                pollInterval,
887
                                postOp,
888
                                feedbackGenerator,
889
                                monitor);
890
                    } catch (Exception ex) {
891
                        return new Status(Status.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
892
                    }
893
                    final StringBuilder reportSb = new StringBuilder();
894
                    // collect reports
895
//	                    for(String report : remotingMonitor.getResult()) {
896
                        reportSb.append(((ExportResult)remotingMonitor.getResult()).createReport());
897
//	                    }
898
                    if(!StringUtils.isBlank(reportSb.toString())) {
899
                        Display.getDefault().asyncExec(new Runnable() {
900
                            @Override
901
                            public void run() {
902
                                // display reports with possibility to save
903
                                ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
904
                                dialog.setTitle(label + " Report");
905
                                dialog.setReportText(reportSb.toString());
906
                                dialog.open();
907
                            }
908
                        });
909
                    }
910
                    return Status.OK_STATUS;
911
                }
912

    
913
                @Override
914
                protected void canceling() {
915
                    CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
916
                }
917
            };
918

    
919
            // configure the job
920
            job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
921
            job.setUser(true);
922
            // schedule job
923
            job.schedule();
924

    
925
        } catch (Exception e) {
926
            MessagingUtils.errorDialog("Error executing operation",
927
                    AbstractUtility.class,
928
                    "An error occured while executing " + label,
929
                    TaxeditorStorePlugin.PLUGIN_ID,
930
                    e,
931
                    true);
932
        }
933

    
934
        return Status.OK_STATUS;
935
        }
936

    
937
}
(2-2/39)