Project

General

Profile

Download (19.6 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.cache.CdmTransientEntityAndUuidCacher;
28
import eu.etaxonomy.cdm.format.reference.ReferenceEllypsisFormatter.LabelType;
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.AnnotationType;
34
import eu.etaxonomy.cdm.model.common.CdmBase;
35
import eu.etaxonomy.cdm.model.location.Country;
36
import eu.etaxonomy.cdm.model.name.Registration;
37
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
38
import eu.etaxonomy.cdm.model.occurrence.Collection;
39
import eu.etaxonomy.cdm.model.permission.CRUD;
40
import eu.etaxonomy.cdm.model.reference.Reference;
41
import eu.etaxonomy.cdm.model.term.TermType;
42
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
43
import eu.etaxonomy.cdm.persistence.dao.common.Restriction.Operator;
44
import eu.etaxonomy.cdm.persistence.query.MatchMode;
45
import eu.etaxonomy.cdm.service.CdmBeanItemContainerFactory;
46
import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider;
47
import eu.etaxonomy.cdm.service.CdmFilterablePagingProviderFactory;
48
import eu.etaxonomy.cdm.service.ISpecimenTypeDesignationWorkingSetService;
49
import eu.etaxonomy.cdm.service.UserHelperAccess;
50
import eu.etaxonomy.cdm.service.initstrategies.AgentBaseInit;
51
import eu.etaxonomy.cdm.vaadin.component.CollectionRowItemCollection;
52
import eu.etaxonomy.cdm.vaadin.event.EditorActionContext;
53
import eu.etaxonomy.cdm.vaadin.event.EntityChangeEvent;
54
import eu.etaxonomy.cdm.vaadin.event.EntityChangeEventFilter;
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.CollectionCaptionGenerator;
61
import eu.etaxonomy.cdm.vaadin.util.ReferenceEllypsisCaptionGenerator;
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
@SpringComponent
76
@Scope("prototype")
77
public class SpecimenTypeDesignationWorkingsetEditorPresenter
78
    extends AbstractEditorPresenter<SpecimenTypeDesignationWorkingSetDTO , SpecimenTypeDesignationWorkingsetPopupEditorView>
79
    implements CachingPresenter, DisposableBean {
80

    
81
    private static final long serialVersionUID = 4255636253714476918L;
82

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

    
85

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

    
93
    @Autowired
94
    protected CdmFilterablePagingProviderFactory pagingProviderFactory;
95

    
96
    @Autowired
97
    protected CdmBeanItemContainerFactory cdmBeanItemContainerFactory;
98

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

    
105
    private ICdmEntityUuidCacher cache;
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

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

    
132
        cache = new CdmTransientEntityAndUuidCacher(this);
133
        if(identifier != null){
134

    
135
            TypeDesignationWorkingsetEditorIdSet idset = (TypeDesignationWorkingsetEditorIdSet)identifier;
136

    
137
            if(idset.baseEntityRef != null){
138
                workingSetDto = specimenTypeDesignationWorkingSetService.load(idset.registrationUuid, idset.baseEntityRef);
139
                if(workingSetDto.getFieldUnit() == null){
140
                    workingSetDto = specimenTypeDesignationWorkingSetService.fixMissingFieldUnit(workingSetDto);
141
                        // FIXME open Dialog to warn user about adding an empty fieldUnit to the typeDesignations
142
                        //       This method must go again into the presenter !!!!
143
                        logger.info("Basing all typeDesignations on a new fieldUnit");
144
                }
145
                // need to use load but put see #7214
146
                cache.load(workingSetDto.getOwner());
147
                rootEntities.add(workingSetDto.getOwner());
148
            } else {
149
                // create a new workingset, for a new fieldunit which is the base for the workingset
150
                workingSetDto = specimenTypeDesignationWorkingSetService.create(idset.registrationUuid, idset.publicationUuid, idset.typifiedNameUuid);
151
                // need to use load but put see #7214
152
                Registration registration = workingSetDto.getOwner();
153
                cache.load(registration);
154
                if(registration.getName() == null && (registration.getTypeDesignations() == null || registration.getTypeDesignations().isEmpty())){
155
                    // need to add the citation to the cache when there is no name or typedesignation in the registry which would bring the citation otherwise.
156
                    cache.load(workingSetDto.getCitation());
157
                }
158
                cache.load(workingSetDto.getTypifiedName());
159
                rootEntities.add(workingSetDto.getOwner());
160
                rootEntities.add(workingSetDto.getTypifiedName());
161
                rootEntities.add(workingSetDto.getCitation());
162
            }
163

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

    
168
        return workingSetDto;
169
    }
170

    
171

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

    
179
        getView().getCountrySelectField().setContainerDataSource(cdmBeanItemContainerFactory.buildBeanItemContainer(Country.uuidCountryVocabulary));
180

    
181
        CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase> termOrPersonPagingProvider = pagingProviderFactory.teamOrPersonPagingProvider();
182
        CdmFilterablePagingProvider<AgentBase, Person> personPagingProvider = pagingProviderFactory.personPagingProvider();
183
        termOrPersonPagingProvider.setInitStrategy(AgentBaseInit.TEAM_OR_PERSON_INIT_STRATEGY);
184
        // the ToOneRelatedEntityReloader is added internally in the TeamOrPersonField:
185
        getView().getCollectorField().setFilterablePersonPagingProvider(personPagingProvider, this);
186
        getView().getCollectorField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
187

    
188
        getView().getExactLocationField().getReferenceSystemSelect().setContainerDataSource(cdmBeanItemContainerFactory.buildBeanItemContainer(TermType.ReferenceSystem));
189
        getView().getExactLocationField().getReferenceSystemSelect().setItemCaptionPropertyId("label");
190

    
191
        getView().getTypeDesignationsCollectionField().addElementRemovedListener(e -> deleteTypeDesignation(e.getElement()));
192
        getView().getTypeDesignationsCollectionField().addElementAddedListener(e -> addTypeDesignation(e.getElement()));
193

    
194
        getView().getAnnotationsField().setAnnotationTypeItemContainer(cdmBeanItemContainerFactory.buildBeanItemContainer(
195
                AnnotationType.EDITORIAL().getVocabulary().getUuid()));
196

    
197
        popuEditorTypeDesignationSourceRows.clear();
198
        CdmFilterablePagingProvider<Collection, Collection> collectionPagingProvider = new CdmFilterablePagingProvider<Collection, Collection>(getRepo().getCollectionService());
199
        collectionPagingProvider.getRestrictions().add(new Restriction<>("institute.titleCache", Operator.OR, MatchMode.ANYWHERE, CdmFilterablePagingProvider.QUERY_STRING_PLACEHOLDER));
200

    
201
        CdmFilterablePagingProvider<Reference, Reference> referencePagingProvider = pagingProviderFactory.referencePagingProvider();
202

    
203

    
204
        getView().getTypeDesignationsCollectionField().setEditorInstantiator(new AbstractElementCollection.Instantiator<SpecimenTypeDesignationDTORow>() {
205

    
206
            @Override
207
            public SpecimenTypeDesignationDTORow create() {
208

    
209
                SpecimenTypeDesignationDTORow row = new SpecimenTypeDesignationDTORow();
210

    
211
                row.kindOfUnit.setContainerDataSource(cdmBeanItemContainerFactory.buildTermItemContainer(
212
                        RegistrationTermLists.KIND_OF_UNIT_TERM_UUIDS())
213
                        );
214
                row.kindOfUnit.setNullSelectionAllowed(false);
215

    
216
                row.typeStatus.setContainerDataSource(cdmBeanItemContainerFactory.buildTermItemContainer(
217
                        RegistrationTermLists.SPECIMEN_TYPE_DESIGNATION_STATUS_UUIDS())
218
                        );
219
                row.typeStatus.setNullSelectionAllowed(false);
220

    
221

    
222
                row.collection.loadFrom(
223
                        collectionPagingProvider,
224
                        collectionPagingProvider,
225
                        collectionPagingProvider.getPageSize()
226
                        );
227
                row.collection.getSelect().setCaptionGenerator(new CollectionCaptionGenerator());
228
                row.collection.getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<Collection>(row.collection.getSelect(),
229
                        SpecimenTypeDesignationWorkingsetEditorPresenter.this));
230
                row.collection.addClickListenerAddEntity(e -> doCollectionEditorAdd(row));
231
                row.collection.addClickListenerEditEntity(e -> {
232
                        if(row.collection.getValue() != null){
233
                            doCollectionEditorEdit(row);
234
                        }
235
                    });
236

    
237
                row.mediaSpecimenReference.loadFrom(
238
                        referencePagingProvider,
239
                        referencePagingProvider,
240
                        referencePagingProvider.getPageSize()
241
                        );
242

    
243
                row.mediaSpecimenReference.getSelect().setCaptionGenerator(new ReferenceEllypsisCaptionGenerator(LabelType.BIBLIOGRAPHIC, row.mediaSpecimenReference.getSelect()));
244
                row.mediaSpecimenReference.getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<Reference>(row.mediaSpecimenReference.getSelect(),
245
                        SpecimenTypeDesignationWorkingsetEditorPresenter.this));
246
                row.mediaSpecimenReference.addClickListenerAddEntity(e -> doReferenceEditorAdd(row));
247
                row.mediaSpecimenReference.addClickListenerEditEntity(e -> {
248
                    if(row.mediaSpecimenReference.getValue() != null){
249
                        doReferenceEditorEdit(row);
250
                    }
251
                });
252

    
253
                getView().applyDefaultComponentStyle(row.components());
254

    
255
                popuEditorTypeDesignationSourceRows.add(row);
256

    
257
                return row;
258
            }
259

    
260
        });
