Project

General

Profile

« Previous | Next » 

Revision 4fbf8f87

Added by Patrick Plitzner over 4 years ago

ref #7095 Add non-editable additional columns with extra info to matrix

View differences:

eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/CharacterMatrix.java
11 11
import java.util.ArrayList;
12 12
import java.util.Collection;
13 13
import java.util.Collections;
14
import java.util.HashMap;
14 15
import java.util.List;
16
import java.util.Map;
15 17
import java.util.Set;
16 18
import java.util.UUID;
17 19

  
......
19 21
import javax.annotation.PreDestroy;
20 22
import javax.inject.Inject;
21 23

  
24
import org.apache.commons.collections4.map.LinkedMap;
22 25
import org.eclipse.core.runtime.IProgressMonitor;
23 26
import org.eclipse.e4.ui.di.Focus;
24 27
import org.eclipse.e4.ui.di.Persist;
......
79 82
import eu.etaxonomy.cdm.model.description.DescriptionBase;
80 83
import eu.etaxonomy.cdm.model.description.Feature;
81 84
import eu.etaxonomy.cdm.model.description.FeatureTree;
85
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
82 86
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
83 87
import eu.etaxonomy.cdm.model.description.State;
84 88
import eu.etaxonomy.cdm.model.description.WorkingSet;
......
89 93
import eu.etaxonomy.taxeditor.editor.workingSet.matrix.quantitative.QuantitativeDataDisplayConverter;
90 94
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
91 95
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
96
import eu.etaxonomy.taxeditor.model.MessagingUtils;
92 97
import eu.etaxonomy.taxeditor.store.CdmStore;
93 98
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
94 99

  
......
99 104
 */
100 105
public class CharacterMatrix implements IE4SavablePart, IPartContentHasDetails, IConversationEnabled, IDirtyMarkable{
101 106

  
107
    private static final int LEADING_COLUMN_COUNT = 4;
108
    private static final String TAXON_COLUMN = "taxon_column";
109
    private static final String COLLECTOR_COLUMN = "collector_column";
110
    private static final String IDENTIFIER_COLUMN = "identifier_column";
111
    private static final String COUNTRY_COLUMN = "country_column";
112

  
102 113
    private WorkingSet workingSet;
103 114

  
104 115
    private Composite parent;
......
116 127

  
117 128
    private NatTable natTable;
118 129

  
119
    private List<Feature> features;
130
    private Map<Integer, Feature> indexToFeatureMap = new HashMap<>();
131

  
132
    private LinkedMap<String, String> propertyToLabelMap = new LinkedMap<>();
120 133

  
121 134
    @PostConstruct
122 135
    public void create(Composite parent) {
......
137 150

  
138 151
        //get features/columns stored in working set
139 152
        FeatureTree tree = workingSet.getDescriptiveSystem();
140
        features = new ArrayList<>(tree.getDistinctFeatures());
153
        List<Feature> features = new ArrayList<>(tree.getDistinctFeatures());
141 154
        Collections.sort(features);
142 155

  
143 156

  
......
147 160
        /**
148 161
         * data provider
149 162
         */
150
        SpecimenColumnPropertyAccessor columnPropertyAccessor = new SpecimenColumnPropertyAccessor(features);
163
        SpecimenColumnPropertyAccessor columnPropertyAccessor = new SpecimenColumnPropertyAccessor(this);
151 164
        IDataProvider bodyDataProvider = new ListDataProvider<SpecimenDescription>(sortedList, columnPropertyAccessor);
152 165

  
153 166
        /**
......
156 169
        DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);
157 170
        final ColumnOverrideLabelAccumulator columnLabelAccumulator =new ColumnOverrideLabelAccumulator(bodyDataLayer);
158 171
        bodyDataLayer.setConfigLabelAccumulator(columnLabelAccumulator);
159
        registerColumnLabels(columnLabelAccumulator);
172
        for(int i=0;i<features.size();i++){
173
            Feature feature = features.get(i);
174
            initLabels(features, columnLabelAccumulator, i, feature);
175
        }
160 176
        GlazedListsEventLayer<SpecimenDescription> eventLayer = new GlazedListsEventLayer<>(bodyDataLayer, sortedList);
161 177

  
162 178
        RowReorderLayer rowReorderLayer = new RowReorderLayer(eventLayer);
......
168 184
         * column header layer
169 185
         */
170 186
        IDataProvider columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(
171
                columnPropertyAccessor.getPropertyToLabelMap().values().toArray(new String[] {}), columnPropertyAccessor.getPropertyToLabelMap());
187
                propertyToLabelMap.values().toArray(new String[] {}), propertyToLabelMap);
172 188
        DataLayer columnHeaderDataLayer = new DataLayer(columnHeaderDataProvider);
173 189
        ILayer columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, viewportLayer, selectionLayer);
