Project

General

Profile

Download (19 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.Arrays;
12
import java.util.EnumSet;
13
import java.util.HashMap;
14
import java.util.HashSet;
15
import java.util.Map;
16
import java.util.Set;
17
import java.util.Stack;
18

    
19
import org.springframework.beans.factory.DisposableBean;
20
import org.springframework.beans.factory.annotation.Autowired;
21
import org.springframework.context.annotation.Scope;
22
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
23
import org.vaadin.viritin.fields.AbstractElementCollection;
24

    
25
import com.vaadin.spring.annotation.SpringComponent;
26

    
27
import eu.etaxonomy.cdm.api.service.IRegistrationService;
28
import eu.etaxonomy.cdm.cache.CdmTransientEntityAndUuidCacher;
29
import eu.etaxonomy.cdm.model.ICdmEntityUuidCacher;
30
import eu.etaxonomy.cdm.model.agent.AgentBase;
31
import eu.etaxonomy.cdm.model.agent.Person;
32
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
33
import eu.etaxonomy.cdm.model.common.CdmBase;
34
import eu.etaxonomy.cdm.model.location.Country;
35
import eu.etaxonomy.cdm.model.name.Registration;
36
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
37
import eu.etaxonomy.cdm.model.occurrence.Collection;
38
import eu.etaxonomy.cdm.model.reference.Reference;
39
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
40
import eu.etaxonomy.cdm.persistence.dao.common.Restriction.Operator;
41
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
42
import eu.etaxonomy.cdm.persistence.query.MatchMode;
43
import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider;
44
import eu.etaxonomy.cdm.service.CdmFilterablePagingProviderFactory;
45
import eu.etaxonomy.cdm.service.CdmStore;
46
import eu.etaxonomy.cdm.service.ISpecimenTypeDesignationWorkingSetService;
47
import eu.etaxonomy.cdm.service.UserHelperAccess;
48
import eu.etaxonomy.cdm.service.initstrategies.AgentBaseInit;
49
import eu.etaxonomy.cdm.vaadin.component.CdmBeanItemContainerFactory;
50
import eu.etaxonomy.cdm.vaadin.component.CollectionRowItemCollection;
51
import eu.etaxonomy.cdm.vaadin.event.EditorActionContext;
52
import eu.etaxonomy.cdm.vaadin.event.EntityChangeEvent;
53
import eu.etaxonomy.cdm.vaadin.event.EntityChangeEventFilter;
54
import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityButtonUpdater;
55
import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityReloader;
56
import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationTermLists;
57
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationDTO;
58
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationWorkingSetDTO;
59
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
60
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
61
import eu.etaxonomy.cdm.vaadin.util.CollectionCaptionGenerator;
62
import eu.etaxonomy.cdm.vaadin.view.occurrence.CollectionPopupEditor;
63
import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
64
import eu.etaxonomy.vaadin.component.ToOneRelatedEntityCombobox;
65
import eu.etaxonomy.vaadin.mvp.AbstractEditorPresenter;
66
import eu.etaxonomy.vaadin.mvp.AbstractPopupEditor;
67
import eu.etaxonomy.vaadin.mvp.AbstractView;
68
/**
69
 * SpecimenTypeDesignationWorkingsetPopupEditorView implementation must override the showInEditor() method,
70
 * see {@link #prepareAsFieldGroupDataSource()} for details.
71
 *
72
 * @author a.kohlbecker
73
 * @since Jun 13, 2017
74
 *
75
 */
76
@SpringComponent
77
@Scope("prototype")
78
public class SpecimenTypeDesignationWorkingsetEditorPresenter
79
    extends AbstractEditorPresenter<SpecimenTypeDesignationWorkingSetDTO , SpecimenTypeDesignationWorkingsetPopupEditorView>
80
    implements CachingPresenter, DisposableBean {
81

    
82
    private static final long serialVersionUID = 4255636253714476918L;
83

    
84
    private static final EnumSet<CRUD> COLLECTION_EDITOR_CRUD = EnumSet.of(CRUD.UPDATE, CRUD.DELETE);
85

    
86
    CdmStore<Registration, IRegistrationService> store;
87

    
88

    
89
    /**
90
     * This object for this field will either be injected by the {@link PopupEditorFactory} or by a Spring
91
     * {@link BeanFactory}
92
     */
93
    @Autowired
94
    private ISpecimenTypeDesignationWorkingSetService specimenTypeDesignationWorkingSetService;
95

    
96
    /**
97
     * if not null, this CRUD set is to be used to create a CdmAuthoritiy for the base entitiy which will be
98
     * granted to the current use as long this grant is not assigned yet.
99
     */
100
    private EnumSet<CRUD> crud = null;
101

    
102
    private ICdmEntityUuidCacher cache;
103

    
104
    @Autowired
105
    protected CdmFilterablePagingProviderFactory pagingProviderFactory;
106

    
107
    SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto;
108

    
109
    private Map<CollectionPopupEditor, SpecimenTypeDesignationDTORow> collectionPopupEditorsRowMap = new HashMap<>();
110

    
111
    private Map<ReferencePopupEditor, SpecimenTypeDesignationDTORow> referencePopupEditorsRowMap = new HashMap<>();
112

    
113
    private Set<CollectionRowItemCollection> popuEditorTypeDesignationSourceRows = new HashSet<>();
114

    
115
    private java.util.Collection<CdmBase> rootEntities = new HashSet<>();
116

    
117
    protected CdmStore<Registration, IRegistrationService> getStore() {
118
        if(store == null){
119
            store = new CdmStore<>(getRepo(), getRepo().getRegistrationService());
120
        }
121
        return store;
122
    }
123

    
124
    /**
125
     * Loads an existing working set from the database. This process actually involves
126
     * loading the Registration specified by the <code>RegistrationAndWorkingsetId.registrationId</code> and in
127
     * a second step to find the workingset by the <code>registrationAndWorkingsetId.workingsetId</code>.
128
     * <p>
129
     * The <code>identifier</code> must be of the type {@link TypeDesignationWorkingsetEditorIdSet} whereas the field <code>egistrationId</code>
130
     * must be present, the field <code>workingsetId</code>,  however can be null. I this case a new workingset with a new {@link FieldUnit} as
131
     * base entity is being created.
132
     *
133
     * @param identifier a {@link TypeDesignationWorkingsetEditorIdSet}
134
     */
135
    @Override
136
    protected SpecimenTypeDesignationWorkingSetDTO<Registration> loadBeanById(Object identifier) {
137

    
138
        cache = new CdmTransientEntityAndUuidCacher(this);
139
        if(identifier != null){
140

    
141
            TypeDesignationWorkingsetEditorIdSet idset = (TypeDesignationWorkingsetEditorIdSet)identifier;
142

    
143
            if(idset.baseEntityRef != null){
144
                workingSetDto = specimenTypeDesignationWorkingSetService.load(idset.registrationUuid, idset.baseEntityRef);
145
                if(workingSetDto.getFieldUnit() == null){
146
                    workingSetDto = specimenTypeDesignationWorkingSetService.fixMissingFieldUnit(workingSetDto);
147
                        // FIXME open Dialog to warn user about adding an empty fieldUnit to the typeDesignations
148
                        //       This method must go again into the presenter !!!!
149
                        logger.info("Basing all typeDesignations on a new fieldUnit");
150
                }
151
                // need to use load but put see #7214
152
                cache.load(workingSetDto.getOwner());
153
                rootEntities.add(workingSetDto.getOwner());
154
            } else {
155
                // create a new workingset, for a new fieldunit which is the base for the workingset
156
                workingSetDto = specimenTypeDesignationWorkingSetService.create(idset.registrationUuid, idset.publicationUuid, idset.typifiedNameUuid);
157
                // need to use load but put see #7214
158
                cache.load(workingSetDto.getOwner());
159
                cache.load(workingSetDto.getTypifiedName());
160
                rootEntities.add(workingSetDto.getOwner());
161
            }
162

    
163
        } else {
164
            workingSetDto = null;
165
        }
166

    
167
        return workingSetDto;
168
    }
169

    
170

    
171
    /**
172
     * {@inheritDoc}
173
     */
174
    @SuppressWarnings("serial")
175
    @Override
176
    public void handleViewEntered() {
177

    
178
        CdmBeanItemContainerFactory selectFactory = new CdmBeanItemContainerFactory(getRepo());
179
        getView().getCountrySelectField().setContainerDataSource(selectFactory.buildBeanItemContainer(Country.uuidCountryVocabulary));
180

    
181
        CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase> termOrPersonPagingProvider = new CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase>(getRepo().getAgentService(), TeamOrPersonBase.class);
182
        CdmFilterablePagingProvider<AgentBase, Person> personPagingProvider = new CdmFilterablePagingProvider<AgentBase, Person>(getRepo().getAgentService(), Person.class);
183
        termOrPersonPagingProvider.setInitStrategy(AgentBaseInit.TEAM_OR_PERSON_INIT_STRATEGY);
184
        getView().getCollectorField().setFilterablePersonPagingProvider(personPagingProvider, this);
185
        getView().getCollectorField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
186

    
187
        getView().getTypeDesignationsCollectionField().addElementRemovedListener(e -> deleteTypeDesignation(e.getElement()));
188
        getView().getTypeDesignationsCollectionField().addElementAddedListener(e -> addTypeDesignation(e.getElement()));
189

    
190

    
191
        popuEditorTypeDesignationSourceRows.clear();
192
        CdmFilterablePagingProvider<Collection, Collection> collectionPagingProvider = new CdmFilterablePagingProvider<Collection, Collection>(getRepo().getCollectionService());
193
        collectionPagingProvider.getRestrictions().add(new Restriction<>("institute.titleCache", Operator.OR, MatchMode.ANYWHERE, CdmFilterablePagingProvider.QUERY_STRING_PLACEHOLDER));
194

    
195
        CdmFilterablePagingProvider<Reference, Reference> referencePagingProvider = pagingProviderFactory.referencePagingProvider();
196

    
197
        getView().getTypeDesignationsCollectionField().setEditorInstantiator(new AbstractElementCollection.Instantiator<SpecimenTypeDesignationDTORow>() {
198

    
199
            @Override
200
            public SpecimenTypeDesignationDTORow create() {
201

    
202
                SpecimenTypeDesignationDTORow row = new SpecimenTypeDesignationDTORow();
203

    
204
                row.kindOfUnit.setContainerDataSource(selectFactory.buildTermItemContainer(
205
                        RegistrationTermLists.KIND_OF_UNIT_TERM_UUIDS())
206
                        );
207
                row.kindOfUnit.setNullSelectionAllowed(false);
208

    
209
                row.typeStatus.setContainerDataSource(selectFactory.buildTermItemContainer(
210
                        RegistrationTermLists.SPECIMEN_TYPE_DESIGNATION_STATUS_UUIDS())
211
                        );
212
                row.typeStatus.setNullSelectionAllowed(false);
213

    
214

    
215
                row.collection.loadFrom(
216
                        collectionPagingProvider,
217
                        collectionPagingProvider,
218
                        collectionPagingProvider.getPageSize()
219
                        );
220
                row.collection.getSelect().setCaptionGenerator(new CollectionCaptionGenerator());
221
                row.collection.setNestedButtonStateUpdater(new ToOneRelatedEntityButtonUpdater<Collection>(row.collection));
222
                row.collection.getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<Collection>(row.collection.getSelect(),
223
                        SpecimenTypeDesignationWorkingsetEditorPresenter.this));
224
                row.collection.addClickListenerAddEntity(e -> doCollectionEditorAdd(row));
225
                row.collection.addClickListenerEditEntity(e -> {
226
                        if(row.collection.getValue() != null){
227
                            doCollectionEditorEdit(row);
228
                        }
229
                    });
230

    
231
                row.mediaSpecimenReference.loadFrom(
232
                        referencePagingProvider,
233
                        referencePagingProvider,
234
                        collectionPagingProvider.getPageSize()
235
                        );
236

    
237
                row.mediaSpecimenReference.getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
238
                row.mediaSpecimenReference.getSelect().addValueChangeListener(new ToOneRelatedEntityButtonUpdater<Reference>(row.mediaSpecimenReference));
239
                row.mediaSpecimenReference.getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<Reference>(row.mediaSpecimenReference.getSelect(),
240
                        SpecimenTypeDesignationWorkingsetEditorPresenter.this));
241
                row.mediaSpecimenReference.addClickListenerAddEntity(e -> doReferenceEditorAdd(row));
242
                row.mediaSpecimenReference.addClickListenerEditEntity(e -> {
243
                    if(row.mediaSpecimenReference.getValue() != null){
244
                        doReferenceEditorEdit(row);
245
                    }
246
                });
247

    
248
                getView().applyDefaultComponentStyle(row.components());
249

    
250
                popuEditorTypeDesignationSourceRows.add(row);
251

    
252
                return row;
253
            }
254

    
255
        });
256

    
257
    }
