Project

General

Profile

Download (17.4 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.component.ReloadableSelect;
50
import eu.etaxonomy.vaadin.mvp.AbstractCdmEditorPresenter;
51
import eu.etaxonomy.vaadin.mvp.BeanInstantiator;
52
import eu.etaxonomy.vaadin.ui.view.DoneWithPopupEvent;
53
import eu.etaxonomy.vaadin.ui.view.DoneWithPopupEvent.Reason;
54

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

    
64
    /**
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
        CdmFilterablePagingProvider<AgentBase, Person> personPagingProvider = new CdmFilterablePagingProvider<AgentBase, Person>(getRepo().getAgentService(), Person.class);
108

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

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

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

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

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

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

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

    
135
    /**
136
     * {@inheritDoc}
137
     */
138
    @Override
139
    protected TaxonName loadCdmEntityById(Integer identifier) {
140

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

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

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

    
151
                "status.type",
152

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

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

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

    
172
                }
173
        );
174

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

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

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

    
210
            }
211
        }
212

    
213
        return taxonName;
214
    }
215

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

    
225
    }
226

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

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

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

    
242

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

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

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

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

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

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

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

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

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

    
311

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

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

    
329
    @EventBusListenerMethod
330
    public void onDoneWithPopupEvent(DoneWithPopupEvent event){
331

    
332
        if(event.getPopup() == referenceEditorPopup){
333
            if(event.getReason() == Reason.SAVE){
334

    
335
                getCache().load(referenceEditorPopup.getBean());
336
                getView().getNomReferenceCombobox().reload(); // refreshSelectedValue(modifiedReference);
337
                getView().getCombinationAuthorshipField().discard(); //refresh from the datasource
338
                getView().updateAuthorshipFields();
339
            }
340

    
341
            referenceEditorPopup = null;
342
        }
343
        if(event.getPopup() == basionymNamePopup){
344
            if(event.getReason() == Reason.SAVE){
345

    
346
                getCache().load(basionymNamePopup.getBean());
347
                ((ReloadableSelect)basionymSourceField).reload();
348
                getView().getBasionymAuthorshipField().discard(); //refresh from the datasource
349
                getView().getExBasionymAuthorshipField().discard(); //refresh from the datasource
350
                getView().updateAuthorshipFields();
351

    
352
            }
353
            if(event.getReason() == Reason.DELETE){
354
                basionymSourceField.setValue(null);
355
            }
356

    
357
            basionymNamePopup = null;
358
            basionymSourceField = null;
359
        }
360
    }
361

    
362
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
363
    public void onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
364

    
365
        if(getView() == null || event.getSourceView() != getView() ){
366
            return;
367
        }
368

    
369
        basionymSourceField = (AbstractField<TaxonName>)event.getSourceComponent();
370

    
371
        basionymNamePopup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class, getView());
372
        basionymNamePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
373
        basionymNamePopup.withDeleteButton(true);
374
        getView().getModesActive().stream()
375
                .filter(
376
                        m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
377
                .forEach(m -> basionymNamePopup.enableMode(m));
378
        basionymNamePopup.loadInEditor(event.getEntityId());
379
        basionymNamePopup.getBasionymToggle().setVisible(false);
380

    
381
    }
382

    
383
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
384
    public void oTaxonNameEditorActionAdd(TaxonNameEditorAction event) {
385

    
386
        if(getView() == null || event.getSourceView() != getView() ){
387
            return;
388
        }
389

    
390
        basionymSourceField = (AbstractField<TaxonName>)event.getSourceComponent();
391

    
392
        basionymNamePopup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class, getView());
393
        basionymNamePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
394
        basionymNamePopup.withDeleteButton(true);
395
        getView().getModesActive().stream()
396
                .filter(
397
                        m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
398
                .forEach(m -> basionymNamePopup.enableMode(m));
399
        basionymNamePopup.loadInEditor(null);
400
        basionymNamePopup.getBasionymToggle().setVisible(false);
401
    }
402

    
403

    
404

    
405

    
406
}
(9-9/13)