Project

General

Profile

Download (17.5 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.cache.CdmEntityCache;
25
import eu.etaxonomy.cdm.debug.PersistentContextAnalyzer;
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.ReferenceEditorAction;
41
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
42
import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityButtonUpdater;
43
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
44
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
45
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
46
import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
47
import eu.etaxonomy.vaadin.mvp.AbstractCdmEditorPresenter;
48
import eu.etaxonomy.vaadin.mvp.BeanInstantiator;
49
import eu.etaxonomy.vaadin.ui.view.DoneWithPopupEvent;
50
import eu.etaxonomy.vaadin.ui.view.DoneWithPopupEvent.Reason;
51

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

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

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

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

    
68
    private ReferencePopupEditor referenceEditorPopup = null;
69

    
70
    private TaxonNamePopupEditor basionymNamePopup = null;
71

    
72
    private CdmFilterablePagingProvider<Reference, Reference> referencePagingProvider;
73

    
74
    private Reference publishedUnit;
75

    
76
    private BeanInstantiator<Reference> newReferenceInstantiator;
77

    
78
    private BeanInstantiator<TaxonName> newBasionymNameInstantiator;
79

    
80
    private AbstractField<TaxonName> basionymSourceField;
81

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

    
88
        super.handleViewEntered();
89

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

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

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

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

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

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

    
109
        getView().getNomReferenceCombobox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
110
        referencePagingProvider = new CdmFilterablePagingProvider<Reference, Reference>(getRepo().getReferenceService());
111
        getView().getNomReferenceCombobox().loadFrom(referencePagingProvider, referencePagingProvider, referencePagingProvider.getPageSize());
112
        getView().getNomReferenceCombobox().getSelect().addValueChangeListener(new ToOneRelatedEntityButtonUpdater<Reference>(getView().getNomReferenceCombobox()));
113

    
114
        getView().getBasionymComboboxSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
115

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

    
121
    /**
122
     * {@inheritDoc}
123
     */
124
    @Override
125
    protected TaxonName loadCdmEntityById(Integer identifier) {
126

    
127
        List<String> initStrategy = Arrays.asList(new String []{
128

    
129
                "$",
130
                "rank.vocabulary", // needed for comparing ranks
131

    
132
                "nomenclaturalReference.authorship",
133
                "nomenclaturalReference.inReference",
134

    
135
                "status.type",
136

    
137
                "combinationAuthorship",
138
                "exCombinationAuthorship",
139
                "basionymAuthorship",
140
                "exBasionymAuthorship",
141

    
142
                // basionyms: relationsToThisName.fromName
143
                "relationsToThisName.type",
144
                "relationsToThisName.fromName.rank",
145
                "relationsToThisName.fromName.nomenclaturalReference.authorship",
146
                "relationsToThisName.fromName.nomenclaturalReference.inReference",
147
                "relationsToThisName.fromName.relationsToThisName",
148
                "relationsToThisName.fromName.relationsFromThisName",
149

    
150
                "relationsFromThisName",
151
                //"relationsToThisName",
152
                "homotypicalGroup.typifiedNames"
153

    
154
                }
155
        );
156

    
157
        TaxonName taxonName;
158
        if(identifier != null){
159
            taxonName = getRepo().getNameService().load(identifier, initStrategy);
160
        } else {
161
            taxonName = TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
162
        }
163

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

    
182
                // new Reference only a sub sections of the publishedUnit
183
                newReferenceInstantiator = new BeanInstantiator<Reference>() {
184
                    @Override
185
                    public Reference createNewBean() {
186
                        Reference newRef = ReferenceFactory.newSection();
187
                        newRef.setInReference(publishedUnit);
188
                        return newRef;
189
                    }
190
                };
191

    
192
            }
193
        }
194

    
195
        return taxonName;
196
    }
197

    
198
    /**
199
     * {@inheritDoc}
200
     */
201
    @Override
202
    protected void guaranteePerEntityCRUDPermissions(Integer identifier) {
203
        if(crud != null){
204
            newAuthorityCreated = UserHelper.fromSession().createAuthorityForCurrentUser(TaxonName.class, identifier, crud, null);
205
        }
206

    
207
    }
208

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

    
219
    @Override
