Project

General

Profile

Download (17.3 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

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

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

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

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

    
63
    /**
64
     *
65
     */
66
    private static final List<String> BASIONYM_INIT_STRATEGY = Arrays.asList("$", "relationsFromThisName", "relationsToThisName.type", "homotypicalGroup.typifiedNames");
67

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

    
70
    private static final long serialVersionUID = -3538980627079389221L;
71

    
72
    private static final Logger logger = Logger.getLogger(TaxonNameEditorPresenter.class);
73

    
74
    private ReferencePopupEditor referenceEditorPopup = null;
75

    
76
    private TaxonNamePopupEditor basionymNamePopup = null;
77

    
78
    private CdmFilterablePagingProvider<Reference, Reference> referencePagingProvider;
79

    
80
    private Reference publishedUnit;
81

    
82
    private BeanInstantiator<Reference> newReferenceInstantiator;
83

    
84
    private BeanInstantiator<TaxonName> newBasionymNameInstantiator;
85

    
86
    private AbstractField<TaxonName> basionymSourceField;
87

    
88
    /**
89
     * {@inheritDoc}
90
     */
91
    @Override
92
    public void handleViewEntered() {
93

    
94
        super.handleViewEntered();
95

    
96
        CdmBeanItemContainerFactory selectFieldFactory = new CdmBeanItemContainerFactory(getRepo());
97
        getView().getRankSelect().setContainerDataSource(selectFieldFactory.buildBeanItemContainer(TermType.Rank));
98
        getView().getRankSelect().setItemCaptionPropertyId("label");
99

    
100
        CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase> termOrPersonPagingProvider = new CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase>(getRepo().getAgentService(), TeamOrPersonBase.class);
101
        CdmFilterablePagingProvider<AgentBase, Person> personPagingProvider = new CdmFilterablePagingProvider<AgentBase, Person>(getRepo().getAgentService(), Person.class);
102

    
103
        getView().getCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
104
        getView().getCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
105

    
106
        getView().getExCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
107
        getView().getExCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
108

    
109
        getView().getBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
110
        getView().getBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
111

    
112
        getView().getExBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
113
        getView().getExBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
114

    
115
        getView().getNomReferenceCombobox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
116
        referencePagingProvider = new CdmFilterablePagingProvider<Reference, Reference>(getRepo().getReferenceService());
117
        referencePagingProvider.setInitStrategy(REFERENCE_INIT_STRATEGY);
118
        getView().getNomReferenceCombobox().loadFrom(referencePagingProvider, referencePagingProvider, referencePagingProvider.getPageSize());
119
        getView().getNomReferenceCombobox().getSelect().addValueChangeListener(new ToOneRelatedEntityButtonUpdater<Reference>(getView().getNomReferenceCombobox()));
120
        getView().getNomReferenceCombobox().getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getNomReferenceCombobox(), this));
121

    
122
        getView().getBasionymComboboxSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
123

    
124
        CdmFilterablePagingProvider<TaxonName, TaxonName> basionymPagingProvider = new CdmFilterablePagingProvider<TaxonName, TaxonName>(getRepo().getNameService());
125
        basionymPagingProvider.setInitStrategy(BASIONYM_INIT_STRATEGY);
126
        getView().getBasionymComboboxSelect().setPagingProviders(basionymPagingProvider, basionymPagingProvider, basionymPagingProvider.getPageSize(), this);
127
    }
128

    
129
    /**
130
     * {@inheritDoc}
131
     */
132
    @Override