261

    
262
    }
263

    
264

    
265
    /**
266
     * {@inheritDoc}
267
     */
268
    @Override
269
    protected void saveBean(SpecimenTypeDesignationWorkingSetDTO dto) {
270

    
271
        if(crud != null){
272
            UserHelperAccess.userHelper().createAuthorityForCurrentUser(dto.getFieldUnit(), crud, null);
273
        }
274

    
275
        specimenTypeDesignationWorkingSetService.save(dto);
276
    }
277

    
278
    /**
279
     * {@inheritDoc}
280
     */
281
    @Override
282
    protected void deleteBean(SpecimenTypeDesignationWorkingSetDTO bean) {
283
        specimenTypeDesignationWorkingSetService.delete(bean, true);
284
    }
285

    
286
    /**
287
     * @param element
288
     * @return
289
     */
290
    private void addTypeDesignation(SpecimenTypeDesignationDTO element) {
291
        getView().updateAllowDeleteTypeDesignation();
292
    }
293

    
294

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

    
306
        Registration reg = workingSetDto.getOwner();
307
        SpecimenTypeDesignation std = element.asSpecimenTypeDesignation();
308

    
309
        reg.getTypeDesignations().remove(std);
310

    
311
        getView().updateAllowDeleteTypeDesignation();
312
    }
