Merge branch 'release/5.19.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / model / AbstractUtility.java
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 package eu.etaxonomy.taxeditor.model;
10
11 import java.io.BufferedWriter;
12 import java.io.File;
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;
23 import java.util.Map;
24 import java.util.Set;
25 import java.util.TreeSet;
26 import java.util.UUID;
27 import java.util.zip.ZipEntry;
28 import java.util.zip.ZipOutputStream;
29
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;
59
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.common.monitor.IRemotingProgressMonitor;
64 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
65 import eu.etaxonomy.cdm.io.common.ExportDataWrapper;
66 import eu.etaxonomy.cdm.io.common.ExportResult;
67 import eu.etaxonomy.cdm.io.common.ExportResultType;
68 import eu.etaxonomy.cdm.io.common.ExportType;
69 import eu.etaxonomy.cdm.model.common.CdmBase;
70 import eu.etaxonomy.cdm.model.taxon.Synonym;
71 import eu.etaxonomy.cdm.model.taxon.Taxon;
72 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
73 import eu.etaxonomy.cdm.model.term.IEnumTerm;
74 import eu.etaxonomy.taxeditor.event.EventUtility;
75 import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
76 import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
77 import eu.etaxonomy.taxeditor.operation.IFeedbackGenerator;
78 import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
79 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
80 import eu.etaxonomy.taxeditor.operation.e4.RemotingCdmHandlerE4;
81 import eu.etaxonomy.taxeditor.store.CdmStore;
82 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
83 import eu.etaxonomy.taxeditor.ui.dialog.ReportTextDialog;
84 import eu.etaxonomy.taxeditor.view.e4.AbstractCdmDataViewerE4;
85 import eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4;
86 import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
87
88 /**
89 * @author n.hoffmann
90 * @created 11.05.2009
91 */
92 public abstract class AbstractUtility {
93
94 protected static final Logger logger = Logger.getLogger(AbstractUtility.class);
95
96 /** Constant <code>statusLineManager</code> */
97 protected static IStatusLineManager statusLineManager;
98 /** Constant <code>DATE_FORMAT_NOW="yyyyMMddHHmm"</code> */
99 public static final String DATE_FORMAT_NOW = "yyyyMMddHHmm";
100
101 public static Object getActivePart() {
102 MPart activePart = EventUtility.getActivePart();
103 if(activePart!=null){
104 return activePart.getObject();
105 }
106 return null;
107 }
108
109 public static Shell getShell() {
110 return EventUtility.getShell();
111 }
112
113 public static IWorkbench getWorkbench() {
114 return TaxeditorStorePlugin.getDefault().getWorkbench();
115 }
116
117 @SuppressWarnings("unchecked")
118 public static Object getService(Class api) {
119 return TaxeditorStorePlugin.getDefault().getWorkbench().getService(api);
120 }
121
122 public static Font getFont(String symbolicName) {
123 return FontResources.getFont(symbolicName);
124 }
125
126 public static Color getColor(String symbolicName) {
127 return ColorResources.getColor(symbolicName);
128 }
129
130 public static IStatus executeOperation(final AbstractPostOperation operation, UISynchronize sync) {
131 if (getOperationHistory() == null) {
132 throw new IllegalArgumentException(
133 "There is no operation history for this context");
134 }
135
136 final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
137 .getUIInfoAdapter(getShell());
138
139 Job job = Job.create(operation.getLabel(), (ICoreRunnable) monitor -> {
140 sync.syncExec(() -> {
141 String operationlabel = operation.getLabel();
142 monitor.beginTask(operationlabel, 100);
143 IStatus status = Status.CANCEL_STATUS;
144 try {
145 operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
146 status = operation.execute(monitor, uiInfoAdapter);
147 } catch (ExecutionException e) {
148
149 MessagingUtils.operationDialog(AbstractUtility.class, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
150
151 } finally {
152 monitor.done();
153 }
154
155 String statusString = status.equals(Status.OK_STATUS) ? "completed"
156 : "cancelled";
157 setStatusLine(operationlabel + " " + statusString + ".");
158 IPostOperationEnabled postOperationEnabled = operation
159 .getPostOperationEnabled();
160 if (postOperationEnabled != null) {
161 postOperationEnabled.onComplete();
162 }
163 });
164 });
165
166 try {
167 job.setUser(true);
168 job.schedule();
169 } catch (Exception e) {
170 MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occurred while executing " + operation.getLabel(), e);
171 }
172
173 return Status.OK_STATUS;
174 }
175
176 public static IStatus executeOperation(final AbstractOperation operation, final RemotingCdmHandlerE4 handler, UISynchronize sync) {
177 return executeOperation_internal(operation, handler, sync);
178 }
179
180 private static IStatus executeOperation_internal(final AbstractOperation operation, final RemotingCdmHandlerE4 handler,
181 UISynchronize sync) {
182 if (getOperationHistory() == null) {
183 throw new IllegalArgumentException(
184 "There is no operation history for this context");
185 }
186
187 final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
188 .getUIInfoAdapter(getShell());
189
190
191 Job job = Job.create(operation.getLabel(), (ICoreRunnable) monitor -> {
192 sync.syncExec(() -> {
193 String operationlabel = operation.getLabel();
194 monitor.beginTask(operationlabel, 100);
195 IStatus status = Status.CANCEL_STATUS;
196 try {
197 operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
198 status = operation.execute(monitor,
199 uiInfoAdapter);
200 handler.postOperation(status);
201 } catch (ExecutionException e) {
202 MessagingUtils.operationDialog(AbstractUtility.class, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
203 } finally {
204 monitor.done();
205 }
206
207 String statusString = status.equals(Status.OK_STATUS) ? "completed"
208 : "cancelled";
209 setStatusLine(operationlabel + " " + statusString + ".");
210 });
211 });
212
213 try {
214 job.setUser(true);
215 sync.syncExec(()->job.schedule());
216 } catch (Exception e) {
217 MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occurred while executing " + operation.getLabel(), e);
218 }
219
220 return Status.OK_STATUS;
221 }
222
223 /**
224 * Executes a remoting monitored operation
225 *
226 * @param label for the operation
227 * @param uuid of the remoting monitor already started on the server
228 * @param pollInterval in milliseconds
229 * @param cancelable flag which determines whether the operation can be cancelled
230 * @param postOp callback for running post operation logic
231 * @return
232 */
233 public static IStatus executeMoniteredExport(final String label,
234 final UUID uuid,
235 final int pollInterval,
236 final boolean cancelable,
237 final IPostMoniteredOperationEnabled postOp,
238 final IFeedbackGenerator feedbackGenerator,
239 String urlString,
240 boolean createZip) {
241
242 try {
243 // get the remoting monitor the first time to make sure that the
244 // operation is valid
245 final IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
246 final IRemotingProgressMonitor firstRemotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
247 if(firstRemotingMonitor == null) {
248 throw new IllegalStateException("Remoting progress monitor is null");
249 }
250 if (firstRemotingMonitor.isDone()){
251 createExportResult(label, urlString, createZip, firstRemotingMonitor);
252 }
253
254 Job job = new Job(label) {
255
256
257 @Override
258 public IStatus run(IProgressMonitor monitor) {
259 // run the monitor until the operation is finished
260 SubMonitor subMonitor = SubMonitor.convert(monitor, 100);
261 //subMonitor.beginTask("Start", 100);
262 IRemotingProgressMonitor remotingMonitor;
263 try {
264 remotingMonitor = CdmStore.getProgressMonitorClientManager().pollMonitor(label,
265 uuid,
266 pollInterval,
267 postOp,
268 feedbackGenerator,
269 subMonitor);
270 } catch (Exception ex) {
271 return new Status(IStatus.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
272 }
273
274 createExportResult(label, urlString, createZip, remotingMonitor);
275 return Status.OK_STATUS;
276 }
277
278
279
280 @Override
281 protected void canceling() {
282 CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
283 }
284 };
285
286 // configure the job
287 job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
288 job.setUser(true);
289 job.setName(label);
290 // schedule job
291 job.schedule();
292
293 } catch (Exception e) {
294 MessagingUtils.errorDialog("Error executing operation",
295 AbstractUtility.class,
296 "An error occurred while executing " + label,
297 TaxeditorStorePlugin.PLUGIN_ID,
298 e,
299 true);
300 }
301
302 return Status.OK_STATUS;
303 }
304
305 public static IOperationHistory getOperationHistory() {
306 return getWorkbench().getOperationSupport().getOperationHistory();
307 }
308
309 public static void setStatusLine(final String message) {
310 Display.getDefault().asyncExec(new Runnable() {
311
312 @Override
313 public void run() {
314 statusLineManager.setMessage(message);
315 }
316
317 });
318
319 }
320
321 public static IProgressMonitor getMonitor() {
322 statusLineManager.setCancelEnabled(false);
323 return statusLineManager.getProgressMonitor();
324 }
325
326 /**
327 * Starts either the given {@link IProgressMonitor} if it's not
328 * <code>null</code> or a new {@link NullProgressMonitor}.
329 *
330 * @param progressMonitor
331 * The {@link IProgressMonitor} or <code>null</code> if no
332 * progress should be reported.
333 * @param taskName
334 * The name of the main task.
335 * @param steps
336 * The number of steps this task is subdivided into.
337 * @return The {@link IProgressMonitor}.
338 */
339 public static IProgressMonitor startMainMonitor(
340 IProgressMonitor progressMonitor, String taskName, int steps) {
341 IProgressMonitor newMonitor = progressMonitor;
342 if (newMonitor == null) {
343 newMonitor = new NullProgressMonitor();
344 }
345 newMonitor.beginTask(taskName == null ? "" : taskName, steps);
346 newMonitor.subTask(" ");
347 return newMonitor;
348 }
349
350 /**
351 * Creates a {@link SubProgressMonitor} if the given
352 * {@link IProgressMonitor} is not <code>null</code> and not a
353 * {@link NullProgressMonitor}.
354 *
355 * @param progressMonitor
356 * The parent {@link IProgressMonitor} of the
357 * {@link SubProgressMonitor} to be created.
358 * @param ticks
359 * The number of steps this subtask is subdivided into. Must be a
360 * positive number and must not be
361 * {@link IProgressMonitor#UNKNOWN}.
362 * @return The {@link IProgressMonitor}.
363 */
364 public static IProgressMonitor getSubProgressMonitor(
365 IProgressMonitor progressMonitor, int ticks) {
366 if (progressMonitor == null) {
367 return new NullProgressMonitor();
368 }
369 if (progressMonitor instanceof NullProgressMonitor) {
370 return progressMonitor;
371 }
372
373 return new SubProgressMonitor(progressMonitor, ticks);
374 }
375
376 /**
377 * Checks whether the user canceled this operation. If not canceled, the
378 * given number of steps are declared as done.
379 *
380 * @param newMonitor
381 * a {@link org.eclipse.core.runtime.IProgressMonitor} object.
382 * @param steps
383 * a int.
384 */
385 public static void workedChecked(IProgressMonitor newMonitor, int steps) {
386 // In case the progress monitor was canceled throw an exception.
387 if (newMonitor.isCanceled()) {
388 throw new OperationCanceledException();
389 }
390 // Otherwise declare this step as done.
391 newMonitor.worked(steps);
392 }
393
394 public static String getPluginId() {
395 return "eu.taxeditor";
396 }
397
398 public static Object getActiveEditor() {
399 MPart activePart = EventUtility.getActivePart();
400 if(activePart!=null && activePart.getObject()!=null
401 && activePart.getObject() instanceof IE4SavablePart){
402 return activePart.getObject();
403 }
404 return null;
405 }
406
407 public static DetailsPartE4 getDetailsView(EPartService partService) {
408 MPart part = partService.findPart("eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4");
409 if(part!=null){
410 return (DetailsPartE4) part.getObject();
411 }
412 return null;
413 }
414
415 public static void refreshDetailsViewer(EPartService partService) {
416 if (getDetailsView(partService) != null) {
417 ((AbstractCdmDataViewerE4) getDetailsView(partService).getViewer()).refresh();
418 }
419 }
420
421 public static void reflowDetailsViewer(EPartService partService) {
422 if (getDetailsView(partService) != null) {
423 ((AbstractCdmDataViewerE4) getDetailsView(partService).getViewer()).reflow();
424 }
425 }
426
427
428 /**
429 * Orders a Collection of {@link IEnumTerm}s according to the term
430 * hierarchy. <br>
431 * <br>
432 * The returned map will be be ordered primarily by root elements,
433 * secondarily by the child elements and their children resp., both ascending alphabetically. <br>
434 * @param terms
435 * A {@link Collection} of {@link IEnumTerm}s for which the term
436 * hierarchy should be created
437 * @return a map which holds the terms as keys and their string
438 * representation via {@link IEnumTerm#getMessage()} as values
439 */
440 public static <T extends IEnumTerm<T>> LinkedHashMap<T, String> orderTerms(Collection<T> terms) {
441 TreeSet<TermNode<T>> parentElements = new TreeSet<TermNode<T>>();
442 parentElements.addAll(getTermHierarchy(terms));
443
444 // create list according to the type hierarchy (root elements alphabetically with recursive children also alphabetically)
445 LinkedHashMap<T, String> result = new LinkedHashMap<T, String>();
446 parseTermTree(parentElements, result, -1);
447 return result;
448 }
449
450 private static<T extends IEnumTerm<T>> void parseTermTree(Collection<TermNode<T>> children, LinkedHashMap<T, String> result, int depth){
451 depth++;
452 for(TermNode<T> node:children){
453 String indentString = "";
454 for(int i=0;i<depth;i++){
455 indentString += " ";
456 }
457 if(depth>0){
458 indentString += "- ";
459 }
460 result.put(node.term, indentString + node.term.getLabel());
461 parseTermTree(node.children, result, depth);
462 }
463 }
464
465 private static<T extends IEnumTerm<T>> void addToParents(List<TermNode<T>> parents, Collection<T> terms){
466 List<TermNode<T>> hasChildrenList = new ArrayList<TermNode<T>>();
467 for(T term:terms){
468 // only terms with parents
469 if(term.getKindOf()!=null){
470 TermNode<T> parentNode = new TermNode<T>(term.getKindOf());
471 TermNode<T> childNode = new TermNode<T>(term);
472 if(parents.contains(parentNode)){
473 // parent found in parent list -> add this term to parent's child list
474 parents.get(parents.indexOf(parentNode)).addChild(childNode);
475 if(!term.getGeneralizationOf().isEmpty()){
476 // has more children -> add to list which will be the parent for the next recursion
477 hasChildrenList.add(childNode);
478 }
479 }
480 }
481 }
482 if(!hasChildrenList.isEmpty()){
483 addToParents(hasChildrenList, terms);
484 }
485 }
486
487 private static<T extends IEnumTerm<T>> List<TermNode<T>> getTermHierarchy(Collection<T> terms){
488 List<TermNode<T>> parents = new ArrayList<TermNode<T>>();
489 // get root elements
490 for(T term:terms){
491 T parentTerm = term.getKindOf();
492 if(parentTerm==null){
493 // root element
494 parents.add(new TermNode<T>(term));
495 }
496 }
497 addToParents(parents, terms);
498 return parents;
499 }
500
501 @SuppressWarnings("unchecked")
502 /**
503 * Recursively iterates over all term parents until no more parent is found i.e. the root node
504 * @param term The term for which the parent should be found
505 * @return the root terms of the term hierarchy
506 */
507 private static<T extends IEnumTerm<T>> T getParentFor(T term){
508 // PP: cast should be safe. Why is Eclipse complaining??
509 T parent = term.getKindOf();
510 if(parent==null){
511 return term;
512 }
513 else{
514 return getParentFor(term.getKindOf());
515 }
516 }
517
518 private static class TermNode<T extends IEnumTerm<T>> implements Comparable<TermNode<T>>{
519 private final T term;
520 private final TreeSet<TermNode<T>> children;
521
522 public TermNode(T term) {
523 super();
524 this.term = term;
525 this.children = new TreeSet<TermNode<T>>();
526 }
527
528 public void addChild(TermNode<T> child){
529 this.children.add(child);
530 }
531
532 public TreeSet<TermNode<T>> getChildren() {
533 return children;
534 }
535
536 public T getTerm() {
537 return term;
538 }
539
540 @Override
541 public int hashCode() {
542 final int prime = 31;
543 int result = 1;
544 result = prime * result + ((term == null) ? 0 : term.hashCode());
545 return result;
546 }
547
548 @Override
549 public boolean equals(Object obj) {
550 if (this == obj) {
551 return true;
552 }
553 if (obj == null) {
554 return false;
555 }
556 if (getClass() != obj.getClass()) {
557 return false;
558 }
559 TermNode other = (TermNode) obj;
560 if (term == null) {
561 if (other.term != null) {
562 return false;
563 }
564 } else if (!term.equals(other.term)) {
565 return false;
566 }
567 return true;
568 }
569
570 @Override
571 public int compareTo(TermNode<T> that) {
572 return this.term.getLabel().compareTo(that.term.getLabel());
573 }
574 }
575
576 public static Object getElementsFromSelectionChangedEvent(SelectionChangedEvent event) {
577 IStructuredSelection selection = (IStructuredSelection) event.getSelection();
578 Object selectionToSet = selection;
579 if(selection.size() == 1){
580 selectionToSet = selection.getFirstElement();
581 }
582 else if(!selection.isEmpty()){
583 selectionToSet = selection.toArray();
584 }
585 return selectionToSet;
586 }
587
588 /**
589 * Executes a remoting monitored import
590 *
591 * @param label for the import
592 * @param uuid of the remoting monitor already started on the server
593 * @param pollInterval in milliseconds
594 * @param cancelable flag which determines whether the operation can be cancelled
595 * @param postOp callback for running post operation logic
596 * @return
597 */
598 public static IStatus executeMoniteredOperation(final String label,
599 final UUID uuid,
600 final int pollInterval,
601 final boolean cancelable,
602 final IPostMoniteredOperationEnabled postOp,
603 final IFeedbackGenerator feedbackGenerator,
604 final boolean showResult) {
605
606 try{
607 // get the remoting monitor the first time to make sure that the
608 // operation is valid
609 final IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
610 final IRemotingProgressMonitor firstRemotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
611 if(firstRemotingMonitor == null) {
612 throw new IllegalStateException("Remoting progress monitor is null");
613 }
614 if (firstRemotingMonitor.isDone()){
615 createResult(label, showResult, firstRemotingMonitor);
616 Set<Taxon> taxaToUpdate = getTaxaToUpdate(firstRemotingMonitor);
617 updateNameEditors(taxaToUpdate);
618 return Status.OK_STATUS;
619 }
620
621 Job job = new Job(label) {
622 @Override
623 public IStatus run(IProgressMonitor monitor) {
624 // run the monitor until the operation is finished
625 SubMonitor subMonitor = SubMonitor.convert(monitor, 100);
626
627
628 IRemotingProgressMonitor remotingMonitor;
629 try {
630 remotingMonitor = CdmStore.getProgressMonitorClientManager().pollMonitor(label,
631 uuid,
632 pollInterval,
633 postOp,
634 feedbackGenerator,
635 subMonitor);
636 } catch (Exception ex) {
637 return new Status(IStatus.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
638 }
639
640 // collect reports
641 // for(String report : remotingMonitor.getResult()) {
642 createResult(label, showResult, remotingMonitor);
643 Set<Taxon> taxaToUpdate = getTaxaToUpdate(remotingMonitor);
644 updateNameEditors(taxaToUpdate);
645 if (!taxaToUpdate.isEmpty()){
646 refreshNavigator();
647 }
648 return Status.OK_STATUS;
649 }
650
651 private void refreshNavigator() {
652 EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAVIGATOR, true);
653 }
654
655 @Override
656 protected void canceling() {
657 CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
658 }
659 };
660
661 // configure the job
662 job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
663
664 job.setUser(true);
665 // schedule job
666 job.schedule();
667
668 } catch (Exception e) {
669 MessagingUtils.errorDialog("Error executing operation",
670 AbstractUtility.class,
671 "An error occurred while executing " + label,
672 TaxeditorStorePlugin.PLUGIN_ID,
673 e,
674 true);
675 }
676
677 return Status.OK_STATUS;
678 }
679
680 private static Set<Taxon> getTaxaToUpdate(IRemotingProgressMonitor remotingMonitor) {
681 Set<Taxon> taxaToUpdate = new HashSet<>();
682 if (remotingMonitor.getResult() instanceof UpdateResult){
683 for (CdmBase object: ((UpdateResult)remotingMonitor.getResult()).getUpdatedObjects()){
684 Taxon taxon = null;
685
686 if (object instanceof Taxon){
687 taxon = HibernateProxyHelper.deproxy(object, Taxon.class);
688 }else if (object instanceof Synonym){
689 Synonym syn = HibernateProxyHelper.deproxy(object, Synonym.class);
690 taxon = syn.getAcceptedTaxon();
691 }else if (object instanceof TaxonNode){
692 taxon = ((TaxonNode)object).getTaxon() != null? ((TaxonNode)object).getTaxon():null;
693 }
694 if (taxon != null){
695 taxaToUpdate.add(taxon);
696 }
697 }
698 }
699 return taxaToUpdate;
700 }
701 public static void createResult(String label, boolean showResult,
702 IRemotingProgressMonitor remotingMonitor) {
703 final StringBuilder reportSb = new StringBuilder();
704 if (remotingMonitor.getResult() instanceof ExportResult) {
705 reportSb.append(((ExportResult)remotingMonitor.getResult()).createReport());
706 }else if (remotingMonitor.getResult() instanceof UpdateResult){
707 if (((UpdateResult)remotingMonitor.getResult()).isOk()){
708 int count = ((UpdateResult)remotingMonitor.getResult()).getUpdatedObjects().size();
709 if (count == 0){
710 count = ((UpdateResult)remotingMonitor.getResult()).getUpdatedCdmIds().size();
711 }
712
713 reportSb.append("Update successful. \n"+"Updated Objects: " +count);
714 }
715 if (!((UpdateResult)remotingMonitor.getResult()).getExceptions().isEmpty()){
716 reportSb.append(((UpdateResult)remotingMonitor.getResult()).getExceptions().toString());
717 }
718 }else if (remotingMonitor.getReports()!= null){
719 for (String o:remotingMonitor.getReports()){
720 reportSb.append(o);
721 }
722 }
723 if(showResult && !StringUtils.isBlank(reportSb.toString()) && reportSb.length() != 0) {
724 Display.getDefault().asyncExec(new Runnable() {
725 @Override
726 public void run() {
727 // display reports with possibility to save
728 ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
729 dialog.setTitle(label + " Report");
730 dialog.setReportText(reportSb.toString());
731 dialog.open();
732 }
733 });
734 }
735 }
736
737 private static void createExportResult(final String label, String urlString, boolean createZip,
738 IRemotingProgressMonitor remotingMonitor) {
739
740 final StringBuilder reportSb = new StringBuilder();
741 if (remotingMonitor.getResult() instanceof ExportResult){
742 ExportResult result = (ExportResult)remotingMonitor.getResult();
743
744 reportSb.append(result.createReport());
745
746 if(!StringUtils.isBlank(reportSb.toString())) {
747 Display.getDefault().asyncExec(new Runnable() {
748 @Override
749 public void run() {
750 // display reports with possibility to save
751 ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
752 dialog.setTitle(label + " Report");
753 dialog.setReportText(reportSb.toString());
754 dialog.open();
755 }
756 });
757 }
758
759 if (urlString != null){
760 ExportDataWrapper<?> data = result.getExportData();
761 try{
762 if (result.getExportData().getType().equals(ExportResultType.BYTE_ARRAY)){
763 byte[] exportData = (byte[])data.getExportData();
764 if(exportData != null){
765 File file = new File(urlString);
766 FileOutputStream stream = new FileOutputStream(file);
767 Writer out = new BufferedWriter(new OutputStreamWriter(
768 stream, "UTF8"));
769
770 stream.write(exportData);
771 out.flush();
772 stream.close();
773 }
774 } else if (result.getExportData().getType().equals(ExportResultType.MAP_BYTE_ARRAY)){
775 Map<String, byte[]> resultMap = (Map<String, byte[]>)data.getExportData();
776 Set<String> keySet = resultMap.keySet();
777 SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
778 Calendar cal = Calendar.getInstance();
779 String fileEnding = ".csv";
780
781 if (createZip){
782 // File file = new File(urlString+File.separator + sdf.format(cal.getTime())+ ".zip");
783 File file = new File(urlString+ ".zip");
784 FileOutputStream stream = new FileOutputStream(file);
785 ZipOutputStream zos = new ZipOutputStream(stream);
786 for (String key: keySet){
787 byte[] fileData = resultMap.get(key);
788 ZipEntry entry = new ZipEntry( key + fileEnding);
789 zos.putNextEntry(entry);
790 zos.write(fileData);
791 zos.closeEntry();
792 }
793 zos.close();
794 }else{
795 if(result.getExportType().equals(ExportType.DWCA)){
796
797 File file = new File(urlString);
798 FileOutputStream stream = new FileOutputStream(file);
799 ZipOutputStream zos = new ZipOutputStream(stream);
800 for (String key: keySet){
801 byte[] fileData = resultMap.get(key);
802 ZipEntry entry = new ZipEntry( key);
803 zos.putNextEntry(entry);
804 zos.write(fileData);
805 zos.closeEntry();
806 }
807 zos.close();
808 }else{
809 for (String key: keySet){
810 byte[] fileData = resultMap.get(key);
811 File file = new File(urlString+File.separator + key + fileEnding);
812 FileOutputStream stream = new FileOutputStream(file);
813 Writer out = new BufferedWriter(new OutputStreamWriter(
814 stream, "UTF8"));
815 stream.write(fileData);
816 stream.close();
817 }
818 }
819 }
820 }else{
821 logger.error("This kind of result data is not supported yet." + result.getExportData().getType().toString());
822 }
823 } catch(Exception e){
824 logger.error(e.getStackTrace());
825 }
826 }
827 }
828 }
829 public static void updateNameEditors(Set<Taxon> taxaToUpdate){
830 for (Taxon tax: taxaToUpdate){
831 if (tax != null){
832 EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAME_EDITOR, tax.getUuid());
833 }
834 }
835 }
836 }