fe0599703a5efbf2a08979579fc5b4d836e5add5
[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.IDescriptionService;
28 import eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService;
29 import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
30 import eu.etaxonomy.cdm.api.service.UpdateResult;
31 import eu.etaxonomy.cdm.api.service.dto.RowWrapperDTO;
32 import eu.etaxonomy.cdm.api.service.dto.SpecimenRowWrapperDTO;
33 import eu.etaxonomy.cdm.api.service.dto.TaxonRowWrapperDTO;
34 import eu.etaxonomy.cdm.common.CdmUtils;
35 import eu.etaxonomy.cdm.model.description.CategoricalData;
36 import eu.etaxonomy.cdm.model.description.Feature;
37 import eu.etaxonomy.cdm.model.description.QuantitativeData;
38 import eu.etaxonomy.cdm.model.description.SpecimenDescription;
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.model.ImageResources;
44 import eu.etaxonomy.taxeditor.model.MessagingUtils;
45 import eu.etaxonomy.taxeditor.store.CdmStore;
46 import eu.etaxonomy.taxeditor.ui.dialog.selection.TaxonSelectionDialog;
47
48 /**
49 * @author pplitzner
50 * @since Jul 9, 2018
51 *
52 */
53 public class CharacterMatrixBottomToolbar extends Composite{
54
55 private CharacterMatrix matrix;
56
57 public CharacterMatrixBottomToolbar(CharacterMatrix matrix, int style) {
58 super(matrix, style);
59 this.matrix = matrix;
60
61 init();
62 }
63
64 private void init() {
65
66 setLayout(new RowLayout());
67 GridDataFactory.fillDefaults().grab(true, false).applyTo(this);
68
69 /**
70 * Add description button
71 */
72 Button btnAddDescription = new Button(this, SWT.PUSH);
73 btnAddDescription.setImage(ImageResources.getImage(ImageResources.ADD_ICON_GREEN));
74 btnAddDescription.addSelectionListener(new SelectionAdapter() {
75 @Override
76 public void widgetSelected(SelectionEvent e) {
77 String error = "";
78 SpecimenSelectionDialog dialog = new SpecimenSelectionDialog(matrix.getShell(), matrix);
79 if(dialog.open()==Window.OK){
80 Collection<SpecimenNodeWrapper> wrappers = dialog.getSpecimen();
81 for (SpecimenNodeWrapper wrapper : wrappers) {
82 SpecimenDescription specimenDescription = CdmStore.getService(IDescriptiveDataSetService.class)
83 .findSpecimenDescription(matrix.getDescriptiveDataSet().getUuid(),
84 wrapper.getUuidAndTitleCache().getUuid());
85 SpecimenRowWrapperDTO rowWrapper = CdmStore.getService(IDescriptiveDataSetService.class)
86 .createSpecimenRowWrapper(specimenDescription, matrix.getDescriptiveDataSet(), true);
87 if(rowWrapper==null){
88 error += specimenDescription;
89 continue;
90 }
91 //add specimen description
92 matrix.getDescriptions().add(rowWrapper);
93 matrix.getDescriptiveDataSet().addDescription(specimenDescription);
94 matrix.getCdmEntitiySession().load(specimenDescription, true);
95
96 //add taxon description
97 TaxonRowWrapperDTO taxonDescription = rowWrapper.getDefaultTaxonDescription();
98 matrix.getDescriptiveDataSet().addDescription(taxonDescription.getDescription());
99 matrix.getCdmEntitiySession().load(taxonDescription.getDescription(), true);
100
101 matrix.setDirty();
102 matrix.getSpecimenCache().remove(wrapper);
103 }
104 if(CdmUtils.isNotBlank(error)){
105 MessagingUtils.warningDialog("Errors during row creation", this,
106 String.format("Could not create rows for the following description:\n\n%s", 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 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 matrix.getDescriptiveDataSet().removeDescription(rowToRemove.getDescription());
130 matrix.setDirty();
131 });
132 }
133 });
134 /**
135 * Aggregate button
136 */
137 Button btnAggregate = new Button(this, SWT.PUSH);
138 btnAggregate.setText("Aggregate");
139 btnAggregate.addSelectionListener(new SelectionAdapter() {
140 @Override
141 public void widgetSelected(SelectionEvent e) {
142 List<TaxonNode> taxonSubtreeFilter = CdmStore.getService(IDescriptiveDataSetService.class).loadFilteredTaxonNodes(matrix.getDescriptiveDataSet(), null);
143 List<TaxonNodeDto> nodeDtos = taxonSubtreeFilter.stream()
144 .map(node -> new TaxonNodeDto(node)).collect(Collectors.toList());
145 TaxonNodeDto parentDto = CdmStore.getService(ITaxonNodeService.class).findCommonParentDto(nodeDtos);
146 UUID taxonUuid = parentDto.getTaxonUuid();
147 int response = MessagingUtils.confirmDialog(
148 "Choose location for the aggregated description",
149 String.format("The aggregated description will be stored at "
150 + "the common parent taxon of this data set:\n%s\n\n"
151 + "Do you want to use this taxon?"
152 , parentDto.getTaxonTitleCache()), "Yes", "Choose taxon", "Cancel");
153 if(response==2){
154 return;
155 }
156 else if(response==1){
157 Taxon taxon = TaxonSelectionDialog.selectTaxon(getShell(), null);
158 if(taxon==null){
159 return;
160 }
161 taxonUuid = taxon.getUuid();
162 }
163 List<UUID> descriptionUuids = new ArrayList<>();
164 matrix.getDescriptiveDataSet().getDescriptions().forEach(desc->descriptionUuids.add(desc.getUuid()));
165 UpdateResult result = CdmStore.getService(IDescriptionService.class).aggregateDescription(taxonUuid, descriptionUuids, matrix.getDescriptiveDataSet().getLabel(), matrix.getDescriptiveDataSet().getUuid());
166 matrix.addUpdateResult(result);
167 matrix.setDirty();
168
169 aggregateCategorcialHistogram(matrix.getFeatureToHistogramMap());
170 aggregateQuantitativeSummary(matrix.getFeatureToQuantDataStatisticsMap());
171 }
172
173 });
174 }
175
176 @SuppressWarnings("unchecked")
177 private void aggregateCategorcialHistogram(Map<Feature, CategoricalDataHistogram> featureToHistogramMap) {
178 featureToHistogramMap.clear();
179 matrix.getDescriptions().stream()
180 .filter(desc->desc instanceof SpecimenRowWrapperDTO)
181 .forEach(o -> ((SpecimenRowWrapperDTO) o).getDescription().getElements().stream()
182 .filter(descriptionElement -> descriptionElement instanceof CategoricalData)
183 .forEach(categoricalData -> {
184 Feature feature = ((CategoricalData) categoricalData).getFeature();
185 CategoricalDataHistogram dataHistogram = featureToHistogramMap.get(feature);
186 if(dataHistogram==null){
187 dataHistogram = new CategoricalDataHistogram(feature);
188 }
189 featureToHistogramMap.put(feature, dataHistogram);
190 ((CategoricalData) categoricalData).getStateData()
191 .forEach(stateData -> featureToHistogramMap.get(feature).addState(stateData.getState()));
192 }));
193 }
194
195 @SuppressWarnings("unchecked")
196 private void aggregateQuantitativeSummary(Map<Feature, QuantitativeDataStatistics> featureToQuantDataStatisticsMap) {
197 featureToQuantDataStatisticsMap.clear();
198 matrix.getDescriptions().stream()
199 .filter(desc->desc instanceof SpecimenRowWrapperDTO)
200 .forEach(o -> ((SpecimenRowWrapperDTO) o).getDescription().getElements().stream()
201 .filter(descriptionElement -> descriptionElement instanceof QuantitativeData)
202 .forEach(quantData -> {
203 Feature feature = ((QuantitativeData) quantData).getFeature();
204 QuantitativeDataStatistics dataStatistics = featureToQuantDataStatisticsMap.get(feature);
205 if(dataStatistics==null){
206 dataStatistics = new QuantitativeDataStatistics();
207 }
208 featureToQuantDataStatisticsMap.put(feature, dataStatistics);
209 dataStatistics.addQuantitativeData((QuantitativeData) quantData);
210 }));
211 }
212
213 }