Merge branch 'release/5.5.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / descriptiveDataSet / matrix / CharacterMatrixBottomToolbar.java
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 import java.util.stream.Collectors;
17
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;
26
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;
49
50 /**
51 * @author pplitzner
52 * @since Jul 9, 2018
53 *
54 */
55 public class CharacterMatrixBottomToolbar extends Composite{
56
57 private CharacterMatrix matrix;
58
59 public CharacterMatrixBottomToolbar(CharacterMatrix matrix, int style) {
60 super(matrix, style);
61 this.matrix = matrix;
62
63 init();
64 }
65
66 private void init() {
67
68 setLayout(new RowLayout());
69 GridDataFactory.fillDefaults().grab(true, false).applyTo(this);
70
71 /**
72 * Add description button
73 */
74 Button btnAddDescription = new Button(this, SWT.PUSH);
75 btnAddDescription.setImage(ImageResources.getImage(ImageResources.ADD_ICON_GREEN));
76 btnAddDescription.addSelectionListener(new SelectionAdapter() {
77 @Override
78 public void widgetSelected(SelectionEvent e) {
79 if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
80 return;
81 }
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());
92 if(rowWrapper==null){
93 error += specimenDescription;
94 continue;
95 }
96 //add specimen description
97 matrix.getDescriptions().add(rowWrapper);
98 matrix.getDescriptiveDataSet().addDescription(specimenDescription);
99 matrix.getCdmEntitiySession().load(specimenDescription, true);
100
101 matrix.setDirty();
102 matrix.getSpecimenCache().remove(wrapper);
103 }
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));
107 }
108 }
109 }
110 });
111 /**
112 * Remove description button
113 */
114 Button btnRemoveDescription = new Button(this, SWT.PUSH);
115 btnRemoveDescription.setImage(ImageResources.getImage(ImageResources.ACTIVE_DELETE_ICON));
116 btnRemoveDescription.addSelectionListener(new SelectionAdapter() {
117 @Override
118 public void widgetSelected(SelectionEvent e) {
119 if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
120 return;
121 }
122 if(!MessagingUtils.confirmDialog(Messages.CharacterMatrixBottomToolbar_CONFIRM_DELETE_TITLE, Messages.CharacterMatrixBottomToolbar_CONFIRM_DELETE_MESSAGE)){
123 return;
124 }
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);
131 }
132 }
133 toRemove.forEach(rowToRemove -> {
134 matrix.getDescriptions().remove(rowToRemove);
135 CdmStore.getService(IDescriptiveDataSetService.class).removeDescription(
136 rowToRemove.getDescription().getUuid(), matrix.getDescriptiveDataSet().getUuid());
137 });
138 }
139 });
140 /**
141 * Aggregate button
142 */
143 Button btnAggregate = new Button(this, SWT.PUSH);
144 btnAggregate.setText(Messages.CharacterMatrixBottomToolbar_AGGREGATE);
145 btnAggregate.addSelectionListener(new SelectionAdapter() {
146 @Override
147 public void widgetSelected(SelectionEvent e) {
148 if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
149 return;
150 }
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);
160 if(response==2){
161 return;
162 }
163 else if(response==1){
164 Taxon taxon = TaxonSelectionDialog.selectTaxon(getShell(), null);
165 if(taxon==null){
166 return;
167 }
168 taxonUuid = taxon.getUuid();
169 }
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);
176
177 aggregateCategorcialHistogram(matrix.getFeatureToHistogramMap());
178 aggregateQuantitativeSummary(matrix.getFeatureToQuantDataStatisticsMap());
179 }
180
181 });
182 }
183
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);
196 }
197 featureToHistogramMap.put(feature, dataHistogram);
198 ((CategoricalData) categoricalData).getStateData()
199 .forEach(stateData -> featureToHistogramMap.get(feature).addState(stateData.getState()));
200 }));
201 }
202
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();
215 }
216 featureToQuantDataStatisticsMap.put(feature, dataStatistics);
217 dataStatistics.addQuantitativeData((QuantitativeData) quantData);
218 }));
219 }
220
221 }