Project

General

Profile

Download (34.1 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2007 EDIT
3
 * European Distributed Institute of Taxonomy
4
 * http://www.e-taxonomy.eu
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version 1.1
7
 * See LICENSE.TXT at the top of this package for the full license terms.
8
 */
9

    
10
package eu.etaxonomy.taxeditor.model;
11

    
12
import java.io.BufferedWriter;
13
import java.io.File;
14
import java.io.FileOutputStream;
15
import java.io.OutputStreamWriter;
16
import java.io.Writer;
17
import java.text.SimpleDateFormat;
18
import java.util.ArrayList;
19
import java.util.Calendar;
20
import java.util.Collection;
21
import java.util.HashSet;
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.lang3.StringUtils;
32
import org.apache.log4j.Logger;
33
import org.eclipse.core.commands.ExecutionException;
34
import org.eclipse.core.commands.operations.AbstractOperation;
35
import org.eclipse.core.commands.operations.IOperationHistory;
36
import org.eclipse.core.runtime.IAdaptable;
37
import org.eclipse.core.runtime.ICoreRunnable;
38
import org.eclipse.core.runtime.IProgressMonitor;
39
import org.eclipse.core.runtime.IStatus;
40
import org.eclipse.core.runtime.NullProgressMonitor;
41
import org.eclipse.core.runtime.OperationCanceledException;
42
import org.eclipse.core.runtime.Status;
43
import org.eclipse.core.runtime.SubMonitor;
44
import org.eclipse.core.runtime.SubProgressMonitor;
45
import org.eclipse.core.runtime.jobs.Job;
46
import org.eclipse.e4.ui.di.UISynchronize;
47
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
48
import org.eclipse.e4.ui.workbench.modeling.EPartService;
49
import org.eclipse.jface.action.IStatusLineManager;
50
import org.eclipse.jface.viewers.IStructuredSelection;
51
import org.eclipse.jface.viewers.SelectionChangedEvent;
52
import org.eclipse.swt.graphics.Color;
53
import org.eclipse.swt.graphics.Font;
54
import org.eclipse.swt.widgets.Display;
55
import org.eclipse.swt.widgets.Shell;
56
import org.eclipse.ui.IWorkbench;
57
import org.eclipse.ui.PlatformUI;
58
import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
59
import org.eclipse.ui.progress.IProgressConstants;
60

    
61
import eu.etaxonomy.cdm.api.application.CdmApplicationState;
62
import eu.etaxonomy.cdm.api.service.IProgressMonitorService;
63
import eu.etaxonomy.cdm.api.service.UpdateResult;
64
import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
65
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
66
import eu.etaxonomy.cdm.io.common.ExportDataWrapper;
67
import eu.etaxonomy.cdm.io.common.ExportResult;
68
import eu.etaxonomy.cdm.io.common.ExportResultType;
69
import eu.etaxonomy.cdm.io.common.ExportType;
70
import eu.etaxonomy.cdm.io.common.ImportResult;
71
import eu.etaxonomy.cdm.model.common.CdmBase;
72
import eu.etaxonomy.cdm.model.taxon.Synonym;
73
import eu.etaxonomy.cdm.model.taxon.Taxon;
74
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
75
import eu.etaxonomy.cdm.model.term.IEnumTerm;
76
import eu.etaxonomy.taxeditor.event.EventUtility;
77
import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
78
import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
79
import eu.etaxonomy.taxeditor.operation.IFeedbackGenerator;
80
import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
81
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
82
import eu.etaxonomy.taxeditor.operation.e4.RemotingCdmHandlerE4;
83
import eu.etaxonomy.taxeditor.store.CdmStore;
84
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
85
import eu.etaxonomy.taxeditor.ui.dialog.ReportTextDialog;
86
import eu.etaxonomy.taxeditor.view.e4.AbstractCdmDataViewerE4;
87
import eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4;
88
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
89

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

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

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

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

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

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

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

    
125
    public static Font getFont(String symbolicName) {
126
        return FontResources.getFont(symbolicName);
127
    }
128

    
129
    public static Color getColor(String symbolicName) {
130
        return ColorResources.getColor(symbolicName);
131
    }
132

    
133
    public static IStatus executeOperation(final AbstractPostOperation operation, UISynchronize sync) {
134
        if (getOperationHistory() == null) {
135
            throw new IllegalArgumentException(
136
                    "There is no operation history for this context");
137
        }
138

    
139
        final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
140
                .getUIInfoAdapter(getShell());
141

    
142
        Job job = Job.create(operation.getLabel(), (ICoreRunnable) monitor -> {
143
            sync.syncExec(() -> {
144
                String operationlabel = operation.getLabel();
145
                monitor.beginTask(operationlabel, 100);
146
                IStatus status = Status.CANCEL_STATUS;
147
                try {
148
                    operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
149
                    status = operation.execute(monitor, uiInfoAdapter);
150
                } catch (ExecutionException e) {
151

    
152
                    MessagingUtils.operationDialog(AbstractUtility.class, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
153

    
154
                } finally {
155
                    monitor.done();
156
                }
157

    
158
                String statusString = status.equals(Status.OK_STATUS) ? "completed"
159
                        : "cancelled";
160
                setStatusLine(operationlabel + " " + statusString + ".");
161
                IPostOperationEnabled postOperationEnabled = operation
162
                        .getPostOperationEnabled();
163
                if (postOperationEnabled != null) {
164
                    postOperationEnabled.onComplete();
165
                }
166
            });
167
        });
168

    
169
        try {
170
            job.setUser(true);
171
            job.schedule();
172
        } catch (Exception e) {
173
            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occurred while executing " + operation.getLabel(), e);
174
        }
175

    
176
        return Status.OK_STATUS;
177
    }
178

    
179
    public static IStatus executeOperation(final AbstractOperation operation, final RemotingCdmHandlerE4 handler, UISynchronize sync) {
180
        return executeOperation_internal(operation, handler, sync);
181
    }
182

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

    
190
        final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
191
                .getUIInfoAdapter(getShell());
192

    
193

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

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

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

    
223
        return Status.OK_STATUS;
224
    }
225

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

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

    
257
            Job job = new Job(label) {
258

    
259

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

    
277
                    createExportResult(label, urlString, createZip, remotingMonitor);
278
                    return Status.OK_STATUS;
279
                }
280

    
281

    
282

    
283
                @Override
284
                protected void canceling() {
285
                    CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
286
                }
287
            };