220
    protected TaxonName handleTransientProperties(TaxonName bean) {
221

    
222
        logger.trace(this._toString() + ".onEditorSaveEvent - handling transient properties");
223

    
224

    
225
        List<TaxonName> newBasionymNames = getView().getBasionymComboboxSelect().getValueFromNestedFields();
226
        Set<TaxonName> oldBasionyms = bean.getBasionyms();
227
        Set<TaxonName> updateBasionyms = new HashSet<>();
228
        Set<TaxonName> removeBasionyms = new HashSet<>();
229

    
230
        for(TaxonName newB : newBasionymNames){
231
            if(!oldBasionyms.contains(newB)){
232
                updateBasionyms.add(newB);
233
            }
234
        }
235

    
236
        for(TaxonName oldB : oldBasionyms){
237
            if(!newBasionymNames.contains(oldB)){
238
                removeBasionyms.add(oldB);
239
            }
240
        }
241
        for(TaxonName removeBasionym :removeBasionyms){
242
            Set<NameRelationship> removeRelations = new HashSet<NameRelationship>();
243
            for (NameRelationship nameRelation : bean.getRelationsToThisName()){
244
                if (nameRelation.getType().isBasionymRelation() && nameRelation.getFromName().equals(removeBasionym)){
245
                    removeRelations.add(nameRelation);
246
                }
247
            }
248
            for (NameRelationship relation : removeRelations){
249
                bean.removeNameRelationship(relation);
250
            }
251
        }
252
        // updateBasionyms.clear(); // DEBUGGING #########################
253
        getRepo().getSession().clear();
254
        for(TaxonName addBasionymName :updateBasionyms){
255
            if(addBasionymName != null){
256
                // if(addBasionymName.getUuid() != null){
257
                    // reload
258

    
259
                    System.err.println("====== Cache ======");
260
                    addBasionymName = getRepo().getNameService().load(addBasionymName.getUuid(), BASIONYM_INIT_STRATEGY);
261
                    PersistentContextAnalyzer pca = new PersistentContextAnalyzer((CdmEntityCache)getCache(), getRepo().getSession());
262
                    pca.setShowHashCodes(true);
263
                    pca.printEntityGraph(System.err);
264
                    pca.printCopyEntities(System.err);
265

    
266
                    System.err.println("====== Basionym ======");
267
                    PersistentContextAnalyzer basiopca = new PersistentContextAnalyzer(addBasionymName, getRepo().getSession());
268
                    basiopca.setShowHashCodes(true);
269
                    basiopca.printEntityGraph(System.err);
270

    
271
                    TaxonName cachedName = getCache().find(addBasionymName);
272
                    if(cachedName != null){
273
                        System.err.println("====== Cached Basionym ======");
274
                        PersistentContextAnalyzer cahedbasiopca = new PersistentContextAnalyzer(addBasionymName, getRepo().getSession());
275
                        cahedbasiopca.setShowHashCodes(true);
276
                        cahedbasiopca.printEntityGraph(System.err);
277
                        addBasionymName = cachedName;
278
                    }
279
                // }
280
                bean.addBasionym(addBasionymName);
281
            }
282
        }
283
        return bean;
284
    }
285

    
286
    /**
287
     * {@inheritDoc}
288
     */
289
    @Override
290
    protected INameService getService() {
291
        return getRepo().getNameService();
292
    }
293

    
294
    @EventListener(condition = "#event.type == T(eu.etaxonomy.vaadin.event.EditorActionType).ADD")
295
    public void onReferenceEditorActionAdd(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(null);
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(condition = "#event.type == T(eu.etaxonomy.vaadin.event.EditorActionType).EDIT")
315
    public void onReferenceEditorActionEdit(ReferenceEditorAction event) {
316

    
317
        if(getView() == null || event.getSourceView() != getView() ){
318
            return;
319
        }
320
        referenceEditorPopup = getNavigationManager().showInPopup(ReferencePopupEditor.class);
321

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

    
334
    @EventListener
335
    public void onDoneWithPopupEvent(DoneWithPopupEvent event){
336

    
337
        if(event.getPopup() == referenceEditorPopup){
338
            if(event.getReason() == Reason.SAVE){
339

    
340
                Reference modifiedReference = referenceEditorPopup.getBean();
341

    
342
                // TODO the bean contained in the popup editor is not yet updated at this point.
343
                //      so re reload it using the uuid since new beans will not have an Id at this point.
344
                modifiedReference = getRepo().getReferenceService().load(modifiedReference.getUuid(), Arrays.asList("inReference"));
345
                getView().getNomReferenceCombobox().setValue(modifiedReference);
346
            }
347

    
348
            referenceEditorPopup = null;
349
        }
350
        if(event.getPopup() == basionymNamePopup){
351
            if(event.getReason() == Reason.SAVE){
352
                TaxonName modifiedTaxonName = basionymNamePopup.getBean();
353

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

    
359
                // TODO create blocking registration
360
            }
361
            if(event.getReason() == Reason.DELETE){
362
                basionymSourceField.setValue(null);
363
            }
364

    
365
            basionymNamePopup = null;
366
            basionymSourceField = null;
367
        }
368
    }
369

    
370
    @EventListener(condition = "#event.type == T(eu.etaxonomy.vaadin.event.EditorActionType).EDIT")
371
    public void onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
372

    
373
        if(getView() == null || event.getSourceView() != getView() ){
374
            return;
375
        }
376
        basionymSourceField = (AbstractField<TaxonName>)event.getSourceComponent();
377

    
378
        basionymNamePopup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class);
379
        basionymNamePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
380
        basionymNamePopup.withDeleteButton(true);
381
        basionymNamePopup.loadInEditor(event.getEntityId());
382
        basionymNamePopup.getBasionymToggle().setVisible(false);
383

    
384
    }
385

    
386
    @EventListener(condition = "#event.type == T(eu.etaxonomy.vaadin.event.EditorActionType).ADD")
387
    public void onReferenceEditorActionAdd(TaxonNameEditorAction event) {
388

    
389
        if(getView() == null || event.getSourceView() != getView() ){
390
            return;
391
        }
392
        basionymSourceField = (AbstractField<TaxonName>)event.getSourceComponent();
393

    
394
        basionymNamePopup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class);
395
        basionymNamePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
396
        basionymNamePopup.withDeleteButton(true);
397
        basionymNamePopup.loadInEditor(null);
398
        basionymNamePopup.getBasionymToggle().setVisible(false);
399
    }
400

    
401

    
402
}
(6-6/10)