133
    protected TaxonName loadCdmEntityById(Integer identifier) {
134

    
135
        List<String> initStrategy = Arrays.asList(new String []{
136

    
137
                "$",
138
                "rank.vocabulary", // needed for comparing ranks
139

    
140
                "nomenclaturalReference.authorship",
141
                "nomenclaturalReference.inReference.authorship",
142
                "nomenclaturalReference.inReference.inReference.authorship",
143
                "nomenclaturalReference.inReference.inReference.inReference.authorship",
144

    
145
                "status.type",
146

    
147
                "combinationAuthorship",
148
                "exCombinationAuthorship",
149
                "basionymAuthorship",
150
                "exBasionymAuthorship",
151

    
152
                // basionyms: relationsToThisName.fromName
153
                "relationsToThisName.type",
154
                "relationsToThisName.fromName.rank",
155
                "relationsToThisName.fromName.nomenclaturalReference.authorship",
156
                "relationsToThisName.fromName.nomenclaturalReference.inReference.authorship",
157
                "relationsToThisName.fromName.nomenclaturalReference.inReference.inReference.inReference.authorship",
158
                "relationsToThisName.fromName.relationsToThisName",
159
                "relationsToThisName.fromName.relationsFromThisName",
160

    
161
                "relationsFromThisName",
162
                "homotypicalGroup.typifiedNames"
163

    
164
                }
165
        );
166

    
167
        TaxonName taxonName;
168
        if(identifier != null){
169
            taxonName = getRepo().getNameService().load(identifier, initStrategy);
170
        } else {
171
            taxonName = TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
172
        }
173

    
174
        if(getView().isModeEnabled(TaxonNamePopupEditorMode.nomenclaturalReferenceSectionEditingOnly)){
175
            if(taxonName.getNomenclaturalReference() != null){
176
                Reference nomRef = (Reference)taxonName.getNomenclaturalReference();
177
                //getView().getNomReferenceCombobox().setEnabled(nomRef.isOfType(ReferenceType.Section));
178
                publishedUnit = nomRef;
179
                while(publishedUnit.isOfType(ReferenceType.Section) && publishedUnit.getInReference() != null){
180
                    publishedUnit = nomRef.getInReference();
181
                }
182
                // reduce available references to those which are sections of the publishedUnit and the publishedUnit itself
183
                // referencePagingProvider
184
                referencePagingProvider.getCriteria().add(Restrictions.or(
185
                        Restrictions.and(Restrictions.eq("inReference", publishedUnit), Restrictions.eq("type", ReferenceType.Section)),
186
                        Restrictions.idEq(publishedUnit.getId())
187
                        )
188
                );
189
                // and remove the empty option
190
                getView().getNomReferenceCombobox().getSelect().setNullSelectionAllowed(false);
191

    
192
                // new Reference only a sub sections of the publishedUnit
193
                newReferenceInstantiator = new BeanInstantiator<Reference>() {
194
                    @Override
195
                    public Reference createNewBean() {
196
                        Reference newRef = ReferenceFactory.newSection();
197
                        newRef.setInReference(publishedUnit);
198
                        return newRef;
199
                    }
200
                };
201

    
202
            }
203
        }
204

    
205
        return taxonName;
206
    }
207

    
208
    /**
209
     * {@inheritDoc}
210
     */
211
    @Override
212
    protected void guaranteePerEntityCRUDPermissions(Integer identifier) {
213
        if(crud != null){
214
            newAuthorityCreated = UserHelper.fromSession().createAuthorityForCurrentUser(TaxonName.class, identifier, crud, null);
215
        }
216

    
217
    }
218

    
219
    /**
220
     * {@inheritDoc}
221
     */
222
    @Override
223
    protected void guaranteePerEntityCRUDPermissions(TaxonName bean) {
224
        if(crud != null){
225
            newAuthorityCreated = UserHelper.fromSession().createAuthorityForCurrentUser(bean, crud, null);
226
        }
227
    }
228

    
229
    @Override
230
    protected TaxonName handleTransientProperties(TaxonName bean) {
231

    
232
        logger.trace(this._toString() + ".onEditorSaveEvent - handling transient properties");
233

    
234

    
235
        List<TaxonName> newBasionymNames = getView().getBasionymComboboxSelect().getValueFromNestedFields();
236
        Set<TaxonName> oldBasionyms = bean.getBasionyms();
237
        Set<TaxonName> updateBasionyms = new HashSet<>();
238
        Set<TaxonName> removeBasionyms = new HashSet<>();
239

    
240
        for(TaxonName newB : newBasionymNames){
241
            if(!oldBasionyms.contains(newB)){
242
                updateBasionyms.add(newB);
243
            }
244
        }
245

    
246
        for(TaxonName oldB : oldBasionyms){
247
            if(!newBasionymNames.contains(oldB)){
248
                removeBasionyms.add(oldB);
249
            }
250
        }
251
        for(TaxonName removeBasionym :removeBasionyms){
252
            Set<NameRelationship> removeRelations = new HashSet<NameRelationship>();
253
            for (NameRelationship nameRelation : bean.getRelationsToThisName()){
254
                if (nameRelation.getType().isBasionymRelation() && nameRelation.getFromName().equals(removeBasionym)){
255
                    removeRelations.add(nameRelation);
256
                }
257
            }
258
            for (NameRelationship relation : removeRelations){
259
                bean.removeNameRelationship(relation);
260
            }
261
        }
262
        getRepo().getSession().clear();
263
        for(TaxonName addBasionymName :updateBasionyms){
264
            if(addBasionymName != null){
265
                bean.addBasionym(addBasionymName);
266
            }
267
        }
268
        return bean;
269
    }
270

    
271
    /**
272
     * {@inheritDoc}
273
     */
274
    @Override
275
    protected INameService getService() {
276
        return getRepo().getNameService();
277
    }
