Project

General

Profile

Download (13.7 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.Map;
15
import java.util.UUID;
16

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

    
34
import eu.etaxonomy.cdm.api.application.CdmApplicationState;
35
import eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService;
36
import eu.etaxonomy.cdm.api.service.IPolytomousKeyService;
37
import eu.etaxonomy.cdm.api.service.UpdateResult;
38
import eu.etaxonomy.cdm.api.service.config.DescriptionAggregationConfiguration;
39
import eu.etaxonomy.cdm.api.service.config.IdentifiableServiceConfiguratorImpl;
40
import eu.etaxonomy.cdm.api.service.dto.RowWrapperDTO;
41
import eu.etaxonomy.cdm.api.service.dto.SpecimenRowWrapperDTO;
42
import eu.etaxonomy.cdm.common.CdmUtils;
43
import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
44
import eu.etaxonomy.cdm.model.description.CategoricalData;
45
import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
46
import eu.etaxonomy.cdm.model.description.Feature;
47
import eu.etaxonomy.cdm.model.description.PolytomousKey;
48
import eu.etaxonomy.cdm.model.description.QuantitativeData;
49
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
50
import eu.etaxonomy.cdm.persistence.dto.SpecimenNodeWrapper;
51
import eu.etaxonomy.cdm.strategy.generate.PolytomousKeyGenerator;
52
import eu.etaxonomy.cdm.strategy.generate.PolytomousKeyGeneratorConfigurator;
53
import eu.etaxonomy.taxeditor.editor.internal.TaxeditorEditorPlugin;
54
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
55
import eu.etaxonomy.taxeditor.model.ImageResources;
56
import eu.etaxonomy.taxeditor.model.MessagingUtils;
57
import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
58
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
59
import eu.etaxonomy.taxeditor.store.CdmStore;
60
import eu.etaxonomy.taxeditor.store.StoreUtil;
61

    
62
/**
63
 * @author pplitzner
64
 * @since Jul 9, 2018
65
 *
66
 */
67
public class CharacterMatrixBottomToolbar extends Composite{
68

    
69
    private CharacterMatrix matrix;
70

    
71
    public CharacterMatrixBottomToolbar(CharacterMatrix matrix, int style) {
72
        super(matrix, style);
73
        this.matrix = matrix;
74

    
75
        init();
76
    }
77

    
78
    private void init() {
79

    
80
        setLayout(new RowLayout());
81
        GridDataFactory.fillDefaults().grab(true, false).applyTo(this);
82

    
83
        /**
84
         * Add description button
85
         */
86
        Button btnAddDescription = new Button(this, SWT.PUSH);
87
        btnAddDescription.setImage(ImageResources.getImage(ImageResources.ADD_ICON_GREEN));
88
        btnAddDescription.addSelectionListener(new SelectionAdapter() {
89
            @Override
90
            public void widgetSelected(SelectionEvent e) {
91
                if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
92
                    return;
93
                }
94
                String error = ""; //$NON-NLS-1$
95
                SpecimenSelectionDialog dialog = new SpecimenSelectionDialog(matrix.getShell(), matrix);
96
                if(dialog.open()==Window.OK){
97
                    Collection<SpecimenNodeWrapper> wrappers = dialog.getSpecimen();
98
                    for (SpecimenNodeWrapper wrapper : wrappers) {
99
                        SpecimenDescription specimenDescription = CdmStore.getService(IDescriptiveDataSetService.class)
100
                                .findSpecimenDescription(matrix.getDescriptiveDataSet().getUuid(),
101
                                        wrapper.getUuidAndTitleCache().getUuid(), true);
102
                        SpecimenRowWrapperDTO rowWrapper = CdmStore.getService(IDescriptiveDataSetService.class)
103
                                .createSpecimenRowWrapper(specimenDescription, matrix.getDescriptiveDataSet());
104
                        if(rowWrapper==null){
105
                            error += specimenDescription;
106
                            continue;
107
                        }
108
                        //add specimen description
109
                        matrix.getDescriptions().add(rowWrapper);
110
                        matrix.getDescriptiveDataSet().addDescription(specimenDescription);
111
                        matrix.getCdmEntitiySession().load(specimenDescription, true);
112

    
113
                        matrix.setDirty();
114
                        matrix.getSpecimenCache().remove(wrapper);
115
                    }
116
                    if(CdmUtils.isNotBlank(error)){
117
                        MessagingUtils.warningDialog(Messages.CharacterMatrixBottomToolbar_ERROR_ROW_CREATION_TITLE, this,
118
                                String.format(Messages.CharacterMatrixBottomToolbar_ERROR_ROW_CREATION_MESSAGE, error));
119
                    }
120
                }
121
            }
122
        });
123
        /**
124
         * Remove description button
125
         */
126
        Button btnRemoveDescription = new Button(this, SWT.PUSH);
127
        btnRemoveDescription.setImage(ImageResources.getImage(ImageResources.ACTIVE_DELETE_ICON));
128
        btnRemoveDescription.addSelectionListener(new SelectionAdapter() {
129
            @Override
130
            public void widgetSelected(SelectionEvent e) {
131
                if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
132
                    return;
133
                }
134
                if(!MessagingUtils.confirmDialog(Messages.CharacterMatrixBottomToolbar_CONFIRM_DELETE_TITLE, Messages.CharacterMatrixBottomToolbar_CONFIRM_DELETE_MESSAGE)){
135
                    return;
136
                }
137
                int[] fullySelectedRowPositions = matrix.getBodyLayer().getSelectionLayer().getFullySelectedRowPositions();
138
                List<RowWrapperDTO> toRemove = new ArrayList<>();
139
                for (int i : fullySelectedRowPositions) {
140
                    Object rowObject = matrix.getBodyDataProvider().getRowObject(i);
141
                    if(rowObject instanceof RowWrapperDTO){
142
                        toRemove.add((RowWrapperDTO) rowObject);
143
                    }
144
                }
145
                toRemove.forEach(rowToRemove -> {
146
                    matrix.getDescriptions().remove(rowToRemove);
147
                    CdmStore.getService(IDescriptiveDataSetService.class).removeDescription(
148
                            rowToRemove.getDescription().getUuid(), matrix.getDescriptiveDataSet().getUuid());
149
                });
150
            }
151
        });
152
        /**
153
         * Aggregate button
154
         */
155
        Button btnAggregate = new Button(this, SWT.PUSH);
156
        btnAggregate.setText(Messages.CharacterMatrixBottomToolbar_AGGREGATE);
157
        btnAggregate.addSelectionListener(new SelectionAdapter() {
158
            @Override
159
            public void widgetSelected(SelectionEvent e) {
160
                if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
161
                    return;
162
                }
163
                aggregatDescriptiveDataSet(matrix.getDescriptiveDataSet().getUuid());
164

    
165
                aggregateCharts();
166
            }
167
        });
