Project

General

Profile

« Previous | Next » 

Revision f2e0fed4

Added by Patrick Plitzner almost 6 years ago

Refactor CharacterMatrix code

  • extract bottom toolbar composite

View differences:

eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/matrix/CharacterMatrix.java
12 12
import java.util.ArrayList;
13 13
import java.util.Collection;
14 14
import java.util.HashMap;
15
import java.util.HashSet;
16 15
import java.util.List;
17 16
import java.util.Map;
18 17
import java.util.Properties;
......
27 26
import org.eclipse.jface.layout.GridDataFactory;
28 27
import org.eclipse.jface.viewers.ComboViewer;
29 28
import org.eclipse.jface.viewers.StructuredSelection;
30
import org.eclipse.jface.window.Window;
31 29
import org.eclipse.nebula.widgets.nattable.NatTable;
32 30
import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
33 31
import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
......
90 88
import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
91 89
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
92 90
import org.eclipse.swt.SWT;
93
import org.eclipse.swt.events.SelectionAdapter;
94
import org.eclipse.swt.events.SelectionEvent;
95 91
import org.eclipse.swt.graphics.Color;
96 92
import org.eclipse.swt.graphics.FontData;
97 93
import org.eclipse.swt.layout.GridData;
98 94
import org.eclipse.swt.layout.GridLayout;
99
import org.eclipse.swt.layout.RowLayout;
100 95
import org.eclipse.swt.widgets.Button;
101 96
import org.eclipse.swt.widgets.Composite;
102 97

  
......
105 100
import ca.odell.glazedlists.SortedList;
106 101
import ca.odell.glazedlists.TreeList;
107 102
import eu.etaxonomy.cdm.api.application.CdmApplicationState;
108
import eu.etaxonomy.cdm.api.service.IDescriptionService;
109 103
import eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService;
110
import eu.etaxonomy.cdm.api.service.IOccurrenceService;
111 104
import eu.etaxonomy.cdm.api.service.IProgressMonitorService;
112 105
import eu.etaxonomy.cdm.api.service.dto.RowWrapperDTO;
113 106
import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
114
import eu.etaxonomy.cdm.model.description.CategoricalData;
115
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
116 107
import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
117 108
import eu.etaxonomy.cdm.model.description.Feature;
118 109
import eu.etaxonomy.cdm.model.description.FeatureNode;
119 110
import eu.etaxonomy.cdm.model.description.FeatureTree;
120 111
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
121
import eu.etaxonomy.cdm.model.description.QuantitativeData;
122 112
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
123 113
import eu.etaxonomy.cdm.model.description.State;
124
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
125 114
import eu.etaxonomy.cdm.persistence.dto.SpecimenNodeWrapper;
126 115
import eu.etaxonomy.taxeditor.editor.descriptiveDataSet.matrix.categorical.CategoricalDataCellEditor;
127 116
import eu.etaxonomy.taxeditor.editor.descriptiveDataSet.matrix.categorical.CategoricalDataDisplayConverter;
......
130 119
import eu.etaxonomy.taxeditor.editor.descriptiveDataSet.matrix.supplementalInfo.SupplementalInfoDisplayConverter;
131 120
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
132 121
import eu.etaxonomy.taxeditor.model.ColorResources;
133
import eu.etaxonomy.taxeditor.model.DescriptionHelper;
134
import eu.etaxonomy.taxeditor.model.ImageResources;
135 122
import eu.etaxonomy.taxeditor.model.MessagingUtils;
136 123
import eu.etaxonomy.taxeditor.preference.Resources;
137 124
import eu.etaxonomy.taxeditor.store.CdmStore;
......
209 196
        toolbar = new CharacterMatrixToolbar(this, SWT.NONE);
210 197
    }
211 198

  
199
    @SuppressWarnings("unused")
212 200
    private void createBottomToolbar() {
213
        Composite buttonPanel = new Composite(this, SWT.NONE);
214

  
215
        buttonPanel.setLayout(new RowLayout());
216
        GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonPanel);
217

  
218
        /**
219
         * Add description button
220
         */
221
        Button btnAddDescription = new Button(buttonPanel, SWT.PUSH);
222
        btnAddDescription.setImage(ImageResources.getImage(ImageResources.ADD_ICON_GREEN));