313

    
314
    /**
315
     * @param crud
316
     */
317
    public void setGrantsForCurrentUser(EnumSet<CRUD> crud) {
318
        this.crud = crud;
319

    
320
    }
321

    
322
    /**
323
     * {@inheritDoc}
324
     */
325
    @Override
326
    public ICdmEntityUuidCacher getCache() {
327
        return cache;
328
    }
329

    
330
    @Override
331
    public void disposeCache() {
332
        cache.dispose();
333
    }
334

    
335
    public void doCollectionEditorAdd(SpecimenTypeDesignationDTORow row) {
336

    
337
        CollectionPopupEditor collectionPopupEditor = openPopupEditor(CollectionPopupEditor.class, null);
338

    
339
        collectionPopupEditor.grantToCurrentUser(COLLECTION_EDITOR_CRUD);
340
        collectionPopupEditor.withDeleteButton(true);
341
        collectionPopupEditor.loadInEditor(null);
342

    
343
        collectionPopupEditorsRowMap.put(collectionPopupEditor, row);
344
    }
345

    
346
    public void doCollectionEditorEdit(SpecimenTypeDesignationDTORow row) {
347

    
348
        CollectionPopupEditor collectionPopupEditor = openPopupEditor(CollectionPopupEditor.class, null);
349

    
350
        collectionPopupEditor.grantToCurrentUser(COLLECTION_EDITOR_CRUD);
351
        collectionPopupEditor.withDeleteButton(true);
352
        collectionPopupEditor.loadInEditor(row.collection.getValue().getUuid());
353

    
354
        collectionPopupEditorsRowMap.put(collectionPopupEditor, row);
355
    }
