Project

General

Profile

Download (19.2 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.List;
14
import java.util.UUID;
15

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

    
21
import com.vaadin.spring.annotation.SpringComponent;
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.Rank;
29
import eu.etaxonomy.cdm.model.name.TaxonName;
30
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
31
import eu.etaxonomy.cdm.model.reference.Reference;
32
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
33
import eu.etaxonomy.cdm.model.reference.ReferenceType;
34
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
35
import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider;
36
import eu.etaxonomy.cdm.service.initstrategies.AgentBaseInit;
37
import eu.etaxonomy.cdm.vaadin.component.CdmBeanItemContainerFactory;
38
import eu.etaxonomy.cdm.vaadin.event.EditorActionTypeFilter;
39
import eu.etaxonomy.cdm.vaadin.event.EntityChangeEvent;
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.event.ToOneRelatedEntityReloader;
44
import eu.etaxonomy.cdm.vaadin.model.name.TaxonNameDTO;
45
import eu.etaxonomy.cdm.vaadin.permission.UserHelper;
46
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
47
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
48
import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
49
import eu.etaxonomy.vaadin.component.ReloadableLazyComboBox;
50
import eu.etaxonomy.vaadin.mvp.AbstractCdmDTOEditorPresenter;
51
import eu.etaxonomy.vaadin.mvp.AbstractPopupEditor;
52
import eu.etaxonomy.vaadin.mvp.BeanInstantiator;
53
import eu.etaxonomy.vaadin.mvp.BoundField;
54
import eu.etaxonomy.vaadin.ui.view.PopupView;
55
import eu.etaxonomy.vaadin.util.PropertyIdPath;
56

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

    
66

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

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

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

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

    
80
    private CdmFilterablePagingProvider<Reference, Reference> referencePagingProvider;
81

    
82
    private Reference publishedUnit;
83

    
84
    private BeanInstantiator<Reference> newReferenceInstantiator;
85

    
86
    /**
87
     * {@inheritDoc}
88
     */
89
    @Override
90
    public void handleViewEntered() {
91

    
92
        super.handleViewEntered();
93

    
94
        CdmBeanItemContainerFactory selectFieldFactory = new CdmBeanItemContainerFactory(getRepo());
95
        getView().getRankSelect().setContainerDataSource(selectFieldFactory.buildBeanItemContainer(TermType.Rank));
96
        getView().getRankSelect().setItemCaptionPropertyId("label");
97

    
98
        CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase> termOrPersonPagingProvider = new CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase>(getRepo().getAgentService(), TeamOrPersonBase.class);
99
        termOrPersonPagingProvider.setInitStrategy(AgentBaseInit.TEAM_OR_PERSON_INIT_STRATEGY);
100
        CdmFilterablePagingProvider<AgentBase, Person> personPagingProvider = new CdmFilterablePagingProvider<AgentBase, Person>(getRepo().getAgentService(), Person.class);
101

    
102
        getView().getCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
103
        getView().getCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
104

    
105
        getView().getExCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
106
        getView().getExCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
107

    
108
        getView().getBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
109
        getView().getBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
110

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

    
114
        getView().getNomReferenceCombobox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
115
        referencePagingProvider = new CdmFilterablePagingProvider<Reference, Reference>(getRepo().getReferenceService());
116
        referencePagingProvider.setInitStrategy(REFERENCE_INIT_STRATEGY);
117
        getView().getNomReferenceCombobox().loadFrom(referencePagingProvider, referencePagingProvider, referencePagingProvider.getPageSize());
118
        getView().getNomReferenceCombobox().getSelect().addValueChangeListener(new ToOneRelatedEntityButtonUpdater<Reference>(getView().getNomReferenceCombobox()));
119
        getView().getNomReferenceCombobox().getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getNomReferenceCombobox(), this));
120

    
121
        getView().getBasionymComboboxSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
122
        CdmFilterablePagingProvider<TaxonName, TaxonName> basionymPagingProvider = new CdmFilterablePagingProvider<TaxonName, TaxonName>(getRepo().getNameService());
123
        basionymPagingProvider.setInitStrategy(BASIONYM_INIT_STRATEGY);
124
        getView().getBasionymComboboxSelect().setPagingProviders(basionymPagingProvider, basionymPagingProvider, basionymPagingProvider.getPageSize(), this);
125

    
126
        getView().getReplacedSynonymsComboboxSelect().setCaptionGenerator( new CdmTitleCacheCaptionGenerator<TaxonName>());
127
        // reusing the basionymPagingProvider for the replaced synonyms to benefit from caching
128
        getView().getReplacedSynonymsComboboxSelect().setPagingProviders(basionymPagingProvider, basionymPagingProvider, basionymPagingProvider.getPageSize(), this);
129

    
130
        getView().getValidationField().getValidatedNameComboBox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