288

    
289
            // configure the job
290
            job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
291
            job.setUser(true);
292
            job.setName(label);
293
            // schedule job
294
            job.schedule();
295

    
296
        } catch (Exception e) {
297
            MessagingUtils.errorDialog("Error executing operation",
298
                    AbstractUtility.class,
299
                    "An error occurred while executing " + label,
300
                    TaxeditorStorePlugin.PLUGIN_ID,
301
                    e,
302
                    true);
303
        }
304

    
305
        return Status.OK_STATUS;
306
    }
307

    
308
    public static IOperationHistory getOperationHistory() {
309
        return getWorkbench().getOperationSupport().getOperationHistory();
310
    }
311

    
312
    public static void setStatusLine(final String message) {
313
        Display.getDefault().asyncExec(new Runnable() {
314

    
315
            @Override
316
            public void run() {
317
                statusLineManager.setMessage(message);
318
            }
319

    
320
        });
321

    
322
    }
323

    
324
    public static IProgressMonitor getMonitor() {
325
        statusLineManager.setCancelEnabled(false);
326
        return statusLineManager.getProgressMonitor();
327
    }
328

    
329
    /**
330
     * Starts either the given {@link IProgressMonitor} if it's not
331
     * <code>null</code> or a new {@link NullProgressMonitor}.
332
     *
333
     * @param progressMonitor
334
     *            The {@link IProgressMonitor} or <code>null</code> if no
335
     *            progress should be reported.
336
     * @param taskName
337
     *            The name of the main task.
338
     * @param steps
339
     *            The number of steps this task is subdivided into.
340
     * @return The {@link IProgressMonitor}.
341
     */
