Project

General

Profile

Download (20.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.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> nomReferencePagingProvider;
81

    
82
    private Reference publishedUnit;
83

    
84
    private BeanInstantiator<Reference> newReferenceInstantiator;
85

    
86

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

    
93
        super.handleViewEntered();
94

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

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

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

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

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

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

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

    
122
        getView().getBasionymComboboxSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
123

    
124
        CdmFilterablePagingProvider<TaxonName, TaxonName> basionymPagingProvider = new CdmFilterablePagingProvider<TaxonName, TaxonName>(getRepo().getNameService());
125
        basionymPagingProvider.setInitStrategy(BASIONYM_INIT_STRATEGY);
126
        getView().getBasionymComboboxSelect().setPagingProviders(basionymPagingProvider, basionymPagingProvider, basionymPagingProvider.getPageSize(), this);
127

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

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

    
137
        getView().getNomReferenceCombobox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
138
        CdmFilterablePagingProvider<Reference, Reference> icbnCodesPagingProvider = pagingProviderFactory.referencePagingProvider();
139
        icbnCodesPagingProvider.setInitStrategy(REFERENCE_INIT_STRATEGY);
140
        // @formatter:off
141
        // TODO use markers on references instead of isbn. The marker type MarkerType.NOMENCLATURAL_RELEVANT() has already prepared (#7466)
142
        icbnCodesPagingProvider.getCriteria().add(Restrictions.in("isbn", new String[]{
143
                "3-904144-22-7",     // Saint Louis Code
144
                "3-906166-48-1",     // Vienna Code
145
                "978-3-87429-425-6", // Melbourne Code
146
                "978-3-946583-16-5", // Shenzhen Code
147
                "0-85301-006-4"      // ICZN 1999
148
                                     // ICNB
149
                }));
150
        // @formatter:on
151
        getView().getValidationField().getCitatonComboBox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
152
        getView().getValidationField().getCitatonComboBox().loadFrom(icbnCodesPagingProvider, icbnCodesPagingProvider, icbnCodesPagingProvider.getPageSize());
153
        getView().getValidationField().getCitatonComboBox().getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getValidationField().getCitatonComboBox(), this));
154
    }
155

    
156
    /**
157
     * {@inheritDoc}
158
     */
159
    @Override
160
    protected TaxonName loadCdmEntity(UUID identifier) {
161

    
162
        List<String> initStrategy = Arrays.asList(new String []{
163

    
164
                "$",
165
                "rank.vocabulary", // needed for comparing ranks
166

    
167
                "nomenclaturalReference.authorship",
168
                "nomenclaturalReference.inReference.authorship",
169
                "nomenclaturalReference.inReference.inReference.authorship",
170
                "nomenclaturalReference.inReference.inReference.inReference.authorship",
171

    
172
                "status.type",
173

    
174
                "combinationAuthorship",
175
                "exCombinationAuthorship",
176
                "basionymAuthorship",
177
                "exBasionymAuthorship",
178

    
179
                // basionyms: relationsToThisName.fromName
180
                "relationsToThisName.type",
181
                "relationsToThisName.fromName.rank",
182
                "relationsToThisName.fromName.combinationAuthorship",
183
                "relationsToThisName.fromName.exCombinationAuthorship",
184
                "relationsToThisName.fromName.nomenclaturalReference.authorship",
185
                "relationsToThisName.fromName.nomenclaturalReference.inReference.authorship",
186
                "relationsToThisName.fromName.nomenclaturalReference.inReference.inReference.inReference.authorship",
187
                "relationsToThisName.fromName.relationsToThisName",
188
                "relationsToThisName.fromName.relationsFromThisName",
189
                "relationsToThisName.citation",
190

    
191
                "relationsFromThisName",
192
                "homotypicalGroup.typifiedNames"
193

    
194
                }
195
        );
196

    
197
        TaxonName taxonName;
198
        if(identifier != null){
199
            taxonName = getRepo().getNameService().load(identifier, initStrategy);
200
        } else {
201
            taxonName = TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
202
        }
203

    
204
        if(getView().isModeEnabled(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY)){
205
            if(taxonName.getNomenclaturalReference() != null){
206
                Reference nomRef = taxonName.getNomenclaturalReference();
207
                //getView().getNomReferenceCombobox().setEnabled(nomRef.isOfType(ReferenceType.Section));
208
                publishedUnit = nomRef;
209
                while(publishedUnit.isOfType(ReferenceType.Section) && publishedUnit.getInReference() != null){
210
                    publishedUnit = nomRef.getInReference();
211
                }
212
                // reduce available references to those which are sections of the publishedUnit and the publishedUnit itself
213
                // nomReferencePagingProvider
214
                nomReferencePagingProvider.getCriteria().add(Restrictions.or(
215
                        Restrictions.and(Restrictions.eq("inReference", publishedUnit), Restrictions.eq("type", ReferenceType.Section)),
216
                        Restrictions.idEq(publishedUnit.getId())
217
                        )
218
                );
219
                // and remove the empty option
220
                getView().getNomReferenceCombobox().getSelect().setNullSelectionAllowed(false);
221

    
222
                // new Reference only a sub sections of the publishedUnit
223
                newReferenceInstantiator = new BeanInstantiator<Reference>() {
224
                    @Override
225
                    public Reference createNewBean() {
226
                        Reference newRef = ReferenceFactory.newSection();
227
                        newRef.setInReference(publishedUnit);
228
                        return newRef;
229
                    }
230
                };
231

    
232
            }
233
        }
234

    
235
        return taxonName;
236
    }