131
        // reusing the basionymPagingProvider for the replaced synonyms to benefit from caching
132
        getView().getValidationField().getValidatedNameComboBox().loadFrom(basionymPagingProvider, basionymPagingProvider, basionymPagingProvider.getPageSize());
133
        getView().getValidationField().getValidatedNameComboBox().getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getValidationField().getValidatedNameComboBox(), this));
134

    
135

    
136
        getView().getValidationField().getCitatonComboBox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
137
        getView().getValidationField().getCitatonComboBox().loadFrom(referencePagingProvider, referencePagingProvider, referencePagingProvider.getPageSize());
138
        getView().getValidationField().getCitatonComboBox().getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getValidationField().getCitatonComboBox(), this));
139

    
140
    }
141

    
142
    /**
143
     * {@inheritDoc}
144
     */
145
    @Override
146
    protected TaxonName loadCdmEntity(UUID identifier) {
147

    
148
        List<String> initStrategy = Arrays.asList(new String []{
149

    
150
                "$",
151
                "rank.vocabulary", // needed for comparing ranks
152

    
153
                "nomenclaturalReference.authorship",
154
                "nomenclaturalReference.inReference.authorship",
155
                "nomenclaturalReference.inReference.inReference.authorship",
156
                "nomenclaturalReference.inReference.inReference.inReference.authorship",
157

    
158
                "status.type",
159

    
160
                "combinationAuthorship",
161
                "exCombinationAuthorship",
162
                "basionymAuthorship",
163
                "exBasionymAuthorship",
164

    
165
                // basionyms: relationsToThisName.fromName
166
                "relationsToThisName.type",
167
                "relationsToThisName.fromName.rank",
168
                "relationsToThisName.fromName.combinationAuthorship",
169
                "relationsToThisName.fromName.exCombinationAuthorship",
170
                "relationsToThisName.fromName.nomenclaturalReference.authorship",
171
                "relationsToThisName.fromName.nomenclaturalReference.inReference.authorship",
172
                "relationsToThisName.fromName.nomenclaturalReference.inReference.inReference.inReference.authorship",
173
                "relationsToThisName.fromName.relationsToThisName",
174
                "relationsToThisName.fromName.relationsFromThisName",
175
                "relationsToThisName.citation",
176

    
177
                "relationsFromThisName",
178
                "homotypicalGroup.typifiedNames"
179

    
180
                }
181
        );
182

    
183
        TaxonName taxonName;
184
        if(identifier != null){
185
            taxonName = getRepo().getNameService().load(identifier, initStrategy);
186
        } else {
187
            taxonName = TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
188
        }
189

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

    
208
                // new Reference only a sub sections of the publishedUnit
209
                newReferenceInstantiator = new BeanInstantiator<Reference>() {
210
                    @Override
211
                    public Reference createNewBean() {
212
                        Reference newRef = ReferenceFactory.newSection();
213
                        newRef.setInReference(publishedUnit);
214
                        return newRef;
215
                    }
216
                };
217

    
218
            }
219
        }
220

    
221
        return taxonName;
222
    }
223

    
224
    /**
225
     * {@inheritDoc}
226
     */
227
    @Override
228
    protected void guaranteePerEntityCRUDPermissions(UUID identifier) {
229
        if(crud != null){
230
            newAuthorityCreated = UserHelper.fromSession().createAuthorityForCurrentUser(TaxonName.class, identifier, crud, null);
231
        }
232

    
233
    }
234

    
235
    /**
236
     * {@inheritDoc}
237
     */
238
    @Override
239
    protected void guaranteePerEntityCRUDPermissions(TaxonName bean) {
240
        if(crud != null){
241
            newAuthorityCreated = UserHelper.fromSession().createAuthorityForCurrentUser(bean, crud, null);
242
        }
243
    }
244

    
245
    /**
246
     * {@inheritDoc}
247
     */
248
    @Override
249
    protected INameService getService() {
250
        return getRepo().getNameService();
251
    }
252

    
253
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
254
    public void onReferenceEditorActionAdd(ReferenceEditorAction event) {
255

    
256
        if(getView() == null || event.getSourceView() != getView() ){
257
            return;
258
        }
259

    
260
        ReferencePopupEditor referenceEditorPopup = openPopupEditor(ReferencePopupEditor.class, event);
261

    
262
        referenceEditorPopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
263
        referenceEditorPopup.withDeleteButton(true);
264
        referenceEditorPopup.setBeanInstantiator(newReferenceInstantiator);
265
        referenceEditorPopup.loadInEditor(null);
266
        if(newReferenceInstantiator != null){
267
            // this is a bit clumsy, we actually need to inject something like a view configurer
268
            // which can enable, disable fields
269
            referenceEditorPopup.getInReferenceCombobox().setEnabled(false);
270
            referenceEditorPopup.getTypeSelect().setEnabled(false);
271
        }
272
    }
