Project

General

Profile

Download (18.1 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.model.name.TaxonNameDTO;
49
import eu.etaxonomy.cdm.vaadin.permission.UserHelper;
50
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
51
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
52
import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
53
import eu.etaxonomy.vaadin.component.ReloadableLazyComboBox;
54
import eu.etaxonomy.vaadin.component.ReloadableSelect;
55
import eu.etaxonomy.vaadin.mvp.AbstractCdmDTOEditorPresenter;
56
import eu.etaxonomy.vaadin.mvp.BeanInstantiator;
57

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

    
67

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

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

    
77
    private static final long serialVersionUID = -3538980627079389221L;
78

    
79
    private static final Logger logger = Logger.getLogger(TaxonNameEditorPresenter.class);
80

    
81
    private ReferencePopupEditor referenceEditorPopup = null;
82

    
83
    private TaxonNamePopupEditor basionymNamePopup = null;
84

    
85
    private CdmFilterablePagingProvider<Reference, Reference> referencePagingProvider;
86

    
87
    private Reference publishedUnit;
88

    
89
    private BeanInstantiator<Reference> newReferenceInstantiator;
90

    
91
    private BeanInstantiator<TaxonName> newBasionymNameInstantiator;
92

    
93
    private AbstractField<TaxonName> basionymSourceField;
94

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

    
101
        super.handleViewEntered();
102

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

    
107
        CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase> termOrPersonPagingProvider = new CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase>(getRepo().getAgentService(), TeamOrPersonBase.class);
108
        termOrPersonPagingProvider.setInitStrategy(AgentBaseInit.TEAM_OR_PERSON_INIT_STRATEGY);
109
        CdmFilterablePagingProvider<AgentBase, Person> personPagingProvider = new CdmFilterablePagingProvider<AgentBase, Person>(getRepo().getAgentService(), Person.class);
110

    
111
        getView().getCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
112
        getView().getCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
113

    
114
        getView().getExCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
115
        getView().getExCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
116

    
117
        getView().getBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
118
        getView().getBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
119

    
120
        getView().getExBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
121
        getView().getExBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
122

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

    
130
        getView().getBasionymComboboxSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
131

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

    
137
    /**
138
     * {@inheritDoc}
139
     */
140
    @Override
141
    protected TaxonName loadCdmEntity(UUID identifier) {
142

    
143
        List<String> initStrategy = Arrays.asList(new String []{
144

    
145
                "$",
146
                "rank.vocabulary", // needed for comparing ranks
147

    
148
                "nomenclaturalReference.authorship",
149
                "nomenclaturalReference.inReference.authorship",
150
                "nomenclaturalReference.inReference.inReference.authorship",
151
                "nomenclaturalReference.inReference.inReference.inReference.authorship",
152

    
153
                "status.type",
154

    
155
                "combinationAuthorship",
156
                "exCombinationAuthorship",
157
                "basionymAuthorship",
158
                "exBasionymAuthorship",
159

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

    
171
                "relationsFromThisName",
172
                "homotypicalGroup.typifiedNames"
173

    
174
                }
175
        );
176

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

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

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

    
212
            }
213
        }
214

    
215
        return taxonName;
216
    }
217

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

    
227
    }
228

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

    
239
    @Override