342
    public static IProgressMonitor startMainMonitor(
343
            IProgressMonitor progressMonitor, String taskName, int steps) {
344
        IProgressMonitor newMonitor = progressMonitor;
345
        if (newMonitor == null) {
346
            newMonitor = new NullProgressMonitor();
347
        }
348
        newMonitor.beginTask(taskName == null ? "" : taskName, steps);
349
        newMonitor.subTask(" ");
350
        return newMonitor;
351
    }
352

    
353
    /**
354
     * Creates a {@link SubProgressMonitor} if the given
355
     * {@link IProgressMonitor} is not <code>null</code> and not a
356
     * {@link NullProgressMonitor}.
357
     *
358
     * @param progressMonitor
359
     *            The parent {@link IProgressMonitor} of the
360
     *            {@link SubProgressMonitor} to be created.
361
     * @param ticks
362
     *            The number of steps this subtask is subdivided into. Must be a
363
     *            positive number and must not be
364
     *            {@link IProgressMonitor#UNKNOWN}.
365
     * @return The {@link IProgressMonitor}.
366
     */
367
    public static IProgressMonitor getSubProgressMonitor(
368
            IProgressMonitor progressMonitor, int ticks) {
369
        if (progressMonitor == null) {
370
            return new NullProgressMonitor();
371
        }
372
        if (progressMonitor instanceof NullProgressMonitor) {
373
            return progressMonitor;
374
        }
375

    
376
        return new SubProgressMonitor(progressMonitor, ticks);
377
    }
378

    
379
    /**
380
     * Checks whether the user canceled this operation. If not canceled, the
381
     * given number of steps are declared as done.
382
     *
383
     * @param newMonitor
384
     *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
385
     * @param steps
386
     *            a int.
387
     */
388
    public static void workedChecked(IProgressMonitor newMonitor, int steps) {
389
        // In case the progress monitor was canceled throw an exception.
390
        if (newMonitor.isCanceled()) {
391
            throw new OperationCanceledException();
392
        }
393
        // Otherwise declare this step as done.
394
        newMonitor.worked(steps);
395
    }
396

    
397
    public static String getPluginId() {
398
        return "eu.taxeditor";
399
    }
400

    
401
    public static Object getActiveEditor() {
402
        MPart activePart = EventUtility.getActivePart();
403
        if(activePart!=null && activePart.getObject()!=null
404
                && activePart.getObject() instanceof IE4SavablePart){
405
            return activePart.getObject();
406
        }
407
        return null;
408
    }
409

    
410
    public static DetailsPartE4 getDetailsView(EPartService partService) {
411
        MPart part = partService.findPart("eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4");
412
        if(part!=null){
413
            return (DetailsPartE4) part.getObject();
414
        }
415
        return null;
416
    }
417

    
418
    public static void refreshDetailsViewer(EPartService partService) {
419
        if (getDetailsView(partService) != null) {
420
            ((AbstractCdmDataViewerE4) getDetailsView(partService).getViewer()).refresh();
421
        }
422
    }
423

    
424
    public static void reflowDetailsViewer(EPartService partService) {
425
        if (getDetailsView(partService) != null) {
426
            ((AbstractCdmDataViewerE4) getDetailsView(partService).getViewer()).reflow();
427
        }
428
    }
429

    
430

    
431
    /**
432
     * Orders a Collection of {@link IEnumTerm}s according to the term
433
     * hierarchy. <br>
434
     * <br>
435
     * The returned map will be be ordered primarily by root elements,
436
     * secondarily by the child elements and their children resp., both ascending alphabetically. <br>
437
     * @param terms
438
     *            A {@link Collection} of {@link IEnumTerm}s for which the term
439
     *            hierarchy should be created
440
     * @return a map which holds the terms as keys and their string
441
     *         representation via {@link IEnumTerm#getMessage()} as values
442
     */