273

    
274
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
275
    public void onReferenceEditorActionEdit(ReferenceEditorAction event) {
276

    
277

    
278
        if(getView() == null || event.getSourceView() != getView() ){
279
            return;
280
        }
281
        ReferencePopupEditor referenceEditorPopup = openPopupEditor(ReferencePopupEditor.class, event);
282

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

    
294
    @EventBusListenerMethod
295
    public void onEntityChangeEvent(EntityChangeEvent<?> event){
296

    
297
        if(event.getSourceView() instanceof AbstractPopupEditor) {
298

    
299
            BoundField boundTargetField = boundTargetField((PopupView) event.getSourceView());
300

    
301
            if(boundTargetField != null){
302
                if(boundTargetField.matchesPropertyIdPath("nomenclaturalReference")){
303
                    if(event.isCreateOrModifiedType()){
304

    
305
                        getCache().load(event.getEntity());
306
                        if(event.isCreatedType()){
307
                            getView().getNomReferenceCombobox().setValue((Reference) event.getEntity());
308
                        } else {
309
                            getView().getNomReferenceCombobox().reload(); // refreshSelectedValue(modifiedReference);
310
                        }
311
                        getView().getCombinationAuthorshipField().discard(); //refresh from the datasource
312
                        getView().updateAuthorshipFields();
313
                    }
314
                }
315
                if(boundTargetField.matchesPropertyIdPath("validationFor.otherName")){
316
                    ReloadableLazyComboBox<TaxonName> otherNameField = (ReloadableLazyComboBox<TaxonName>)boundTargetField.getField(TaxonName.class);
317
                    if(event.isCreateOrModifiedType()){
318
                        getCache().load(event.getEntity());
319
                        if(event.isCreatedType()){
320
                            otherNameField.setValue((TaxonName) event.getEntity());
321
                        } else {
322
                            otherNameField.reload();
323
                        }
324
                    } else
325
                    if(event.isRemovedType()){
326
                        otherNameField.setValue(null);
327
                    }
328
                } else
329
                if(boundTargetField.matchesPropertyIdPath("basionyms")){
330
                    ReloadableLazyComboBox<TaxonName> basionymSourceField = (ReloadableLazyComboBox<TaxonName>)boundTargetField.getField(TaxonName.class);
331
                    if(event.isCreateOrModifiedType()){
332
                        getCache().load(event.getEntity());
333
                        if(event.isCreatedType()){
334
                            basionymSourceField .setValue((TaxonName) event.getEntity());
335
                        } else {
336
                            basionymSourceField.reload();
337
                        }
338
                        getView().getBasionymAuthorshipField().discard(); //refresh from the datasource
339
                        getView().getExBasionymAuthorshipField().discard(); //refresh from the datasource
340
                        getView().updateAuthorshipFields();
341
                    } else
342
                    if(event.isRemovedType()){
343
                        basionymSourceField.setValue(null);
344
                        getView().updateAuthorshipFields();
345
                    }
346
                }
347

    
348
            }
349
        }
350
    }
351

    
352

    
353

    
354
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
355
    public void onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
356

    
357
        if(getView() == null || event.getSourceView() != getView() ){
358
            return;
359
        }
360

    
361
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
362

    
363
        if(boundPropertyId != null){
364
            if(boundPropertyId.matches("validationFor.otherName") || boundPropertyId.matches("basionyms") || boundPropertyId.matches("replacedSynonyms")){
365
                TaxonNamePopupEditor validatedNamePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
366
                validatedNamePopup.withDeleteButton(true);
367
                getView().getModesActive().stream()
368
                    .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
369
                    .forEach(m -> validatedNamePopup.enableMode(m));
370
                validatedNamePopup.loadInEditor(event.getEntityUuid());
371
            }
372
        }
373

    
374
    }
375

    
376
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
377
    public void onTaxonNameEditorActionAdd(TaxonNameEditorAction event) {
378

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

    
383
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
384

    
385
        if(boundPropertyId != null){
386
            if(boundPropertyId.matches("validationFor.otherName") || boundPropertyId.matches("basionyms") || boundPropertyId.matches("replacedSynonyms")){
387
                TaxonNamePopupEditor validatedNamePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
388
                validatedNamePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
389
                validatedNamePopup.withDeleteButton(true);
390
                getView().getModesActive().stream()
391
                        .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
392
                        .forEach(m -> validatedNamePopup.enableMode(m));
393
                validatedNamePopup.loadInEditor(null);
394
            }
395
        }
396
    }
397

    
398
    /**
399
     * {@inheritDoc}
400
     */
401
    @Override
402
    protected TaxonNameDTO createDTODecorator(TaxonName cdmEntitiy) {
403
        return new TaxonNameDTO(cdmEntitiy);
404
    }
405

    
406

    
407

    
408

    
409
}
(9-9/13)