258

    
259

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

    
266
        if(crud != null){
267
            UserHelperAccess.userHelper().createAuthorityForCurrentUser(dto.getFieldUnit(), crud, null);
268
        }
269

    
270
        specimenTypeDesignationWorkingSetService.save(dto);
271
    }
272

    
273
    /**
274
     * {@inheritDoc}
275
     */
276
    @Override
277
    protected void deleteBean(SpecimenTypeDesignationWorkingSetDTO bean) {
278
        specimenTypeDesignationWorkingSetService.delete(bean, true);
279
    }
280

    
281
    /**
282
     * @param element
283
     * @return
284
     */
285
    private void addTypeDesignation(SpecimenTypeDesignationDTO element) {
286
        getView().updateAllowDelete();
287
    }
288

    
289

    
290
    /**
291
     * In this method the SpecimenTypeDesignation is dissociated from the Registration.
292
     * The actual deletion of the SpecimenTypeDesignation and DerivedUnit will take place in {@link #saveBean(SpecimenTypeDesignationWorkingSetDTO)}
293
     *
294
     * TODO once https://dev.e-taxonomy.eu/redmine/issues/7077 is fixed dissociating from the Registration could be removed here
295
     *
296
     * @param e
297
     * @return
298
     */
299
    private void deleteTypeDesignation(SpecimenTypeDesignationDTO element) {
300

    
301
        Registration reg = workingSetDto.getOwner();
302
        SpecimenTypeDesignation std = element.asSpecimenTypeDesignation();
303

    
304
        reg.getTypeDesignations().remove(std);
305

    
306
        getView().updateAllowDelete();
307
    }