443
    public static <T extends IEnumTerm<T>> LinkedHashMap<T, String> orderTerms(Collection<T> terms) {
444
        TreeSet<TermNode<T>> parentElements = new TreeSet<TermNode<T>>();
445
        parentElements.addAll(getTermHierarchy(terms));
446

    
447
        // create list according to the type hierarchy (root elements alphabetically with recursive children also alphabetically)
448
        LinkedHashMap<T, String> result = new LinkedHashMap<T, String>();
449
        parseTermTree(parentElements, result, -1);
450
        return result;
451
    }
452

    
453
    private static<T extends IEnumTerm<T>> void parseTermTree(Collection<TermNode<T>> children, LinkedHashMap<T, String> result, int depth){
454
        depth++;
455
        for(TermNode<T> node:children){
456
            String indentString = "";
457
            for(int i=0;i<depth;i++){
458
                indentString += "  ";
459
            }
460
            if(depth>0){
461
                indentString += "- ";
462
            }
463
            result.put(node.term, indentString + node.term.getLabel());
464
            parseTermTree(node.children, result, depth);
465
        }
466
    }
467

    
468
    private static<T extends IEnumTerm<T>> void addToParents(List<TermNode<T>> parents, Collection<T> terms){
469
        List<TermNode<T>> hasChildrenList = new ArrayList<TermNode<T>>();
470
        for(T term:terms){
471
            // only terms with parents
472
            if(term.getKindOf()!=null){
473
                TermNode<T> parentNode = new TermNode<T>(term.getKindOf());
474
                TermNode<T> childNode = new TermNode<T>(term);
475
                if(parents.contains(parentNode)){
476
                    // parent found in parent list -> add this term to parent's child list
477
                    parents.get(parents.indexOf(parentNode)).addChild(childNode);
478
                    if(!term.getGeneralizationOf().isEmpty()){
479
                        // has more children -> add to list which will be the parent for the next recursion
480
                        hasChildrenList.add(childNode);
481
                    }
482
                }
483
            }
484
        }
485
        if(!hasChildrenList.isEmpty()){
486
            addToParents(hasChildrenList, terms);
487
        }
488
    }
489

    
490
    private static<T extends IEnumTerm<T>> List<TermNode<T>> getTermHierarchy(Collection<T> terms){
491
        List<TermNode<T>> parents = new ArrayList<TermNode<T>>();
492
        // get root elements
493
        for(T term:terms){
494
            T parentTerm = term.getKindOf();
495
            if(parentTerm==null){
496
                // root element
497
                parents.add(new TermNode<T>(term));
498
            }
499
        }
500
        addToParents(parents, terms);
501
        return parents;
502
    }
503

    
504
    @SuppressWarnings("unchecked")
505
    /**
506
     * Recursively iterates over all term parents until no more parent is found i.e. the root node
507
     * @param term The term for which the parent should be found
508
     * @return the root terms of the term hierarchy
509
     */
510
    private static<T extends IEnumTerm<T>> T getParentFor(T term){
511
        // PP: cast should be safe. Why is Eclipse complaining??
512
        T parent = term.getKindOf();
513
        if(parent==null){
514
            return term;
515
        }
516
        else{
517
            return getParentFor(term.getKindOf());
518
        }
519
    }
520

    
521
    private static class TermNode<T extends IEnumTerm<T>> implements Comparable<TermNode<T>>{
522
        private final T term;
523
        private final TreeSet<TermNode<T>> children;
524

    
525
        public TermNode(T term) {
526
            super();
527
            this.term = term;
528
            this.children = new TreeSet<TermNode<T>>();
529
        }
530

    
531
        public void addChild(TermNode<T> child){
532
            this.children.add(child);
533
        }
534

    
535
        public TreeSet<TermNode<T>> getChildren() {
536
            return children;
537
        }
538

    
539
        public T getTerm() {
540
            return term;
541
        }
542

    
543
        @Override
544
        public int hashCode() {
545
            final int prime = 31;
546
            int result = 1;
547
            result = prime * result + ((term == null) ? 0 : term.hashCode());
548
            return result;
549
        }
550

    
551
        @Override
552
        public boolean equals(Object obj) {
553
            if (this == obj) {
554
                return true;
555
            }
556
            if (obj == null) {
557
                return false;
558
            }
559
            if (getClass() != obj.getClass()) {
560
                return false;
561
            }
562
            TermNode other = (TermNode) obj;
563
            if (term == null) {
564
                if (other.term != null) {
565
                    return false;
566
                }
567
            } else if (!term.equals(other.term)) {
568
                return false;
569
            }
570
            return true;
571
        }
572

    
573
        @Override
574
        public int compareTo(TermNode<T> that) {
575
            return this.term.getLabel().compareTo(that.term.getLabel());
576
        }
577
    }
