Project

General

Profile

Download (15.1 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.cdm.vaadin.view.name;
10

    
11
import java.util.EnumSet;
12
import java.util.HashSet;
13
import java.util.Iterator;
14
import java.util.Set;
15

    
16
import org.hibernate.Session;
17
import org.springframework.beans.factory.BeanFactory;
18
import org.springframework.beans.factory.annotation.Autowired;
19
import org.vaadin.viritin.fields.AbstractElementCollection;
20

    
21
import eu.etaxonomy.cdm.api.service.IRegistrationService;
22
import eu.etaxonomy.cdm.model.common.VersionableEntity;
23
import eu.etaxonomy.cdm.model.location.Country;
24
import eu.etaxonomy.cdm.model.name.Registration;
25
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
26
import eu.etaxonomy.cdm.model.name.TaxonName;
27
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
28
import eu.etaxonomy.cdm.model.occurrence.Collection;
29
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
30
import eu.etaxonomy.cdm.model.occurrence.DerivationEventType;
31
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
32
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
33
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
34
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
35
import eu.etaxonomy.cdm.model.reference.Reference;
36
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
37
import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider;
38
import eu.etaxonomy.cdm.service.CdmStore;
39
import eu.etaxonomy.cdm.service.IRegistrationWorkingSetService;
40
import eu.etaxonomy.cdm.service.RegistrationWorkingSetService;
41
import eu.etaxonomy.cdm.vaadin.component.CdmBeanItemContainerFactory;
42
import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityButtonUpdater;
43
import eu.etaxonomy.cdm.vaadin.model.TypedEntityReference;
44
import eu.etaxonomy.cdm.vaadin.model.registration.DerivationEventTypes;
45
import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationTermLists;
46
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationDTO;
47
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationWorkingSetDTO;
48
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
49
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
50
import eu.etaxonomy.cdm.vaadin.util.converter.TypeDesignationSetManager.TypeDesignationWorkingSet;
51
import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationDTO;
52
import eu.etaxonomy.vaadin.mvp.AbstractEditorPresenter;
53
import eu.etaxonomy.vaadin.ui.view.PopupEditorFactory;
54
/**
55
 * SpecimenTypeDesignationWorkingsetPopupEditorView implementation must override the showInEditor() method,
56
 * see {@link #prepareAsFieldGroupDataSource()} for details.
57
 *
58
 * @author a.kohlbecker
59
 * @since Jun 13, 2017
60
 *
61
 */
62
public class SpecimenTypeDesignationWorkingsetEditorPresenter
63
    extends AbstractEditorPresenter<SpecimenTypeDesignationWorkingSetDTO , SpecimenTypeDesignationWorkingsetPopupEditorView> {
64

    
65
    private static final long serialVersionUID = 4255636253714476918L;
66

    
67
    CdmStore<Registration, IRegistrationService> store;
68

    
69
    private Reference citation;
70

    
71
    private TaxonName typifiedName;
72

    
73
    /**
74
     * This object for this field will either be injected by the {@link PopupEditorFactory} or by a Spring
75
     * {@link BeanFactory}
76
     */
77
    @Autowired
78
    private IRegistrationWorkingSetService registrationWorkingSetService;
79

    
80
    /**
81
     * if not null, this CRUD set is to be used to create a CdmAuthoritiy for the base entitiy which will be
82
     * granted to the current use as long this grant is not assigned yet.
83
     */
84
    private EnumSet<CRUD> crud = null;
85

    
86
    protected CdmStore<Registration, IRegistrationService> getStore() {
87
        if(store == null){
88
            store = new CdmStore<>(getRepo(), getRepo().getRegistrationService());
89
        }
90
        return store;
91
    }
92

    
93

    
94
    /**
95
     * Loads an existing working set from the database. This process actually involves
96
     * loading the Registration specified by the <code>RegistrationAndWorkingsetId.registrationId</code> and in
97
     * a second step to find the workingset by the <code>registrationAndWorkingsetId.workingsetId</code>.
98
     * <p>
99
     * The <code>identifier</code> must be of the type {@link TypeDesignationWorkingsetEditorIdSet} whereas the field <code>egistrationId</code>
100
     * must be present, the field <code>workingsetId</code>,  however can be null. I this case a new workingset with a new {@link FieldUnit} as
101
     * base entity is being created.
102
     *
103
     * @param identifier a {@link TypeDesignationWorkingsetEditorIdSet}
104
     */
105
    @Override
106
    protected SpecimenTypeDesignationWorkingSetDTO loadBeanById(Object identifier) {
107

    
108
        SpecimenTypeDesignationWorkingSetDTO workingSetDto;
109
        if(identifier != null){
110

    
111
            TypeDesignationWorkingsetEditorIdSet idset = (TypeDesignationWorkingsetEditorIdSet)identifier;
112

    
113
            if(idset.workingsetId != null){
114
                RegistrationDTO regDTO = registrationWorkingSetService.loadDtoById(idset.registrationId);
115
                // find the working set
116
                TypeDesignationWorkingSet typeDesignationWorkingSet = regDTO.getTypeDesignationWorkingSet(idset.workingsetId);
117
                workingSetDto = regDTO.getSpecimenTypeDesignationWorkingSetDTO(typeDesignationWorkingSet.getBaseEntityReference());
118
                citation = (Reference) regDTO.getCitation();
119
            } else {
120
                // create a new workingset, for a new fieldunit which is the base for the workingset
121
                FieldUnit newfieldUnit = FieldUnit.NewInstance();
122
                Registration reg = getRepo().getRegistrationService().load(idset.registrationId,
123
                        RegistrationWorkingSetService.REGISTRATION_INIT_STRATEGY);
124
                //TODO checkif passing reg as owner parameter is needed at all
125
                workingSetDto = new SpecimenTypeDesignationWorkingSetDTO(reg, newfieldUnit, null);
126
                citation = getRepo().getReferenceService().find(idset.publicationId);
127
                typifiedName = getRepo().getNameService().find(idset.typifiedNameId);
128
            }
129

    
130
        } else {
131
            workingSetDto = null;
132
        }
133
        return workingSetDto;
134
    }
135

    
136

    
137
    /**
138
     * {@inheritDoc}
139
     */
140
    @SuppressWarnings("serial")
141
    @Override
142
    public void handleViewEntered() {
143

    
144
        CdmBeanItemContainerFactory selectFactory = new CdmBeanItemContainerFactory(getRepo());
145
        getView().getCountrySelectField().setContainerDataSource(selectFactory.buildBeanItemContainer(Country.uuidCountryVocabulary));
146

    
147
        getView().getTypeDesignationsCollectionField().setEditorInstantiator(new AbstractElementCollection.Instantiator<SpecimenTypeDesignationDTORow>() {
148

    
149
            CdmFilterablePagingProvider<Collection> collectionPagingProvider = new CdmFilterablePagingProvider<Collection>(getRepo().getCollectionService());
150

    
151
            CdmFilterablePagingProvider<Reference> referencePagingProvider = new CdmFilterablePagingProvider<Reference>(getRepo().getReferenceService());
152

    
153
            @Override
154
            public SpecimenTypeDesignationDTORow create() {
155

    
156
                SpecimenTypeDesignationDTORow row = new SpecimenTypeDesignationDTORow();
157

    
158
                row.derivationEventType.setContainerDataSource(selectFactory.buildTermItemContainer(
159
                        RegistrationTermLists.DERIVATION_EVENT_TYPE_UUIDS())
160
                        );
161
                row.derivationEventType.setNullSelectionAllowed(false);
162

    
163
                row.derivationEventType.addValueChangeListener(e -> {
164
                    SpecimenTypeDesignationDTORow currentRow = row;
165
                    updateRowItemEnablement(currentRow);
166
                });
167

    
168
                row.typeStatus.setContainerDataSource(selectFactory.buildTermItemContainer(
169
                        RegistrationTermLists.SPECIMEN_TYPE_DESIGNATION_STATUS_UUIDS())
170
                        );
171
                row.typeStatus.setNullSelectionAllowed(false);
172

    
173

    
174
                row.collection.loadFrom(
175
                        collectionPagingProvider,
176
                        collectionPagingProvider,
177
                        collectionPagingProvider.getPageSize()
178
                        );
179
                row.collection.getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Collection>());
180
                row.collection.getSelect().addValueChangeListener(new ToOneRelatedEntityButtonUpdater<Collection>(row.collection));
181

    
182
                row.mediaSpecimenReference.loadFrom(
183
                        referencePagingProvider,
184
                        referencePagingProvider,
185
                        collectionPagingProvider.getPageSize()
186
                        );
187
                row.mediaSpecimenReference.getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
188
                row.mediaSpecimenReference.getSelect().addValueChangeListener(new ToOneRelatedEntityButtonUpdater<Reference>(row.mediaSpecimenReference));
189

    
190
                getView().applyDefaultComponentStyle(row.components());
191

    
192
                updateRowItemEnablement(row);
193

    
194
                return row;
195
            }
196

    
197
            private void updateRowItemEnablement(SpecimenTypeDesignationDTORow row) {
198

    
199
                DerivationEventType derivationEventType = (DerivationEventType)row.derivationEventType.getValue();
200

    
201
                boolean publishedImageType = derivationEventType != null && derivationEventType.equals(DerivationEventTypes.PUBLISHED_IMAGE());
202
                boolean unPublishedImageType = derivationEventType != null && derivationEventType.equals(DerivationEventTypes.UNPUBLISHED_IMAGE());
203

    
204
                row.mediaSpecimenReference.setEnabled(publishedImageType);
205
                row.mediaSpecimenReferenceDetail.setEnabled(publishedImageType);
206
                row.mediaUri.setEnabled(unPublishedImageType);
207

    
208
            }
209
        });
210
    }
211

    
212
    /**
213
     * {@inheritDoc}
214
     *
215
     * see also {@link SpecimenTypeDesignationWorkingsetPopupEditor#showInEditor()}
216
     */
217
    @Override
218
    protected SpecimenTypeDesignationWorkingSetDTO prepareAsFieldGroupDataSource(SpecimenTypeDesignationWorkingSetDTO bean) {
219

    
220
        if(bean.getFieldUnit() == null){
221
            // in case the base unit of the working set is not a FieldUnit all contained TypeDesignations must be modified
222
            // so that they are based on an empty FieldUnit with an associated Gathering Event
223
            if(Registration.class.isAssignableFrom(bean.getOwner().getClass())){
224
                // FIXME open Dialog to warn user about adding an empty fieldUnit to the typeDesignations
225
                logger.info("Basing all typeDesignations on a new fieldUnit");
226
                Session session = getSession();
227
                Registration reg = getRepo().getRegistrationService().find(bean.getOwner().getId());
228
                RegistrationDTO regDTO = new RegistrationDTO(reg);
229

    
230
                FieldUnit fieldUnit = FieldUnit.NewInstance();
231
                GatheringEvent gatheringEvent = GatheringEvent.NewInstance();
232
                fieldUnit.setGatheringEvent(gatheringEvent);
233
                getRepo().getOccurrenceService().save(fieldUnit);
234

    
235
                VersionableEntity baseEntity = bean.getBaseEntity();
236
                Set<TypeDesignationBase> typeDesignations = regDTO.getTypeDesignationsInWorkingSet(
237
                        new TypedEntityReference(baseEntity.getClass(), baseEntity.getId(), baseEntity.toString())
238
                        );
239
                for(TypeDesignationBase td : typeDesignations){
240
                    DerivationEvent de = DerivationEvent.NewInstance();//
241
                    de.addOriginal(fieldUnit);
242
                    de.addDerivative(((SpecimenTypeDesignation)td).getTypeSpecimen());
243
                    de.setType(DerivationEventType.GATHERING_IN_SITU());
244
                }
245

    
246
                getRepo().getRegistrationService().saveOrUpdate(reg);
247
                session.flush();
248
                session.close();
249
            } else {
250
                throw new RuntimeException("Usupported owner type " + bean.getOwner().getClass() + ", needs to be implemented.");
251
            }
252
        }
253
        return super.prepareAsFieldGroupDataSource(bean);
254
    }
255

    
256

    
257

    
258
    /**
259
     * {@inheritDoc}
260
     */
261
    @Override
262
    protected void saveBean(SpecimenTypeDesignationWorkingSetDTO dto) {
263

    
264
        Registration reg = (Registration) dto.getOwner();
265

    
266
        // associate all type designations with the fieldUnit
267
        // 1. new ones are not yet associated
268
        // 2. ones which had incomplete data are also not connected
269
        for(SpecimenTypeDesignationDTO stdDTO : dto.getSpecimenTypeDesignationDTOs()){
270
            try {
271
                SpecimenOrObservationBase<?> original = findEarliestOriginal(stdDTO.asSpecimenTypeDesignation().getTypeSpecimen());
272
                if(original instanceof DerivedUnit){
273
                    DerivedUnit du = (DerivedUnit)original;
274
                    du.getDerivedFrom().addOriginal(dto.getFieldUnit());
275
                }
276
            } catch (Exception e) {
277
                // TODO Auto-generated catch block
278
                e.printStackTrace();
279
            }
280
        }
281

    
282
        // add newly added typeDesignations
283
        Set<SpecimenTypeDesignation> addCandidates = new HashSet<>();
284
        for(SpecimenTypeDesignationDTO stdDTO : dto.getSpecimenTypeDesignationDTOs()){
285
            SpecimenTypeDesignation std = stdDTO.asSpecimenTypeDesignation();
286
            if(reg.getTypeDesignations().isEmpty() || !reg.getTypeDesignations().stream().filter(td -> td.equals(std)).findFirst().isPresent()){
287
                std.setCitation(citation);
288
                typifiedName.addTypeDesignation(std, false);
289
                addCandidates.add(std);
290
            }
291
        }
292
        addCandidates.forEach(std -> reg.addTypeDesignation(std));
293

    
294

    
295
        if(crud != null){
296
            UserHelper.fromSession().createAuthorityForCurrentUser(dto.getFieldUnit(), crud, null);
297
        }
298

    
299
        getStore().saveBean(reg);
300
    }
301

    
302
    /**
303
     * {@inheritDoc}
304
     */
305
    @Override
306
    protected void deleteBean(SpecimenTypeDesignationWorkingSetDTO bean) {
307
        // TODO Auto-generated method stub
308

    
309
    }
310

    
311

    
312
    /**
313
     * @param std
314
     * @return
315
     * @throws Exception
316
     */
317
    private SpecimenOrObservationBase<?> findEarliestOriginal(DerivedUnit du) throws Exception {
318

    
319
        SpecimenOrObservationBase original = du;
320

    
321
        while(du != null && du.getDerivedFrom() != null && !du.getDerivedFrom().getOriginals().isEmpty()) {
322
            Iterator<SpecimenOrObservationBase> it = du.getDerivedFrom().getOriginals().iterator();
323
            SpecimenOrObservationBase nextOriginal = it.next();
324
            if(nextOriginal == null){
325
                break;
326
            }
327
            original = nextOriginal;
328
            if(original instanceof DerivedUnit){
329
                du = (DerivedUnit)original;
330
            } else {
331
                // so this must be a FieldUnit,
332
               break;
333
            }
334
            if(it.hasNext()){
335
                throw new Exception(String.format("%s has more than one originals", du.toString()));
336
            }
337
        }
338
        return original;
339
    }
340

    
341

    
342
    /**
343
     * @param crud
344
     */
345
    public void setGrantsForCurrentUser(EnumSet<CRUD> crud) {
346
        this.crud = crud;
347

    
348
    }
349

    
350

    
351
}
(2-2/8)