Project

General

Profile

Download (18 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.HashSet;
14
import java.util.List;
15
import java.util.Set;
16
import java.util.UUID;
17

    
18
import org.apache.log4j.Logger;
19
import org.hibernate.criterion.Restrictions;
20
import org.springframework.context.annotation.Scope;
21
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
22

    
23
import com.vaadin.spring.annotation.SpringComponent;
24
import com.vaadin.ui.AbstractField;
25

    
26
import eu.etaxonomy.cdm.api.service.INameService;
27
import eu.etaxonomy.cdm.model.agent.AgentBase;
28
import eu.etaxonomy.cdm.model.agent.Person;
29
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
30
import eu.etaxonomy.cdm.model.common.TermType;
31
import eu.etaxonomy.cdm.model.name.NameRelationship;
32
import eu.etaxonomy.cdm.model.name.Rank;
33
import eu.etaxonomy.cdm.model.name.TaxonName;
34
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
35
import eu.etaxonomy.cdm.model.reference.Reference;
36
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
37
import eu.etaxonomy.cdm.model.reference.ReferenceType;
38
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
39
import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider;
40
import eu.etaxonomy.cdm.service.initstrategies.AgentBaseInit;
41
import eu.etaxonomy.cdm.vaadin.component.CdmBeanItemContainerFactory;
42
import eu.etaxonomy.cdm.vaadin.event.EditorActionTypeFilter;
43
import eu.etaxonomy.cdm.vaadin.event.EntityChangeEvent;
44
import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
45
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
46
import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityButtonUpdater;
47
import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityReloader;
48
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
49
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
50
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
51
import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
52
import eu.etaxonomy.vaadin.component.ReloadableLazyComboBox;
53
import eu.etaxonomy.vaadin.component.ReloadableSelect;
54
import eu.etaxonomy.vaadin.mvp.AbstractCdmEditorPresenter;
55
import eu.etaxonomy.vaadin.mvp.BeanInstantiator;
56

    
57
/**
58
 * @author a.kohlbecker
59
 * @since May 22, 2017
60
 *
61
 */
62
@SpringComponent
63
@Scope("prototype")
64
public class TaxonNameEditorPresenter extends AbstractCdmEditorPresenter<TaxonName, TaxonNamePopupEditorView> {
65

    
66

    
67
    private static final List<String> BASIONYM_INIT_STRATEGY = Arrays.asList(
68
            "$",
69
            "relationsFromThisName",
70
            "relationsToThisName.type",
71
            "homotypicalGroup.typifiedNames"
72
            );
73

    
74
    private static final List<String> REFERENCE_INIT_STRATEGY = Arrays.asList("authorship", "inReference.authorship", "inReference.inReference.authorship", "inReference.inReference.inReference.authorship");
75

    
76
    private static final long serialVersionUID = -3538980627079389221L;
77

    
78
    private static final Logger logger = Logger.getLogger(TaxonNameEditorPresenter.class);
79

    
80
    private ReferencePopupEditor referenceEditorPopup = null;
81

    
82
    private TaxonNamePopupEditor basionymNamePopup = null;
83

    
84
    private CdmFilterablePagingProvider<Reference, Reference> referencePagingProvider;
85

    
86
    private Reference publishedUnit;
87

    
88
    private BeanInstantiator<Reference> newReferenceInstantiator;
89

    
90
    private BeanInstantiator<TaxonName> newBasionymNameInstantiator;
91

    
92
    private AbstractField<TaxonName> basionymSourceField;
93

    
94
    /**
95
     * {@inheritDoc}
96
     */
97
    @Override
98
    public void handleViewEntered() {
99

    
100
        super.handleViewEntered();
101

    
102
        CdmBeanItemContainerFactory selectFieldFactory = new CdmBeanItemContainerFactory(getRepo());
103
        getView().getRankSelect().setContainerDataSource(selectFieldFactory.buildBeanItemContainer(TermType.Rank));
104
        getView().getRankSelect().setItemCaptionPropertyId("label");
105

    
106
        CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase> termOrPersonPagingProvider = new CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase>(getRepo().getAgentService(), TeamOrPersonBase.class);
107
        termOrPersonPagingProvider.setInitStrategy(AgentBaseInit.TEAM_OR_PERSON_INIT_STRATEGY);
108
        CdmFilterablePagingProvider<AgentBase, Person> personPagingProvider = new CdmFilterablePagingProvider<AgentBase, Person>(getRepo().getAgentService(), Person.class);
109

    
110
        getView().getCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
111
        getView().getCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
112

    
113
        getView().getExCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
114
        getView().getExCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
115

    
116
        getView().getBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
117
        getView().getBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
118

    
119
        getView().getExBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
120
        getView().getExBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
121

    
122
        getView().getNomReferenceCombobox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
123
        referencePagingProvider = new CdmFilterablePagingProvider<Reference, Reference>(getRepo().getReferenceService());
124
        referencePagingProvider.setInitStrategy(REFERENCE_INIT_STRATEGY);
125
        getView().getNomReferenceCombobox().loadFrom(referencePagingProvider, referencePagingProvider, referencePagingProvider.getPageSize());
126
        getView().getNomReferenceCombobox().getSelect().addValueChangeListener(new ToOneRelatedEntityButtonUpdater<Reference>(getView().getNomReferenceCombobox()));
127
        getView().getNomReferenceCombobox().getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getNomReferenceCombobox(), this));
128

    
129
        getView().getBasionymComboboxSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
130

    
131
        CdmFilterablePagingProvider<TaxonName, TaxonName> basionymPagingProvider = new CdmFilterablePagingProvider<TaxonName, TaxonName>(getRepo().getNameService());
132
        basionymPagingProvider.setInitStrategy(BASIONYM_INIT_STRATEGY);
133
        getView().getBasionymComboboxSelect().setPagingProviders(basionymPagingProvider, basionymPagingProvider, basionymPagingProvider.getPageSize(), this);
134
    }
