Project

General

Profile

Download (16.7 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.event.EventListener;
20

    
21
import com.vaadin.ui.AbstractField;
22

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

    
51
/**
52
 * @author a.kohlbecker
53
 * @since May 22, 2017
54
 *
55
 */
56
public class TaxonNameEditorPresenter extends AbstractCdmEditorPresenter<TaxonName, TaxonNamePopupEditorView> {
57

    
58
    /**
59
     *
60
     */
61
    private static final List<String> BASIONYM_INIT_STRATEGY = Arrays.asList("$", "relationsFromThisName", "relationsToThisName.type", "homotypicalGroup.typifiedNames");
62

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

    
65
    private static final long serialVersionUID = -3538980627079389221L;
66

    
67
    private static final Logger logger = Logger.getLogger(TaxonNameEditorPresenter.class);
68

    
69
    private ReferencePopupEditor referenceEditorPopup = null;
70

    
71
    private TaxonNamePopupEditor basionymNamePopup = null;
72

    
73
    private CdmFilterablePagingProvider<Reference, Reference> referencePagingProvider;
74

    
75
    private Reference publishedUnit;
76

    
77
    private BeanInstantiator<Reference> newReferenceInstantiator;
78

    
79
    private BeanInstantiator<TaxonName> newBasionymNameInstantiator;
80

    
81
    private AbstractField<TaxonName> basionymSourceField;
82

    
83
    /**
84
     * {@inheritDoc}
85
     */
86
    @Override
87
    public void handleViewEntered() {
88

    
89
        super.handleViewEntered();
90

    
91
        CdmBeanItemContainerFactory selectFieldFactory = new CdmBeanItemContainerFactory(getRepo());
92
        getView().getRankSelect().setContainerDataSource(selectFieldFactory.buildBeanItemContainer(TermType.Rank));
93
        getView().getRankSelect().setItemCaptionPropertyId("label");
94

    
95
        CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase> termOrPersonPagingProvider = new CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase>(getRepo().getAgentService(), TeamOrPersonBase.class);
96
        CdmFilterablePagingProvider<AgentBase, Person> personPagingProvider = new CdmFilterablePagingProvider<AgentBase, Person>(getRepo().getAgentService(), Person.class);
97

    
98
        getView().getCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
99
        getView().getCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
100

    
101
        getView().getExCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
102
        getView().getExCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
103

    
104
        getView().getBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
105
        getView().getBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
106

    
107
        getView().getExBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
108
        getView().getExBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
109

    
110
        getView().getNomReferenceCombobox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
111
        referencePagingProvider = new CdmFilterablePagingProvider<Reference, Reference>(getRepo().getReferenceService());
112
        referencePagingProvider.setInitStrategy(REFERENCE_INIT_STRATEGY);
113
        getView().getNomReferenceCombobox().loadFrom(referencePagingProvider, referencePagingProvider, referencePagingProvider.getPageSize());
114
        getView().getNomReferenceCombobox().getSelect().addValueChangeListener(new ToOneRelatedEntityButtonUpdater<Reference>(getView().getNomReferenceCombobox()));
115
        getView().getNomReferenceCombobox().getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getNomReferenceCombobox(), this));
116

    
117
        getView().getBasionymComboboxSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
118

    
119
        CdmFilterablePagingProvider<TaxonName, TaxonName> basionymPagingProvider = new CdmFilterablePagingProvider<TaxonName, TaxonName>(getRepo().getNameService());
120
        basionymPagingProvider.setInitStrategy(BASIONYM_INIT_STRATEGY);
121
        getView().getBasionymComboboxSelect().setPagingProviders(basionymPagingProvider, basionymPagingProvider, basionymPagingProvider.getPageSize(), this);
122
    }
123

    
124
    /**
125
     * {@inheritDoc}
126
     */
127
    @Override
128
    protected TaxonName loadCdmEntityById(Integer identifier) {
129

    
130
        List<String> initStrategy = Arrays.asList(new String []{
131

    
132
                "$",
133
                "rank.vocabulary", // needed for comparing ranks
134

    
135
                "nomenclaturalReference.authorship",
136
                "nomenclaturalReference.inReference.authorship",
137
                "nomenclaturalReference.inReference.inReference.authorship",
138
                "nomenclaturalReference.inReference.inReference.inReference.authorship",
139

    
140
                "status.type",
141

    
142
                "combinationAuthorship",
143
                "exCombinationAuthorship",
144
                "basionymAuthorship",
145
                "exBasionymAuthorship",
146

    
147
                // basionyms: relationsToThisName.fromName
148
                "relationsToThisName.type",
149
                "relationsToThisName.fromName.rank",
150
                "relationsToThisName.fromName.nomenclaturalReference.authorship",
151
                "relationsToThisName.fromName.nomenclaturalReference.inReference.authorship",
152
                "relationsToThisName.fromName.nomenclaturalReference.inReference.inReference.inReference.authorship",
153
                "relationsToThisName.fromName.relationsToThisName",
154
                "relationsToThisName.fromName.relationsFromThisName",
155

    
156
                "relationsFromThisName",
157
                "homotypicalGroup.typifiedNames"
158

    
159
                }
160
        );
161

    
162
        TaxonName taxonName;
163
        if(identifier != null){
164
            taxonName = getRepo().getNameService().load(identifier, initStrategy);
165
        } else {
166
            taxonName = TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
167
        }
168

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

    
187
                // new Reference only a sub sections of the publishedUnit
188
                newReferenceInstantiator = new BeanInstantiator<Reference>() {
189
                    @Override
190
                    public Reference createNewBean() {
191
                        Reference newRef = ReferenceFactory.newSection();
192
                        newRef.setInReference(publishedUnit);
193
                        return newRef;
194
                    }
195
                };
196

    
197
            }