174 190

  
......
221 237
        natTable.addConfiguration(new SingleClickSortConfiguration());
222 238

  
223 239

  
224
        // add custom configuration for data conversion
240
        // add custom configuration for data conversion and add column labels for each feature
225 241
        viewportLayer.addConfiguration(new AbstractRegistryConfiguration() {
226 242
            @Override
227 243
            public void configureRegistry(IConfigRegistry configRegistry) {
228
                features.forEach(feature -> registerColumnConfiguration(feature, configRegistry));
229
                }
244
                features.forEach(feature->registerColumnConfiguration(feature, configRegistry));
230 245
            }
231
        );
246

  
247
        });
232 248

  
233 249
        // add the ExportCommandHandler to the ViewportLayer in order to make
234 250
        // exporting work
......
269 285
        parent.layout();
270 286
    }
271 287

  
272
    private void registerColumnLabels(ColumnOverrideLabelAccumulator columnLabelAccumulator) {
273
        for(int i=0;i<features.size();i++){
274
            columnLabelAccumulator.registerColumnOverrides(i, getProperty(features.get(i)));
288
    private void initLabels(List<Feature> features, final ColumnOverrideLabelAccumulator columnLabelAccumulator,
289
            int index, Feature feature) {
290

  
291
        propertyToLabelMap.put(TAXON_COLUMN, "Taxon");
292
        propertyToLabelMap.put(COLLECTOR_COLUMN, "Collector + No");
293
        propertyToLabelMap.put(IDENTIFIER_COLUMN, "Identifier");
294
        propertyToLabelMap.put(COUNTRY_COLUMN, "Country");
295

  
296
        columnLabelAccumulator.registerColumnOverrides(index+LEADING_COLUMN_COUNT, getProperty(features.get(index)));
297
        indexToFeatureMap.put(index+LEADING_COLUMN_COUNT, feature);
298

  
299
        String featureLabel = feature.getLabel();
300
        String property = featureLabel;
301
        //show unit for quantitative data
302
        if(feature.isSupportsQuantitativeData()){
303
            Set<MeasurementUnit> recommendedMeasurementUnits = feature.getRecommendedMeasurementUnits();
304
            if(recommendedMeasurementUnits.size()!=1){
305
                MessagingUtils.error(SpecimenColumnPropertyAccessor.class, "Only one unit is allowed for quantitative data", null);
306
                return;
307
            }
308
            MeasurementUnit unit = recommendedMeasurementUnits.iterator().next();
309
            featureLabel += " ["+unit.getLabel()+"]";
275 310
        }
311
        propertyToLabelMap.put(property, featureLabel);
276 312
    }
277 313

  
278 314
    private void registerColumnConfiguration(Feature feature, IConfigRegistry configRegistry) {
......
311 347
                @Override
312 348
                public List<?> getValues(int columnIndex, int rowIndex) {
313 349
                    List<State> states = new ArrayList<>();
314
                    Feature feature = features.get(columnIndex);
350
                    Feature feature = indexToFeatureMap.get(columnIndex);
315 351
                    if(feature.isSupportsCategoricalData()){
316 352
                        Set<TermVocabulary<State>> stateVocs = feature.getSupportedCategoricalEnumerations();
317 353
                        for (TermVocabulary<State> voc : stateVocs) {
......
342 378
        return descriptions;
343 379
    }
344 380

  
345
    public List<Feature> getFeatures() {
346
        return features;
347
    }
348

  
349 381
    private String getProperty(Feature feature){
350 382
        return feature.getLabel();
351 383
    }
352 384

  
385
    public Map<Integer, Feature> getIndexToFeatureMap() {
386
        return indexToFeatureMap;
387
    }
388

  
389
    public LinkedMap<String, String> getPropertyToLabelMap() {
390
        return propertyToLabelMap;
391
    }
392

  
353 393
    public void setDirty() {
354 394
        this.dirty.setDirty(true);
355 395
    }
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/SpecimenColumnPropertyAccessor.java
11 11
import java.util.ArrayList;
12 12
import java.util.Collection;
13 13
import java.util.List;
14
import java.util.Map;
15 14
import java.util.Set;
16 15

  
17
import org.apache.commons.collections4.map.LinkedMap;
18 16
import org.eclipse.nebula.widgets.nattable.data.IColumnPropertyAccessor;
19 17

  
18
import eu.etaxonomy.cdm.api.service.IOccurrenceService;
19
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
20 20
import eu.etaxonomy.cdm.model.description.CategoricalData;
21 21
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
22 22
import eu.etaxonomy.cdm.model.description.Feature;
23
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
24 23
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
25 24
import eu.etaxonomy.cdm.model.description.State;
26 25
import eu.etaxonomy.cdm.model.description.StateData;
27
import eu.etaxonomy.taxeditor.model.MessagingUtils;
26
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
27
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
28
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
29
import eu.etaxonomy.taxeditor.store.CdmStore;
28 30

  
29 31
/**
30 32
 * @author pplitzner
......
33 35
 */
34 36
public class SpecimenColumnPropertyAccessor implements IColumnPropertyAccessor<SpecimenDescription>{
35 37

  
36
    private final List<Feature> features;
37
    private LinkedMap<String, String> propertyToLabelMap = new LinkedMap<>();
38

  
39

  
40
    public SpecimenColumnPropertyAccessor(final List<Feature> features) {
41
        this.features = features;
42
        for (Feature feature : features) {
43
            String featureLabel = feature.getLabel();
44
            String property = featureLabel;
45
            //show unit for quantitative data
46
            if(feature.isSupportsQuantitativeData()){
47
                Set<MeasurementUnit> recommendedMeasurementUnits = feature.getRecommendedMeasurementUnits();
48
                if(recommendedMeasurementUnits.size()!=1){
49
                    MessagingUtils.error(SpecimenColumnPropertyAccessor.class, "Only one unit is allowed for quantitative data", null);
50
                    continue;
51
                }
52
                MeasurementUnit unit = recommendedMeasurementUnits.iterator().next();
53
                featureLabel += " ["+unit.getLabel()+"]";
54
            }
55
            propertyToLabelMap.put(property, featureLabel);
56
        }
57
    }
38
    private CharacterMatrix matrix;
58 39

  
59
    public Map<String, String> getPropertyToLabelMap() {
60
        return propertyToLabelMap;
40
    public SpecimenColumnPropertyAccessor(CharacterMatrix matrix) {
41
        this.matrix = matrix;
61 42
    }
62 43

  
44

  
63 45
    /**
64 46
     * {@inheritDoc}
65 47
     */
66 48
    @Override
67
    public DescriptionElementBase getDataValue(SpecimenDescription rowObject, int columnIndex) {
68
        Feature feature = features.get(columnIndex);
49
    public Object getDataValue(SpecimenDescription rowObject, int columnIndex) {
50
        IOccurrenceService occurrenceService = CdmStore.getService(IOccurrenceService.class);
51
        SpecimenOrObservationBase<?> specimen = rowObject.getDescribedSpecimenOrObservation();
52
        Collection<FieldUnit> fieldUnits = occurrenceService.getFieldUnits(specimen.getUuid());
53
        switch (columnIndex) {
54
        case 0:
55
            return occurrenceService.listAssociatedTaxa(specimen, null, null, null, null);
56
        case 1:
57
            if(fieldUnits.size()!=1){
58
                return "More than one or no field unit found for specimen";
59
            }
60
            return fieldUnits.iterator().next();
61
        case 2:
62
            if(specimen instanceof DerivedUnit){
63
                return occurrenceService.getMostSignificantIdentifier(HibernateProxyHelper.deproxy(specimen, DerivedUnit.class));
64
            }
65
            return null;
66
        case 3:
67
            if(fieldUnits.size()!=1){
68
                return "More than one or no field unit found for specimen";
69
            }
70
            FieldUnit fieldUnit = fieldUnits.iterator().next();
71
            if(fieldUnit.getGatheringEvent()!=null){
72
                return fieldUnit.getGatheringEvent().getCountry();
73
            }
74
            return null;
75

  
76
        default:
77
            break;
78
        }
79
        Feature feature = matrix.getIndexToFeatureMap().get(columnIndex);
69 80
        Set<DescriptionElementBase> elements = rowObject.getElements();
70 81
        for (DescriptionElementBase descriptionElementBase : elements) {
71 82
            if(descriptionElementBase.getFeature().equals(feature)){
......
80 91
     */
81 92
    @Override
82 93
    public void setDataValue(SpecimenDescription rowObject, int columnIndex, Object newValue) {
83
        Feature feature = features.get(columnIndex);
94
        Feature feature = matrix.getIndexToFeatureMap().get(columnIndex);
84 95
        Set<DescriptionElementBase> elements = rowObject.getElements();
85 96
        for (DescriptionElementBase descriptionElementBase : elements) {
86 97
            if(descriptionElementBase.getFeature().equals(feature)){
87
                setDescriptionElement(rowObject, descriptionElementBase, feature, newValue);
98
                setDescriptionElement(descriptionElementBase, feature, newValue);
88 99
            }
89 100
        }
90 101
    }
91 102

  
92 103

  
93
    private void setDescriptionElement(SpecimenDescription description, DescriptionElementBase descriptionElementBase, Feature feature, Object newValue) {
104
    private void setDescriptionElement(DescriptionElementBase descriptionElementBase, Feature feature, Object newValue) {
94 105
        //FIXME move this to cdmlib service layer
95 106
        if(feature.isSupportsCategoricalData() && descriptionElementBase instanceof CategoricalData && newValue instanceof Collection){
96 107
            CategoricalData categoricalData = (CategoricalData)descriptionElementBase;
......
110 121
     */
111 122
    @Override
112 123
    public int getColumnCount() {
113
        return features.size();
124
        return matrix.getPropertyToLabelMap().size();
114 125
    }
115 126

  
116 127
    /**
......
118 129
     */
119 130
    @Override
120 131
    public String getColumnProperty(int columnIndex) {
121
        return features.get(columnIndex).getLabel();
132
        return matrix.getPropertyToLabelMap().get(columnIndex);
122 133
    }
123 134

  
124 135
    /**
......
126 137
     */
127 138
    @Override
128 139
    public int getColumnIndex(String propertyName){
129
        return propertyToLabelMap.indexOf(propertyName);
140
        return matrix.getPropertyToLabelMap().indexOf(propertyName);
130 141
    }
131 142

  
132 143
}
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/categorical/CategoricalDataDisplayConverter.java
32 32
        else if(canonicalValue instanceof State){
33 33
            return ((State) canonicalValue).getLabel();
34 34
        }
35
        return canonicalValue.toString();
35
        else if(canonicalValue!=null){
36
            return canonicalValue.toString();
37
        }
38
        return null;
36 39
    }
37 40

  
38 41
    /**

Also available in: Unified diff