237

    
238
    /**
239
     * {@inheritDoc}
240
     */
241
    @Override
242
    protected void guaranteePerEntityCRUDPermissions(UUID identifier) {
243
        if(crud != null){
244
            newAuthorityCreated = UserHelper.fromSession().createAuthorityForCurrentUser(TaxonName.class, identifier, crud, null);
245
        }
246

    
247
    }
248

    
249
    /**
250
     * {@inheritDoc}
251
     */
252
    @Override
253
    protected void guaranteePerEntityCRUDPermissions(TaxonName bean) {
254
        if(crud != null){
255
            newAuthorityCreated = UserHelper.fromSession().createAuthorityForCurrentUser(bean, crud, null);
256
        }
257
    }
258

    
259
    /**
260
     * {@inheritDoc}
261
     */
262
    @Override
263
    protected INameService getService() {
264
        return getRepo().getNameService();
265
    }
266

    
267
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
268
    public void onReferenceEditorActionAdd(ReferenceEditorAction event) {
269

    
270
        if(getView() == null || event.getSourceView() != getView() ){
271
            return;
272
        }
273

    
274
        ReferencePopupEditor referenceEditorPopup = openPopupEditor(ReferencePopupEditor.class, event);
275

    
276
        referenceEditorPopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
277
        referenceEditorPopup.withDeleteButton(true);
278
        referenceEditorPopup.setBeanInstantiator(newReferenceInstantiator);
279
        referenceEditorPopup.loadInEditor(null);
280
        if(newReferenceInstantiator != null){
281
            // this is a bit clumsy, we actually need to inject something like a view configurer
282
            // which can enable, disable fields
283
            referenceEditorPopup.getInReferenceCombobox().setEnabled(false);
284
            referenceEditorPopup.getTypeSelect().setEnabled(false);
285
        }
286
    }
287

    
288
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
289
    public void onReferenceEditorActionEdit(ReferenceEditorAction event) {
290

    
291

    
292
        if(getView() == null || event.getSourceView() != getView() ){
293
            return;
294
        }
295
        ReferencePopupEditor referenceEditorPopup = openPopupEditor(ReferencePopupEditor.class, event);
296

    
297
        referenceEditorPopup.withDeleteButton(true);
298
        referenceEditorPopup.setBeanInstantiator(newReferenceInstantiator);
299
        referenceEditorPopup.loadInEditor(event.getEntityUuid());
300
        if(newReferenceInstantiator != null){
301
            // this is a bit clumsy, we actually need to inject something like a view configurator
302
            // which can enable, disable fields
303
            referenceEditorPopup.getInReferenceCombobox().setEnabled(false);
304
            referenceEditorPopup.getTypeSelect().setEnabled(false);
305
        }
306
    }
307

    
308
    @EventBusListenerMethod