278

    
279
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
280
    public void onReferenceEditorActionAdd(ReferenceEditorAction event) {
281

    
282
        if(getView() == null || event.getSourceView() != getView() ){
283
            return;
284
        }
285

    
286
        referenceEditorPopup = getNavigationManager().showInPopup(ReferencePopupEditor.class, getView());
287

    
288
        referenceEditorPopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
289
        referenceEditorPopup.withDeleteButton(true);
290
        referenceEditorPopup.setBeanInstantiator(newReferenceInstantiator);
291
        referenceEditorPopup.loadInEditor(null);
292
        if(newReferenceInstantiator != null){
293
            // this is a bit clumsy, we actually need to inject something like a view configurer
294
            // which can enable, disable fields
295
            referenceEditorPopup.getInReferenceCombobox().setEnabled(false);
296
            referenceEditorPopup.getTypeSelect().setEnabled(false);
297
        }
298
    }
299

    
300
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
301
    public void onReferenceEditorActionEdit(ReferenceEditorAction event) {
302

    
303

    
304
        if(getView() == null || event.getSourceView() != getView() ){
305
            return;
306
        }
307
        referenceEditorPopup = getNavigationManager().showInPopup(ReferencePopupEditor.class, getView());
308

    
309
        referenceEditorPopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
310
        referenceEditorPopup.withDeleteButton(true);
311
        referenceEditorPopup.setBeanInstantiator(newReferenceInstantiator);
312
        referenceEditorPopup.loadInEditor(event.getEntityId());
313
        if(newReferenceInstantiator != null){
314
            // this is a bit clumsy, we actually need to inject something like a view configurer
315
            // which can enable, disable fields
316
            referenceEditorPopup.getInReferenceCombobox().setEnabled(false);
317
            referenceEditorPopup.getTypeSelect().setEnabled(false);
318
        }
319
    }
320

    
321
    @EventBusListenerMethod
322
    public void onDoneWithPopupEvent(DoneWithPopupEvent event){
323

    
324
        if(event.getPopup() == referenceEditorPopup){
325
            if(event.getReason() == Reason.SAVE){
326

    
327
                Reference modifiedReference = referenceEditorPopup.getBean();
328

    
329
                // the bean contained in the popup editor is not yet updated at this point.
330
                // so re reload it using the uuid since new beans might not have an Id at this point.
331
                modifiedReference = getRepo().getReferenceService().load(modifiedReference.getUuid(), Arrays.asList("inReference"));
332
                getView().getNomReferenceCombobox().setValue(modifiedReference);
333
            }
334

    
335
            referenceEditorPopup = null;
336
        }
337
        if(event.getPopup() == basionymNamePopup){
338
            if(event.getReason() == Reason.SAVE){
339
                TaxonName modifiedTaxonName = basionymNamePopup.getBean();
340

    
341
                // the bean contained in the popup editor is not yet updated at this point.
342
                // so re reload it using the uuid since new beans might not have an Id at this point.
343
                modifiedTaxonName = getRepo().getNameService().load(modifiedTaxonName.getUuid(), BASIONYM_INIT_STRATEGY);
344
                basionymSourceField.setValue(modifiedTaxonName);
345

    
346
            }
347
            if(event.getReason() == Reason.DELETE){
348
                basionymSourceField.setValue(null);
349
            }
350

    
351
            basionymNamePopup = null;
352
            basionymSourceField = null;
353
        }
354
    }
355

    
356
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
357
    public void onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
358

    
359
        if(getView() == null || event.getSourceView() != getView() ){
360
            return;
361
        }
362

    
363
        basionymSourceField = (AbstractField<TaxonName>)event.getSourceComponent();
364

    
365
        basionymNamePopup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class, getView());
366
        basionymNamePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
367
        basionymNamePopup.withDeleteButton(true);
368
        getView().getModesActive().stream()
369
                .filter(
370
                        m -> !TaxonNamePopupEditorMode.nomenclaturalReferenceSectionEditingOnly.equals(m))
371
                .forEach(m -> basionymNamePopup.enableMode(m));
372
        basionymNamePopup.loadInEditor(event.getEntityId());
373
        basionymNamePopup.getBasionymToggle().setVisible(false);
374

    
375
    }
376

    
377
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
378
    public void oTaxonNameEditorActionAdd(TaxonNameEditorAction event) {
379

    
380
        if(getView() == null || event.getSourceView() != getView() ){
381
            return;
382
        }
383

    
384
        basionymSourceField = (AbstractField<TaxonName>)event.getSourceComponent();
385

    
386
        basionymNamePopup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class, getView());
387
        basionymNamePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
388
        basionymNamePopup.withDeleteButton(true);
389
        getView().getModesActive().stream()
390
                .filter(
391
                        m -> !TaxonNamePopupEditorMode.nomenclaturalReferenceSectionEditingOnly.equals(m))
392
                .forEach(m -> basionymNamePopup.enableMode(m));
393
        basionymNamePopup.loadInEditor(null);
394
        basionymNamePopup.getBasionymToggle().setVisible(false);
395
    }
396

    
397

    
398

    
399

    
400
}
(9-9/13)