Project

General

Profile

Download (36.4 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.jface.action.IStatusLineManager;
49
import org.eclipse.jface.operation.IRunnableWithProgress;
50
import org.eclipse.jface.resource.ColorRegistry;
51
import org.eclipse.jface.resource.FontRegistry;
52
import org.eclipse.jface.viewers.IStructuredSelection;
53
import org.eclipse.jface.viewers.SelectionChangedEvent;
54
import org.eclipse.swt.graphics.Color;
55
import org.eclipse.swt.graphics.Font;
56
import org.eclipse.swt.widgets.Display;
57
import org.eclipse.swt.widgets.Shell;
58
import org.eclipse.ui.IEditorPart;
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.IWorkbenchPart;
64
import org.eclipse.ui.IWorkbenchWindow;
65
import org.eclipse.ui.PartInitException;
66
import org.eclipse.ui.PlatformUI;
67
import org.eclipse.ui.handlers.IHandlerService;
68
import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
69
import org.eclipse.ui.part.EditorPart;
70
import org.eclipse.ui.progress.IProgressConstants;
71
import org.eclipse.ui.progress.IProgressService;
72
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
73
import org.eclipse.ui.themes.ITheme;
74
import org.eclipse.ui.themes.IThemeManager;
75

    
76
import eu.etaxonomy.cdm.api.application.CdmApplicationState;
77
import eu.etaxonomy.cdm.api.service.IProgressMonitorService;
78
import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
79
import eu.etaxonomy.cdm.io.common.ExportDataWrapper;
80
import eu.etaxonomy.cdm.io.common.ExportResult;
81
import eu.etaxonomy.cdm.io.common.ExportResultType;
82
import eu.etaxonomy.cdm.model.common.IEnumTerm;
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.store.CdmStore;
89
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
90
import eu.etaxonomy.taxeditor.ui.dialog.ReportTextDialog;
91
import eu.etaxonomy.taxeditor.view.AbstractCdmDataViewer;
92
import eu.etaxonomy.taxeditor.view.detail.DetailsViewPart;
93
import eu.etaxonomy.taxeditor.view.supplementaldata.SupplementalDataViewPart;
94
import eu.etaxonomy.taxeditor.workbench.WorkbenchUtility;
95

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

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

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

    
111
    public static boolean closeAll() {
112
        if(getActivePage()!=null){
113
            return getActivePage().closeAllEditors(true);
114
        }
115
        return false;
116
    }
117

    
118
    /**
119
     * Close the given editor.
120
     *
121
     * @param editor
122
     *            The <tt>MultipageTaxonEditor</tt> to close.
123
     * @return <tt>true</tt> on success
124
     */
125
    public static boolean close(EditorPart editor) {
126
        return getActivePage() != null ? getActivePage().closeEditor(editor, true):false;
127
    }
128

    
129
    public static Shell getShell() {
130

    
131
        return TaxeditorStorePlugin.getDefault().getWorkbench()
132
                .getActiveWorkbenchWindow().getShell();
133
    }
134

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

    
144
    public static IWorkbenchPart getActiveWorkbenchPart() {
145
        IWorkbenchPage activePage = getActivePage();
146
        if(activePage!=null){
147
            IWorkbenchPart activePart = activePage.getActivePart();
148
            if(activePart!=null){
149
                return activePart;
150
            }
151
        }
152
        return null;
153
    }
154

    
155
    public static Object getActiveE4Part() {
156
        IWorkbenchPage activePage = getActivePage();
157
        if(activePage!=null){
158
            IWorkbenchPart activePart = activePage.getActivePart();
159
            Object e4WrappedPart = WorkbenchUtility.getE4WrappedPart(activePart);
160
            return e4WrappedPart!=null?e4WrappedPart:activePart;
161
        }
162
        return null;
163
    }
164

    
165
    public static IWorkbench getWorkbench() {
166
        return TaxeditorStorePlugin.getDefault().getWorkbench();
167
    }
168

    
169
    public static IWorkbenchWindow getWorkbenchWindow() {
170
        if (getWorkbench().getWorkbenchWindowCount() > 1) {
171
            throw new IllegalStateException("More than one workbench window");
172
        }
173
        return getWorkbench().getWorkbenchWindows()[0];
174
    }
175

    
176
    public static IViewPart showView(String id) {
177
        try {
178
            return PlatformUI.getWorkbench().getActiveWorkbenchWindow()
179
                    .getActivePage()
180
                    .showView(id, null, IWorkbenchPage.VIEW_VISIBLE);
181
        } catch (PartInitException e) {
182
            MessagingUtils.messageDialog("Error opening view", AbstractUtility.class, "Could not open view: " + id, e);
183
            return null;
184
        }
185
    }
186

    
187
    public static void hideView(IViewPart view) {
188
        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
189
        .hideView(view);
190
    }
191

    
192
    public static IViewPart getView(String id, boolean restore) {
193
    	IWorkbench workbench = PlatformUI.getWorkbench();
194
        IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
195
    	IViewReference[] references = null;
196
    	if(activeWorkbenchWindow!=null && activeWorkbenchWindow.getActivePage()!=null){
197
    	    references = activeWorkbenchWindow.getActivePage().getViewReferences();
198
    	}
199
    	else if(workbench.getWorkbenchWindows().length>0 && workbench.getWorkbenchWindows()[0].getActivePage()!=null){
200
    		references = workbench.getWorkbenchWindows()[0].getActivePage().getViewReferences();
201
    	}
202
    	if(references!=null){
203
    		for (IViewReference reference : references) {
204
    			if (reference.getId().equals(id)) {
205
    				return reference.getView(restore);
206
    			}
207
    		}
208
    	}
209
        return null;
210
    }
211

    
212
    public static Object getService(Class api) {
213
        return TaxeditorStorePlugin.getDefault().getWorkbench().getService(api);
214
    }
215

    
216
    public static ITheme getCurrentTheme() {
217
        IThemeManager themeManager = TaxeditorStorePlugin.getDefault()
218
                .getWorkbench().getThemeManager();
219
        return themeManager.getCurrentTheme();
220
    }
221

    
222
    /**
223
     * Fonts registered to the plugin may be obtained with the Eclipse themeing
224
     * functionality. Thus fonts are chooseable by the user via
225
     * Preferences->General->Appearance->Colors and Fonts
226
     *
227
     * @return the FontRegistry for the current theme
228
     */
229
    public static FontRegistry getFontRegistry() {
230
        return getCurrentTheme().getFontRegistry();
231
    }
232

    
233
    public static Font getFont(String symbolicName) {
234
        return getFontRegistry().get(symbolicName);
235
    }
236

    
237
    /**
238
     * Color registered to the plugin may be obtained with the Eclipse themeing
239
     * functionality. Thus colors are editable by the user via
240
     * Preferences->General->Appearance->Colors and Fonts
241
     *
242
     * @return the ColorRegistry for the current theme
243
     */
244
    public static ColorRegistry getColorRegistry() {
245
        return getCurrentTheme().getColorRegistry();
246
    }
247

    
248
    public static Color getColor(String symbolicName) {
249
        return getColorRegistry().get(symbolicName);
250
    }
251

    
252
    public static IStatus executeOperation(final AbstractPostOperation operation) {
253
        if (getOperationHistory() == null) {
254
            throw new IllegalArgumentException(
255
                    "There is no operation history for this context");
256
        }
257

    
258
        final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
259
                .getUIInfoAdapter(getShell());
260

    
261
        IRunnableWithProgress runnable = new IRunnableWithProgress() {
262

    
263
            @Override
264
            public void run(IProgressMonitor monitor)
265
                    throws InvocationTargetException, InterruptedException {
266
                String operationlabel = operation.getLabel();
267
                monitor.beginTask(operationlabel, 100);
268
                IStatus status = Status.CANCEL_STATUS;
269
                try {
270
                    operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
271
                    status = getOperationHistory().execute(operation, monitor,
272
                            uiInfoAdapter);
273
                } catch (ExecutionException e) {
274

    
275
                    MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
276

    
277
                } finally {
278
                    monitor.done();
279
                }
280

    
281
                String statusString = status.equals(Status.OK_STATUS) ? "completed"
282
                        : "cancelled";
283
                setStatusLine(operationlabel + " " + statusString + ".");
284

    
285
            }
286
        };
287

    
288
        try {
289
            runInUI(runnable, null);
290
        } catch (Exception e) {
291
            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
292
        }
293

    
294
        IPostOperationEnabled postOperationEnabled = operation
295
                .getPostOperationEnabled();
296
        if (postOperationEnabled != null) {
297
            postOperationEnabled.onComplete();
298
        }
299
        return Status.OK_STATUS;
300
    }
301

    
302
    public static IStatus executeOperation(final AbstractOperation operation, final RemotingCdmHandler handler) {
303
        if (getOperationHistory() == null) {
304
            throw new IllegalArgumentException(
305
                    "There is no operation history for this context");
306
        }
307

    
308
        final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
309
                .getUIInfoAdapter(getShell());
310

    
311
        IRunnableWithProgress runnable = new IRunnableWithProgress() {
312

    
313
            @Override
314
            public void run(IProgressMonitor monitor)
315
                    throws InvocationTargetException, InterruptedException {
316
                String operationlabel = operation.getLabel();
317
                monitor.beginTask(operationlabel, 100);
318
                IStatus status = Status.CANCEL_STATUS;
319
                try {
320
                    operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
321
                    status = getOperationHistory().execute(operation, monitor,
322
                            uiInfoAdapter);
323
                    if(handler != null) {
324
                        handler.postOperation(status);
325
                    }
326
                } catch (ExecutionException e) {
327
                    MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
328
                } finally {
329
                    monitor.done();
330
                }
331

    
332
                String statusString = status.equals(Status.OK_STATUS) ? "completed"
333
                        : "cancelled";
334
                setStatusLine(operationlabel + " " + statusString + ".");
335

    
336
            }
337
        };
338

    
339
        try {
340
            runInUI(runnable, null);
341
        } catch (Exception e) {
342
            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
343
        }
344

    
345
        return Status.OK_STATUS;
346
    }
347

    
348
    /**
349
     * Executes a remoting monitored operation
350
     *
351
     * @param label for the operation
352
     * @param uuid of the remoting monitor already started on the server
353
     * @param pollInterval in milliseconds
354
     * @param cancelable flag which determines whether the operation can be cancelled
355
     * @param postOp callback for running post operation logic
356
     * @return
357
     */
358
    public static IStatus executeMoniteredExport(final String label,
359
            final UUID uuid,
360
            final int pollInterval,
361
            final boolean cancelable,
362
            final IPostMoniteredOperationEnabled postOp,
363
            final IFeedbackGenerator feedbackGenerator,
364
            String urlString,
365
            boolean createZip) {
366

    
367
        try {
368
            // get the remoting monitor the first time to make sure that the
369
            // operation is valid
370
            final IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
371
            final IRemotingProgressMonitor firstRemotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
372
            if(firstRemotingMonitor == null) {
373
                throw new IllegalStateException("Remoting progress monitor is null");
374
            }
375

    
376
            Job job = new Job(label) {
377

    
378

    
379
                @Override
380
                public IStatus run(IProgressMonitor monitor) {
381
                    // run the monitor until the operation is finished
382
                	monitor.beginTask("Start", 100);
383
                    IRemotingProgressMonitor remotingMonitor;
384
                    try {
385
                        remotingMonitor = CdmStore.getProgressMonitorClientManager().pollMonitor(label,
386
                                uuid,
387
                                pollInterval,
388
                                postOp,
389
                                feedbackGenerator,
390
                                monitor);
391
                    } catch (Exception ex) {
392
                        return new Status(Status.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
393
                    }
394
                    final StringBuilder reportSb = new StringBuilder();
395
                    if (remotingMonitor.getResult() instanceof ExportResult){
396
                    	ExportResult result = (ExportResult)remotingMonitor.getResult();
397
                    	
398
	                    reportSb.append(result.createReport());
399
	                    
400
	                    if(!StringUtils.isBlank(reportSb.toString())) {
401
	                        Display.getDefault().asyncExec(new Runnable() {
402
	                            @Override
403
	                            public void run() {
404
	                                // display reports with possibility to save
405
	                                ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
406
	                                dialog.setTitle(label + " Report");
407
	                                dialog.setReportText(reportSb.toString());
408
	                                dialog.open();
409
	                            }
410
	                        });
411
	                    }
412
	                    
413
	                    if (urlString != null){
414
	                    	 ExportDataWrapper data = result.getExportData();
415
	                         try{
416
	                             if (result.getExportData().getType().equals(ExportResultType.BYTE_ARRAY)){
417
	                                 byte[] exportData = (byte[])data.getExportData();
418
	                                 if(exportData != null){
419
	                                     File file = new File(urlString);
420
	                                     FileOutputStream stream = new FileOutputStream(file);
421
	                                     Writer out = new BufferedWriter(new OutputStreamWriter(
422
	                                 			stream, "UTF8"));
423

    
424
	                                 	stream.write(exportData);
425
	                                    out.flush();
426
	                                    stream.close();
427
	                                 }
428
	                             } else if (result.getExportData().getType().equals(ExportResultType.MAP_BYTE_ARRAY)){
429
	                                 Map<String, byte[]> resultMap = (Map<String, byte[]>)data.getExportData();
430
	                                 Set<String> keySet = resultMap.keySet();
431
	                                 SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
432
	                                 Calendar cal = Calendar.getInstance();
433
	                                 String fileEnding = ".csv";
434
	                                 
435
	                                 if (createZip){      
436
	                            		 File file = new File(urlString+File.separator +  sdf.format(cal.getTime())+ ".zip");                              
437
	                                     FileOutputStream stream = new FileOutputStream(file);
438
	                                     ZipOutputStream zos = new ZipOutputStream(stream);
439
	                                     for (String key: keySet){
440
	                                    	byte[] fileData = resultMap.get(key);
441
	                                    	ZipEntry entry = new ZipEntry( key + fileEnding); 
442
	         								zos.putNextEntry(entry);
443
	         								zos.write(fileData);
444
	         								zos.closeEntry();
445
	                                     }
446
	                                     zos.close();
447
	                            	 }else{
448
	                            		 for (String key: keySet){
449
	                            			 byte[] fileData = resultMap.get(key);
450
	                            			 File file = new File(urlString+File.separator + key + fileEnding);
451
	                                         FileOutputStream stream = new FileOutputStream(file);
452
	                                         Writer out = new BufferedWriter(new OutputStreamWriter(
453
	                                     			stream, "UTF8"));
454
	                                         stream.write(fileData);
455
	                                         stream.close();
456
	                                     }
457
	                            	 }
458
	                            }else{
459
	                                 logger.error("This kind of result data is not supported yet." + result.getExportData().getType().toString());
460
	                             }
461
	                         } catch(Exception e){
462
	                             logger.error(e.getStackTrace());
463
	                         }
464
	                    }
465
                    }
466
                    return Status.OK_STATUS;
467
                }
468

    
469
                @Override
470
                protected void canceling() {
471
                    CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
472
                }
473
            };
474

    
475
            // configure the job
476
            job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
477
            job.setUser(true);
478
            // schedule job
479
            job.schedule();
480

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

    
490
        return Status.OK_STATUS;
491
    }
492

    
493
    public static IOperationHistory getOperationHistory() {
494
        return getWorkbench().getOperationSupport().getOperationHistory();
495
    }
496

    
497
    public static void setStatusLine(final String message) {
498
        Display.getDefault().asyncExec(new Runnable() {
499

    
500
            @Override
501
            public void run() {
502
                statusLineManager.setMessage(message);
503
            }
504

    
505
        });
506

    
507
    }
508

    
509
    public static IProgressMonitor getMonitor() {
510
        statusLineManager.setCancelEnabled(false);
511
        return statusLineManager.getProgressMonitor();
512
    }
513

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

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

    
561
        return new SubProgressMonitor(progressMonitor, ticks);
562
    }
563

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

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

    
597
    public static void runInUI(IRunnableWithProgress runnable,
598
            ISchedulingRule rule) throws InvocationTargetException,
599
            InterruptedException {
600
        getProgressService().runInUI(getWorkbenchWindow(), runnable, rule);
601
    }
602

    
603
    public static void run(boolean fork, boolean cancelable,
604
            IRunnableWithProgress runnable) throws InvocationTargetException,
605
            InterruptedException {
606
        getProgressService().run(fork, cancelable, runnable);
607
    }
608

    
609
    public static IProgressService getProgressService() {
610
        IWorkbench workbench = PlatformUI.getWorkbench();
611
        return workbench.getProgressService();
612
    }
613

    
614
    public static IWorkbenchSiteProgressService getProgressService2() {
615
        return (IWorkbenchSiteProgressService) getService(IWorkbenchSiteProgressService.class);
616
    }
617

    
618
    public static String getPluginId() {
619
        return "eu.taxeditor";
620
    }
621

    
622
    public static IEditorPart getActiveEditor() {
623
        return getActivePage() != null ? getActivePage().getActiveEditor()
624
                : null;
625
    }
626

    
627
    public static Object getActiveE4Editor() {
628
        if(getActivePage()!=null){
629
            IEditorPart activeEditor = getActivePage().getActiveEditor();
630
            Object wrappedPart = WorkbenchUtility.getE4WrappedPart(getActivePage().getActivePart());
631
            return wrappedPart!=null?wrappedPart:activeEditor;
632
        }
633
        return null;
634
    }
635

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

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

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

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

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

    
664

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
813

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

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

    
851
    /**
852
     * Executes a remoting monitored import
853
     *
854
     * @param label for the import
855
     * @param uuid of the remoting monitor already started on the server
856
     * @param pollInterval in milliseconds
857
     * @param cancelable flag which determines whether the operation can be cancelled
858
     * @param postOp callback for running post operation logic
859
     * @return
860
     */
861
    public static IStatus executeMoniteredOperation(final String label,
862
            final UUID uuid,
863
            final int pollInterval,
864
            final boolean cancelable,
865
            final IPostMoniteredOperationEnabled postOp,
866
            final IFeedbackGenerator feedbackGenerator) {
867
    	
868
    	try{
869
    		// get the remoting monitor the first time to make sure that the
870
            // operation is valid
871
            final IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
872
            final IRemotingProgressMonitor firstRemotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
873
            if(firstRemotingMonitor == null) {
874
                throw new IllegalStateException("Remoting progress monitor is null");
875
            }
876

    
877
            Job job = new Job(label) {
878

    
879

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

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

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

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

    
936
        return Status.OK_STATUS;
937
        }
938

    
939
}
(2-2/39)