223
        btnAddDescription.addSelectionListener(new SelectionAdapter() {
224
            @Override
225
            public void widgetSelected(SelectionEvent e) {
226
                SpecimenSelectionDialog dialog = new SpecimenSelectionDialog(natTable.getShell(), CharacterMatrix.this);
227
                if(dialog.open()==Window.OK){
228
                    Collection<SpecimenNodeWrapper> wrappers = dialog.getSpecimen();
229
                    for (SpecimenNodeWrapper wrapper : wrappers) {
230
                        SpecimenOrObservationBase specimen = CdmStore.getService(IOccurrenceService.class).load(wrapper.getUuidAndTitleCache().getUuid());
231
                        SpecimenDescription description = getDescriptionForDescriptiveDataSet(specimen);
232
                        //description elements
233
                        Map<Feature, DescriptionElementBase> featureToElementMap = new HashMap<>();
234
                        Set<DescriptionElementBase> elements = description.getElements();
235
                        for (DescriptionElementBase descriptionElementBase : elements) {
236
                            Feature feature = descriptionElementBase.getFeature();
237
                            featureToElementMap.put(feature, descriptionElementBase);
238
                        }
239
                        RowWrapperDTO rowWrapper = CdmStore.getService(IDescriptiveDataSetService.class).createRowWrapper(description, descriptiveDataSet);
240
                        CharacterMatrix.this.descriptions.add(rowWrapper);
241
                        descriptiveDataSet.addDescription(description);
242
                        setDirty();
243
                        specimenCache.remove(wrapper);
244
                    }
245
                }
246
            }
247
        });
248
        /**
249
         * Remove description button
250
         */
251
        Button btnRemoveDescription = new Button(buttonPanel, SWT.PUSH);
252
        btnRemoveDescription.setImage(ImageResources.getImage(ImageResources.ACTIVE_DELETE_ICON));
253
        btnRemoveDescription.addSelectionListener(new SelectionAdapter() {
254
            @Override
255
            public void widgetSelected(SelectionEvent e) {
256
                int[] fullySelectedRowPositions = bodyLayer.getSelectionLayer().getFullySelectedRowPositions();
257
                List<RowWrapperDTO> toRemove = new ArrayList<>();
258
                for (int i : fullySelectedRowPositions) {
259
                    Object rowObject = bodyDataProvider.getRowObject(i);
260
                    if(rowObject instanceof RowWrapperDTO){
261
                        toRemove.add((RowWrapperDTO) rowObject);
262
                    }
263
                }
264
                toRemove.forEach(rowToRemove->{
265
                    CharacterMatrix.this.descriptions.remove(rowToRemove);
266
                    descriptiveDataSet.removeDescription(rowToRemove.getSpecimenDescription());
267
                    setDirty();
268
                });
269
            }
270
        });
201
        new CharacterMatrixBottomToolbar(this, SWT.NONE);
271 202
    }
272 203

  
273 204
    private void applyStyles(){
......
699 630
        }
700 631
    }
