2 * Copyright (C) 2018 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.taxeditor
.editor
.descriptiveDataSet
.matrix
;
11 import java
.util
.ArrayList
;
12 import java
.util
.Collection
;
13 import java
.util
.List
;
15 import java
.util
.UUID
;
16 import java
.util
.stream
.Collectors
;
18 import org
.eclipse
.jface
.layout
.GridDataFactory
;
19 import org
.eclipse
.jface
.window
.Window
;
20 import org
.eclipse
.swt
.SWT
;
21 import org
.eclipse
.swt
.events
.SelectionAdapter
;
22 import org
.eclipse
.swt
.events
.SelectionEvent
;
23 import org
.eclipse
.swt
.layout
.RowLayout
;
24 import org
.eclipse
.swt
.widgets
.Button
;
25 import org
.eclipse
.swt
.widgets
.Composite
;
27 import eu
.etaxonomy
.cdm
.api
.service
.IDescriptiveDataSetService
;
28 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonNodeService
;
29 import eu
.etaxonomy
.cdm
.api
.service
.UpdateResult
;
30 import eu
.etaxonomy
.cdm
.api
.service
.dto
.RowWrapperDTO
;
31 import eu
.etaxonomy
.cdm
.api
.service
.dto
.SpecimenRowWrapperDTO
;
32 import eu
.etaxonomy
.cdm
.api
.service
.dto
.TaxonRowWrapperDTO
;
33 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
34 import eu
.etaxonomy
.cdm
.model
.description
.CategoricalData
;
35 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
36 import eu
.etaxonomy
.cdm
.model
.description
.QuantitativeData
;
37 import eu
.etaxonomy
.cdm
.model
.description
.SpecimenDescription
;
38 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
39 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
40 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
41 import eu
.etaxonomy
.cdm
.persistence
.dto
.SpecimenNodeWrapper
;
42 import eu
.etaxonomy
.cdm
.persistence
.dto
.TaxonNodeDto
;
43 import eu
.etaxonomy
.taxeditor
.editor
.l10n
.Messages
;
44 import eu
.etaxonomy
.taxeditor
.model
.ImageResources
;
45 import eu
.etaxonomy
.taxeditor
.model
.MessagingUtils
;
46 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
47 import eu
.etaxonomy
.taxeditor
.store
.StoreUtil
;
48 import eu
.etaxonomy
.taxeditor
.ui
.dialog
.selection
.TaxonSelectionDialog
;
55 public class CharacterMatrixBottomToolbar
extends Composite
{
57 private CharacterMatrix matrix
;
59 public CharacterMatrixBottomToolbar(CharacterMatrix matrix
, int style
) {
68 setLayout(new RowLayout());
69 GridDataFactory
.fillDefaults().grab(true, false).applyTo(this);
72 * Add description button
74 Button btnAddDescription
= new Button(this, SWT
.PUSH
);
75 btnAddDescription
.setImage(ImageResources
.getImage(ImageResources
.ADD_ICON_GREEN
));
76 btnAddDescription
.addSelectionListener(new SelectionAdapter() {
78 public void widgetSelected(SelectionEvent e
) {
79 if(StoreUtil
.promptCheckIsDirty(matrix
.getPart())){
82 String error
= ""; //$NON-NLS-1$
83 SpecimenSelectionDialog dialog
= new SpecimenSelectionDialog(matrix
.getShell(), matrix
);
84 if(dialog
.open()==Window
.OK
){
85 Collection
<SpecimenNodeWrapper
> wrappers
= dialog
.getSpecimen();
86 for (SpecimenNodeWrapper wrapper
: wrappers
) {
87 SpecimenDescription specimenDescription
= CdmStore
.getService(IDescriptiveDataSetService
.class)
88 .findSpecimenDescription(matrix
.getDescriptiveDataSet().getUuid(),
89 wrapper
.getUuidAndTitleCache().getUuid(), true);
90 SpecimenRowWrapperDTO rowWrapper
= CdmStore
.getService(IDescriptiveDataSetService
.class)
91 .createSpecimenRowWrapper(specimenDescription
, matrix
.getDescriptiveDataSet());
93 error
+= specimenDescription
;
96 //add specimen description
97 matrix
.getDescriptions().add(rowWrapper
);
98 matrix
.getDescriptiveDataSet().addDescription(specimenDescription
);
99 matrix
.getCdmEntitiySession().load(specimenDescription
, true);
102 matrix
.getSpecimenCache().remove(wrapper
);
104 if(CdmUtils
.isNotBlank(error
)){
105 MessagingUtils
.warningDialog(Messages
.CharacterMatrixBottomToolbar_ERROR_ROW_CREATION_TITLE
, this,
106 String
.format(Messages
.CharacterMatrixBottomToolbar_ERROR_ROW_CREATION_MESSAGE
, error
));
112 * Remove description button
114 Button btnRemoveDescription
= new Button(this, SWT
.PUSH
);
115 btnRemoveDescription
.setImage(ImageResources
.getImage(ImageResources
.ACTIVE_DELETE_ICON
));
116 btnRemoveDescription
.addSelectionListener(new SelectionAdapter() {
118 public void widgetSelected(SelectionEvent e
) {
119 if(StoreUtil
.promptCheckIsDirty(matrix
.getPart())){
122 if(!MessagingUtils
.confirmDialog(Messages
.CharacterMatrixBottomToolbar_CONFIRM_DELETE_TITLE
, Messages
.CharacterMatrixBottomToolbar_CONFIRM_DELETE_MESSAGE
)){
125 int[] fullySelectedRowPositions
= matrix
.getBodyLayer().getSelectionLayer().getFullySelectedRowPositions();
126 List
<RowWrapperDTO
> toRemove
= new ArrayList
<>();
127 for (int i
: fullySelectedRowPositions
) {
128 Object rowObject
= matrix
.getBodyDataProvider().getRowObject(i
);
129 if(rowObject
instanceof RowWrapperDTO
){
130 toRemove
.add((RowWrapperDTO
) rowObject
);
133 toRemove
.forEach(rowToRemove
-> {
134 matrix
.getDescriptions().remove(rowToRemove
);
135 CdmStore
.getService(IDescriptiveDataSetService
.class).removeDescription(
136 rowToRemove
.getDescription().getUuid(), matrix
.getDescriptiveDataSet().getUuid());
143 Button btnAggregate
= new Button(this, SWT
.PUSH
);
144 btnAggregate
.setText(Messages
.CharacterMatrixBottomToolbar_AGGREGATE
);
145 btnAggregate
.addSelectionListener(new SelectionAdapter() {
147 public void widgetSelected(SelectionEvent e
) {
148 if(StoreUtil
.promptCheckIsDirty(matrix
.getPart())){
151 List
<TaxonNode
> taxonSubtreeFilter
= CdmStore
.getService(IDescriptiveDataSetService
.class).loadFilteredTaxonNodes(matrix
.getDescriptiveDataSet(), null);
152 List
<TaxonNodeDto
> nodeDtos
= taxonSubtreeFilter
.stream()
153 .map(node
-> new TaxonNodeDto(node
)).collect(Collectors
.toList());
154 TaxonNodeDto parentDto
= CdmStore
.getService(ITaxonNodeService
.class).findCommonParentDto(nodeDtos
);
155 UUID taxonUuid
= parentDto
.getTaxonUuid();
156 int response
= MessagingUtils
.confirmDialog(
157 Messages
.CharacterMatrixBottomToolbar_AGGREGATION_TITLE
,
158 String
.format(Messages
.CharacterMatrixBottomToolbar_AGGREGATION_MESSAGE
159 , parentDto
.getTaxonTitleCache()), Messages
.CharacterMatrixBottomToolbar_YES
, Messages
.CharacterMatrixBottomToolbar_CHOOSE_TAXON
, Messages
.CharacterMatrixBottomToolbar_CANCEL
);
163 else if(response
==1){
164 Taxon taxon
= TaxonSelectionDialog
.selectTaxon(getShell(), null);
168 taxonUuid
= taxon
.getUuid();
170 List
<UUID
> descriptionUuids
= new ArrayList
<>();
171 matrix
.getDescriptiveDataSet().getDescriptions().forEach(desc
->descriptionUuids
.add(desc
.getUuid()));
172 UpdateResult result
= CdmStore
.getService(IDescriptiveDataSetService
.class).aggregateDescription(taxonUuid
, descriptionUuids
, matrix
.getDescriptiveDataSet().getLabel(), matrix
.getDescriptiveDataSet().getUuid());
173 TaxonDescription taxonDescription
= (TaxonDescription
) result
.getCdmEntity();
174 TaxonRowWrapperDTO taxonRowWrapper
= CdmStore
.getService(IDescriptiveDataSetService
.class).createTaxonRowWrapper(taxonDescription
.getUuid(), matrix
.getDescriptiveDataSet().getUuid());
175 matrix
.getDescriptions().add(taxonRowWrapper
);
177 aggregateCategorcialHistogram(matrix
.getFeatureToHistogramMap());
178 aggregateQuantitativeSummary(matrix
.getFeatureToQuantDataStatisticsMap());
184 @SuppressWarnings("unchecked")
185 private void aggregateCategorcialHistogram(Map
<Feature
, CategoricalDataHistogram
> featureToHistogramMap
) {
186 featureToHistogramMap
.clear();
187 matrix
.getDescriptions().stream()
188 .filter(desc
->desc
instanceof SpecimenRowWrapperDTO
)
189 .forEach(o
-> ((SpecimenRowWrapperDTO
) o
).getDescription().getElements().stream()
190 .filter(descriptionElement
-> descriptionElement
instanceof CategoricalData
)
191 .forEach(categoricalData
-> {
192 Feature feature
= ((CategoricalData
) categoricalData
).getFeature();
193 CategoricalDataHistogram dataHistogram
= featureToHistogramMap
.get(feature
);
194 if(dataHistogram
==null){
195 dataHistogram
= new CategoricalDataHistogram(feature
);
197 featureToHistogramMap
.put(feature
, dataHistogram
);
198 ((CategoricalData
) categoricalData
).getStateData()
199 .forEach(stateData
-> featureToHistogramMap
.get(feature
).addState(stateData
.getState()));
203 @SuppressWarnings("unchecked")
204 private void aggregateQuantitativeSummary(Map
<Feature
, QuantitativeDataStatistics
> featureToQuantDataStatisticsMap
) {
205 featureToQuantDataStatisticsMap
.clear();
206 matrix
.getDescriptions().stream()
207 .filter(desc
->desc
instanceof SpecimenRowWrapperDTO
)
208 .forEach(o
-> ((SpecimenRowWrapperDTO
) o
).getDescription().getElements().stream()
209 .filter(descriptionElement
-> descriptionElement
instanceof QuantitativeData
)
210 .forEach(quantData
-> {
211 Feature feature
= ((QuantitativeData
) quantData
).getFeature();
212 QuantitativeDataStatistics dataStatistics
= featureToQuantDataStatisticsMap
.get(feature
);
213 if(dataStatistics
==null){
214 dataStatistics
= new QuantitativeDataStatistics();
216 featureToQuantDataStatisticsMap
.put(feature
, dataStatistics
);
217 dataStatistics
.addQuantitativeData((QuantitativeData
) quantData
);