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 MPart getActivePart() {
113
        return EventUtility.getActivePart();
114
    }
115

    
116
    public static boolean closeAll() {
117
        if(getActivePage()!=null){
118
            return getActivePage().closeAllEditors(true);
119
        }
120
        return false;
121
    }
122

    
123
    public static Shell getShell() {
124

    
125
        return TaxeditorStorePlugin.getDefault().getWorkbench()
126
                .getActiveWorkbenchWindow().getShell();
127
    }
128

    
129
    public static IWorkbenchPage getActivePage() {
130
        try{
131
            return TaxeditorStorePlugin.getDefault().getWorkbench()
132
                    .getActiveWorkbenchWindow().getActivePage();
133
        } catch(NullPointerException npe){
134
            return null;
135
        }
136
    }
137

    
138
    public static Object getActiveE4Part() {
139
        //TODO merge with getActivePart()
140
        return getActivePart();
141
    }
142

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

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

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

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

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

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

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

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

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

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

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

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

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

    
239
        IRunnableWithProgress runnable = new IRunnableWithProgress() {
240

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

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

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

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

    
263
            }
264
        };
265

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

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

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

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

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

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

    
297
        IRunnableWithProgress runnable = new IRunnableWithProgress() {
298

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

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

    
325
            }
326
        };
327

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

    
334
        return Status.OK_STATUS;
335
    }
336

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

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

    
365
            Job job = new Job(label) {
366

    
367

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

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

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

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

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

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

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

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

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

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

    
494
        return Status.OK_STATUS;
495
    }
496

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

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

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

    
509
        });
510

    
511
    }
512

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
663

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
812

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

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

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

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

    
876
            Job job = new Job(label) {
877

    
878

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

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

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

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

    
935
        return Status.OK_STATUS;
936
        }
937

    
938
}
(2-2/39)