Project

General

Profile

Download (15.8 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2018 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;
10

    
11
import java.util.ArrayList;
12
import java.util.Collection;
13
import java.util.List;
14
import java.util.Set;
15
import java.util.UUID;
16
import java.util.stream.Collectors;
17

    
18
import org.eclipse.core.runtime.ICoreRunnable;
19
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.SubMonitor;
21
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
22
import org.eclipse.core.runtime.jobs.Job;
23
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
24
import org.eclipse.jface.layout.GridDataFactory;
25
import org.eclipse.jface.viewers.IStructuredSelection;
26
import org.eclipse.jface.window.Window;
27
import org.eclipse.jface.wizard.WizardDialog;
28
import org.eclipse.swt.SWT;
29
import org.eclipse.swt.events.SelectionAdapter;
30
import org.eclipse.swt.events.SelectionEvent;
31
import org.eclipse.swt.layout.RowLayout;
32
import org.eclipse.swt.widgets.Button;
33
import org.eclipse.swt.widgets.Composite;
34

    
35
import eu.etaxonomy.cdm.api.application.CdmApplicationState;
36
import eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService;
37
import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
38
import eu.etaxonomy.cdm.api.service.UpdateResult;
39
import eu.etaxonomy.cdm.api.service.description.AggregationMode;
40
import eu.etaxonomy.cdm.api.service.description.StructuredDescriptionAggregationConfiguration;
41
import eu.etaxonomy.cdm.api.service.dto.RowWrapperDTO;
42
import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
43
import eu.etaxonomy.cdm.filter.TaxonNodeFilter;
44
import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
45
import eu.etaxonomy.cdm.model.location.NamedArea;
46
import eu.etaxonomy.cdm.model.taxon.Taxon;
47
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
48
import eu.etaxonomy.cdm.persistence.dto.SpecimenNodeWrapper;
49
import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
50
import eu.etaxonomy.taxeditor.editor.internal.TaxeditorEditorPlugin;
51
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
52
import eu.etaxonomy.taxeditor.model.ImageResources;
53
import eu.etaxonomy.taxeditor.model.MessagingUtils;
54
import eu.etaxonomy.taxeditor.store.CdmStore;
55
import eu.etaxonomy.taxeditor.store.StoreUtil;
56
import eu.etaxonomy.taxeditor.ui.dialog.configurator.StructuredAggregationConfigurationWizard;
57
import eu.etaxonomy.taxeditor.ui.dialog.selection.TaxonSelectionDialog;
58

    
59
/**
60
 * @author pplitzner
61
 * @since Jul 9, 2018
62
 */
63
public class CharacterMatrixBottomToolbar extends Composite{
64

    
65
    private CharacterMatrix matrix;
66

    
67
    public CharacterMatrixBottomToolbar(CharacterMatrix matrix, int style) {
68
        super(matrix, style);
69
        this.matrix = matrix;
70

    
71
        init();
72
    }
73

    
74
    private void init() {
75

    
76
        setLayout(new RowLayout());
77
        GridDataFactory.fillDefaults().grab(true, false).applyTo(this);
78

    
79
        /**
80
         * Add description button
81
         */
82
        Button btnAddDescription = new Button(this, SWT.PUSH);
83
        btnAddDescription.setImage(ImageResources.getImage(ImageResources.ADD_ICON_GREEN));
84
        btnAddDescription.addSelectionListener(new SelectionAdapter() {
85
            @Override
86
            public void widgetSelected(SelectionEvent e) {
87
                if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
88
                    return;
89
                }
90
                SpecimenSelectionDialog dialog = new SpecimenSelectionDialog(matrix.getShell(), matrix);
91
                if(dialog.open()==Window.OK){
92
                    Collection<SpecimenNodeWrapper> wrappers = dialog.getSpecimen();
93
                    if(wrappers.stream().anyMatch(wrapper->wrapper.getTaxonDescriptionUuid()==null)
94
                            && !MessagingUtils.confirmDialog(
95
                                    "Create Taxon Association",
96
                                    "Some specimens are not linked with taxon via IndividualsAssociation yet.\n"
97
                                    + "Do you want to create this association?")){
98
                        return;
99
                    }
100
                    addRowsToMatrix(wrappers, matrix.getDescriptiveDataSet().getUuid());
101
                    wrappers.forEach(wrapper->matrix.getSpecimenCache().remove(wrapper));
102
                }
103
            }
104
        });
105
        /**
106
         * Remove description button
107
         */
108
        Button btnRemoveDescription = new Button(this, SWT.PUSH);
109
        btnRemoveDescription.setImage(ImageResources.getImage(ImageResources.ACTIVE_DELETE_ICON));
110
        btnRemoveDescription.addSelectionListener(new SelectionAdapter() {
111
            @Override
112
            public void widgetSelected(SelectionEvent e) {
113
                if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
114
                    return;
115
                }
116
                if(!MessagingUtils.confirmDialog(Messages.CharacterMatrixBottomToolbar_CONFIRM_DELETE_TITLE, Messages.CharacterMatrixBottomToolbar_CONFIRM_DELETE_MESSAGE)){
117
                    return;
118
                }
119
                int[] fullySelectedRowPositions = matrix.getBodyLayer().getSelectionLayer().getFullySelectedRowPositions();
120
                List<RowWrapperDTO> toRemove = new ArrayList<>();
121
                for (int i : fullySelectedRowPositions) {
122
                    Object rowObject = matrix.getBodyDataProvider().getRowObject(i);
123
                    if(rowObject instanceof RowWrapperDTO){
124
                        toRemove.add((RowWrapperDTO) rowObject);
125
                    }
126
                }
127
                toRemove.forEach(rowToRemove -> {
128
                    matrix.getDescriptions().remove(rowToRemove);
129
                    CdmStore.getService(IDescriptiveDataSetService.class).removeDescription(
130
                            rowToRemove.getDescription().getUuid(), matrix.getDescriptiveDataSet().getUuid());
131
                });
132
            }
133
        });
134
        /**
135
         * Aggregate button
136
         */
137
        Button btnAggregate = new Button(this, SWT.PUSH);
138
        btnAggregate.setText(Messages.CharacterMatrixBottomToolbar_AGGREGATE);
139
        btnAggregate.addSelectionListener(new SelectionAdapter() {
140
            @Override
141
            public void widgetSelected(SelectionEvent e) {
142
                if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
143
                    return;
144
                }
145
                aggregatDescriptiveDataSet(matrix.getDescriptiveDataSet().getUuid());
146
            }
147
        });