198
        }
199

    
200
        return taxonName;
201
    }
202

    
203
    /**
204
     * {@inheritDoc}
205
     */
206
    @Override
207
    protected void guaranteePerEntityCRUDPermissions(Integer identifier) {
208
        if(crud != null){
209
            newAuthorityCreated = UserHelper.fromSession().createAuthorityForCurrentUser(TaxonName.class, identifier, crud, null);
210
        }
211

    
212
    }
213

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

    
224
    @Override
225
    protected TaxonName handleTransientProperties(TaxonName bean) {
226

    
227
        logger.trace(this._toString() + ".onEditorSaveEvent - handling transient properties");
228

    
229

    
230
        List<TaxonName> newBasionymNames = getView().getBasionymComboboxSelect().getValueFromNestedFields();
231
        Set<TaxonName> oldBasionyms = bean.getBasionyms();
232
        Set<TaxonName> updateBasionyms = new HashSet<>();
233
        Set<TaxonName> removeBasionyms = new HashSet<>();
234

    
235
        for(TaxonName newB : newBasionymNames){
236
            if(!oldBasionyms.contains(newB)){
237
                updateBasionyms.add(newB);
238
            }
239
        }
240

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

    
266
    /**
267
     * {@inheritDoc}
268
     */
269
    @Override
270
    protected INameService getService() {
271
        return getRepo().getNameService();
272
    }
273

    
274
    @EventListener(condition = "#event.type == T(eu.etaxonomy.vaadin.event.EditorActionType).ADD")
275
    public void onReferenceEditorActionAdd(ReferenceEditorAction event) {
276

    
277
        if(getView() == null || event.getSourceView() != getView() ){
278
            return;
279
        }
280
        referenceEditorPopup = getNavigationManager().showInPopup(ReferencePopupEditor.class);
281

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

    
294
    @EventListener(condition = "#event.type == T(eu.etaxonomy.vaadin.event.EditorActionType).EDIT")
295
    public void onReferenceEditorActionEdit(ReferenceEditorAction event) {
296

    
297
        if(getView() == null || event.getSourceView() != getView() ){
298
            return;
299
        }
300
        referenceEditorPopup = getNavigationManager().showInPopup(ReferencePopupEditor.class);
301

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

    
314
    @EventListener
315
    public void onDoneWithPopupEvent(DoneWithPopupEvent event){
316

    
317
        if(event.getPopup() == referenceEditorPopup){
318
            if(event.getReason() == Reason.SAVE){
319

    
320
                Reference modifiedReference = referenceEditorPopup.getBean();
321

    
322
                // TODO the bean contained in the popup editor is not yet updated at this point.
323
                //      so re reload it using the uuid since new beans will not have an Id at this point.
324
                modifiedReference = getRepo().getReferenceService().load(modifiedReference.getUuid(), Arrays.asList("inReference"));
325
                getView().getNomReferenceCombobox().setValue(modifiedReference);
326
            }
327

    
328
            referenceEditorPopup = null;
329
        }
330
        if(event.getPopup() == basionymNamePopup){
331
            if(event.getReason() == Reason.SAVE){
332
                TaxonName modifiedTaxonName = basionymNamePopup.getBean();
333

    
334
                // TODO the bean contained in the popup editor is not yet updated at this point.
335
                //      so re reload it using the uuid since new beans will not have an Id at this point.
336
                modifiedTaxonName = getRepo().getNameService().load(modifiedTaxonName.getUuid(), BASIONYM_INIT_STRATEGY);
337
                basionymSourceField.setValue(modifiedTaxonName);
338

    
339
                // TODO create blocking registration
340
            }
341
            if(event.getReason() == Reason.DELETE){
342
                basionymSourceField.setValue(null);
343
            }
344

    
345
            basionymNamePopup = null;
346
            basionymSourceField = null;
347
        }
348
    }
349

    
350
    @EventListener(condition = "#event.type == T(eu.etaxonomy.vaadin.event.EditorActionType).EDIT")
351
    public void onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
352

    
353
        if(getView() == null || event.getSourceView() != getView() ){
354
            return;
355
        }
356
        basionymSourceField = (AbstractField<TaxonName>)event.getSourceComponent();
357

    
358
        basionymNamePopup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class);
359
        basionymNamePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
360
        basionymNamePopup.withDeleteButton(true);
361
        basionymNamePopup.loadInEditor(event.getEntityId());
362
        basionymNamePopup.getBasionymToggle().setVisible(false);
363

    
364
    }
365

    
366
    @EventListener(condition = "#event.type == T(eu.etaxonomy.vaadin.event.EditorActionType).ADD")
367
    public void onReferenceEditorActionAdd(TaxonNameEditorAction event) {
368

    
369
        if(getView() == null || event.getSourceView() != getView() ){
370
            return;
371
        }
372
        basionymSourceField = (AbstractField<TaxonName>)event.getSourceComponent();
373

    
374
        basionymNamePopup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class);
375
        basionymNamePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
376
        basionymNamePopup.withDeleteButton(true);
377
        basionymNamePopup.loadInEditor(null);
378
        basionymNamePopup.getBasionymToggle().setVisible(false);
379
    }
380

    
381

    
382
}
(6-6/10)