168
        if(PreferencesUtil.getBooleanValue(IPreferenceKeys.SHOW_EXPERIMENTAL_FEATURES)){
169
            /**
170
             * Key generation button
171
             */
172
            Button btnGenerateKey = new Button(this, SWT.PUSH);
173
            btnGenerateKey.setText("Generate Polytomous Key");
174
            btnGenerateKey.addSelectionListener(new SelectionAdapter() {
175
                @Override
176
                public void widgetSelected(SelectionEvent e) {
177
                    if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
178
                        return;
179
                    }
180
                    PolytomousKeyGeneratorConfigurator keyConfig = new PolytomousKeyGeneratorConfigurator();
181
                    DescriptiveDataSet descriptiveDataSet = matrix.getDescriptiveDataSet();
182
                    keyConfig.setDataSet(descriptiveDataSet);
183
                    PolytomousKey key = new PolytomousKeyGenerator().invoke(keyConfig);
184
                    IPolytomousKeyService keyService = CdmStore.getService(IPolytomousKeyService.class);
185
                    IdentifiableServiceConfiguratorImpl<PolytomousKey> serviceConfig= new IdentifiableServiceConfiguratorImpl<>();
186
                    serviceConfig.setTitleSearchString(descriptiveDataSet.getTitleCache());
187
                    List<PolytomousKey> list = keyService.findByTitle(serviceConfig).getRecords();
188
                    if(list!=null){
189
                        // TODO clear old key
190
                        System.out.println("Key with same name found for this data set found");
191
                    }
192
                    key.setTitleCache(descriptiveDataSet.getTitleCache(), true);
193
                    keyService.save(key);
194
                    key.print(System.out);
195
                }
196
            });
197
        }
198
    }