135

    
136
    /**
137
     * {@inheritDoc}
138
     */
139
    @Override
140
    protected TaxonName loadCdmEntity(UUID identifier) {
141

    
142
        List<String> initStrategy = Arrays.asList(new String []{
143

    
144
                "$",
145
                "rank.vocabulary", // needed for comparing ranks
146

    
147
                "nomenclaturalReference.authorship",
148
                "nomenclaturalReference.inReference.authorship",
149
                "nomenclaturalReference.inReference.inReference.authorship",
150
                "nomenclaturalReference.inReference.inReference.inReference.authorship",
151

    
152
                "status.type",
153

    
154
                "combinationAuthorship.teamMembers",
155
                "exCombinationAuthorship.teamMembers",
156
                "basionymAuthorship.teamMembers",
157
                "exBasionymAuthorship.teamMembers",
158

    
159
                // basionyms: relationsToThisName.fromName
160
                "relationsToThisName.type",
161
                "relationsToThisName.fromName.rank",
162
                "relationsToThisName.fromName.combinationAuthorship.teamMembers",
163
                "relationsToThisName.fromName.exCombinationAuthorship.teamMembers",
164
                "relationsToThisName.fromName.nomenclaturalReference.authorship.teamMembers",
165
                "relationsToThisName.fromName.nomenclaturalReference.inReference.authorship.teamMembers",
166
                "relationsToThisName.fromName.nomenclaturalReference.inReference.inReference.inReference.authorship.teamMembers",
167
                "relationsToThisName.fromName.relationsToThisName",
168
                "relationsToThisName.fromName.relationsFromThisName",
169

    
170
                "relationsFromThisName",
171
                "homotypicalGroup.typifiedNames"
172

    
173
                }
174
        );
175

    
176
        TaxonName taxonName;
177
        if(identifier != null){
178
            taxonName = getRepo().getNameService().load(identifier, initStrategy);
179
        } else {
180
            taxonName = TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
181
        }
182

    
183
        if(getView().isModeEnabled(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY)){
184
            if(taxonName.getNomenclaturalReference() != null){
185
                Reference nomRef = (Reference)taxonName.getNomenclaturalReference();
186
                //getView().getNomReferenceCombobox().setEnabled(nomRef.isOfType(ReferenceType.Section));
187
                publishedUnit = nomRef;
188
                while(publishedUnit.isOfType(ReferenceType.Section) && publishedUnit.getInReference() != null){
189
                    publishedUnit = nomRef.getInReference();
190
                }
191
                // reduce available references to those which are sections of the publishedUnit and the publishedUnit itself
192
                // referencePagingProvider
193
                referencePagingProvider.getCriteria().add(Restrictions.or(
194
                        Restrictions.and(Restrictions.eq("inReference", publishedUnit), Restrictions.eq("type", ReferenceType.Section)),
195
                        Restrictions.idEq(publishedUnit.getId())
196
                        )
197
                );
198
                // and remove the empty option
199
                getView().getNomReferenceCombobox().getSelect().setNullSelectionAllowed(false);
200

    
201
                // new Reference only a sub sections of the publishedUnit
202
                newReferenceInstantiator = new BeanInstantiator<Reference>() {
203
                    @Override
204
                    public Reference createNewBean() {
205
                        Reference newRef = ReferenceFactory.newSection();
206
                        newRef.setInReference(publishedUnit);
207
                        return newRef;
208
                    }
209
                };
210

    
211
            }
212
        }
213

    
214
        return taxonName;
215
    }
