Project

General

Profile

Download (14.4 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.hibernate.HibernateProxyHelper;
45
import eu.etaxonomy.cdm.model.description.CategoricalData;
46
import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
47
import eu.etaxonomy.cdm.model.description.Feature;
48
import eu.etaxonomy.cdm.model.description.PolytomousKey;
49
import eu.etaxonomy.cdm.model.description.QuantitativeData;
50
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
51
import eu.etaxonomy.cdm.model.description.TaxonDescription;
52
import eu.etaxonomy.cdm.persistence.dto.SpecimenNodeWrapper;
53
import eu.etaxonomy.cdm.strategy.generate.PolytomousKeyGenerator;
54
import eu.etaxonomy.cdm.strategy.generate.PolytomousKeyGeneratorConfigurator;
55
import eu.etaxonomy.taxeditor.editor.internal.TaxeditorEditorPlugin;
56
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
57
import eu.etaxonomy.taxeditor.model.ImageResources;
58
import eu.etaxonomy.taxeditor.model.MessagingUtils;
59
import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
60
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
61
import eu.etaxonomy.taxeditor.store.CdmStore;
62
import eu.etaxonomy.taxeditor.store.StoreUtil;
63

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

    
71
    private CharacterMatrix matrix;
72

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

    
77
        init();
78
    }
79

    
80
    private void init() {
81

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

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

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

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

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

    
207
        String jobLabel = "Aggregate Descriptive Data Set";
208
        Job job = Job.create(jobLabel, (ICoreRunnable) monitor -> {
209
            SubMonitor subMonitor = SubMonitor.convert(monitor);
210
            subMonitor.beginTask(jobLabel, IProgressMonitor.UNKNOWN);
211
            IRemotingProgressMonitor remotingMonitor;
212
            try {
213
                remotingMonitor = CdmStore.getProgressMonitorClientManager()
214
                        .pollMonitor(jobLabel,
215
                                monitorUuid,
216
                                50,
217
                                null,
218
                                (List)null,
219
                                subMonitor);
220
                Object resultObject = remotingMonitor.getResult();
221
                if(resultObject instanceof Exception){
222
                    MessagingUtils.errorDialog("Aggregation failed", this, "Aggregation was not successfull", TaxeditorEditorPlugin.PLUGIN_ID, (Exception)resultObject, true, true);
223
                }
224
                else if(resultObject instanceof UpdateResult){
225
                    UpdateResult result = (UpdateResult) resultObject;
226
                IDescriptiveDataSetService dataSetService = CdmStore.getService(IDescriptiveDataSetService.class);
227
                result.getUpdatedObjects().stream()
228
                .filter(o -> o instanceof TaxonDescription)
229
                .map(o -> HibernateProxyHelper.deproxy(o, TaxonDescription.class))
230
                .forEach(taxonDescription -> matrix.getDescriptions()
231
                        .add(dataSetService.createTaxonRowWrapper(
232
                                taxonDescription.getUuid(),
233
                                matrix.getDescriptiveDataSet().getUuid())));
234
                }
235
            } catch (InterruptedException e) {
236
                return;
237
            }
238
            monitor.done();
239
        });
240
        job.addJobChangeListener(new JobChangeAdapter(){
241
            @Override
242
            public void done(IJobChangeEvent event) {
243
                CharacterMatrixBottomToolbar.this.getDisplay().asyncExec(()->{
244
                    matrix.redraw();
245
                });
246
            }
247
        });
248
        job.schedule();
249
    }
250

    
251
    private void aggregateCharts() {
252
        new Job("aggregate charts") {
253

    
254
            @Override
255
            protected IStatus run(IProgressMonitor monitor) {
256
                aggregateCategorcialHistogram(matrix.getFeatureToHistogramMap());
257
                aggregateQuantitativeSummary(matrix.getFeatureToQuantDataStatisticsMap());
258
                return Status.OK_STATUS;
259
            }
260
        }.schedule();
261
    }
262

    
263
    @SuppressWarnings("unchecked")
264
    private void aggregateCategorcialHistogram(Map<Feature, CategoricalDataHistogram> featureToHistogramMap) {
265
        featureToHistogramMap.clear();
266
        matrix.getDescriptions().stream()
267
        .filter(desc->desc instanceof SpecimenRowWrapperDTO)
268
        .forEach(o -> ((SpecimenRowWrapperDTO) o).getDescription().getElements().stream()
269
                .filter(descriptionElement -> descriptionElement instanceof CategoricalData)
270
                .forEach(categoricalData -> {
271
                    Feature feature = ((CategoricalData) categoricalData).getFeature();
272
                    CategoricalDataHistogram dataHistogram = featureToHistogramMap.get(feature);
273
                    if(dataHistogram==null){
274
                        dataHistogram = new CategoricalDataHistogram(feature);
275
                    }
276
                    featureToHistogramMap.put(feature, dataHistogram);
277
                    ((CategoricalData) categoricalData).getStateData()
278
                    .forEach(stateData -> featureToHistogramMap.get(feature).addState(stateData.getState()));
279
                }));
280
    }
281

    
282
    @SuppressWarnings("unchecked")
283
    private void aggregateQuantitativeSummary(Map<Feature, QuantitativeDataStatistics> featureToQuantDataStatisticsMap) {
284
        featureToQuantDataStatisticsMap.clear();
285
        matrix.getDescriptions().stream()
286
        .filter(desc->desc instanceof SpecimenRowWrapperDTO)
287
        .forEach(o -> ((SpecimenRowWrapperDTO) o).getDescription().getElements().stream()
288
                .filter(descriptionElement -> descriptionElement instanceof QuantitativeData)
289
                .forEach(quantData -> {
290
                    Feature feature = ((QuantitativeData) quantData).getFeature();
291
                    QuantitativeDataStatistics dataStatistics = featureToQuantDataStatisticsMap.get(feature);
292
                    if(dataStatistics==null){
293
                        dataStatistics = new QuantitativeDataStatistics();
294
                    }
295
                    featureToQuantDataStatisticsMap.put(feature, dataStatistics);
296
                    dataStatistics.addQuantitativeData((QuantitativeData) quantData);
297
                }));
298
    }
299

    
300
}
(7-7/21)