148
        /**
149
         * Key generation button
150
         */
151
        Button btnGenerateKey = new Button(this, SWT.PUSH);
152
        btnGenerateKey.setText("Generate Polytomous Key");
153
        btnGenerateKey.addSelectionListener(new SelectionAdapter() {
154
            @Override
155
            public void widgetSelected(SelectionEvent e) {
156
                if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
157
                    return;
158
                }
159
                Set<TaxonNodeDto> nodeDtos = matrix.getDescriptiveDataSet().getTaxonSubtreeFilter().stream()
160
                        .map(node->new TaxonNodeDto(node))
161
                        .collect(Collectors.toSet());
162
                TaxonNodeDto parentDto = CdmStore.getService(ITaxonNodeService.class).findCommonParentDto(nodeDtos);
163
                UUID taxonUuid = parentDto.getTaxonUuid();
164
                int response = MessagingUtils.confirmDialog(
165
                        "Choose taxonomic scope",
166
                        String.format("The common parent taxon of this data set is :\n%s\n\n"
167
                                + "Do you want to use this as the taxonomic scope for the polytomous key?"
168
                                , parentDto.getTaxonTitleCache()), "Yes", "Choose different taxon", "Cancel");
169
                if(response==2){
170
                    return;
171
                }
172
                else if(response==1){
173
                    Taxon taxon = TaxonSelectionDialog.selectTaxon(getShell(), null);
174
                    if(taxon==null){
175
                        return;
176
                    }
177
                    taxonUuid = taxon.getUuid();
178
                }
179
                generateKey(matrix.getDescriptiveDataSet().getUuid(), taxonUuid);
180
            }
181

    
182
        });
183
    }
