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.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.reference.Reference;
40
import eu.etaxonomy.cdm.model.term.TermType;
41
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
42
import eu.etaxonomy.cdm.persistence.dao.common.Restriction.Operator;
43
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
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
 */
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

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

    
94
    @Autowired
95
    protected CdmFilterablePagingProviderFactory pagingProviderFactory;
96

    
97
    @Autowired
98
    protected CdmBeanItemContainerFactory cdmBeanItemContainerFactory;
99

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

    
106
    private ICdmEntityUuidCacher cache;
107

    
108
    SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto;
109

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

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

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

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

    
118

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

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

    
136
            TypeDesignationWorkingsetEditorIdSet idset = (TypeDesignationWorkingsetEditorIdSet)identifier;
137

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

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

    
169
        return workingSetDto;
170
    }
171

    
172

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

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

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

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

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

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

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

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

    
204

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

    
207
            @Override
208
            public SpecimenTypeDesignationDTORow create() {
209

    
210
                SpecimenTypeDesignationDTORow row = new SpecimenTypeDesignationDTORow();
211

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

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

    
222

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

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

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

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

    
256
                popuEditorTypeDesignationSourceRows.add(row);
257

    
258
                return row;
259
            }
260

    
261
        });
262

    
263
    }
264

    
265

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

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

    
276
        specimenTypeDesignationWorkingSetService.save(dto);
277
    }
278

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

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

    
295

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

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

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

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

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

    
321
    }
322

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

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

    
336
    public void doCollectionEditorAdd(SpecimenTypeDesignationDTORow row) {
337

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

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

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

    
347
    public void doCollectionEditorEdit(SpecimenTypeDesignationDTORow row) {
348

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

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

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

    
358

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

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

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

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

    
386
        }
387
    }
388

    
389
    public void doReferenceEditorAdd(SpecimenTypeDesignationDTORow row) {
390

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

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

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

    
401
    public void doReferenceEditorEdit(SpecimenTypeDesignationDTORow row) {
402

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

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

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

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

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

    
429
    }
430

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

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

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

    
456
}
(8-8/15)