240
    protected TaxonNameDTO handleTransientProperties(TaxonNameDTO dto) {
241

    
242
        TaxonName bean = cdmEntity(dto);
243

    
244
        logger.trace(this._toString() + ".onEditorSaveEvent - handling transient properties");
245

    
246

    
247
        List<TaxonName> newBasionymNames = getView().getBasionymComboboxSelect().getValueFromNestedFields();
248
        Set<TaxonName> oldBasionyms = bean.getBasionyms();
249
        Set<TaxonName> updateBasionyms = new HashSet<>();
250
        Set<TaxonName> removeBasionyms = new HashSet<>();
251

    
252
        for(TaxonName newB : newBasionymNames){
253
            if(!oldBasionyms.contains(newB)){
254
                updateBasionyms.add(newB);
255
            }
256
        }
257

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

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

    
291
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
292
    public void onReferenceEditorActionAdd(ReferenceEditorAction event) {
293

    
294
        if(getView() == null || event.getSourceView() != getView() ){
295
            return;
296
        }
297

    
298
        referenceEditorPopup = getNavigationManager().showInPopup(ReferencePopupEditor.class, getView());
299

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

    
312
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
313
    public void onReferenceEditorActionEdit(ReferenceEditorAction event) {
314

    
315

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

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

    
332
    @EventBusListenerMethod
333
    public void onEntityChangeEvent(EntityChangeEvent<?> event){
334

    
335
        if(event.getSourceView() == referenceEditorPopup){
336
            if(event.isCreateOrModifiedType()){
337

    
338
                getCache().load(event.getEntity());
339
                if(event.isCreatedType()){
340
                    getView().getNomReferenceCombobox().setValue((Reference) event.getEntity());
341
                } else {
342
                    getView().getNomReferenceCombobox().reload(); // refreshSelectedValue(modifiedReference);
343
                }
344
                getView().getCombinationAuthorshipField().discard(); //refresh from the datasource
345
                getView().updateAuthorshipFields();
346
            }
347

    
348
            referenceEditorPopup = null;
349
        }
350
        if(event.getSourceView()  == basionymNamePopup){
351
            if(event.isCreateOrModifiedType()){
352

    
353
                getCache().load(event.getEntity());
354
                if(event.isCreatedType()){
355
                    basionymSourceField.setValue((TaxonName) event.getEntity());
356
                } else {
357
                    ((ReloadableSelect)basionymSourceField).reload();
358
                }
359
                getView().getBasionymAuthorshipField().discard(); //refresh from the datasource
360
                getView().getExBasionymAuthorshipField().discard(); //refresh from the datasource
361
                getView().updateAuthorshipFields();
362

    
363
            }
364
            if(event.isRemovedType()){
365
                basionymSourceField.setValue(null);
366
                getView().updateAuthorshipFields();
367
            }
368

    
369
            basionymNamePopup = null;
370
            basionymSourceField = null;
371
        }
372
    }
373

    
374
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
375
    public void onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
376

    
377
        if(getView() == null || event.getSourceView() != getView() ){
378
            return;
379
        }
380

    
381
        basionymSourceField = (ReloadableLazyComboBox<TaxonName>)event.getSourceComponent();
382

    
383
        basionymNamePopup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class, getView());
384
        basionymNamePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
385
        basionymNamePopup.withDeleteButton(true);
386
        getView().getModesActive().stream()
387
                .filter(
388
                        m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
389
                .forEach(m -> basionymNamePopup.enableMode(m));
390
        basionymNamePopup.loadInEditor(event.getEntityUuid());
391
        basionymNamePopup.getBasionymToggle().setVisible(false);
392

    
393
    }
394

    
395
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
396
    public void oTaxonNameEditorActionAdd(TaxonNameEditorAction event) {
397

    
398
        if(getView() == null || event.getSourceView() != getView() ){
399
            return;
400
        }
401

    
402
        basionymSourceField = (AbstractField<TaxonName>)event.getSourceComponent();
403

    
404
        basionymNamePopup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class, getView());
405
        basionymNamePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
406
        basionymNamePopup.withDeleteButton(true);
407
        getView().getModesActive().stream()
408
                .filter(
409
                        m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
410
                .forEach(m -> basionymNamePopup.enableMode(m));
411
        basionymNamePopup.loadInEditor(null);
412
        basionymNamePopup.getBasionymToggle().setVisible(false);
413
    }
414

    
415
    /**
416
     * {@inheritDoc}
417
     */
418
    @Override
419
    protected TaxonNameDTO createDTODecorator(TaxonName cdmEntitiy) {
420
        return new TaxonNameDTO(cdmEntitiy);
421
    }
422

    
423

    
424

    
425

    
426
}
(9-9/13)