2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.taxeditor
.model
;
11 import java
.io
.BufferedWriter
;
13 import java
.io
.FileOutputStream
;
14 import java
.io
.OutputStreamWriter
;
15 import java
.io
.Writer
;
16 import java
.text
.SimpleDateFormat
;
17 import java
.util
.ArrayList
;
18 import java
.util
.Calendar
;
19 import java
.util
.Collection
;
20 import java
.util
.HashSet
;
21 import java
.util
.LinkedHashMap
;
22 import java
.util
.List
;
25 import java
.util
.TreeSet
;
26 import java
.util
.UUID
;
27 import java
.util
.zip
.ZipEntry
;
28 import java
.util
.zip
.ZipOutputStream
;
30 import org
.apache
.commons
.lang3
.StringUtils
;
31 import org
.apache
.log4j
.Logger
;
32 import org
.eclipse
.core
.commands
.ExecutionException
;
33 import org
.eclipse
.core
.commands
.operations
.AbstractOperation
;
34 import org
.eclipse
.core
.commands
.operations
.IOperationHistory
;
35 import org
.eclipse
.core
.runtime
.IAdaptable
;
36 import org
.eclipse
.core
.runtime
.ICoreRunnable
;
37 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
38 import org
.eclipse
.core
.runtime
.IStatus
;
39 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
40 import org
.eclipse
.core
.runtime
.OperationCanceledException
;
41 import org
.eclipse
.core
.runtime
.Status
;
42 import org
.eclipse
.core
.runtime
.SubMonitor
;
43 import org
.eclipse
.core
.runtime
.SubProgressMonitor
;
44 import org
.eclipse
.core
.runtime
.jobs
.Job
;
45 import org
.eclipse
.e4
.ui
.di
.UISynchronize
;
46 import org
.eclipse
.e4
.ui
.model
.application
.ui
.basic
.MPart
;
47 import org
.eclipse
.e4
.ui
.workbench
.modeling
.EPartService
;
48 import org
.eclipse
.jface
.action
.IStatusLineManager
;
49 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
50 import org
.eclipse
.jface
.viewers
.SelectionChangedEvent
;
51 import org
.eclipse
.swt
.graphics
.Color
;
52 import org
.eclipse
.swt
.graphics
.Font
;
53 import org
.eclipse
.swt
.widgets
.Display
;
54 import org
.eclipse
.swt
.widgets
.Shell
;
55 import org
.eclipse
.ui
.IWorkbench
;
56 import org
.eclipse
.ui
.PlatformUI
;
57 import org
.eclipse
.ui
.ide
.undo
.WorkspaceUndoUtil
;
58 import org
.eclipse
.ui
.progress
.IProgressConstants
;
60 import eu
.etaxonomy
.cdm
.api
.application
.CdmApplicationState
;
61 import eu
.etaxonomy
.cdm
.api
.service
.IProgressMonitorService
;
62 import eu
.etaxonomy
.cdm
.api
.service
.UpdateResult
;
63 import eu
.etaxonomy
.cdm
.api
.service
.dto
.CdmEntityIdentifier
;
64 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
65 import eu
.etaxonomy
.cdm
.common
.SetMap
;
66 import eu
.etaxonomy
.cdm
.common
.monitor
.IRemotingProgressMonitor
;
67 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
68 import eu
.etaxonomy
.cdm
.io
.common
.ExportDataWrapper
;
69 import eu
.etaxonomy
.cdm
.io
.common
.ExportResult
;
70 import eu
.etaxonomy
.cdm
.io
.common
.ExportResultType
;
71 import eu
.etaxonomy
.cdm
.io
.common
.ExportType
;
72 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
73 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
74 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
75 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
76 import eu
.etaxonomy
.cdm
.model
.term
.IEnumTerm
;
77 import eu
.etaxonomy
.taxeditor
.event
.EventUtility
;
78 import eu
.etaxonomy
.taxeditor
.event
.WorkbenchEventConstants
;
79 import eu
.etaxonomy
.taxeditor
.operation
.AbstractPostOperation
;
80 import eu
.etaxonomy
.taxeditor
.operation
.IFeedbackGenerator
;
81 import eu
.etaxonomy
.taxeditor
.operation
.IPostMoniteredOperationEnabled
;
82 import eu
.etaxonomy
.taxeditor
.operation
.IPostOperationEnabled
;
83 import eu
.etaxonomy
.taxeditor
.operation
.e4
.CdmHandlerE4
;
84 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
85 import eu
.etaxonomy
.taxeditor
.store
.internal
.TaxeditorStorePlugin
;
86 import eu
.etaxonomy
.taxeditor
.ui
.dialog
.ReportTextDialog
;
87 import eu
.etaxonomy
.taxeditor
.view
.e4
.AbstractCdmDataViewerE4
;
88 import eu
.etaxonomy
.taxeditor
.view
.e4
.details
.DetailsPartE4
;
89 import eu
.etaxonomy
.taxeditor
.workbench
.part
.IE4SavablePart
;
95 public abstract class AbstractUtility
{
97 protected static final Logger logger
= Logger
.getLogger(AbstractUtility
.class);
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";
104 public static Object
getActivePart() {
105 MPart activePart
= EventUtility
.getActivePart();
106 if(activePart
!=null){
107 return activePart
.getObject();
112 public static Shell
getShell() {
113 return EventUtility
.getShell();
116 public static IWorkbench
getWorkbench() {
117 return TaxeditorStorePlugin
.getDefault().getWorkbench();
120 @SuppressWarnings("unchecked")
121 public static Object
getService(Class api
) {
122 return TaxeditorStorePlugin
.getDefault().getWorkbench().getService(api
);
125 public static Font
getFont(String symbolicName
) {
126 return FontResources
.getFont(symbolicName
);
129 public static Color
getColor(String symbolicName
) {
130 return ColorResources
.getColor(symbolicName
);
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");
139 final IAdaptable uiInfoAdapter
= WorkspaceUndoUtil
140 .getUIInfoAdapter(getShell());
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
;
148 operation
.addContext(IOperationHistory
.GLOBAL_UNDO_CONTEXT
);
149 status
= operation
.execute(monitor
, uiInfoAdapter
);
150 } catch (ExecutionException e
) {
152 MessagingUtils
.operationDialog(AbstractUtility
.class, e
, TaxeditorStorePlugin
.PLUGIN_ID
, operationlabel
, null);
158 String statusString
= status
.equals(Status
.OK_STATUS
) ?
"completed"
160 setStatusLine(operationlabel
+ " " + statusString
+ ".");
161 IPostOperationEnabled postOperationEnabled
= operation
162 .getPostOperationEnabled();
163 if (postOperationEnabled
!= null) {
164 postOperationEnabled
.onComplete();
172 } catch (Exception e
) {
173 MessagingUtils
.messageDialog("Error executing operation", AbstractUtility
.class, "An error occurred while executing " + operation
.getLabel(), e
);
176 return Status
.OK_STATUS
;
179 public static IStatus
executeOperation(final AbstractOperation operation
, final CdmHandlerE4 handler
, UISynchronize sync
) {
180 return executeOperation_internal(operation
, handler
, sync
);
183 private static IStatus
executeOperation_internal(final AbstractOperation operation
, final CdmHandlerE4 handler
,
184 UISynchronize sync
) {
185 if (getOperationHistory() == null) {
186 throw new IllegalArgumentException(
187 "There is no operation history for this context");
190 final IAdaptable uiInfoAdapter
= WorkspaceUndoUtil
191 .getUIInfoAdapter(getShell());
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
;
200 operation
.addContext(IOperationHistory
.GLOBAL_UNDO_CONTEXT
);
201 status
= operation
.execute(monitor
,
203 handler
.postOperation(status
);
204 } catch (ExecutionException e
) {
205 MessagingUtils
.operationDialog(AbstractUtility
.class, e
, TaxeditorStorePlugin
.PLUGIN_ID
, operationlabel
, null);
210 String statusString
= status
.equals(Status
.OK_STATUS
) ?
"completed"
212 setStatusLine(operationlabel
+ " " + statusString
+ ".");
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
);
223 return Status
.OK_STATUS
;
227 * Executes a remoting monitored operation
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
236 public static IStatus
executeMoniteredExport(final String label
,
238 final int pollInterval
,
239 final boolean cancelable
,
240 final IPostMoniteredOperationEnabled postOp
,
241 final IFeedbackGenerator feedbackGenerator
,
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");
253 if (firstRemotingMonitor
.isDone()){
254 createExportResult(label
, urlString
, createZip
, firstRemotingMonitor
);
257 Job job
= new Job(label
) {
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
;
267 remotingMonitor
= CdmStore
.getProgressMonitorClientManager().pollMonitor(label
,
273 } catch (Exception ex
) {
274 return new Status(IStatus
.ERROR
, TaxeditorStorePlugin
.PLUGIN_ID
, "Operation Interrupted", ex
);
277 createExportResult(label
, urlString
, createZip
, remotingMonitor
);
278 return Status
.OK_STATUS
;
284 protected void canceling() {
285 CdmStore
.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid
);
290 job
.setProperty(IProgressConstants
.KEEP_PROPERTY
, true);
296 } catch (Exception e
) {
297 MessagingUtils
.errorDialog("Error executing operation",
298 AbstractUtility
.class,
299 "An error occurred while executing " + label
,
300 TaxeditorStorePlugin
.PLUGIN_ID
,
305 return Status
.OK_STATUS
;
308 public static IOperationHistory
getOperationHistory() {
309 return getWorkbench().getOperationSupport().getOperationHistory();
312 public static void setStatusLine(final String message
) {
313 Display
.getDefault().asyncExec(new Runnable() {
317 statusLineManager
.setMessage(message
);
324 public static IProgressMonitor
getMonitor() {
325 statusLineManager
.setCancelEnabled(false);
326 return statusLineManager
.getProgressMonitor();
330 * Starts either the given {@link IProgressMonitor} if it's not
331 * <code>null</code> or a new {@link NullProgressMonitor}.
333 * @param progressMonitor
334 * The {@link IProgressMonitor} or <code>null</code> if no
335 * progress should be reported.
337 * The name of the main task.
339 * The number of steps this task is subdivided into.
340 * @return The {@link IProgressMonitor}.
342 public static IProgressMonitor
startMainMonitor(
343 IProgressMonitor progressMonitor
, String taskName
, int steps
) {
344 IProgressMonitor newMonitor
= progressMonitor
;
345 if (newMonitor
== null) {
346 newMonitor
= new NullProgressMonitor();
348 newMonitor
.beginTask(taskName
== null ?
"" : taskName
, steps
);
349 newMonitor
.subTask(" ");
354 * Creates a {@link SubProgressMonitor} if the given
355 * {@link IProgressMonitor} is not <code>null</code> and not a
356 * {@link NullProgressMonitor}.
358 * @param progressMonitor
359 * The parent {@link IProgressMonitor} of the
360 * {@link SubProgressMonitor} to be created.
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}.
367 public static IProgressMonitor
getSubProgressMonitor(
368 IProgressMonitor progressMonitor
, int ticks
) {
369 if (progressMonitor
== null) {
370 return new NullProgressMonitor();
372 if (progressMonitor
instanceof NullProgressMonitor
) {
373 return progressMonitor
;
376 return new SubProgressMonitor(progressMonitor
, ticks
);
380 * Checks whether the user canceled this operation. If not canceled, the
381 * given number of steps are declared as done.
384 * a {@link org.eclipse.core.runtime.IProgressMonitor} object.
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();
393 // Otherwise declare this step as done.
394 newMonitor
.worked(steps
);
397 public static String
getPluginId() {
398 return "eu.taxeditor";
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();
410 public static DetailsPartE4
getDetailsView(EPartService partService
) {
411 MPart part
= partService
.findPart("eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4");
413 return (DetailsPartE4
) part
.getObject();
418 public static void refreshDetailsViewer(EPartService partService
) {
419 if (getDetailsView(partService
) != null) {
420 ((AbstractCdmDataViewerE4
) getDetailsView(partService
).getViewer()).refresh();
424 public static void reflowDetailsViewer(EPartService partService
) {
425 if (getDetailsView(partService
) != null) {
426 ((AbstractCdmDataViewerE4
) getDetailsView(partService
).getViewer()).reflow();
432 * Orders a Collection of {@link IEnumTerm}s according to the term
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>
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
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
));
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);
453 private static<T
extends IEnumTerm
<T
>> void parseTermTree(Collection
<TermNode
<T
>> children
, LinkedHashMap
<T
, String
> result
, int depth
){
455 for(TermNode
<T
> node
:children
){
456 String indentString
= "";
457 for(int i
=0;i
<depth
;i
++){
461 indentString
+= "- ";
463 result
.put(node
.term
, indentString
+ node
.term
.getLabel());
464 parseTermTree(node
.children
, result
, depth
);
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
>>();
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
);
485 if(!hasChildrenList
.isEmpty()){
486 addToParents(hasChildrenList
, terms
);
490 private static<T
extends IEnumTerm
<T
>> List
<TermNode
<T
>> getTermHierarchy(Collection
<T
> terms
){
491 List
<TermNode
<T
>> parents
= new ArrayList
<TermNode
<T
>>();
494 T parentTerm
= term
.getKindOf();
495 if(parentTerm
==null){
497 parents
.add(new TermNode
<T
>(term
));
500 addToParents(parents
, terms
);
504 @SuppressWarnings("unchecked")
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
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();
517 return getParentFor(term
.getKindOf());
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
;
525 public TermNode(T term
) {
528 this.children
= new TreeSet
<TermNode
<T
>>();
531 public void addChild(TermNode
<T
> child
){
532 this.children
.add(child
);
535 public TreeSet
<TermNode
<T
>> getChildren() {
544 public int hashCode() {
545 final int prime
= 31;
547 result
= prime
* result
+ ((term
== null) ?
0 : term
.hashCode());
552 public boolean equals(Object obj
) {
559 if (getClass() != obj
.getClass()) {
562 TermNode
<?
> other
= (TermNode
<?
>) obj
;
564 if (other
.term
!= null) {
567 } else if (!term
.equals(other
.term
)) {
574 public int compareTo(TermNode
<T
> that
) {
575 return this.term
.getLabel().compareTo(that
.term
.getLabel());
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();
585 else if(!selection
.isEmpty()){
586 selectionToSet
= selection
.toArray();
588 return selectionToSet
;
592 * Executes a remoting monitored import
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
601 public static IStatus
executeMoniteredOperation(final String label
,
603 final int pollInterval
,
604 final boolean cancelable
,
605 final IPostMoniteredOperationEnabled postOp
,
606 final IFeedbackGenerator feedbackGenerator
,
607 final boolean showResult
,
608 final boolean updateNavigator
) {
611 // get the remoting monitor the first time to make sure that the
612 // operation is valid
613 final IProgressMonitorService progressMonitorService
= CdmApplicationState
.getCurrentAppConfig().getProgressMonitorService();
614 final IRemotingProgressMonitor firstRemotingMonitor
= progressMonitorService
.getRemotingMonitor(uuid
);
615 if(firstRemotingMonitor
== null) {
616 throw new IllegalStateException("Remoting progress monitor is null");
618 if (firstRemotingMonitor
.isDone()){
619 createResult(label
, showResult
, firstRemotingMonitor
);
620 Set
<Taxon
> taxaToUpdate
= getTaxaToUpdate(firstRemotingMonitor
);
621 updateNameEditors(taxaToUpdate
);
622 return Status
.OK_STATUS
;
625 Job job
= new Job(label
) {
627 public IStatus
run(IProgressMonitor monitor
) {
628 // run the monitor until the operation is finished
629 SubMonitor subMonitor
= SubMonitor
.convert(monitor
, 100);
632 IRemotingProgressMonitor remotingMonitor
;
634 remotingMonitor
= CdmStore
.getProgressMonitorClientManager().pollMonitor(label
,
640 } catch (Exception ex
) {
641 return new Status(IStatus
.ERROR
, TaxeditorStorePlugin
.PLUGIN_ID
, "Operation Interrupted", ex
);
645 // for(String report : remotingMonitor.getResult()) {
646 createResult(label
, showResult
, remotingMonitor
);
647 Set
<Taxon
> taxaToUpdate
= getTaxaToUpdate(remotingMonitor
);
648 updateNameEditors(taxaToUpdate
);
649 if (!taxaToUpdate
.isEmpty() && updateNavigator
){
652 subMonitor
.subTask("");
653 return Status
.OK_STATUS
;
656 private void refreshNavigator() {
657 EventUtility
.postEvent(WorkbenchEventConstants
.REFRESH_NAVIGATOR
, true);
661 protected void canceling() {
662 CdmStore
.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid
);
667 job
.setProperty(IProgressConstants
.KEEP_PROPERTY
, true);
673 } catch (Exception e
) {
674 MessagingUtils
.errorDialog("Error executing operation",
675 AbstractUtility
.class,
676 "An error occurred while executing " + label
,
677 TaxeditorStorePlugin
.PLUGIN_ID
,
682 return Status
.OK_STATUS
;
685 private static Set
<Taxon
> getTaxaToUpdate(IRemotingProgressMonitor remotingMonitor
) {
686 Set
<Taxon
> taxaToUpdate
= new HashSet
<>();
687 if (remotingMonitor
!= null && remotingMonitor
.getResult() instanceof UpdateResult
){
688 for (CdmBase object
: ((UpdateResult
)remotingMonitor
.getResult()).getUpdatedObjects()){
691 if (object
instanceof Taxon
){
692 taxon
= HibernateProxyHelper
.deproxy(object
, Taxon
.class);
693 }else if (object
instanceof Synonym
){
694 Synonym syn
= HibernateProxyHelper
.deproxy(object
, Synonym
.class);
695 taxon
= syn
.getAcceptedTaxon();
696 }else if (object
instanceof TaxonNode
){
697 taxon
= ((TaxonNode
)object
).getTaxon() != null?
((TaxonNode
)object
).getTaxon():null;
700 taxaToUpdate
.add(taxon
);
707 public static void createResult(String label
, boolean showResult
,
708 IRemotingProgressMonitor remotingMonitor
) {
709 final StringBuilder reportSb
= new StringBuilder();
710 if (remotingMonitor
== null){
711 reportSb
.append("Something went wrong. No result returned from server.");
712 }else if (remotingMonitor
.getResult() instanceof ExportResult
) {
713 reportSb
.append(((ExportResult
)remotingMonitor
.getResult()).createReport());
714 }else if (remotingMonitor
.getResult() instanceof UpdateResult
){
715 UpdateResult result
= (UpdateResult
)remotingMonitor
.getResult();
716 createUpdateResultReport(reportSb
, result
);
717 }else if (remotingMonitor
.getReports()!= null){
718 for (String o
:remotingMonitor
.getReports()){
722 String report
= reportSb
.toString();
723 if(showResult
&& !StringUtils
.isBlank(report
)) {
724 Display
.getDefault().asyncExec(new Runnable() {
727 // display reports with possibility to save
728 ReportTextDialog dialog
= new ReportTextDialog(PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell());
729 dialog
.setTitle(label
+ " Report");
730 dialog
.setReportText(report
);
737 public static void createUpdateResultReport(final StringBuilder reportSb
, UpdateResult result
) {
738 if (result
.isOk() || result
.isAbort()){
739 SetMap
<Class
<?
extends CdmBase
>, Integer
> map
= getUpdateResultStatistics(result
);
740 reportSb
.append("Update successful. \n"
741 + "Updated Objects: " + map
.sizeAll() + "\n================\n");
742 for (Class
<?
extends CdmBase
> clazz
: map
.keySet()){
743 reportSb
.append( CdmUtils
.userFriendlyClassName(clazz
)+": " + map
.get(clazz
).size() + "\n");
746 if (!result
.getExceptions().isEmpty()){
747 reportSb
.append(result
.getExceptions().toString());
751 //TODO move to cdmlib
752 public static SetMap
<Class
<?
extends CdmBase
>, Integer
> getUpdateResultStatistics(UpdateResult result
) {
753 SetMap
<Class
<?
extends CdmBase
>, Integer
> map
= new SetMap
<>();
754 for (CdmBase cdmBase
: result
.getUpdatedObjects()){
755 map
.putItem(cdmBase
.getClass(), cdmBase
.getId());
757 for (CdmEntityIdentifier entity
: result
.getUpdatedCdmIds()){
758 map
.putItem(entity
.getCdmClass(), entity
.getId());
764 private static void createExportResult(final String label
, String urlString
, boolean createZip
,
765 IRemotingProgressMonitor remotingMonitor
) {
767 final StringBuilder reportSb
= new StringBuilder();
768 if (remotingMonitor
.getResult() instanceof ExportResult
){
769 ExportResult result
= (ExportResult
)remotingMonitor
.getResult();
771 reportSb
.append(result
.createReport());
773 if(!StringUtils
.isBlank(reportSb
.toString())) {
774 Display
.getDefault().asyncExec(new Runnable() {
777 // display reports with possibility to save
778 ReportTextDialog dialog
= new ReportTextDialog(PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell());
779 dialog
.setTitle(label
+ " Report");
780 dialog
.setReportText(reportSb
.toString());
786 if (urlString
!= null){
787 ExportDataWrapper
<?
> data
= result
.getExportData();
789 if (result
.getExportData().getType().equals(ExportResultType
.BYTE_ARRAY
)){
790 byte[] exportData
= (byte[])data
.getExportData();
791 if(exportData
!= null){
792 File file
= new File(urlString
);
793 FileOutputStream stream
= new FileOutputStream(file
);
794 Writer out
= new BufferedWriter(new OutputStreamWriter(
797 stream
.write(exportData
);
801 } else if (result
.getExportData().getType().equals(ExportResultType
.MAP_BYTE_ARRAY
)){
802 Map
<String
, byte[]> resultMap
= (Map
<String
, byte[]>)data
.getExportData();
803 Set
<String
> keySet
= resultMap
.keySet();
804 SimpleDateFormat sdf
= new SimpleDateFormat(DATE_FORMAT_NOW
);
805 Calendar cal
= Calendar
.getInstance();
806 String fileEnding
= ".csv";
809 // File file = new File(urlString+File.separator + sdf.format(cal.getTime())+ ".zip");
810 File file
= new File(urlString
+ ".zip");
811 FileOutputStream stream
= new FileOutputStream(file
);
812 ZipOutputStream zos
= new ZipOutputStream(stream
);
813 for (String key
: keySet
){
814 byte[] fileData
= resultMap
.get(key
);
815 ZipEntry entry
= new ZipEntry( key
+ fileEnding
);
816 zos
.putNextEntry(entry
);
822 if(result
.getExportType().equals(ExportType
.DWCA
)){
824 File file
= new File(urlString
);
825 FileOutputStream stream
= new FileOutputStream(file
);
826 ZipOutputStream zos
= new ZipOutputStream(stream
);
827 for (String key
: keySet
){
828 byte[] fileData
= resultMap
.get(key
);
829 ZipEntry entry
= new ZipEntry( key
);
830 zos
.putNextEntry(entry
);
836 for (String key
: keySet
){
837 byte[] fileData
= resultMap
.get(key
);
838 File file
= new File(urlString
+File
.separator
+ key
+ fileEnding
);
839 FileOutputStream stream
= new FileOutputStream(file
);
840 Writer out
= new BufferedWriter(new OutputStreamWriter(
842 stream
.write(fileData
);
848 logger
.error("This kind of result data is not supported yet." + result
.getExportData().getType().toString());
850 } catch(Exception e
){
851 logger
.error(e
.getStackTrace());
857 public static void updateNameEditors(Set
<Taxon
> taxaToUpdate
){
858 for (Taxon tax
: taxaToUpdate
){
860 EventUtility
.postEvent(WorkbenchEventConstants
.REFRESH_NAME_EDITOR
, tax
.getUuid());