309
    public void onEntityChangeEvent(EntityChangeEvent<?> event){
310

    
311
        if(event.getSourceView() instanceof AbstractPopupEditor) {
312

    
313
            BoundField boundTargetField = boundTargetField((PopupView) event.getSourceView());
314

    
315
            if(boundTargetField != null){
316
                if(boundTargetField.matchesPropertyIdPath("nomenclaturalReference")){
317
                    if(event.isCreateOrModifiedType()){
318

    
319
                        getCache().load(event.getEntity());
320
                        if(event.isCreatedType()){
321
                            getView().getNomReferenceCombobox().setValue((Reference) event.getEntity());
322
                        } else {
323
                            getView().getNomReferenceCombobox().reload(); // refreshSelectedValue(modifiedReference);
324
                        }
325
                        getView().getCombinationAuthorshipField().discard(); //refresh from the datasource
326
                        getView().updateAuthorshipFields();
327
                    }
328
                }
329
                if(boundTargetField.matchesPropertyIdPath("validationFor.otherName")){
330
                    ReloadableLazyComboBox<TaxonName> otherNameField = (ReloadableLazyComboBox<TaxonName>)boundTargetField.getField(TaxonName.class);
331
                    if(event.isCreateOrModifiedType()){
332
                        getCache().load(event.getEntity());
333
                        if(event.isCreatedType()){
334
                            otherNameField.setValue((TaxonName) event.getEntity());
335
                        } else {
336
                            otherNameField.reload();
337
                        }
338
                    } else
339
                    if(event.isRemovedType()){
340
                        otherNameField.setValue(null);
341
                    }
342
                } else
343
                if(boundTargetField.matchesPropertyIdPath("basionyms")){
344
                    ReloadableLazyComboBox<TaxonName> basionymSourceField = (ReloadableLazyComboBox<TaxonName>)boundTargetField.getField(TaxonName.class);
345
                    if(event.isCreateOrModifiedType()){
346
                        getCache().load(event.getEntity());
347
                        if(event.isCreatedType()){
348
                            basionymSourceField .setValue((TaxonName) event.getEntity());
349
                        } else {
350
                            basionymSourceField.reload();
351
                        }
352
                        getView().getBasionymAuthorshipField().discard(); //refresh from the datasource
353
                        getView().getExBasionymAuthorshipField().discard(); //refresh from the datasource
354
                        getView().updateAuthorshipFields();
355
                    } else
356
                    if(event.isRemovedType()){
357
                        basionymSourceField.setValue(null);
358
                        getView().updateAuthorshipFields();
359
                    }
360
                }
361

    
362
            }
363
        }
364
    }
365

    
366

    
367

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

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

    
375
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
376

    
377
        if(boundPropertyId != null){
378
            if(boundPropertyId.matches("validationFor.otherName") || boundPropertyId.matches("basionyms") || boundPropertyId.matches("replacedSynonyms")){
379
                TaxonNamePopupEditor validatedNamePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
380
                validatedNamePopup.withDeleteButton(true);
381
                getView().getModesActive().stream()
382
                    .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
383
                    .forEach(m -> validatedNamePopup.enableMode(m));
384
                validatedNamePopup.loadInEditor(event.getEntityUuid());
385
            }
386
        }
387

    
388
    }
389

    
390
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
391
    public void onTaxonNameEditorActionAdd(TaxonNameEditorAction event) {
392

    
393
        if(getView() == null || event.getSourceView() != getView() ){
394
            return;
395
        }
396

    
397
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
398

    
399
        if(boundPropertyId != null){
400
            if(boundPropertyId.matches("validationFor.otherName") || boundPropertyId.matches("basionyms") || boundPropertyId.matches("replacedSynonyms")){
401
                TaxonNamePopupEditor validatedNamePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
402
                validatedNamePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
403
                validatedNamePopup.withDeleteButton(true);
404
                getView().getModesActive().stream()
405
                        .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
406
                        .forEach(m -> validatedNamePopup.enableMode(m));
407
                validatedNamePopup.loadInEditor(null);
408
            }
409
        }
410
    }
411

    
412
    /**
413
     * {@inheritDoc}
414
     */
415
    @Override
416
    protected TaxonNameDTO createDTODecorator(TaxonName cdmEntitiy) {
417
        return new TaxonNameDTO(cdmEntitiy);
418
    }
419

    
420

    
421

    
422

    
423
}
(9-9/13)