Project

General

Profile

Download (33.9 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.term.IEnumTerm;
75
import eu.etaxonomy.taxeditor.event.EventUtility;
76
import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
77
import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
78
import eu.etaxonomy.taxeditor.operation.IFeedbackGenerator;
79
import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
80
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
81
import eu.etaxonomy.taxeditor.operation.e4.RemotingCdmHandlerE4;
82
import eu.etaxonomy.taxeditor.store.CdmStore;
83
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
84
import eu.etaxonomy.taxeditor.ui.dialog.ReportTextDialog;
85
import eu.etaxonomy.taxeditor.view.e4.AbstractCdmDataViewerE4;
86
import eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4;
87
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
88

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
175
        return Status.OK_STATUS;
176
    }
177

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

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

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

    
192

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

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

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

    
222
        return Status.OK_STATUS;
223
    }
224

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

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

    
256
            Job job = new Job(label) {
257

    
258

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

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

    
280

    
281

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

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

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

    
304
        return Status.OK_STATUS;
305
    }
306

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

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

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

    
319
        });
320

    
321
    }
322

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

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

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

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

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

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

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

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

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

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

    
429

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
621
            Job job = new Job(label) {
622

    
623

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

    
629

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

    
642

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

    
654

    
655

    
656
                private Set<Taxon> getTaxaToUpdate(IRemotingProgressMonitor remotingMonitor) {
657
                    Set<Taxon> taxaToUpdate = new HashSet<>();
658
                    if (remotingMonitor.getResult() instanceof UpdateResult){
659
                        for (CdmBase object: ((UpdateResult)remotingMonitor.getResult()).getUpdatedObjects()){
660
                            Taxon taxon = null;
661

    
662
                            if (object instanceof Taxon){
663
                                taxon = HibernateProxyHelper.deproxy(object, Taxon.class);
664

    
665

    
666
                            }else if (object instanceof Synonym){
667
                                Synonym syn = HibernateProxyHelper.deproxy(object, Synonym.class);
668
                                taxon = syn.getAcceptedTaxon();
669
                            }
670

    
671
                            taxaToUpdate.add(taxon);
672
                        }
673
                    }else if (remotingMonitor.getResult() instanceof ImportResult){
674
                        Map<String, Integer> result = ((ImportResult)remotingMonitor.getResult()).getUpdatedRecords();
675
                        for (Map.Entry<String, Integer> object: result.entrySet()){
676
                            Taxon taxon = null;
677
                            if (object instanceof Taxon){
678
                                taxon = HibernateProxyHelper.deproxy(object, Taxon.class);
679
                            }else if (object instanceof Synonym){
680
                                Synonym syn = HibernateProxyHelper.deproxy(object, Synonym.class);
681
                                taxon = syn.getAcceptedTaxon();
682
                            }
683
                            taxaToUpdate.add(taxon);
684
                       }
685

    
686
                    }
687
                    return taxaToUpdate;
688
                }
689

    
690

    
691

    
692
                private void refreshNavigator() {
693
                    EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAVIGATOR, true);
694

    
695
                }
696

    
697

    
698

    
699
                @Override
700
                protected void canceling() {
701
                    CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
702
                }
703
            };
704

    
705
            // configure the job
706
            job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
707

    
708
            job.setUser(true);
709
            // schedule job
710
            job.schedule();
711

    
712
        } catch (Exception e) {
713
            MessagingUtils.errorDialog("Error executing operation",
714
                    AbstractUtility.class,
715
                    "An error occurred while executing " + label,
716
                    TaxeditorStorePlugin.PLUGIN_ID,
717
                    e,
718
                    true);
719
        }
720

    
721
        return Status.OK_STATUS;
722
        }
723

    
724

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

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

    
762
    private static void createExportResult(final String label, String urlString, boolean createZip,
763
            IRemotingProgressMonitor remotingMonitor) {
764

    
765
        final StringBuilder reportSb = new StringBuilder();
766
        if (remotingMonitor.getResult() instanceof ExportResult){
767
            ExportResult result = (ExportResult)remotingMonitor.getResult();
768

    
769
            reportSb.append(result.createReport());
770

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

    
784
            if (urlString != null){
785
                 ExportDataWrapper data = result.getExportData();
786
                 try{
787
                     if (result.getExportData().getType().equals(ExportResultType.BYTE_ARRAY)){
788
                         byte[] exportData = (byte[])data.getExportData();
789
                         if(exportData != null){
790
                             File file = new File(urlString);
791
                             FileOutputStream stream = new FileOutputStream(file);
792
                             Writer out = new BufferedWriter(new OutputStreamWriter(
793
                                    stream, "UTF8"));
794

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

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

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

    
861

    
862
}
(2-2/41)