578

    
579
    public static Object getElementsFromSelectionChangedEvent(SelectionChangedEvent event) {
580
        IStructuredSelection selection = (IStructuredSelection) event.getSelection();
581
        Object selectionToSet = selection;
582
        if(selection.size() == 1){
583
            selectionToSet = selection.getFirstElement();
584
        }
585
        else if(!selection.isEmpty()){
586
            selectionToSet = selection.toArray();
587
        }
588
        return selectionToSet;
589
    }
590

    
591
    /**
592
     * Executes a remoting monitored import
593
     *
594
     * @param label for the import
595
     * @param uuid of the remoting monitor already started on the server
596
     * @param pollInterval in milliseconds
597
     * @param cancelable flag which determines whether the operation can be cancelled
598
     * @param postOp callback for running post operation logic
599
     * @return
600
     */
601
    public static IStatus executeMoniteredOperation(final String label,
602
            final UUID uuid,
603
            final int pollInterval,
604
            final boolean cancelable,
605
            final IPostMoniteredOperationEnabled postOp,
606
            final IFeedbackGenerator feedbackGenerator,
607
            final boolean showResult) {
608

    
609
    	try{
610
    		// get the remoting monitor the first time to make sure that the
611
            // operation is valid
612
            final IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
613
            final IRemotingProgressMonitor firstRemotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
614
            if(firstRemotingMonitor == null) {
615
                throw new IllegalStateException("Remoting progress monitor is null");
616
            }
617
            if (firstRemotingMonitor.isDone()){
618
                createResult(label, showResult, firstRemotingMonitor);
619
                Set<Taxon> taxaToUpdate = getTaxaToUpdate(firstRemotingMonitor);
620
                updateNameEditors(taxaToUpdate);
621
                return Status.OK_STATUS;
622
            }
623

    
624
            Job job = new Job(label) {
625

    
626

    
627
                @Override
628
                public IStatus run(IProgressMonitor monitor) {
629
                    // run the monitor until the operation is finished
630
                    SubMonitor subMonitor = SubMonitor.convert(monitor, 100);
631

    
632

    
633
                    IRemotingProgressMonitor remotingMonitor;
634
                    try {
635
                        remotingMonitor = CdmStore.getProgressMonitorClientManager().pollMonitor(label,
636
                                uuid,
637
                                pollInterval,
638
                                postOp,
639
                                feedbackGenerator,
640
                                subMonitor);
641
                    } catch (Exception ex) {
642
                        return new Status(Status.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
643
                    }
644

    
645

    
646
                    // collect reports
647
//	                    for(String report : remotingMonitor.getResult()) {
648
                    createResult(label, showResult, remotingMonitor);
649
                    Set<Taxon> taxaToUpdate = getTaxaToUpdate(remotingMonitor);
650
                    updateNameEditors(taxaToUpdate);
651
                    if (!taxaToUpdate.isEmpty()){
652
                        refreshNavigator();
653
                    }
654
                    return Status.OK_STATUS;
655
                }
656

    
657

    
658

    
659

    
660

    
661

    
662

    
663
                private void refreshNavigator() {
664
                    EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAVIGATOR, true);
665

    
666
                }
667

    
668

    
669

    
670
                @Override
671
                protected void canceling() {
672
                    CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
673
                }
674
            };
675

    
676
            // configure the job
677
            job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
678

    
679
            job.setUser(true);
680
            // schedule job
681
            job.schedule();
682

    
683
        } catch (Exception e) {
684
            MessagingUtils.errorDialog("Error executing operation",
685
                    AbstractUtility.class,
686
                    "An error occurred while executing " + label,
687
                    TaxeditorStorePlugin.PLUGIN_ID,
688
                    e,
689
                    true);
690
        }
691

    
692
        return Status.OK_STATUS;
693
        }
