Merge branch 'release/5.29.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / descriptiveDataSet / matrix / handler / AggregationHandler.java
1 /**
2 * Copyright (C) 2020 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.editor.descriptiveDataSet.matrix.handler;
10
11 import java.util.HashSet;
12 import java.util.List;
13 import java.util.Set;
14 import java.util.UUID;
15 import java.util.stream.Collectors;
16
17 import javax.inject.Named;
18
19 import org.eclipse.core.runtime.ICoreRunnable;
20 import org.eclipse.core.runtime.SubMonitor;
21 import org.eclipse.core.runtime.jobs.Job;
22 import org.eclipse.e4.core.di.annotations.CanExecute;
23 import org.eclipse.e4.core.di.annotations.Execute;
24 import org.eclipse.e4.ui.di.UISynchronize;
25 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
26 import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
27 import org.eclipse.e4.ui.services.IServiceConstants;
28 import org.eclipse.jface.viewers.IStructuredSelection;
29 import org.eclipse.jface.window.Window;
30 import org.eclipse.jface.wizard.WizardDialog;
31 import org.eclipse.nebula.widgets.nattable.data.IRowDataProvider;
32 import org.eclipse.swt.widgets.Display;
33
34 import eu.etaxonomy.cdm.api.application.CdmApplicationState;
35 import eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService;
36 import eu.etaxonomy.cdm.api.service.UpdateResult;
37 import eu.etaxonomy.cdm.api.service.description.AggregationMode;
38 import eu.etaxonomy.cdm.api.service.description.StructuredDescriptionAggregationConfiguration;
39 import eu.etaxonomy.cdm.api.service.dto.DescriptionBaseDto;
40 import eu.etaxonomy.cdm.api.service.dto.TaxonRowWrapperDTO;
41 import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
42 import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
43 import eu.etaxonomy.cdm.filter.TaxonNodeFilter;
44 import eu.etaxonomy.cdm.model.common.CdmBase;
45 import eu.etaxonomy.cdm.model.description.DescriptionBase;
46 import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
47 import eu.etaxonomy.cdm.model.description.TaxonDescription;
48 import eu.etaxonomy.cdm.persistence.dto.DescriptiveDataSetBaseDto;
49 import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
50 import eu.etaxonomy.cdm.persistence.dto.TermDto;
51 import eu.etaxonomy.taxeditor.editor.descriptiveDataSet.matrix.CharacterMatrix;
52 import eu.etaxonomy.taxeditor.editor.descriptiveDataSet.matrix.CharacterMatrixPart;
53 import eu.etaxonomy.taxeditor.editor.internal.TaxeditorEditorPlugin;
54 import eu.etaxonomy.taxeditor.event.EventUtility;
55 import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
56 import eu.etaxonomy.taxeditor.model.AbstractUtility;
57 import eu.etaxonomy.taxeditor.model.MessagingUtils;
58 import eu.etaxonomy.taxeditor.operation.IFeedbackGenerator;
59 import eu.etaxonomy.taxeditor.store.CdmStore;
60 import eu.etaxonomy.taxeditor.store.StoreUtil;
61 import eu.etaxonomy.taxeditor.ui.dialog.configurator.StructuredAggregationConfigurationWizard;
62
63 /**
64 * @author k.luther
65 * @since Jun 4, 2020
66 */
67 public class AggregationHandler {
68 UpdateResult result = null;
69 @Execute
70 public void execute(@Named(IServiceConstants.ACTIVE_PART)MPart activePart, UISynchronize sync) {
71
72 // dependent on the selection the specimens are filtered
73 CharacterMatrixPart matrixPart = (CharacterMatrixPart) activePart.getObject();
74
75 CharacterMatrix matrix = matrixPart.getMatrix();
76 if(StoreUtil.promptCheckIsDirty(matrixPart)){
77 return;
78 }
79
80
81 //ranks
82 UUID minRankUuid = matrix.getDescriptiveDataSet().getMinRank() != null? matrix.getDescriptiveDataSet().getMinRank().getUuid(): null;
83 UUID maxRankUuid = matrix.getDescriptiveDataSet().getMaxRank() != null? matrix.getDescriptiveDataSet().getMaxRank().getUuid(): null;
84 TaxonNodeFilter filter = TaxonNodeFilter.NewRankInstance(minRankUuid, maxRankUuid);
85
86 //geofilter
87 if (matrix.getDescriptiveDataSet().getGeoFilter() != null){
88 for (TermDto namedArea : matrix.getDescriptiveDataSet().getGeoFilter()) {
89 filter = filter.orArea(namedArea.getUuid());
90 }
91 }
92
93 //taxon nodes
94 IStructuredSelection sel = matrix.getSelection();
95 @SuppressWarnings("unchecked")
96 List<TaxonNodeDto> nodeDtos = (List<TaxonNodeDto>)sel.toList().stream()
97 .filter(o->o instanceof TaxonNodeDto)
98 .collect(Collectors.toList());
99 if (!nodeDtos.isEmpty()){
100 for (TaxonNodeDto dto: nodeDtos){
101 filter = filter.orSubtree(dto.getUuid());
102 }
103 }else{
104 if (matrix.getDescriptiveDataSet() != null && matrix.getDescriptiveDataSet().getSubTreeFilter() != null){
105 for (TaxonNodeDto taxonNode : matrix.getDescriptiveDataSet().getSubTreeFilter()) {
106 filter = filter.orSubtree(taxonNode.getUuid());
107 }
108 }
109 }
110 filter.setIncludeUnpublished(true);
111
112 StructuredDescriptionAggregationConfiguration config =
113 StructuredDescriptionAggregationConfiguration.NewInstance(filter, (IProgressMonitor)null);
114
115 config.setDatasetUuid(matrix.getDescriptiveDataSet().getUuid());
116 config.setAggregationMode(AggregationMode.byWithinTaxonAndToParent());
117 config.setIncludeLiterature(true);
118 config.setIncludeDefault(true);
119 config.setAdaptBatchSize(false);
120
121 StructuredAggregationConfigurationWizard aggregationWizard = new StructuredAggregationConfigurationWizard(config, matrix.getDescriptiveDataSet(), nodeDtos);
122 WizardDialog dialog = new WizardDialog(AbstractUtility.getShell(),
123 aggregationWizard);
124
125 int open = dialog.open();
126 if (open != Window.OK){
127 return;
128 }
129
130 //job
131 String jobLabel = "Aggregate Descriptive Dataset";
132 UUID monitorUuid = CdmApplicationState.getLongRunningTasksService().invoke(config);
133 Job job = Job.create(jobLabel, (ICoreRunnable) monitor -> {
134 SubMonitor subMonitor = SubMonitor.convert(monitor);
135 subMonitor.beginTask(jobLabel, IProgressMonitor.UNKNOWN);
136 IRemotingProgressMonitor remotingMonitor;
137 try {
138 remotingMonitor = CdmStore.getProgressMonitorClientManager()
139 .pollMonitor(jobLabel,
140 monitorUuid,
141 50,
142 null,
143 (List<IFeedbackGenerator>)null,
144 subMonitor);
145 Object resultObject = remotingMonitor.getResult();
146 if(resultObject instanceof Exception){
147 MessagingUtils.errorDialog("Aggregation failed", this, "Aggregation was not successfull", TaxeditorEditorPlugin.PLUGIN_ID, (Exception)resultObject, true, true);
148 }
149 else if(resultObject instanceof UpdateResult){
150 result = ((UpdateResult) resultObject);
151 if (result.isError()){
152 Exception e = result.getExceptions().isEmpty()? null : result.getExceptions().iterator().next();
153 MessagingUtils.errorDialog("Aggregation failed", this, "Aggregation was not successfull", TaxeditorEditorPlugin.PLUGIN_ID, e, true, true);
154 }
155 Set<UUID> updatedObjects = result.getInsertedOrUpdatedUuids(TaxonDescription.class);
156 Set<TaxonRowWrapperDTO> dtos = new HashSet<>();
157 DescriptiveDataSet dataSet = (DescriptiveDataSet) result.getCdmEntity();
158 for (UUID updatedObj: updatedObjects){
159 TaxonRowWrapperDTO rowWrapper = CdmStore.getService(IDescriptiveDataSetService.class).createTaxonRowWrapper(updatedObj, matrix.getDescriptiveDataSet().getUuid());
160 boolean isRemoved = matrixPart.getMatrix().getDescriptions().remove(rowWrapper);
161 matrixPart.getMatrix().getDescriptions().add(rowWrapper);
162
163 }
164
165
166 }
167 } catch (InterruptedException e) {
168 return;
169 }
170
171 monitor.done();
172 });
173
174 job.schedule();
175
176 }
177
178 @CanExecute
179 public boolean canExecute(@Named(IServiceConstants.ACTIVE_PART)MPart activePart,
180 MHandledMenuItem menuItem){
181 CharacterMatrixPart matrixPart = (CharacterMatrixPart) activePart.getObject();
182 IStructuredSelection selection = matrixPart.getSelection();
183 boolean canExecute = (selection.isEmpty() ||
184 !(selection.getFirstElement() instanceof TaxonRowWrapperDTO) );
185
186 return canExecute;
187 }
188 }