184

    
185
    private void aggregatDescriptiveDataSet(UUID descriptiveDataSetUuid){
186
        // FIXME: set taxon node filter for config (this is still not used in the aggregation)
187
        StructuredDescriptionAggregationConfiguration config = StructuredDescriptionAggregationConfiguration.NewInstance(
188
                null, null);
189
        IStructuredSelection sel = matrix.getSelection();
190
        Object o = sel.getFirstElement();
191
        TaxonNodeFilter filter = TaxonNodeFilter.NewRankInstance(matrix.getDescriptiveDataSet().getMinRank(),
192
                matrix.getDescriptiveDataSet().getMaxRank());
193
        for (NamedArea namedArea : matrix.getDescriptiveDataSet().getGeoFilter()) {
194
            filter = filter.orArea(namedArea.getUuid());
195
        }
196
//        for (TaxonNode taxonNode : matrix.getDescriptiveDataSet().getTaxonSubtreeFilter()) {
197
//            filter = filter.orSubtree(taxonNode);
198
//        }
199

    
200
        if (o instanceof TaxonNodeDto){
201
            filter = filter.orSubtree(CdmStore.getService(ITaxonNodeService.class).load(((TaxonNodeDto)o).getUuid()));
202
        }else{
203
            for (TaxonNode taxonNode : matrix.getDescriptiveDataSet().getTaxonSubtreeFilter()) {
204
                filter = filter.orSubtree(taxonNode);
205
            }
206
        }
207
        config.setTaxonNodeFilter(filter);
208

    
209
        config.setDatasetUuid(matrix.getDescriptiveDataSet().getUuid());
210
        config.setAggregateToHigherRanks(true);
211
        config.setAggregationMode(AggregationMode.byAreasAndRanks());
212
        config.setAdaptBatchSize(false);
213
        StructuredAggregationConfigurationWizard aggregationWizard = new StructuredAggregationConfigurationWizard(config, this.matrix.getDescriptiveDataSet());
214
        WizardDialog dialog = new WizardDialog(StoreUtil.getShell(),
215
                aggregationWizard);
216

    
217
        int open = dialog.open();
218
        if (open != Window.OK){
219
            return;
220
        }
221
        UUID monitorUuid =  CdmApplicationState.getLongRunningTasksService().invoke(config);
222

    
223
        String jobLabel = "Aggregate Descriptive Data Set";
224
        Job job = Job.create(jobLabel, (ICoreRunnable) monitor -> {
225
            SubMonitor subMonitor = SubMonitor.convert(monitor);
226
            subMonitor.beginTask(jobLabel, IProgressMonitor.UNKNOWN);
227
            IRemotingProgressMonitor remotingMonitor;
228
            try {
229
                remotingMonitor = CdmStore.getProgressMonitorClientManager()
230
                        .pollMonitor(jobLabel,
231
                                monitorUuid,
232
                                50,
233
                                null,
234
                                (List)null,
235
                                subMonitor);
236
                Object resultObject = remotingMonitor.getResult();
237
                if(resultObject instanceof Exception){
238
                    MessagingUtils.errorDialog("Aggregation failed", this, "Aggregation was not successfull", TaxeditorEditorPlugin.PLUGIN_ID, (Exception)resultObject, true, true);
239
                }
240
                else if(resultObject instanceof UpdateResult){
241
                    DescriptiveDataSet dataSet = (DescriptiveDataSet) ((UpdateResult) resultObject).getCdmEntity();
242
                    dataSet = matrix.getCdmEntitiySession().load(dataSet, true);
243
                    // update local dataset
244
                    matrix.setDescriptiveDataSet(dataSet);
245
                    matrix.loadDescriptions(descriptiveDataSetUuid, false);
246
                }
247
            } catch (InterruptedException e) {
248
                return;
249
            }
250
            monitor.done();
251
        });
252
        job.addJobChangeListener(new JobChangeAdapter(){
253
            @Override
254
            public void done(IJobChangeEvent event) {
255
                CharacterMatrixBottomToolbar.this.getDisplay().asyncExec(()->{
256
                    matrix.redraw();
257
                });
258
            }
259
        });
260
        job.schedule();
261
    }