694

    
695
    private static Set<Taxon> getTaxaToUpdate(IRemotingProgressMonitor remotingMonitor) {
696
        Set<Taxon> taxaToUpdate = new HashSet<>();
697
        if (remotingMonitor.getResult() instanceof UpdateResult){
698
            for (CdmBase object: ((UpdateResult)remotingMonitor.getResult()).getUpdatedObjects()){
699
                Taxon taxon = null;
700

    
701
                if (object instanceof Taxon){
702
                    taxon = HibernateProxyHelper.deproxy(object, Taxon.class);
703

    
704

    
705
                }else if (object instanceof Synonym){
706
                    Synonym syn = HibernateProxyHelper.deproxy(object, Synonym.class);
707
                    taxon = syn.getAcceptedTaxon();
708
                }else if (object instanceof TaxonNode){
709
                    taxon = ((TaxonNode)object).getTaxon() != null? ((TaxonNode)object).getTaxon():null;
710
                }
711
                if (taxon != null){
712
                    taxaToUpdate.add(taxon);
713
                }
714
            }
715
        }else if (remotingMonitor.getResult() instanceof ImportResult){
716
            Map<String, Integer> result = ((ImportResult)remotingMonitor.getResult()).getUpdatedRecords();
717
            for (Map.Entry<String, Integer> object: result.entrySet()){
718
                Taxon taxon = null;
719
                if (object instanceof Taxon){
720
                    taxon = HibernateProxyHelper.deproxy(object, Taxon.class);
721
                }else if (object instanceof Synonym){
722
                    Synonym syn = HibernateProxyHelper.deproxy(object, Synonym.class);
723
                    taxon = syn.getAcceptedTaxon();
724
                }
725
                taxaToUpdate.add(taxon);
726
           }
727

    
728
        }
729
        return taxaToUpdate;
730
    }
731
    public static void createResult(String label, boolean showResult,
732
            IRemotingProgressMonitor remotingMonitor) {
733
        final StringBuilder reportSb = new StringBuilder();
734
        if (remotingMonitor.getResult() instanceof ExportResult) {
735
            reportSb.append(((ExportResult)remotingMonitor.getResult()).createReport());
736
        }else if (remotingMonitor.getResult() instanceof UpdateResult){
737
            if (((UpdateResult)remotingMonitor.getResult()).isOk()){
738
                int count = ((UpdateResult)remotingMonitor.getResult()).getUpdatedObjects().size();
739
                if (count == 0){
740
                    count = ((UpdateResult)remotingMonitor.getResult()).getUpdatedCdmIds().size();
741
                }
742

    
743
                reportSb.append("Update successful. \n"+"Updated Objects: " +count);
744
            }
745
            if (!((UpdateResult)remotingMonitor.getResult()).getExceptions().isEmpty()){
746
                reportSb.append(((UpdateResult)remotingMonitor.getResult()).getExceptions().toString());
747
            }
748
        }else if (remotingMonitor.getReports()!= null){
749
            for (String o:remotingMonitor.getReports()){
750
                reportSb.append(o);
751
            }
752
        }
753
//          }
754
        if(showResult && !StringUtils.isBlank(reportSb.toString()) && reportSb.length() != 0) {
755
            Display.getDefault().asyncExec(new Runnable() {
756
                @Override
757
                public void run() {
758
                    // display reports with possibility to save
759
                    ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
760
                    dialog.setTitle(label + " Report");
761
                    dialog.setReportText(reportSb.toString());
762
                    dialog.open();
763
                }
764
            });
765
        }
766
    }
