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
.EnumSet
;
12 import java
.util
.HashSet
;
13 import java
.util
.Iterator
;
16 import org
.hibernate
.Session
;
17 import org
.springframework
.beans
.factory
.BeanFactory
;
18 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
19 import org
.vaadin
.viritin
.fields
.AbstractElementCollection
;
21 import eu
.etaxonomy
.cdm
.api
.service
.IRegistrationService
;
22 import eu
.etaxonomy
.cdm
.model
.common
.VersionableEntity
;
23 import eu
.etaxonomy
.cdm
.model
.location
.Country
;
24 import eu
.etaxonomy
.cdm
.model
.name
.Registration
;
25 import eu
.etaxonomy
.cdm
.model
.name
.SpecimenTypeDesignation
;
26 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
27 import eu
.etaxonomy
.cdm
.model
.name
.TypeDesignationBase
;
28 import eu
.etaxonomy
.cdm
.model
.occurrence
.Collection
;
29 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivationEvent
;
30 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivationEventType
;
31 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivedUnit
;
32 import eu
.etaxonomy
.cdm
.model
.occurrence
.FieldUnit
;
33 import eu
.etaxonomy
.cdm
.model
.occurrence
.GatheringEvent
;
34 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
35 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
36 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.CRUD
;
37 import eu
.etaxonomy
.cdm
.service
.CdmFilterablePagingProvider
;
38 import eu
.etaxonomy
.cdm
.service
.CdmStore
;
39 import eu
.etaxonomy
.cdm
.service
.IRegistrationWorkingSetService
;
40 import eu
.etaxonomy
.cdm
.service
.RegistrationWorkingSetService
;
41 import eu
.etaxonomy
.cdm
.vaadin
.component
.CdmBeanItemContainerFactory
;
42 import eu
.etaxonomy
.cdm
.vaadin
.event
.ToOneRelatedEntityButtonUpdater
;
43 import eu
.etaxonomy
.cdm
.vaadin
.model
.TypedEntityReference
;
44 import eu
.etaxonomy
.cdm
.vaadin
.model
.registration
.DerivationEventTypes
;
45 import eu
.etaxonomy
.cdm
.vaadin
.model
.registration
.RegistrationTermLists
;
46 import eu
.etaxonomy
.cdm
.vaadin
.model
.registration
.SpecimenTypeDesignationDTO
;
47 import eu
.etaxonomy
.cdm
.vaadin
.model
.registration
.SpecimenTypeDesignationWorkingSetDTO
;
48 import eu
.etaxonomy
.cdm
.vaadin
.security
.UserHelper
;
49 import eu
.etaxonomy
.cdm
.vaadin
.util
.CdmTitleCacheCaptionGenerator
;
50 import eu
.etaxonomy
.cdm
.vaadin
.util
.converter
.TypeDesignationSetManager
.TypeDesignationWorkingSet
;
51 import eu
.etaxonomy
.cdm
.vaadin
.view
.registration
.RegistrationDTO
;
52 import eu
.etaxonomy
.vaadin
.mvp
.AbstractEditorPresenter
;
53 import eu
.etaxonomy
.vaadin
.ui
.view
.PopupEditorFactory
;
55 * SpecimenTypeDesignationWorkingsetPopupEditorView implementation must override the showInEditor() method,
56 * see {@link #prepareAsFieldGroupDataSource()} for details.
58 * @author a.kohlbecker
62 public class SpecimenTypeDesignationWorkingsetEditorPresenter
63 extends AbstractEditorPresenter
<SpecimenTypeDesignationWorkingSetDTO
, SpecimenTypeDesignationWorkingsetPopupEditorView
> {
65 private static final long serialVersionUID
= 4255636253714476918L;
67 CdmStore
<Registration
, IRegistrationService
> store
;
69 private Reference citation
;
71 private TaxonName typifiedName
;
74 * This object for this field will either be injected by the {@link PopupEditorFactory} or by a Spring
78 private IRegistrationWorkingSetService registrationWorkingSetService
;
81 * if not null, this CRUD set is to be used to create a CdmAuthoritiy for the base entitiy which will be
82 * granted to the current use as long this grant is not assigned yet.
84 private EnumSet
<CRUD
> crud
= null;
86 protected CdmStore
<Registration
, IRegistrationService
> getStore() {
88 store
= new CdmStore
<>(getRepo(), getRepo().getRegistrationService());
95 * Loads an existing working set from the database. This process actually involves
96 * loading the Registration specified by the <code>RegistrationAndWorkingsetId.registrationId</code> and in
97 * a second step to find the workingset by the <code>registrationAndWorkingsetId.workingsetId</code>.
99 * The <code>identifier</code> must be of the type {@link TypeDesignationWorkingsetEditorIdSet} whereas the field <code>egistrationId</code>
100 * must be present, the field <code>workingsetId</code>, however can be null. I this case a new workingset with a new {@link FieldUnit} as
101 * base entity is being created.
103 * @param identifier a {@link TypeDesignationWorkingsetEditorIdSet}
106 protected SpecimenTypeDesignationWorkingSetDTO
loadBeanById(Object identifier
) {
108 SpecimenTypeDesignationWorkingSetDTO workingSetDto
;
109 if(identifier
!= null){
111 TypeDesignationWorkingsetEditorIdSet idset
= (TypeDesignationWorkingsetEditorIdSet
)identifier
;
113 if(idset
.workingsetId
!= null){
114 RegistrationDTO regDTO
= registrationWorkingSetService
.loadDtoById(idset
.registrationId
);
115 // find the working set
116 TypeDesignationWorkingSet typeDesignationWorkingSet
= regDTO
.getTypeDesignationWorkingSet(idset
.workingsetId
);
117 workingSetDto
= regDTO
.getSpecimenTypeDesignationWorkingSetDTO(typeDesignationWorkingSet
.getBaseEntityReference());
118 citation
= (Reference
) regDTO
.getCitation();
119 workingSetDto
= fixMissingFieldUnit(workingSetDto
);
121 // create a new workingset, for a new fieldunit which is the base for the workingset
122 FieldUnit newfieldUnit
= FieldUnit
.NewInstance();
123 Registration reg
= getRepo().getRegistrationService().load(idset
.registrationId
,
124 RegistrationWorkingSetService
.REGISTRATION_INIT_STRATEGY
);
125 //TODO checkif passing reg as owner parameter is needed at all
126 workingSetDto
= new SpecimenTypeDesignationWorkingSetDTO(reg
, newfieldUnit
, null);
127 citation
= getRepo().getReferenceService().find(idset
.publicationId
);
128 typifiedName
= getRepo().getNameService().find(idset
.typifiedNameId
);
132 workingSetDto
= null;
134 return workingSetDto
;
141 @SuppressWarnings("serial")
143 public void handleViewEntered() {
145 CdmBeanItemContainerFactory selectFactory
= new CdmBeanItemContainerFactory(getRepo());
146 getView().getCountrySelectField().setContainerDataSource(selectFactory
.buildBeanItemContainer(Country
.uuidCountryVocabulary
));
148 getView().getTypeDesignationsCollectionField().setEditorInstantiator(new AbstractElementCollection
.Instantiator
<SpecimenTypeDesignationDTORow
>() {
150 CdmFilterablePagingProvider
<Collection
> collectionPagingProvider
= new CdmFilterablePagingProvider
<Collection
>(getRepo().getCollectionService());
152 CdmFilterablePagingProvider
<Reference
> referencePagingProvider
= new CdmFilterablePagingProvider
<Reference
>(getRepo().getReferenceService());
155 public SpecimenTypeDesignationDTORow
create() {
157 SpecimenTypeDesignationDTORow row
= new SpecimenTypeDesignationDTORow();
159 row
.derivationEventType
.setContainerDataSource(selectFactory
.buildTermItemContainer(
160 RegistrationTermLists
.DERIVATION_EVENT_TYPE_UUIDS())
162 row
.derivationEventType
.setNullSelectionAllowed(false);
164 row
.derivationEventType
.addValueChangeListener(e
-> {
165 SpecimenTypeDesignationDTORow currentRow
= row
;
166 updateRowItemEnablement(currentRow
);
169 row
.typeStatus
.setContainerDataSource(selectFactory
.buildTermItemContainer(
170 RegistrationTermLists
.SPECIMEN_TYPE_DESIGNATION_STATUS_UUIDS())
172 row
.typeStatus
.setNullSelectionAllowed(false);
175 row
.collection
.loadFrom(
176 collectionPagingProvider
,
177 collectionPagingProvider
,
178 collectionPagingProvider
.getPageSize()
180 row
.collection
.getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator
<Collection
>());
181 row
.collection
.getSelect().addValueChangeListener(new ToOneRelatedEntityButtonUpdater
<Collection
>(row
.collection
));
183 row
.mediaSpecimenReference
.loadFrom(
184 referencePagingProvider
,
185 referencePagingProvider
,
186 collectionPagingProvider
.getPageSize()
188 row
.mediaSpecimenReference
.getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator
<Reference
>());
189 row
.mediaSpecimenReference
.getSelect().addValueChangeListener(new ToOneRelatedEntityButtonUpdater
<Reference
>(row
.mediaSpecimenReference
));
191 getView().applyDefaultComponentStyle(row
.components());
193 updateRowItemEnablement(row
);
198 private void updateRowItemEnablement(SpecimenTypeDesignationDTORow row
) {
200 DerivationEventType derivationEventType
= (DerivationEventType
)row
.derivationEventType
.getValue();
202 boolean publishedImageType
= derivationEventType
!= null && derivationEventType
.equals(DerivationEventTypes
.PUBLISHED_IMAGE());
203 boolean unPublishedImageType
= derivationEventType
!= null && derivationEventType
.equals(DerivationEventTypes
.UNPUBLISHED_IMAGE());
205 row
.mediaSpecimenReference
.setEnabled(publishedImageType
);
206 row
.mediaSpecimenReferenceDetail
.setEnabled(publishedImageType
);
207 row
.mediaUri
.setEnabled(unPublishedImageType
);
214 private SpecimenTypeDesignationWorkingSetDTO
fixMissingFieldUnit(SpecimenTypeDesignationWorkingSetDTO bean
) {
216 if(bean
.getFieldUnit() == null){
217 // in case the base unit of the working set is not a FieldUnit all contained TypeDesignations must be modified
218 // so that they are based on an empty FieldUnit with an associated Gathering Event
219 if(Registration
.class.isAssignableFrom(bean
.getOwner().getClass())){
220 // FIXME open Dialog to warn user about adding an empty fieldUnit to the typeDesignations
221 logger
.info("Basing all typeDesignations on a new fieldUnit");
222 Session session
= getSession();
223 Registration reg
= getRepo().getRegistrationService().find(bean
.getOwner().getId());
224 RegistrationDTO regDTO
= new RegistrationDTO(reg
);
226 FieldUnit fieldUnit
= FieldUnit
.NewInstance();
227 GatheringEvent gatheringEvent
= GatheringEvent
.NewInstance();
228 fieldUnit
.setGatheringEvent(gatheringEvent
);
229 getRepo().getOccurrenceService().save(fieldUnit
);
231 VersionableEntity baseEntity
= bean
.getBaseEntity();
232 Set
<TypeDesignationBase
> typeDesignations
= regDTO
.getTypeDesignationsInWorkingSet(
233 new TypedEntityReference(baseEntity
.getClass(), baseEntity
.getId(), baseEntity
.toString())
235 for(TypeDesignationBase td
: typeDesignations
){
236 DerivationEvent de
= DerivationEvent
.NewInstance();//
237 de
.addOriginal(fieldUnit
);
238 de
.addDerivative(((SpecimenTypeDesignation
)td
).getTypeSpecimen());
239 de
.setType(DerivationEventType
.GATHERING_IN_SITU());
242 getRepo().getRegistrationService().saveOrUpdate(reg
);
246 throw new RuntimeException("Usupported owner type " + bean
.getOwner().getClass() + ", needs to be implemented.");
258 protected void saveBean(SpecimenTypeDesignationWorkingSetDTO dto
) {
260 Registration reg
= (Registration
) dto
.getOwner();
262 // associate all type designations with the fieldUnit
263 // 1. new ones are not yet associated
264 // 2. ones which had incomplete data are also not connected
265 for(SpecimenTypeDesignationDTO stdDTO
: dto
.getSpecimenTypeDesignationDTOs()){
267 SpecimenOrObservationBase
<?
> original
= findEarliestOriginal(stdDTO
.asSpecimenTypeDesignation().getTypeSpecimen());
268 if(original
instanceof DerivedUnit
){
269 DerivedUnit du
= (DerivedUnit
)original
;
270 du
.getDerivedFrom().addOriginal(dto
.getFieldUnit());
272 } catch (Exception e
) {
273 // TODO Auto-generated catch block
278 // add newly added typeDesignations
279 Set
<SpecimenTypeDesignation
> addCandidates
= new HashSet
<>();
280 for(SpecimenTypeDesignationDTO stdDTO
: dto
.getSpecimenTypeDesignationDTOs()){
281 SpecimenTypeDesignation std
= stdDTO
.asSpecimenTypeDesignation();
282 if(reg
.getTypeDesignations().isEmpty() || !reg
.getTypeDesignations().stream().filter(td
-> td
.equals(std
)).findFirst().isPresent()){
283 std
.setCitation(citation
);
284 typifiedName
.addTypeDesignation(std
, false);
285 addCandidates
.add(std
);
288 addCandidates
.forEach(std
-> reg
.addTypeDesignation(std
));
292 UserHelper
.fromSession().createAuthorityForCurrentUser(dto
.getFieldUnit(), crud
, null);
295 getStore().saveBean(reg
);
302 protected void deleteBean(SpecimenTypeDesignationWorkingSetDTO bean
) {
303 // TODO Auto-generated method stub
313 private SpecimenOrObservationBase
<?
> findEarliestOriginal(DerivedUnit du
) throws Exception
{
315 SpecimenOrObservationBase original
= du
;
317 while(du
!= null && du
.getDerivedFrom() != null && !du
.getDerivedFrom().getOriginals().isEmpty()) {
318 Iterator
<SpecimenOrObservationBase
> it
= du
.getDerivedFrom().getOriginals().iterator();
319 SpecimenOrObservationBase nextOriginal
= it
.next();
320 if(nextOriginal
== null){
323 original
= nextOriginal
;
324 if(original
instanceof DerivedUnit
){
325 du
= (DerivedUnit
)original
;
327 // so this must be a FieldUnit,
331 throw new Exception(String
.format("%s has more than one originals", du
.toString()));
341 public void setGrantsForCurrentUser(EnumSet
<CRUD
> crud
) {