Project

General

Profile

Download (9.15 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2017 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.io.File;
12
import java.io.FileOutputStream;
13
import java.io.IOException;
14
import java.util.Arrays;
15
import java.util.Collection;
16
import java.util.Collections;
17
import java.util.HashMap;
18
import java.util.HashSet;
19
import java.util.List;
20
import java.util.Map;
21
import java.util.UUID;
22

    
23
import javax.annotation.PostConstruct;
24
import javax.annotation.PreDestroy;
25
import javax.inject.Inject;
26

    
27
import org.eclipse.core.runtime.IProgressMonitor;
28
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
29
import org.eclipse.e4.core.contexts.IEclipseContext;
30
import org.eclipse.e4.ui.di.Focus;
31
import org.eclipse.e4.ui.di.Persist;
32
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
33
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
34
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
35
import org.eclipse.nebula.widgets.nattable.NatTable;
36
import org.eclipse.swt.SWT;
37
import org.eclipse.swt.custom.StackLayout;
38
import org.eclipse.swt.widgets.Composite;
39
import org.eclipse.swt.widgets.Label;
40

    
41
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
42
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
43
import eu.etaxonomy.cdm.api.service.IDescriptionService;
44
import eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService;
45
import eu.etaxonomy.cdm.api.service.UpdateResult;
46
import eu.etaxonomy.cdm.api.service.dto.RowWrapperDTO;
47
import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
48
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
49
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
50
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
51
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
52
import eu.etaxonomy.taxeditor.model.MessagingUtils;
53
import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
54
import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
55
import eu.etaxonomy.taxeditor.store.CdmStore;
56
import eu.etaxonomy.taxeditor.workbench.WorkbenchUtility;
57
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
58

    
59
/**
60
 * Character matrix editor for editing specimen/taxon descriptions in a table
61
 * @author pplitzner
62
 * @since Nov 26, 2017
63
 *
64
 */
65
public class CharacterMatrixPart implements IE4SavablePart, IConversationEnabled, IDirtyMarkable,
66
ICdmEntitySessionEnabled{
67

    
68
    private static final List<String> WS_PROPERTY_PATH = Arrays.asList(new String[] {
69
            "descriptions", //$NON-NLS-1$
70
            "descriptions.describedSpecimenOrObservation", //$NON-NLS-1$
71
            "descriptions.describedSpecimenOrObservation.gatheringEvent", //$NON-NLS-1$
72
            "descriptions.describedSpecimenOrObservation.gatheringEvent.actor", //$NON-NLS-1$
73
            "descriptions.descriptionElements", //$NON-NLS-1$
74
            "descriptions.descriptionElements.stateData", //$NON-NLS-1$
75
            "descriptions.descriptionElements.stateData.state", //$NON-NLS-1$
76
            "descriptions.descriptionElements.inDescription", //$NON-NLS-1$
77
            "descriptions.descriptionElements.inDescription.descriptionElements", //$NON-NLS-1$
78
            "descriptions.descriptionElements.feature", //$NON-NLS-1$
79
            "representations", //$NON-NLS-1$
80
            "descriptiveSystem", //$NON-NLS-1$
81
            "taxonSubtreeFilter", //$NON-NLS-1$
82
            "taxonSubtreeFilter.parent", //$NON-NLS-1$
83
            "taxonSubtreeFilter.classification", //$NON-NLS-1$
84
            "taxonSubtreeFilter.taxon", //$NON-NLS-1$
85
            "taxonSubtreeFilter.taxon.name", //$NON-NLS-1$
86
            "taxonSubtreeFilter.taxon.name.rank", //$NON-NLS-1$
87
            "geoFilter", //$NON-NLS-1$
88
            "minRank", //$NON-NLS-1$
89
            "maxRank", //$NON-NLS-1$
90
    });
91

    
92
    private static final String CHARACTER_MATRIX_STATE_PROPERTIES = "characterMatrixState.properties"; //$NON-NLS-1$
93

    
94
    private DescriptiveDataSet descriptiveDataSet;
95

    
96
    private Collection<UpdateResult> updateResults;
97

    
98
    private ConversationHolder conversation;
99

    
100
    private ICdmEntitySession cdmEntitySession;
101

    
102
    @Inject
103
    private ESelectionService selService;
104

    
105
    @Inject
106
    private MDirtyable dirty;
107

    
108
    @Inject
109
    private MPart thisPart;
110

    
111
    private CharacterMatrix matrix;
112

    
113
    private StackLayout stackLayout;
114

    
115
    @PostConstruct
116
    public void create(Composite parent, IEclipseContext context) {
117
        if(CdmStore.isActive() && conversation==null){
118
            conversation = CdmStore.createConversation();
119
        }
120
        if(cdmEntitySession == null){
121
            cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
122
        }
123
        else{
124
            return;
125
        }
126
        stackLayout = new StackLayout();
127
        parent.setLayout(stackLayout);
128
        matrix = new CharacterMatrix(parent, this);
129
        Label label = new Label(parent, SWT.NONE);
130
        label.setText("Loading matrix...");
131
        stackLayout.topControl = label;
132
        ContextInjectionFactory.inject(matrix, context);
133
    }
134

    
135
    public void init(UUID descriptiveDataSetUuid, boolean treeView) {
136
        this.descriptiveDataSet = CdmStore.getService(IDescriptiveDataSetService.class).load(descriptiveDataSetUuid, WS_PROPERTY_PATH);
137
        if(descriptiveDataSet!=null){
138
            if(descriptiveDataSet.getDescriptiveSystem()==null){
139
                MessagingUtils.informationDialog(Messages.CharacterMatrixPart_COULD_NOT_OPEN, Messages.CharacterMatrixPart_COULD_NOT_OPEN_MESSAGE);
140
                return;
141
            }
142
            matrix.initDescriptiveDataSet(descriptiveDataSet);
143
            matrix.createTable(treeView, true);
144
            thisPart.setLabel(descriptiveDataSet.getLabel());
145
            matrix.loadDescriptions(descriptiveDataSet);
146
        }
147
    }
148

    
149
    public void setDirty() {
150
        this.dirty.setDirty(true);
151
    }
152

    
153
    public DescriptiveDataSet getDescriptiveDataSet() {
154
        return descriptiveDataSet;
155
    }
156

    
157
    private File getStatePropertiesFile() {
158
        return new File(WorkbenchUtility.getBaseLocation(), CHARACTER_MATRIX_STATE_PROPERTIES);
159
    }
160

    
161
    public NatTable getNatTable() {
162
        return matrix.getNatTable();
163
    }
164

    
165
    public ESelectionService getSelectionService() {
166
        return selService;
167
    }
168

    
169
    @Persist
170
    @Override
171
    public void save(IProgressMonitor monitor) {
172
        //save descriptions
173
        matrix.getDescriptions().stream()
174
        .filter(o->o instanceof RowWrapperDTO)
175
        .forEach(wrapper->save((RowWrapperDTO)wrapper));
176
        //save data set
177
        CdmStore.getService(IDescriptiveDataSetService.class).merge(descriptiveDataSet);
178

    
179
        //save update results (taxon with aggregated description)
180
        if(updateResults!=null){
181
            updateResults.forEach(result->
182
            CdmStore.getService(result.getCdmEntity()).merge(result.getCdmEntity()));
183
        }
184

    
185
        conversation.commit();
186
        updateResults = null;
187
        dirty.setDirty(false);
188
    }
189

    
190
    private void save(RowWrapperDTO wrapper){
191
        CdmStore.getService(IDescriptionService.class).merge(wrapper.getSpecimenDescription());
192
    }
193

    
194
    @Focus
195
    public void setFocus(){
196
        if(conversation!=null){
197
            conversation.bind();
198
        }
199
        if(cdmEntitySession != null) {
200
            cdmEntitySession.bind();
201
        }
202
    }
203

    
204
    @PreDestroy
205
    public void dispose(){
206
        if (conversation != null) {
207
            conversation.close();
208
            conversation = null;
209
        }
210
        if(cdmEntitySession != null) {
211
            cdmEntitySession.dispose();
212
            cdmEntitySession = null;
213
        }
214
        dirty.setDirty(false);
215
        if(matrix.getNatTableState()!=null){
216
            try (FileOutputStream tableStateStream =
217
                    new FileOutputStream(getStatePropertiesFile())) {
218
                matrix.getNatTableState().store(tableStateStream, null);
219
            } catch (IOException ioe) {
220
                ioe.printStackTrace();
221
            }
222
        }
223
    }
224

    
225
    @Override
226
    public void update(CdmDataChangeMap arg0) {
227
    }
228

    
229
    @Override
230
    public ConversationHolder getConversationHolder() {
231
        return conversation;
232
    }
233

    
234
    @Override
235
    public void changed(Object element) {
236
        setDirty();
237
        matrix.getNatTable().refresh();
238
    }
239

    
240
    @Override
241
    public void forceDirty() {
242
        setDirty();
243
    }
244

    
245
    @Override
246
    public ICdmEntitySession getCdmEntitySession() {
247
        return cdmEntitySession;
248
    }
249

    
250
    @Override
251
    public Collection<DescriptiveDataSet> getRootEntities() {
252
        return Collections.singleton(this.descriptiveDataSet);
253
    }
254

    
255
    @Override
256
    public Map<Object, List<String>> getPropertyPathsMap() {
257
        Map<Object, List<String>> propertyMap = new HashMap<>();
258
        propertyMap.put(SpecimenOrObservationBase.class,WS_PROPERTY_PATH);
259
        return propertyMap;
260
    }
261

    
262
    public void addUpdateResult(UpdateResult result){
263
        if(updateResults==null){
264
            updateResults = new HashSet<>();
265
        }
266
        updateResults.add(result);
267
    }
268

    
269
    public void loadingDone() {
270
        stackLayout.topControl = matrix;
271
        matrix.getParent().layout();
272
    }
273

    
274
}
(11-11/20)