308

    
309
    /**
310
     * @param crud
311
     */
312
    public void setGrantsForCurrentUser(EnumSet<CRUD> crud) {
313
        this.crud = crud;
314

    
315
    }
316

    
317
    /**
318
     * {@inheritDoc}
319
     */
320
    @Override
321
    public ICdmEntityUuidCacher getCache() {
322
        return cache;
323
    }
324

    
325
    @Override
326
    public void disposeCache() {
327
        cache.dispose();
328
    }
329

    
330
    public void doCollectionEditorAdd(SpecimenTypeDesignationDTORow row) {
331

    
332
        CollectionPopupEditor collectionPopupEditor = openPopupEditor(CollectionPopupEditor.class, null);
333

    
334
        collectionPopupEditor.grantToCurrentUser(COLLECTION_EDITOR_CRUD);
335
        collectionPopupEditor.withDeleteButton(true);
336
        collectionPopupEditor.loadInEditor(null);
337

    
338
        collectionPopupEditorsRowMap.put(collectionPopupEditor, row);
339
    }
340

    
341
    public void doCollectionEditorEdit(SpecimenTypeDesignationDTORow row) {
342

    
343
        CollectionPopupEditor collectionPopupEditor = openPopupEditor(CollectionPopupEditor.class, null);
344

    
345
        collectionPopupEditor.grantToCurrentUser(COLLECTION_EDITOR_CRUD);
346
        collectionPopupEditor.withDeleteButton(true);
347
        collectionPopupEditor.loadInEditor(row.collection.getValue().getUuid());
348

    
349
        collectionPopupEditorsRowMap.put(collectionPopupEditor, row);
350
    }