199

    
200
    private void aggregatDescriptiveDataSet(UUID descriptiveDataSetUuid){
201
        DescriptionAggregationConfiguration config = new DescriptionAggregationConfiguration();
202
        config.setRecursiveAggregation(true);
203
        UUID monitorUuid =  CdmApplicationState.getLongRunningTasksService().aggregateDescriptiveDataSet(descriptiveDataSetUuid, config);
204

    
205
        String jobLabel = "Aggregate Descriptive Data Set";
206
        Job job = Job.create(jobLabel, (ICoreRunnable) monitor -> {
207
            SubMonitor subMonitor = SubMonitor.convert(monitor);
208
            subMonitor.beginTask(jobLabel, IProgressMonitor.UNKNOWN);
209
            IRemotingProgressMonitor remotingMonitor;
210
            try {
211
                remotingMonitor = CdmStore.getProgressMonitorClientManager()
212
                        .pollMonitor(jobLabel,
213
                                monitorUuid,
214
                                50,
215
                                null,
216
                                (List)null,
217
                                subMonitor);
218
                Object resultObject = remotingMonitor.getResult();
219
                if(resultObject instanceof Exception){
220
                    MessagingUtils.errorDialog("Aggregation failed", this, "Aggregation was not successfull", TaxeditorEditorPlugin.PLUGIN_ID, (Exception)resultObject, true, true);
221
                }
222
                else if(resultObject instanceof UpdateResult){
223
                    matrix.loadDescriptions(descriptiveDataSetUuid);
224
                }
225
            } catch (InterruptedException e) {
226
                return;
227
            }
228
            monitor.done();
229
        });
230
        job.addJobChangeListener(new JobChangeAdapter(){
231
            @Override
232
            public void done(IJobChangeEvent event) {
233
                CharacterMatrixBottomToolbar.this.getDisplay().asyncExec(()->{
234
                    matrix.redraw();
235
                });
236
            }
237
        });
238
        job.schedule();
239
    }
240

    
241
    private void aggregateCharts() {
242
        new Job("aggregate charts") {
243

    
244
            @Override
245
            protected IStatus run(IProgressMonitor monitor) {
246
                aggregateCategorcialHistogram(matrix.getFeatureToHistogramMap());
247
                aggregateQuantitativeSummary(matrix.getFeatureToQuantDataStatisticsMap());
248
                return Status.OK_STATUS;
249
            }
250
        }.schedule();
251
    }
252

    
253
    @SuppressWarnings("unchecked")
254
    private void aggregateCategorcialHistogram(Map<Feature, CategoricalDataHistogram> featureToHistogramMap) {
255
        featureToHistogramMap.clear();
256
        matrix.getDescriptions().stream()
257
        .filter(desc->desc instanceof SpecimenRowWrapperDTO)
258
        .forEach(o -> ((SpecimenRowWrapperDTO) o).getDescription().getElements().stream()
259
                .filter(descriptionElement -> descriptionElement instanceof CategoricalData)
260
                .forEach(categoricalData -> {
261
                    Feature feature = ((CategoricalData) categoricalData).getFeature();
262
                    CategoricalDataHistogram dataHistogram = featureToHistogramMap.get(feature);
263
                    if(dataHistogram==null){
264
                        dataHistogram = new CategoricalDataHistogram(feature);
265
                    }
266
                    featureToHistogramMap.put(feature, dataHistogram);
267
                    ((CategoricalData) categoricalData).getStateData()
268
                    .forEach(stateData -> featureToHistogramMap.get(feature).addState(stateData.getState()));
269
                }));
270
    }
271

    
272
    @SuppressWarnings("unchecked")
273
    private void aggregateQuantitativeSummary(Map<Feature, QuantitativeDataStatistics> featureToQuantDataStatisticsMap) {
274
        featureToQuantDataStatisticsMap.clear();
275
        matrix.getDescriptions().stream()
276
        .filter(desc->desc instanceof SpecimenRowWrapperDTO)
277
        .forEach(o -> ((SpecimenRowWrapperDTO) o).getDescription().getElements().stream()
278
                .filter(descriptionElement -> descriptionElement instanceof QuantitativeData)
279
                .forEach(quantData -> {
280
                    Feature feature = ((QuantitativeData) quantData).getFeature();
281
                    QuantitativeDataStatistics dataStatistics = featureToQuantDataStatisticsMap.get(feature);
282
                    if(dataStatistics==null){
283
                        dataStatistics = new QuantitativeDataStatistics();
284
                    }
285
                    featureToQuantDataStatisticsMap.put(feature, dataStatistics);
286
                    dataStatistics.addQuantitativeData((QuantitativeData) quantData);
287
                }));
288
    }
289

    
290
}
(7-7/21)