262

    
263
    private void addRowsToMatrix(Collection<SpecimenNodeWrapper> wrappers, UUID descriptiveDataSetUuid){
264
        UUID monitorUuid =  CdmApplicationState.getLongRunningTasksService().addRowWrapperToDataset(wrappers, descriptiveDataSetUuid);
265

    
266
        String jobLabel = "Add specimens to matrix";
267
        Job job = Job.create(jobLabel, (ICoreRunnable) monitor -> {
268
            SubMonitor subMonitor = SubMonitor.convert(monitor);
269
            subMonitor.beginTask(jobLabel, IProgressMonitor.UNKNOWN);
270
            IRemotingProgressMonitor remotingMonitor;
271
            try {
272
                remotingMonitor = CdmStore.getProgressMonitorClientManager()
273
                        .pollMonitor(jobLabel,
274
                                monitorUuid,
275
                                50,
276
                                null,
277
                                (List)null,
278
                                subMonitor);
279
                Object resultObject = remotingMonitor.getResult();
280
                if(resultObject instanceof Exception){
281
                    MessagingUtils.errorDialog("Adding specimens failed", this, "Adding specimens was not successfull", TaxeditorEditorPlugin.PLUGIN_ID, (Exception)resultObject, true, true);
282
                }
283
                else if(resultObject instanceof UpdateResult){
284
                    UpdateResult result = (UpdateResult)resultObject;
285
                    if(!result.getExceptions().isEmpty()){
286
                        MessagingUtils.warningDialog(Messages.CharacterMatrixBottomToolbar_ERROR_ROW_CREATION_TITLE, this,
287
                                String.format(Messages.CharacterMatrixBottomToolbar_ERROR_ROW_CREATION_MESSAGE, result.getExceptions()
288
                                        .stream().map(ex->ex.toString())
289
                                        .collect(Collectors.joining("\n"))));
290
                    }
291
                    DescriptiveDataSet dataSet = (DescriptiveDataSet) result.getCdmEntity();
292
                    dataSet = matrix.getCdmEntitiySession().load(dataSet, true);
293
                    // update local dataset
294
                    matrix.setDescriptiveDataSet(dataSet);
295
                    matrix.loadDescriptions(descriptiveDataSetUuid, false);
296
                }
297
            } catch (InterruptedException e) {
298
                return;
299
            }
300
            monitor.done();
301
        });
302
        job.addJobChangeListener(new JobChangeAdapter(){
303
            @Override
304
            public void done(IJobChangeEvent event) {
305
                CharacterMatrixBottomToolbar.this.getDisplay().asyncExec(()->{
306
                    matrix.redraw();
307
                });
308
            }
309
        });
310
        job.schedule();
311
    }
312

    
313
    private void generateKey(UUID datasetUuid, UUID taxonUuid) {
314

    
315
        UUID monitorUuid =  CdmApplicationState.getLongRunningTasksService().generatePolytomousKey(datasetUuid, taxonUuid);
316

    
317
        String jobLabel = "Generate polytomous key";
318
        Job job = Job.create(jobLabel, (ICoreRunnable) monitor -> {
319
            SubMonitor subMonitor = SubMonitor.convert(monitor);
320
            subMonitor.beginTask(jobLabel, IProgressMonitor.UNKNOWN);
321
            IRemotingProgressMonitor remotingMonitor;
322
            try {
323
                remotingMonitor = CdmStore.getProgressMonitorClientManager()
324
                        .pollMonitor(jobLabel,
325
                                monitorUuid,
326
                                50,
327
                                null,
328
                                (List)null,
329
                                subMonitor);
330
                Object resultObject = remotingMonitor.getResult();
331
                if(resultObject instanceof Exception){
332
                    MessagingUtils.errorDialog("Key generation failed", this, "Generating the polytomous key was not successfull", TaxeditorEditorPlugin.PLUGIN_ID, (Exception)resultObject, true, true);
333
                }
334
            } catch (InterruptedException e) {
335
                return;
336
            }
337
            monitor.done();
338
        });
339
        job.schedule();
340

    
341
    }
342

    
343
}
(5-5/20)