351

    
352

    
353
    @EventBusListenerMethod(filter = EntityChangeEventFilter.OccurrenceCollectionFilter.class)
354
    public void onCollectionEvent(EntityChangeEvent event){
355

    
356
        if(event.getSourceView() instanceof AbstractPopupEditor) {
357

    
358
            Stack<EditorActionContext> context = ((AbstractPopupEditor) event.getSourceView()).getEditorActionContext();
359
            if(context.size() > 1){
360
               AbstractView<?> parentView = context.get(context.size() - 2).getParentView();
361
               if(getView().equals(parentView)){
362
                   Collection newCollection = getRepo().getCollectionService().load(
363
                           event.getEntityUuid(), Arrays.asList(new String[]{"$.institute"})
364
                           );
365
                   cache.load(newCollection);
366

    
367
                   if(event.isCreatedType()){
368
                       SpecimenTypeDesignationDTORow row = collectionPopupEditorsRowMap.get(event.getSourceView());
369
                       ToOneRelatedEntityCombobox<Collection> combobox = row.getComponent(ToOneRelatedEntityCombobox.class, 3);
370
                       combobox.setValue((Collection) event.getEntity());
371
                   }
372
                   for( CollectionRowItemCollection row : popuEditorTypeDesignationSourceRows) {
373
                       ToOneRelatedEntityCombobox<Collection> combobox = row.getComponent(ToOneRelatedEntityCombobox.class, 3);
374
                       combobox.reload();
375
                   }
376
               }
377
            }
378

    
379
        }
380
    }