701 632

  
702
    private SpecimenDescription getDescriptionForDescriptiveDataSet(SpecimenOrObservationBase specimen){
703
        Set<Feature> wsFeatures = descriptiveDataSet.getDescriptiveSystem().getDistinctFeatures();
704
        List<DescriptionElementBase> matchingDescriptionElements = new ArrayList<>();
705

  
706
        for (SpecimenDescription specimenDescription : (Set<SpecimenDescription>) specimen.getDescriptions()) {
707
            specimenDescription = (SpecimenDescription) CdmStore.getService(IDescriptionService.class).load(specimenDescription.getUuid());
708
            Set<Feature> specimenDescriptionFeatures = new HashSet<>();
709
            //gather specimen description features and check for match with WS features
710
            for (DescriptionElementBase specimenDescriptionElement : specimenDescription.getElements()) {
711
                Feature feature = specimenDescriptionElement.getFeature();
712
                specimenDescriptionFeatures.add(feature);
713
                if(wsFeatures.contains(feature)){
714
                    matchingDescriptionElements.add(specimenDescriptionElement);
715
                }
716
            }
717
            //if description with the exact same features is found return the description
718
            if(specimenDescriptionFeatures.equals(wsFeatures)){
719
                return specimenDescription;
720
            }
721
        }
722
        //Create new specimen description if no match was found
723
        setDirty();
724
        SpecimenDescription newDesription = SpecimenDescription.NewInstance(specimen);
725
        newDesription.setTitleCache(Messages.CharacterMatrix_DESCRIPTIVE_DATA_SET+descriptiveDataSet.getLabel()+": "+newDesription.generateTitle(), true); //$NON-NLS-2$
726

  
727
        //check for equals description element (same feature and same values)
728
        Map<Feature, List<DescriptionElementBase>> featureToElementMap = new HashMap<>();
729
        for(DescriptionElementBase element:matchingDescriptionElements){
730
            List<DescriptionElementBase> list = featureToElementMap.get(element.getFeature());
731
            if(list==null){
732
                list = new ArrayList<>();
733
            }
734
            list.add(element);
735
            featureToElementMap.put(element.getFeature(), list);
736
        }
737
        Set<DescriptionElementBase> descriptionElementsToClone = new HashSet<>();
738
        for(Feature feature:featureToElementMap.keySet()){
739
            List<DescriptionElementBase> elements = featureToElementMap.get(feature);
740
            //no duplicate description elements found for this feature
741
            if(elements.size()==1){
742
                descriptionElementsToClone.add(elements.get(0));
743
            }
744
            //duplicates found -> check if all are equal
745
            else{
746
                DescriptionElementBase match = null;
747
                for (DescriptionElementBase descriptionElementBase : elements) {
748
                    if(match==null){
749
                        match = descriptionElementBase;
750
                    }
751
                    else if(!new DescriptionElementCompareWrapper(match).equals(new DescriptionElementCompareWrapper(descriptionElementBase))){
752
                        match = null;
753
                        MessagingUtils.informationDialog(Messages.CharacterMatrix_MULTIPLE_DATA,
754
                                String.format(Messages.CharacterMatrix_MULTIPLE_DATA_MESSAGE, feature.getLabel()));
755
                        break;
756
                    }
757
                }
758
                if(match!=null){
759
                    descriptionElementsToClone.add(match);
760
                }
761
            }
762
        }
763
        //clone matching descriptionElements
764
        for (DescriptionElementBase descriptionElementBase : descriptionElementsToClone) {
765
            DescriptionElementBase clone;
766
            try {
767
                clone = descriptionElementBase.clone(newDesription);
768
                clone.getSources().forEach(source -> source.setOriginalNameString(DescriptionHelper.getLabel(descriptionElementBase)));
769
            } catch (CloneNotSupportedException e) {
770
                MessagingUtils.error(CharacterMatrix.class, e);
771
            }
772
        }
773

  
774
        //add all remaining description elements to the new description
775
        for(Feature wsFeature:wsFeatures){
776
            boolean featureFound = false;
777
            for(DescriptionElementBase element:newDesription.getElements()){
778
                if(element.getFeature().equals(wsFeature)){
779
                    featureFound = true;
780
                    break;
781
                }
782
            }
783
            if(!featureFound){
784
                if(wsFeature.isSupportsCategoricalData()){
785
                    newDesription.addElement(CategoricalData.NewInstance(wsFeature));
786
                }
787
                else if(wsFeature.isSupportsQuantitativeData()){
788
                    newDesription.addElement(QuantitativeData.NewInstance(wsFeature));
789
                }
790
            }
791
        }
792
        return newDesription;
793

  
794
    }
795

  
796 633
    private void initLabels(final ColumnOverrideLabelAccumulator columnLabelAccumulator,
797 634
            int index, Feature feature) {
798 635

  
......
934 771
        return bodyDataProvider;
935 772
    }
936 773

  
774
    DefaultBodyLayerStack getBodyLayer() {
775
        return bodyLayer;
776
    }
777

  
937 778
    File getStatePropertiesFile() {
938 779
        return new File(WorkbenchUtility.getBaseLocation(), CHARACTER_MATRIX_STATE_PROPERTIES);
939 780
    }
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.HashMap;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.Set;
18

  
19
import org.eclipse.jface.layout.GridDataFactory;
20
import org.eclipse.jface.window.Window;
21
import org.eclipse.swt.SWT;
22
import org.eclipse.swt.events.SelectionAdapter;
23
import org.eclipse.swt.events.SelectionEvent;
24
import org.eclipse.swt.layout.RowLayout;
25
import org.eclipse.swt.widgets.Button;
26
import org.eclipse.swt.widgets.Composite;
27

  
28
import eu.etaxonomy.cdm.api.service.IDescriptionService;
29
import eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService;
30
import eu.etaxonomy.cdm.api.service.IOccurrenceService;
31
import eu.etaxonomy.cdm.api.service.dto.RowWrapperDTO;
32
import eu.etaxonomy.cdm.model.description.CategoricalData;
33
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
34
import eu.etaxonomy.cdm.model.description.Feature;
35
import eu.etaxonomy.cdm.model.description.QuantitativeData;
36
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
37
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
38
import eu.etaxonomy.cdm.persistence.dto.SpecimenNodeWrapper;
39
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
40
import eu.etaxonomy.taxeditor.model.DescriptionHelper;
41
import eu.etaxonomy.taxeditor.model.ImageResources;
42
import eu.etaxonomy.taxeditor.model.MessagingUtils;
43
import eu.etaxonomy.taxeditor.store.CdmStore;
44

  
45
/**
46
 * @author pplitzner
47
 * @since Jul 9, 2018
48
 *
49
 */