356

    
357

    
358
    @EventBusListenerMethod(filter = EntityChangeEventFilter.OccurrenceCollectionFilter.class)
359
    public void onCollectionEvent(EntityChangeEvent event){
360

    
361
        if(event.getSourceView() instanceof AbstractPopupEditor) {
362

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

    
372
                   if(event.isCreatedType()){
373
                       SpecimenTypeDesignationDTORow row = collectionPopupEditorsRowMap.get(event.getSourceView());
374
                       ToOneRelatedEntityCombobox<Collection> combobox = row.getComponent(ToOneRelatedEntityCombobox.class, 3);
375
                       combobox.setValue((Collection) event.getEntity());
376
                   } else {
377
                       for( CollectionRowItemCollection row : popuEditorTypeDesignationSourceRows) {
378
                           ToOneRelatedEntityCombobox<Collection> combobox = row.getComponent(ToOneRelatedEntityCombobox.class, 3);
379
                           combobox.reload();
380
                       }
381
                   }
382
               }
383
            }
384

    
385
        }
386
    }
387

    
388
    public void doReferenceEditorAdd(SpecimenTypeDesignationDTORow row) {
389

    
390
        ReferencePopupEditor referencePopupEditor = openPopupEditor(ReferencePopupEditor.class, null);
391

    
392
        referencePopupEditor.withReferenceTypes(RegistrationUIDefaults.MEDIA_REFERENCE_TYPES);
393
        referencePopupEditor.grantToCurrentUser(COLLECTION_EDITOR_CRUD);
394
        referencePopupEditor.withDeleteButton(true);
395
        referencePopupEditor.loadInEditor(null);
396

    
397
        referencePopupEditorsRowMap.put(referencePopupEditor, row);
398
    }
399

    
400
    public void doReferenceEditorEdit(SpecimenTypeDesignationDTORow row) {
401

    
402
        ReferencePopupEditor referencePopupEditor = openPopupEditor(ReferencePopupEditor.class, null);
403
        referencePopupEditor.withReferenceTypes(RegistrationUIDefaults.MEDIA_REFERENCE_TYPES);
404
        referencePopupEditor.grantToCurrentUser(COLLECTION_EDITOR_CRUD);
405
        referencePopupEditor.withDeleteButton(true);
406
        referencePopupEditor.loadInEditor(row.mediaSpecimenReference.getValue().getUuid());
407

    
408
        referencePopupEditorsRowMap.put(referencePopupEditor, row);
409
    }
410

    
411
    @EventBusListenerMethod(filter = EntityChangeEventFilter.ReferenceFilter.class)
412
    public void onReferenceEvent(EntityChangeEvent event){
413

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

    
417
        if(event.isCreatedType()){
418
            SpecimenTypeDesignationDTORow row = referencePopupEditorsRowMap.get(event.getSourceView());
419
            ToOneRelatedEntityCombobox<Reference> combobox = row.getComponent(ToOneRelatedEntityCombobox.class, 7);
420
            combobox.setValue((Reference) event.getEntity());
421
        } else {
422
            for( CollectionRowItemCollection row : popuEditorTypeDesignationSourceRows) {
423
                ToOneRelatedEntityCombobox<Reference> combobox = row.getComponent(ToOneRelatedEntityCombobox.class, 7);
424
                combobox.reload();
425
            }
426
        }
427

    
428
    }
429

    
430
    /**
431
     * {@inheritDoc}
432
     */
433
    @Override
434
    public void addRootEntity(CdmBase entity) {
435
        rootEntities.add(entity);
436
    }
437

    
438
    /**
439
     * {@inheritDoc}
440
     */
441
    @Override
442
    public java.util.Collection<CdmBase> getRootEntities() {
443
        return rootEntities ;
444
    }
445

    
446
    /**
447
     * {@inheritDoc}
448
     */
449
    @Override
450
    public void destroy() throws Exception {
451
        super.destroy();
452
        cache.dispose();
453
    }
454

    
455
}
(8-8/15)