Project

General

Profile

Download (17.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
import java.util.UUID;
17

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

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

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

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

    
65

    
66
    private static final List<String> BASIONYM_INIT_STRATEGY = Arrays.asList(
67
            "$",
68
            "relationsFromThisName",
69
            "relationsToThisName.type",
70
            "homotypicalGroup.typifiedNames"
71
            );
72

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

    
75
    private static final long serialVersionUID = -3538980627079389221L;
76

    
77
    private static final Logger logger = Logger.getLogger(TaxonNameEditorPresenter.class);
78

    
79
    private ReferencePopupEditor referenceEditorPopup = null;
80

    
81
    private TaxonNamePopupEditor basionymNamePopup = null;
82

    
83
    private CdmFilterablePagingProvider<Reference, Reference> referencePagingProvider;
84

    
85
    private Reference publishedUnit;
86

    
87
    private BeanInstantiator<Reference> newReferenceInstantiator;
88

    
89
    private BeanInstantiator<TaxonName> newBasionymNameInstantiator;
90

    
91
    private AbstractField<TaxonName> basionymSourceField;
92

    
93
    /**
94
     * {@inheritDoc}
95
     */
96
    @Override
97
    public void handleViewEntered() {
98

    
99
        super.handleViewEntered();
100

    
101
        CdmBeanItemContainerFactory selectFieldFactory = new CdmBeanItemContainerFactory(getRepo());
102
        getView().getRankSelect().setContainerDataSource(selectFieldFactory.buildBeanItemContainer(TermType.Rank));
103
        getView().getRankSelect().setItemCaptionPropertyId("label");
104

    
105
        CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase> termOrPersonPagingProvider = new CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase>(getRepo().getAgentService(), TeamOrPersonBase.class);
106
        termOrPersonPagingProvider.setInitStrategy(AgentBaseInit.TEAM_OR_PERSON_INIT_STRATEGY);
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 loadCdmEntity(UUID 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(UUID 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.getEntityUuid());
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 onEntityChangeEvent(EntityChangeEvent<?> event){
331

    
332
        if(event.getSourceView() == referenceEditorPopup){
333
            if(event.isCreateOrModifiedType()){
334

    
335
                getCache().load(event.getEntity());
336
                getView().getNomReferenceCombobox().reload(); // refreshSelectedValue(modifiedReference);
337
                if(event.getType().equals(EntityChangeEvent.Type.CREATED)){
338
                    getView().getNomReferenceCombobox().setValue((Reference) event.getEntity());
339
                }
340
                getView().getCombinationAuthorshipField().discard(); //refresh from the datasource
341
                getView().updateAuthorshipFields();
342
            }
343

    
344
            referenceEditorPopup = null;
345
        }
346
        if(event.getSourceView()  == basionymNamePopup){
347
            if(event.isCreateOrModifiedType()){
348

    
349
                getCache().load(event.getEntity());
350
                ((ReloadableSelect)basionymSourceField).reload();
351
                getView().getBasionymAuthorshipField().discard(); //refresh from the datasource
352
                getView().getExBasionymAuthorshipField().discard(); //refresh from the datasource
353
                getView().updateAuthorshipFields();
354

    
355
            }
356
            if(event.isRemovedType()){
357
                basionymSourceField.setValue(null);
358
                getView().updateAuthorshipFields();
359
            }
360

    
361
            basionymNamePopup = null;
362
            basionymSourceField = null;
363
        }
364
    }
365

    
366
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
367
    public void onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
368

    
369
        if(getView() == null || event.getSourceView() != getView() ){
370
            return;
371
        }
372

    
373
        basionymSourceField = (AbstractField<TaxonName>)event.getSourceComponent();
374

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

    
385
    }
386

    
387
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
388
    public void oTaxonNameEditorActionAdd(TaxonNameEditorAction event) {
389

    
390
        if(getView() == null || event.getSourceView() != getView() ){
391
            return;
392
        }
393

    
394
        basionymSourceField = (AbstractField<TaxonName>)event.getSourceComponent();
395

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

    
407

    
408

    
409

    
410
}
(9-9/13)