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", "relationsToThisName.type", "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
                "homotypicalGroup.typifiedNames"
152

    
153
                }
154
        );
155

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

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

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

    
191
            }
192
        }
193

    
194
        return taxonName;
195
    }
196

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

    
206
    }
207

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

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

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

    
223

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

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

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

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

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

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

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

    
293
    @EventListener(condition = "#event.type == T(eu.etaxonomy.vaadin.event.EditorActionType).ADD")
294
    public void onReferenceEditorActionAdd(ReferenceEditorAction event) {
295

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

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

    
313
    @EventListener(condition = "#event.type == T(eu.etaxonomy.vaadin.event.EditorActionType).EDIT")
314
    public void onReferenceEditorActionEdit(ReferenceEditorAction event) {
315

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

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

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

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

    
339
                Reference modifiedReference = referenceEditorPopup.getBean();
340

    
341
                // TODO 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 will not have an Id at this point.
343
                modifiedReference = getRepo().getReferenceService().load(modifiedReference.getUuid(), Arrays.asList("inReference"));
344
                getView().getNomReferenceCombobox().setValue(modifiedReference);
345
            }
346

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

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

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

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

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

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

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

    
383
    }
384

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

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

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

    
400

    
401
}
(6-6/10)