381

    
382
    public void doReferenceEditorAdd(SpecimenTypeDesignationDTORow row) {
383

    
384
        ReferencePopupEditor referencePopupEditor = openPopupEditor(ReferencePopupEditor.class, null);
385

    
386
        referencePopupEditor.withReferenceTypes(RegistrationUIDefaults.MEDIA_REFERENCE_TYPES);
387
        referencePopupEditor.grantToCurrentUser(COLLECTION_EDITOR_CRUD);
388
        referencePopupEditor.withDeleteButton(true);
389
        referencePopupEditor.loadInEditor(null);
390

    
391
        referencePopupEditorsRowMap.put(referencePopupEditor, row);
392
    }
393

    
394
    public void doReferenceEditorEdit(SpecimenTypeDesignationDTORow row) {
395

    
396
        ReferencePopupEditor referencePopupEditor = openPopupEditor(ReferencePopupEditor.class, null);
397
        referencePopupEditor.withReferenceTypes(RegistrationUIDefaults.MEDIA_REFERENCE_TYPES);
398
        referencePopupEditor.grantToCurrentUser(COLLECTION_EDITOR_CRUD);
399
        referencePopupEditor.withDeleteButton(true);
400
        referencePopupEditor.loadInEditor(row.mediaSpecimenReference.getValue().getUuid());
401

    
402
        referencePopupEditorsRowMap.put(referencePopupEditor, row);
403
    }
404

    
405
    @EventBusListenerMethod(filter = EntityChangeEventFilter.ReferenceFilter.class)
406
    public void onReferenceEvent(EntityChangeEvent event){
407

    
408
        Reference newRef = getRepo().getReferenceService().load(event.getEntityUuid(), Arrays.asList(new String[]{"$"}));
409
        cache.load(newRef);
410

    
411
        if(event.isCreatedType()){
412
            SpecimenTypeDesignationDTORow row = referencePopupEditorsRowMap.get(event.getSourceView());
413
            ToOneRelatedEntityCombobox<Reference> combobox = row.getComponent(ToOneRelatedEntityCombobox.class, 7);
414
            combobox.setValue((Reference) event.getEntity());
415

    
416
        } else {
417
            for( CollectionRowItemCollection row : popuEditorTypeDesignationSourceRows) {
418
                ToOneRelatedEntityCombobox<Reference> combobox = row.getComponent(ToOneRelatedEntityCombobox.class, 7);
419
                combobox.reload();
420
            }
421
        }
422
    }
423

    
424
    /**
425
     * {@inheritDoc}
426
     */
427
    @Override
428
    public void addRootEntity(CdmBase entity) {
429
        rootEntities.add(entity);
430
    }
431

    
432
    /**
433
     * {@inheritDoc}
434
     */
435
    @Override
436
    public java.util.Collection<CdmBase> getRootEntities() {
437
        return rootEntities ;
438
    }
439

    
440
    /**
441
     * {@inheritDoc}
442
     */
443
    @Override
444
    public void destroy() throws Exception {
445
        super.destroy();
446
        cache.dispose();
447
    }
448

    
449
}
(6-6/13)