50
public class CharacterMatrixBottomToolbar extends Composite{
51

  
52
    private CharacterMatrix matrix;
53

  
54
    public CharacterMatrixBottomToolbar(CharacterMatrix matrix, int style) {
55
        super(matrix, style);
56
        this.matrix = matrix;
57

  
58
        init();
59
    }
60

  
61
    private void init() {
62

  
63
        setLayout(new RowLayout());
64
        GridDataFactory.fillDefaults().grab(true, false).applyTo(this);
65

  
66
        /**
67
         * Add description button
68
         */
69
        Button btnAddDescription = new Button(this, SWT.PUSH);
70
        btnAddDescription.setImage(ImageResources.getImage(ImageResources.ADD_ICON_GREEN));
71
        btnAddDescription.addSelectionListener(new SelectionAdapter() {
72
            @Override
73
            public void widgetSelected(SelectionEvent e) {
74
                SpecimenSelectionDialog dialog = new SpecimenSelectionDialog(matrix.getShell(), matrix);
75
                if(dialog.open()==Window.OK){
76
                    Collection<SpecimenNodeWrapper> wrappers = dialog.getSpecimen();
77
                    for (SpecimenNodeWrapper wrapper : wrappers) {
78
                        SpecimenOrObservationBase specimen = CdmStore.getService(IOccurrenceService.class).load(wrapper.getUuidAndTitleCache().getUuid());
79
                        SpecimenDescription description = getDescriptionForDescriptiveDataSet(specimen);
80
                        //description elements
81
                        Map<Feature, DescriptionElementBase> featureToElementMap = new HashMap<>();
82
                        Set<DescriptionElementBase> elements = description.getElements();
83
                        for (DescriptionElementBase descriptionElementBase : elements) {
84
                            Feature feature = descriptionElementBase.getFeature();
85
                            featureToElementMap.put(feature, descriptionElementBase);
86
                        }
87
                        RowWrapperDTO rowWrapper = CdmStore.getService(IDescriptiveDataSetService.class).createRowWrapper(description, matrix.getDescriptiveDataSet());
88
                        matrix.getDescriptions().add(rowWrapper);
89
                        matrix.getDescriptiveDataSet().addDescription(description);
90
                        matrix.setDirty();
91
                        matrix.getSpecimenCache().remove(wrapper);
92
                    }
93
                }
94
            }
95
        });
96
        /**
97
         * Remove description button
98
         */
99
        Button btnRemoveDescription = new Button(this, SWT.PUSH);
100
        btnRemoveDescription.setImage(ImageResources.getImage(ImageResources.ACTIVE_DELETE_ICON));
101
        btnRemoveDescription.addSelectionListener(new SelectionAdapter() {
102
            @Override
103
            public void widgetSelected(SelectionEvent e) {
104
                int[] fullySelectedRowPositions = matrix.getBodyLayer().getSelectionLayer().getFullySelectedRowPositions();
105
                List<RowWrapperDTO> toRemove = new ArrayList<>();
106
                for (int i : fullySelectedRowPositions) {
107
                    Object rowObject = matrix.getBodyDataProvider().getRowObject(i);
108
                    if(rowObject instanceof RowWrapperDTO){
109
                        toRemove.add((RowWrapperDTO) rowObject);
110
                    }
111
                }
112
                toRemove.forEach(rowToRemove->{
113
                    matrix.getDescriptions().remove(rowToRemove);
114
                    matrix.getDescriptiveDataSet().removeDescription(rowToRemove.getSpecimenDescription());
115
                    matrix.setDirty();
116
                });
117
            }
118
        });
119

  
120
    }
121
    private SpecimenDescription getDescriptionForDescriptiveDataSet(SpecimenOrObservationBase specimen){
122
        Set<Feature> wsFeatures = matrix.getDescriptiveDataSet().getDescriptiveSystem().getDistinctFeatures();
123
        List<DescriptionElementBase> matchingDescriptionElements = new ArrayList<>();
124

  
125
        for (SpecimenDescription specimenDescription : (Set<SpecimenDescription>) specimen.getDescriptions()) {
126
            specimenDescription = (SpecimenDescription) CdmStore.getService(IDescriptionService.class).load(specimenDescription.getUuid());
127
            Set<Feature> specimenDescriptionFeatures = new HashSet<>();
128
            //gather specimen description features and check for match with WS features
129
            for (DescriptionElementBase specimenDescriptionElement : specimenDescription.getElements()) {
130
                Feature feature = specimenDescriptionElement.getFeature();
131
                specimenDescriptionFeatures.add(feature);
132
                if(wsFeatures.contains(feature)){
133
                    matchingDescriptionElements.add(specimenDescriptionElement);
134
                }
135
            }
136
            //if description with the exact same features is found return the description
137
            if(specimenDescriptionFeatures.equals(wsFeatures)){
138
                return specimenDescription;
139
            }
140
        }
141
        //Create new specimen description if no match was found
142
        matrix.setDirty();
143
        SpecimenDescription newDesription = SpecimenDescription.NewInstance(specimen);
144
        newDesription.setTitleCache(Messages.CharacterMatrix_DESCRIPTIVE_DATA_SET+matrix.getDescriptiveDataSet().getLabel()+": "+newDesription.generateTitle(), true); //$NON-NLS-2$
145

  
146
        //check for equals description element (same feature and same values)
147
        Map<Feature, List<DescriptionElementBase>> featureToElementMap = new HashMap<>();
148
        for(DescriptionElementBase element:matchingDescriptionElements){
149
            List<DescriptionElementBase> list = featureToElementMap.get(element.getFeature());
150
            if(list==null){
151
                list = new ArrayList<>();
152
            }
153
            list.add(element);
154
            featureToElementMap.put(element.getFeature(), list);
155
        }
156
        Set<DescriptionElementBase> descriptionElementsToClone = new HashSet<>();
157
        for(Feature feature:featureToElementMap.keySet()){
158
            List<DescriptionElementBase> elements = featureToElementMap.get(feature);
159
            //no duplicate description elements found for this feature
160
            if(elements.size()==1){
161
                descriptionElementsToClone.add(elements.get(0));
162
            }
163
            //duplicates found -> check if all are equal
164
            else{
165
                DescriptionElementBase match = null;
166
                for (DescriptionElementBase descriptionElementBase : elements) {
167
                    if(match==null){
168
                        match = descriptionElementBase;
169
                    }
170
                    else if(!new DescriptionElementCompareWrapper(match).equals(new DescriptionElementCompareWrapper(descriptionElementBase))){
171
                        match = null;
172
                        MessagingUtils.informationDialog(Messages.CharacterMatrix_MULTIPLE_DATA,
173
                                String.format(Messages.CharacterMatrix_MULTIPLE_DATA_MESSAGE, feature.getLabel()));
174
                        break;
175
                    }
176
                }
177
                if(match!=null){
178
                    descriptionElementsToClone.add(match);
179
                }
180
            }
181
        }
182
        //clone matching descriptionElements
183
        for (DescriptionElementBase descriptionElementBase : descriptionElementsToClone) {
184
            DescriptionElementBase clone;
185
            try {
186
                clone = descriptionElementBase.clone(newDesription);
187
                clone.getSources().forEach(source -> source.setOriginalNameString(DescriptionHelper.getLabel(descriptionElementBase)));
188
            } catch (CloneNotSupportedException e) {
189
                MessagingUtils.error(CharacterMatrix.class, e);
190
            }
191
        }
192

  
193
        //add all remaining description elements to the new description
194
        for(Feature wsFeature:wsFeatures){
195
            boolean featureFound = false;
196
            for(DescriptionElementBase element:newDesription.getElements()){
197
                if(element.getFeature().equals(wsFeature)){
198
                    featureFound = true;
199
                    break;
200
                }
201
            }
202
            if(!featureFound){
203
                if(wsFeature.isSupportsCategoricalData()){
204
                    newDesription.addElement(CategoricalData.NewInstance(wsFeature));
205
                }
206
                else if(wsFeature.isSupportsQuantitativeData()){
207
                    newDesription.addElement(QuantitativeData.NewInstance(wsFeature));
208
                }
209
            }
210
        }
211
        return newDesription;
212

  
213
    }
214
}

Also available in: Unified diff