767

    
768
    private static void createExportResult(final String label, String urlString, boolean createZip,
769
            IRemotingProgressMonitor remotingMonitor) {
770

    
771
        final StringBuilder reportSb = new StringBuilder();
772
        if (remotingMonitor.getResult() instanceof ExportResult){
773
            ExportResult result = (ExportResult)remotingMonitor.getResult();
774

    
775
            reportSb.append(result.createReport());
776

    
777
            if(!StringUtils.isBlank(reportSb.toString())) {
778
                Display.getDefault().asyncExec(new Runnable() {
779
                    @Override
780
                    public void run() {
781
                        // display reports with possibility to save
782
                        ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
783
                        dialog.setTitle(label + " Report");
784
                        dialog.setReportText(reportSb.toString());
785
                        dialog.open();
786
                    }
787
                });
788
            }
789

    
790
            if (urlString != null){
791
                 ExportDataWrapper data = result.getExportData();
792
                 try{
793
                     if (result.getExportData().getType().equals(ExportResultType.BYTE_ARRAY)){
794
                         byte[] exportData = (byte[])data.getExportData();
795
                         if(exportData != null){
796
                             File file = new File(urlString);
797
                             FileOutputStream stream = new FileOutputStream(file);
798
                             Writer out = new BufferedWriter(new OutputStreamWriter(
799
                                    stream, "UTF8"));
800

    
801
                            stream.write(exportData);
802
                            out.flush();
803
                            stream.close();
804
                         }
805
                     } else if (result.getExportData().getType().equals(ExportResultType.MAP_BYTE_ARRAY)){
806
                         Map<String, byte[]> resultMap = (Map<String, byte[]>)data.getExportData();
807
                         Set<String> keySet = resultMap.keySet();
808
                         SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
809
                         Calendar cal = Calendar.getInstance();
810
                         String fileEnding = ".csv";
811

    
812
                         if (createZip){
813
//                             File file = new File(urlString+File.separator +  sdf.format(cal.getTime())+ ".zip");
814
                             File file = new File(urlString+ ".zip");
815
                             FileOutputStream stream = new FileOutputStream(file);
816
                             ZipOutputStream zos = new ZipOutputStream(stream);
817
                             for (String key: keySet){
818
                                byte[] fileData = resultMap.get(key);
819
                                ZipEntry entry = new ZipEntry( key + fileEnding);
820
                                zos.putNextEntry(entry);
821
                                zos.write(fileData);
822
                                zos.closeEntry();
823
                             }
824
                             zos.close();
825
                         }else{
826
                            if(result.getExportType().equals(ExportType.DWCA)){
827

    
828
                                File file = new File(urlString);
829
                                FileOutputStream stream = new FileOutputStream(file);
830
                                ZipOutputStream zos = new ZipOutputStream(stream);
831
                                for (String key: keySet){
832
                                    byte[] fileData = resultMap.get(key);
833
                                    ZipEntry entry = new ZipEntry( key);
834
                                        zos.putNextEntry(entry);
835
                                        zos.write(fileData);
836
                                        zos.closeEntry();
837
                                 }
838
                                 zos.close();
839
                              }else{
840
                                 for (String key: keySet){
841
                                     byte[] fileData = resultMap.get(key);
842
                                     File file = new File(urlString+File.separator + key + fileEnding);
843
                                     FileOutputStream stream = new FileOutputStream(file);
844
                                     Writer out = new BufferedWriter(new OutputStreamWriter(
845
                                            stream, "UTF8"));
846
                                     stream.write(fileData);
847
                                     stream.close();
848
                                 }
849
                              }
850
                         }
851
                    }else{
852
                         logger.error("This kind of result data is not supported yet." + result.getExportData().getType().toString());
853
                     }
854
                 } catch(Exception e){
855
                     logger.error(e.getStackTrace());
856
                 }
857
            }
858
        }
859
    }
860
    public static void updateNameEditors(Set<Taxon> taxaToUpdate){
861
        for (Taxon tax: taxaToUpdate){
862
            if (tax != null){
863
                EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAME_EDITOR, tax.getUuid());
864
            }
865
        }
866
    }
867

    
868

    
869
}
(2-2/41)