216

    
217
    /**
218
     * {@inheritDoc}
219
     */
220
    @Override
221
    protected void guaranteePerEntityCRUDPermissions(UUID identifier) {
222
        if(crud != null){
223
            newAuthorityCreated = UserHelper.fromSession().createAuthorityForCurrentUser(TaxonName.class, identifier, crud, null);
224
        }
225

    
226
    }
227

    
228
    /**
229
     * {@inheritDoc}
230
     */
231
    @Override
232
    protected void guaranteePerEntityCRUDPermissions(TaxonName bean) {
233
        if(crud != null){
234
            newAuthorityCreated = UserHelper.fromSession().createAuthorityForCurrentUser(bean, crud, null);
235
        }
236
    }
237

    
238
    @Override
239
    protected TaxonName handleTransientProperties(TaxonName bean) {
240

    
241
        logger.trace(this._toString() + ".onEditorSaveEvent - handling transient properties");
242

    
243

    
244
        List<TaxonName> newBasionymNames = getView().getBasionymComboboxSelect().getValueFromNestedFields();
245
        Set<TaxonName> oldBasionyms = bean.getBasionyms();
246
        Set<TaxonName> updateBasionyms = new HashSet<>();
247
        Set<TaxonName> removeBasionyms = new HashSet<>();
248

    
249
        for(TaxonName newB : newBasionymNames){
250
            if(!oldBasionyms.contains(newB)){
251
                updateBasionyms.add(newB);
252
            }
253
        }
254

    
255
        for(TaxonName oldB : oldBasionyms){
256
            if(!newBasionymNames.contains(oldB)){
257
                removeBasionyms.add(oldB);
258
            }
259
        }
260
        for(TaxonName removeBasionym :removeBasionyms){
261
            Set<NameRelationship> removeRelations = new HashSet<NameRelationship>();
262
            for (NameRelationship nameRelation : bean.getRelationsToThisName()){
263
                if (nameRelation.getType().isBasionymRelation() && nameRelation.getFromName().equals(removeBasionym)){
264
                    removeRelations.add(nameRelation);
265
                }
266
            }
267
            for (NameRelationship relation : removeRelations){
268
                bean.removeNameRelationship(relation);
269
            }
270
        }
271
        getRepo().getSession().clear();
272
        for(TaxonName addBasionymName :updateBasionyms){
273
            if(addBasionymName != null){
274
                bean.addBasionym(addBasionymName);
275
            }
276
        }
277
        return bean;
278
    }
279

    
280
    /**
281
     * {@inheritDoc}
282
     */
283
    @Override
284
    protected INameService getService() {
285
        return getRepo().getNameService();
286
    }
287

    
288
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
289
    public void onReferenceEditorActionAdd(ReferenceEditorAction event) {
290

    
291
        if(getView() == null || event.getSourceView() != getView() ){
292
            return;
293
        }
294

    
295
        referenceEditorPopup = getNavigationManager().showInPopup(ReferencePopupEditor.class, getView());
296

    
297
        referenceEditorPopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
298
        referenceEditorPopup.withDeleteButton(true);
299
        referenceEditorPopup.setBeanInstantiator(newReferenceInstantiator);
300
        referenceEditorPopup.loadInEditor(null);
301
        if(newReferenceInstantiator != null){
302
            // this is a bit clumsy, we actually need to inject something like a view configurer
303
            // which can enable, disable fields
304
            referenceEditorPopup.getInReferenceCombobox().setEnabled(false);
305
            referenceEditorPopup.getTypeSelect().setEnabled(false);
306
        }
307
    }
