2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.cdm
.vaadin
.view
.name
;
11 import java
.util
.Arrays
;
12 import java
.util
.EnumSet
;
13 import java
.util
.HashMap
;
14 import java
.util
.HashSet
;
18 import org
.springframework
.beans
.factory
.DisposableBean
;
19 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
20 import org
.springframework
.context
.annotation
.Scope
;
21 import org
.vaadin
.spring
.events
.annotation
.EventBusListenerMethod
;
22 import org
.vaadin
.viritin
.fields
.AbstractElementCollection
;
24 import com
.vaadin
.spring
.annotation
.SpringComponent
;
26 import eu
.etaxonomy
.cdm
.api
.service
.IRegistrationService
;
27 import eu
.etaxonomy
.cdm
.cache
.CdmTransientEntityCacher
;
28 import eu
.etaxonomy
.cdm
.model
.ICdmCacher
;
29 import eu
.etaxonomy
.cdm
.model
.agent
.AgentBase
;
30 import eu
.etaxonomy
.cdm
.model
.agent
.Person
;
31 import eu
.etaxonomy
.cdm
.model
.agent
.TeamOrPersonBase
;
32 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
33 import eu
.etaxonomy
.cdm
.model
.location
.Country
;
34 import eu
.etaxonomy
.cdm
.model
.name
.Registration
;
35 import eu
.etaxonomy
.cdm
.model
.name
.SpecimenTypeDesignation
;
36 import eu
.etaxonomy
.cdm
.model
.occurrence
.Collection
;
37 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
38 import eu
.etaxonomy
.cdm
.persistence
.dao
.common
.Restriction
;
39 import eu
.etaxonomy
.cdm
.persistence
.dao
.common
.Restriction
.Operator
;
40 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.CRUD
;
41 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
42 import eu
.etaxonomy
.cdm
.service
.CdmFilterablePagingProvider
;
43 import eu
.etaxonomy
.cdm
.service
.CdmFilterablePagingProviderFactory
;
44 import eu
.etaxonomy
.cdm
.service
.CdmStore
;
45 import eu
.etaxonomy
.cdm
.service
.ISpecimenTypeDesignationWorkingSetService
;
46 import eu
.etaxonomy
.cdm
.service
.UserHelperAccess
;
47 import eu
.etaxonomy
.cdm
.service
.initstrategies
.AgentBaseInit
;
48 import eu
.etaxonomy
.cdm
.vaadin
.component
.CdmBeanItemContainerFactory
;
49 import eu
.etaxonomy
.cdm
.vaadin
.component
.CollectionRowItemCollection
;
50 import eu
.etaxonomy
.cdm
.vaadin
.event
.EntityChangeEvent
;
51 import eu
.etaxonomy
.cdm
.vaadin
.event
.EntityChangeEventFilter
;
52 import eu
.etaxonomy
.cdm
.vaadin
.event
.ToOneRelatedEntityButtonUpdater
;
53 import eu
.etaxonomy
.cdm
.vaadin
.event
.ToOneRelatedEntityReloader
;
54 import eu
.etaxonomy
.cdm
.vaadin
.model
.registration
.RegistrationTermLists
;
55 import eu
.etaxonomy
.cdm
.vaadin
.model
.registration
.SpecimenTypeDesignationDTO
;
56 import eu
.etaxonomy
.cdm
.vaadin
.model
.registration
.SpecimenTypeDesignationWorkingSetDTO
;
57 import eu
.etaxonomy
.cdm
.vaadin
.ui
.RegistrationUIDefaults
;
58 import eu
.etaxonomy
.cdm
.vaadin
.util
.CdmTitleCacheCaptionGenerator
;
59 import eu
.etaxonomy
.cdm
.vaadin
.util
.CollectionCaptionGenerator
;
60 import eu
.etaxonomy
.cdm
.vaadin
.view
.occurrence
.CollectionPopupEditor
;
61 import eu
.etaxonomy
.cdm
.vaadin
.view
.reference
.ReferencePopupEditor
;
62 import eu
.etaxonomy
.vaadin
.component
.ToOneRelatedEntityCombobox
;
63 import eu
.etaxonomy
.vaadin
.mvp
.AbstractEditorPresenter
;
65 * SpecimenTypeDesignationWorkingsetPopupEditorView implementation must override the showInEditor() method,
66 * see {@link #prepareAsFieldGroupDataSource()} for details.
68 * @author a.kohlbecker
74 public class SpecimenTypeDesignationWorkingsetEditorPresenter
75 extends AbstractEditorPresenter
<SpecimenTypeDesignationWorkingSetDTO
, SpecimenTypeDesignationWorkingsetPopupEditorView
>
76 implements CachingPresenter
, DisposableBean
{
78 private static final long serialVersionUID
= 4255636253714476918L;
80 private static final EnumSet
<CRUD
> COLLECTION_EDITOR_CRUD
= EnumSet
.of(CRUD
.UPDATE
, CRUD
.DELETE
);
82 CdmStore
<Registration
, IRegistrationService
> store
;
86 * This object for this field will either be injected by the {@link PopupEditorFactory} or by a Spring
90 private ISpecimenTypeDesignationWorkingSetService specimenTypeDesignationWorkingSetService
;
93 * if not null, this CRUD set is to be used to create a CdmAuthoritiy for the base entitiy which will be
94 * granted to the current use as long this grant is not assigned yet.
96 private EnumSet
<CRUD
> crud
= null;
98 private ICdmCacher cache
;
101 protected CdmFilterablePagingProviderFactory pagingProviderFactory
;
103 SpecimenTypeDesignationWorkingSetDTO
<Registration
> workingSetDto
;
105 private Map
<CollectionPopupEditor
, SpecimenTypeDesignationDTORow
> collectionPopupEditorsRowMap
= new HashMap
<>();
107 private Map
<ReferencePopupEditor
, SpecimenTypeDesignationDTORow
> referencePopupEditorsRowMap
= new HashMap
<>();
109 private Set
<CollectionRowItemCollection
> popuEditorTypeDesignationSourceRows
= new HashSet
<>();
111 private java
.util
.Collection
<CdmBase
> rootEntities
= new HashSet
<>();
113 protected CdmStore
<Registration
, IRegistrationService
> getStore() {
115 store
= new CdmStore
<>(getRepo(), getRepo().getRegistrationService());
121 * Loads an existing working set from the database. This process actually involves
122 * loading the Registration specified by the <code>RegistrationAndWorkingsetId.registrationId</code> and in
123 * a second step to find the workingset by the <code>registrationAndWorkingsetId.workingsetId</code>.
125 * The <code>identifier</code> must be of the type {@link TypeDesignationWorkingsetEditorIdSet} whereas the field <code>egistrationId</code>
126 * must be present, the field <code>workingsetId</code>, however can be null. I this case a new workingset with a new {@link FieldUnit} as
127 * base entity is being created.
129 * @param identifier a {@link TypeDesignationWorkingsetEditorIdSet}
132 protected SpecimenTypeDesignationWorkingSetDTO
<Registration
> loadBeanById(Object identifier
) {
134 cache
= new CdmTransientEntityCacher(this);
135 if(identifier
!= null){
137 TypeDesignationWorkingsetEditorIdSet idset
= (TypeDesignationWorkingsetEditorIdSet
)identifier
;
139 if(idset
.baseEntityRef
!= null){
140 workingSetDto
= specimenTypeDesignationWorkingSetService
.load(idset
.registrationUuid
, idset
.baseEntityRef
);
141 if(workingSetDto
.getFieldUnit() == null){
142 workingSetDto
= specimenTypeDesignationWorkingSetService
.fixMissingFieldUnit(workingSetDto
);
143 // FIXME open Dialog to warn user about adding an empty fieldUnit to the typeDesignations
144 // This method must go again into the presenter !!!!
145 logger
.info("Basing all typeDesignations on a new fieldUnit");
147 // need to use load but put see #7214
148 cache
.load(workingSetDto
.getOwner());
149 rootEntities
.add(workingSetDto
.getOwner());
151 // create a new workingset, for a new fieldunit which is the base for the workingset
152 workingSetDto
= specimenTypeDesignationWorkingSetService
.create(idset
.registrationUuid
, idset
.publicationUuid
, idset
.typifiedNameUuid
);
153 // need to use load but put see #7214
154 cache
.load(workingSetDto
.getOwner());
155 cache
.load(workingSetDto
.getTypifiedName());
156 rootEntities
.add(workingSetDto
.getOwner());
160 workingSetDto
= null;
163 return workingSetDto
;
170 @SuppressWarnings("serial")
172 public void handleViewEntered() {
174 CdmBeanItemContainerFactory selectFactory
= new CdmBeanItemContainerFactory(getRepo());
175 getView().getCountrySelectField().setContainerDataSource(selectFactory
.buildBeanItemContainer(Country
.uuidCountryVocabulary
));
177 CdmFilterablePagingProvider
<AgentBase
, TeamOrPersonBase
> termOrPersonPagingProvider
= new CdmFilterablePagingProvider
<AgentBase
, TeamOrPersonBase
>(getRepo().getAgentService(), TeamOrPersonBase
.class);
178 CdmFilterablePagingProvider
<AgentBase
, Person
> personPagingProvider
= new CdmFilterablePagingProvider
<AgentBase
, Person
>(getRepo().getAgentService(), Person
.class);
179 termOrPersonPagingProvider
.setInitStrategy(AgentBaseInit
.TEAM_OR_PERSON_INIT_STRATEGY
);
180 getView().getCollectorField().setFilterablePersonPagingProvider(personPagingProvider
, this);
181 getView().getCollectorField().setFilterableTeamPagingProvider(termOrPersonPagingProvider
, this);
183 getView().getTypeDesignationsCollectionField().addElementRemovedListener(e
-> deleteTypeDesignation(e
.getElement()));
184 getView().getTypeDesignationsCollectionField().addElementAddedListener(e
-> addTypeDesignation(e
.getElement()));
187 popuEditorTypeDesignationSourceRows
.clear();
188 CdmFilterablePagingProvider
<Collection
, Collection
> collectionPagingProvider
= new CdmFilterablePagingProvider
<Collection
, Collection
>(getRepo().getCollectionService());
189 collectionPagingProvider
.getRestrictions().add(new Restriction
<>("institute.titleCache", Operator
.OR
, MatchMode
.ANYWHERE
, CdmFilterablePagingProvider
.QUERY_STRING_PLACEHOLDER
));
191 CdmFilterablePagingProvider
<Reference
, Reference
> referencePagingProvider
= pagingProviderFactory
.referencePagingProvider();
193 getView().getTypeDesignationsCollectionField().setEditorInstantiator(new AbstractElementCollection
.Instantiator
<SpecimenTypeDesignationDTORow
>() {
196 public SpecimenTypeDesignationDTORow
create() {
198 SpecimenTypeDesignationDTORow row
= new SpecimenTypeDesignationDTORow();
200 row
.kindOfUnit
.setContainerDataSource(selectFactory
.buildTermItemContainer(
201 RegistrationTermLists
.KIND_OF_UNIT_TERM_UUIDS())
203 row
.kindOfUnit
.setNullSelectionAllowed(false);
205 row
.typeStatus
.setContainerDataSource(selectFactory
.buildTermItemContainer(
206 RegistrationTermLists
.SPECIMEN_TYPE_DESIGNATION_STATUS_UUIDS())
208 row
.typeStatus
.setNullSelectionAllowed(false);
211 row
.collection
.loadFrom(
212 collectionPagingProvider
,
213 collectionPagingProvider
,
214 collectionPagingProvider
.getPageSize()
216 row
.collection
.getSelect().setCaptionGenerator(new CollectionCaptionGenerator());
217 row
.collection
.setNestedButtonStateUpdater(new ToOneRelatedEntityButtonUpdater
<Collection
>(row
.collection
));
218 row
.collection
.getSelect().addValueChangeListener(new ToOneRelatedEntityReloader
<Collection
>(row
.collection
.getSelect(),
219 SpecimenTypeDesignationWorkingsetEditorPresenter
.this));
220 row
.collection
.addClickListenerAddEntity(e
-> doCollectionEditorAdd(row
));
221 row
.collection
.addClickListenerEditEntity(e
-> {
222 if(row
.collection
.getValue() != null){
223 doCollectionEditorEdit(row
);
227 row
.mediaSpecimenReference
.loadFrom(
228 referencePagingProvider
,
229 referencePagingProvider
,
230 collectionPagingProvider
.getPageSize()
233 row
.mediaSpecimenReference
.getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator
<Reference
>());
234 row
.mediaSpecimenReference
.getSelect().addValueChangeListener(new ToOneRelatedEntityButtonUpdater
<Reference
>(row
.mediaSpecimenReference
));
235 row
.mediaSpecimenReference
.getSelect().addValueChangeListener(new ToOneRelatedEntityReloader
<Reference
>(row
.mediaSpecimenReference
.getSelect(),
236 SpecimenTypeDesignationWorkingsetEditorPresenter
.this));
237 row
.mediaSpecimenReference
.addClickListenerAddEntity(e
-> doReferenceEditorAdd(row
));
238 row
.mediaSpecimenReference
.addClickListenerEditEntity(e
-> {
239 if(row
.mediaSpecimenReference
.getValue() != null){
240 doReferenceEditorEdit(row
);
244 getView().applyDefaultComponentStyle(row
.components());
246 popuEditorTypeDesignationSourceRows
.add(row
);
260 protected void saveBean(SpecimenTypeDesignationWorkingSetDTO dto
) {
263 UserHelperAccess
.userHelper().createAuthorityForCurrentUser(dto
.getFieldUnit(), crud
, null);
266 specimenTypeDesignationWorkingSetService
.save(dto
);
273 protected void deleteBean(SpecimenTypeDesignationWorkingSetDTO bean
) {
274 specimenTypeDesignationWorkingSetService
.delete(bean
, true);
281 private void addTypeDesignation(SpecimenTypeDesignationDTO element
) {
282 getView().updateAllowDelete();
287 * In this method the SpecimenTypeDesignation is dissociated from the Registration.
288 * The actual deletion of the SpecimenTypeDesignation and DerivedUnit will take place in {@link #saveBean(SpecimenTypeDesignationWorkingSetDTO)}
290 * TODO once https://dev.e-taxonomy.eu/redmine/issues/7077 is fixed dissociating from the Registration could be removed here
295 private void deleteTypeDesignation(SpecimenTypeDesignationDTO element
) {
297 Registration reg
= workingSetDto
.getOwner();
298 SpecimenTypeDesignation std
= element
.asSpecimenTypeDesignation();
300 reg
.getTypeDesignations().remove(std
);
302 getView().updateAllowDelete();
308 public void setGrantsForCurrentUser(EnumSet
<CRUD
> crud
) {
317 public ICdmCacher
getCache() {
322 public void disposeCache() {
326 public void doCollectionEditorAdd(SpecimenTypeDesignationDTORow row
) {
328 CollectionPopupEditor collectionPopupEditor
= openPopupEditor(CollectionPopupEditor
.class, null);
330 collectionPopupEditor
.grantToCurrentUser(COLLECTION_EDITOR_CRUD
);
331 collectionPopupEditor
.withDeleteButton(true);
332 collectionPopupEditor
.loadInEditor(null);
334 collectionPopupEditorsRowMap
.put(collectionPopupEditor
, row
);
337 public void doCollectionEditorEdit(SpecimenTypeDesignationDTORow row
) {
339 CollectionPopupEditor collectionPopupEditor
= openPopupEditor(CollectionPopupEditor
.class, null);
341 collectionPopupEditor
.grantToCurrentUser(COLLECTION_EDITOR_CRUD
);
342 collectionPopupEditor
.withDeleteButton(true);
343 collectionPopupEditor
.loadInEditor(row
.collection
.getValue().getUuid());
345 collectionPopupEditorsRowMap
.put(collectionPopupEditor
, row
);
349 @EventBusListenerMethod(filter
= EntityChangeEventFilter
.OccurrenceCollectionFilter
.class)
350 public void onCollectionEvent(EntityChangeEvent event
){
352 if(!isFromOwnView(event
)){
356 Collection newCollection
= getRepo().getCollectionService().load(
357 event
.getEntityUuid(), Arrays
.asList(new String
[]{"$.institute"})
359 cache
.load(newCollection
);
361 if(event
.isCreatedType()){
362 SpecimenTypeDesignationDTORow row
= collectionPopupEditorsRowMap
.get(event
.getSourceView());
363 ToOneRelatedEntityCombobox
<Collection
> combobox
= row
.getComponent(ToOneRelatedEntityCombobox
.class, 3);
364 combobox
.setValue((Collection
) event
.getEntity());
366 for( CollectionRowItemCollection row
: popuEditorTypeDesignationSourceRows
) {
367 ToOneRelatedEntityCombobox
<Collection
> combobox
= row
.getComponent(ToOneRelatedEntityCombobox
.class, 3);
372 public void doReferenceEditorAdd(SpecimenTypeDesignationDTORow row
) {
374 ReferencePopupEditor referencePopupEditor
= openPopupEditor(ReferencePopupEditor
.class, null);
376 referencePopupEditor
.withReferenceTypes(RegistrationUIDefaults
.MEDIA_REFERENCE_TYPES
);
377 referencePopupEditor
.grantToCurrentUser(COLLECTION_EDITOR_CRUD
);
378 referencePopupEditor
.withDeleteButton(true);
379 referencePopupEditor
.loadInEditor(null);
381 referencePopupEditorsRowMap
.put(referencePopupEditor
, row
);
384 public void doReferenceEditorEdit(SpecimenTypeDesignationDTORow row
) {
386 ReferencePopupEditor referencePopupEditor
= openPopupEditor(ReferencePopupEditor
.class, null);
387 referencePopupEditor
.withReferenceTypes(RegistrationUIDefaults
.MEDIA_REFERENCE_TYPES
);
388 referencePopupEditor
.grantToCurrentUser(COLLECTION_EDITOR_CRUD
);
389 referencePopupEditor
.withDeleteButton(true);
390 referencePopupEditor
.loadInEditor(row
.mediaSpecimenReference
.getValue().getUuid());
392 referencePopupEditorsRowMap
.put(referencePopupEditor
, row
);
395 @EventBusListenerMethod(filter
= EntityChangeEventFilter
.ReferenceFilter
.class)
396 public void onReferenceEvent(EntityChangeEvent event
){
398 Reference newRef
= getRepo().getReferenceService().load(event
.getEntityUuid(), Arrays
.asList(new String
[]{"$"}));
401 if(event
.isCreatedType()){
402 SpecimenTypeDesignationDTORow row
= referencePopupEditorsRowMap
.get(event
.getSourceView());
403 ToOneRelatedEntityCombobox
<Reference
> combobox
= row
.getComponent(ToOneRelatedEntityCombobox
.class, 7);
404 combobox
.setValue((Reference
) event
.getEntity());
407 for( CollectionRowItemCollection row
: popuEditorTypeDesignationSourceRows
) {
408 ToOneRelatedEntityCombobox
<Reference
> combobox
= row
.getComponent(ToOneRelatedEntityCombobox
.class, 7);
418 public void addRootEntity(CdmBase entity
) {
419 rootEntities
.add(entity
);
426 public java
.util
.Collection
<CdmBase
> getRootEntities() {
427 return rootEntities
;
434 public void destroy() throws Exception
{