308

    
309
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
310
    public void onReferenceEditorActionEdit(ReferenceEditorAction event) {
311

    
312

    
313
        if(getView() == null || event.getSourceView() != getView() ){
314
            return;
315
        }
316
        referenceEditorPopup = getNavigationManager().showInPopup(ReferencePopupEditor.class, getView());
317

    
318
        referenceEditorPopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
319
        referenceEditorPopup.withDeleteButton(true);
320
        referenceEditorPopup.setBeanInstantiator(newReferenceInstantiator);
321
        referenceEditorPopup.loadInEditor(event.getEntityUuid());
322
        if(newReferenceInstantiator != null){
323
            // this is a bit clumsy, we actually need to inject something like a view configurer
324
            // which can enable, disable fields
325
            referenceEditorPopup.getInReferenceCombobox().setEnabled(false);
326
            referenceEditorPopup.getTypeSelect().setEnabled(false);
327
        }
328
    }
329

    
330
    @EventBusListenerMethod
331
    public void onEntityChangeEvent(EntityChangeEvent<?> event){
332

    
333
        if(event.getSourceView() == referenceEditorPopup){
334
            if(event.isCreateOrModifiedType()){
335

    
336
                getCache().load(event.getEntity());
337
                if(event.isCreatedType()){
338
                    getView().getNomReferenceCombobox().setValue((Reference) event.getEntity());
339
                } else {
340
                    getView().getNomReferenceCombobox().reload(); // refreshSelectedValue(modifiedReference);
341
                }
342
                getView().getCombinationAuthorshipField().discard(); //refresh from the datasource
343
                getView().updateAuthorshipFields();
344
            }
345

    
346
            referenceEditorPopup = null;
347
        }
348
        if(event.getSourceView()  == basionymNamePopup){
349
            if(event.isCreateOrModifiedType()){
350

    
351
                getCache().load(event.getEntity());
352
                if(event.isCreatedType()){
353
                    basionymSourceField.setValue((TaxonName) event.getEntity());
354
                } else {
355
                    ((ReloadableSelect)basionymSourceField).reload();
356
                }
357
                getView().getBasionymAuthorshipField().discard(); //refresh from the datasource
358
                getView().getExBasionymAuthorshipField().discard(); //refresh from the datasource
359
                getView().updateAuthorshipFields();
360

    
361
            }
362
            if(event.isRemovedType()){
363
                basionymSourceField.setValue(null);
364
                getView().updateAuthorshipFields();
365
            }
366

    
367
            basionymNamePopup = null;
368
            basionymSourceField = null;
369
        }
370
    }
371

    
372
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
373
    public void onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
374

    
375
        if(getView() == null || event.getSourceView() != getView() ){
376
            return;
377
        }
378

    
379
        basionymSourceField = (ReloadableLazyComboBox<TaxonName>)event.getSourceComponent();
380

    
381
        basionymNamePopup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class, getView());
382
        basionymNamePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
383
        basionymNamePopup.withDeleteButton(true);
384
        getView().getModesActive().stream()
385
                .filter(
386
                        m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
387
                .forEach(m -> basionymNamePopup.enableMode(m));
388
        basionymNamePopup.loadInEditor(event.getEntityUuid());
389
        basionymNamePopup.getBasionymToggle().setVisible(false);
390

    
391
    }
392

    
393
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
394
    public void oTaxonNameEditorActionAdd(TaxonNameEditorAction event) {
395

    
396
        if(getView() == null || event.getSourceView() != getView() ){
397
            return;
398
        }
399

    
400
        basionymSourceField = (AbstractField<TaxonName>)event.getSourceComponent();
401

    
402
        basionymNamePopup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class, getView());
403
        basionymNamePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
404
        basionymNamePopup.withDeleteButton(true);
405
        getView().getModesActive().stream()
406
                .filter(
407
                        m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
408
                .forEach(m -> basionymNamePopup.enableMode(m));
409
        basionymNamePopup.loadInEditor(null);
410
        basionymNamePopup.getBasionymToggle().setVisible(false);
411
    }
412

    
413

    
414

    
415

    
416
}
(9-9/13)