ref #7222 removing the 'Hint:' line in TaxonNameEditor
[cdm-vaadin.git] / src / main / java / eu / etaxonomy / cdm / vaadin / view / name / SpecimenTypeDesignationWorkingsetEditorPresenter.java
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.HashMap;
14 import java.util.HashSet;
15 import java.util.Map;
16 import java.util.Set;
17
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;
23
24 import com.vaadin.spring.annotation.SpringComponent;
25
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;
64 /**
65 * SpecimenTypeDesignationWorkingsetPopupEditorView implementation must override the showInEditor() method,
66 * see {@link #prepareAsFieldGroupDataSource()} for details.
67 *
68 * @author a.kohlbecker
69 * @since Jun 13, 2017
70 *
71 */
72 @SpringComponent
73 @Scope("prototype")
74 public class SpecimenTypeDesignationWorkingsetEditorPresenter
75 extends AbstractEditorPresenter<SpecimenTypeDesignationWorkingSetDTO , SpecimenTypeDesignationWorkingsetPopupEditorView>
76 implements CachingPresenter, DisposableBean {
77
78 private static final long serialVersionUID = 4255636253714476918L;
79
80 private static final EnumSet<CRUD> COLLECTION_EDITOR_CRUD = EnumSet.of(CRUD.UPDATE, CRUD.DELETE);
81
82 CdmStore<Registration, IRegistrationService> store;
83
84
85 /**
86 * This object for this field will either be injected by the {@link PopupEditorFactory} or by a Spring
87 * {@link BeanFactory}
88 */
89 @Autowired
90 private ISpecimenTypeDesignationWorkingSetService specimenTypeDesignationWorkingSetService;
91
92 /**
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.
95 */
96 private EnumSet<CRUD> crud = null;
97
98 private ICdmCacher cache;
99
100 @Autowired
101 protected CdmFilterablePagingProviderFactory pagingProviderFactory;
102
103 SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto;
104
105 private Map<CollectionPopupEditor, SpecimenTypeDesignationDTORow> collectionPopupEditorsRowMap = new HashMap<>();
106
107 private Map<ReferencePopupEditor, SpecimenTypeDesignationDTORow> referencePopupEditorsRowMap = new HashMap<>();
108
109 private Set<CollectionRowItemCollection> popuEditorTypeDesignationSourceRows = new HashSet<>();
110
111 private java.util.Collection<CdmBase> rootEntities = new HashSet<>();
112
113 protected CdmStore<Registration, IRegistrationService> getStore() {
114 if(store == null){
115 store = new CdmStore<>(getRepo(), getRepo().getRegistrationService());
116 }
117 return store;
118 }
119
120 /**
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>.
124 * <p>
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.
128 *
129 * @param identifier a {@link TypeDesignationWorkingsetEditorIdSet}
130 */
131 @Override
132 protected SpecimenTypeDesignationWorkingSetDTO<Registration> loadBeanById(Object identifier) {
133
134 cache = new CdmTransientEntityCacher(this);
135 if(identifier != null){
136
137 TypeDesignationWorkingsetEditorIdSet idset = (TypeDesignationWorkingsetEditorIdSet)identifier;
138
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");
146 }
147 // need to use load but put see #7214
148 cache.load(workingSetDto.getOwner());
149 rootEntities.add(workingSetDto.getOwner());
150 } else {
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());
157 }
158
159 } else {
160 workingSetDto = null;
161 }
162
163 return workingSetDto;
164 }
165
166
167 /**
168 * {@inheritDoc}
169 */
170 @SuppressWarnings("serial")
171 @Override
172 public void handleViewEntered() {
173
174 CdmBeanItemContainerFactory selectFactory = new CdmBeanItemContainerFactory(getRepo());
175 getView().getCountrySelectField().setContainerDataSource(selectFactory.buildBeanItemContainer(Country.uuidCountryVocabulary));
176
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);
182
183 getView().getTypeDesignationsCollectionField().addElementRemovedListener(e -> deleteTypeDesignation(e.getElement()));
184 getView().getTypeDesignationsCollectionField().addElementAddedListener(e -> addTypeDesignation(e.getElement()));
185
186
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));
190
191 CdmFilterablePagingProvider<Reference, Reference> referencePagingProvider = pagingProviderFactory.referencePagingProvider();
192
193 getView().getTypeDesignationsCollectionField().setEditorInstantiator(new AbstractElementCollection.Instantiator<SpecimenTypeDesignationDTORow>() {
194
195 @Override
196 public SpecimenTypeDesignationDTORow create() {
197
198 SpecimenTypeDesignationDTORow row = new SpecimenTypeDesignationDTORow();
199
200 row.kindOfUnit.setContainerDataSource(selectFactory.buildTermItemContainer(
201 RegistrationTermLists.KIND_OF_UNIT_TERM_UUIDS())
202 );
203 row.kindOfUnit.setNullSelectionAllowed(false);
204
205 row.typeStatus.setContainerDataSource(selectFactory.buildTermItemContainer(
206 RegistrationTermLists.SPECIMEN_TYPE_DESIGNATION_STATUS_UUIDS())
207 );
208 row.typeStatus.setNullSelectionAllowed(false);
209
210
211 row.collection.loadFrom(
212 collectionPagingProvider,
213 collectionPagingProvider,
214 collectionPagingProvider.getPageSize()
215 );
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);
224 }
225 });
226
227 row.mediaSpecimenReference.loadFrom(
228 referencePagingProvider,
229 referencePagingProvider,
230 collectionPagingProvider.getPageSize()
231 );
232
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);
241 }
242 });
243
244 getView().applyDefaultComponentStyle(row.components());
245
246 popuEditorTypeDesignationSourceRows.add(row);
247
248 return row;
249 }
250
251 });
252
253 }
254
255
256 /**
257 * {@inheritDoc}
258 */
259 @Override
260 protected void saveBean(SpecimenTypeDesignationWorkingSetDTO dto) {
261
262 if(crud != null){
263 UserHelperAccess.userHelper().createAuthorityForCurrentUser(dto.getFieldUnit(), crud, null);
264 }
265
266 specimenTypeDesignationWorkingSetService.save(dto);
267 }
268
269 /**
270 * {@inheritDoc}
271 */
272 @Override
273 protected void deleteBean(SpecimenTypeDesignationWorkingSetDTO bean) {
274 specimenTypeDesignationWorkingSetService.delete(bean, true);
275 }
276
277 /**
278 * @param element
279 * @return
280 */
281 private void addTypeDesignation(SpecimenTypeDesignationDTO element) {
282 getView().updateAllowDelete();
283 }
284
285
286 /**
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)}
289 *
290 * TODO once https://dev.e-taxonomy.eu/redmine/issues/7077 is fixed dissociating from the Registration could be removed here
291 *
292 * @param e
293 * @return
294 */
295 private void deleteTypeDesignation(SpecimenTypeDesignationDTO element) {
296
297 Registration reg = workingSetDto.getOwner();
298 SpecimenTypeDesignation std = element.asSpecimenTypeDesignation();
299
300 reg.getTypeDesignations().remove(std);
301
302 getView().updateAllowDelete();
303 }
304
305 /**
306 * @param crud
307 */
308 public void setGrantsForCurrentUser(EnumSet<CRUD> crud) {
309 this.crud = crud;
310
311 }
312
313 /**
314 * {@inheritDoc}
315 */
316 @Override
317 public ICdmCacher getCache() {
318 return cache;
319 }
320
321 @Override
322 public void disposeCache() {
323 cache.dispose();
324 }
325
326 public void doCollectionEditorAdd(SpecimenTypeDesignationDTORow row) {
327
328 CollectionPopupEditor collectionPopupEditor = openPopupEditor(CollectionPopupEditor.class, null);
329
330 collectionPopupEditor.grantToCurrentUser(COLLECTION_EDITOR_CRUD);
331 collectionPopupEditor.withDeleteButton(true);
332 collectionPopupEditor.loadInEditor(null);
333
334 collectionPopupEditorsRowMap.put(collectionPopupEditor, row);
335 }
336
337 public void doCollectionEditorEdit(SpecimenTypeDesignationDTORow row) {
338
339 CollectionPopupEditor collectionPopupEditor = openPopupEditor(CollectionPopupEditor.class, null);
340
341 collectionPopupEditor.grantToCurrentUser(COLLECTION_EDITOR_CRUD);
342 collectionPopupEditor.withDeleteButton(true);
343 collectionPopupEditor.loadInEditor(row.collection.getValue().getUuid());
344
345 collectionPopupEditorsRowMap.put(collectionPopupEditor, row);
346 }
347
348
349 @EventBusListenerMethod(filter = EntityChangeEventFilter.OccurrenceCollectionFilter.class)
350 public void onCollectionEvent(EntityChangeEvent event){
351
352 if(!isFromOwnView(event)){
353 return;
354 }
355
356 Collection newCollection = getRepo().getCollectionService().load(
357 event.getEntityUuid(), Arrays.asList(new String[]{"$.institute"})
358 );
359 cache.load(newCollection);
360
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());
365 }
366 for( CollectionRowItemCollection row : popuEditorTypeDesignationSourceRows) {
367 ToOneRelatedEntityCombobox<Collection> combobox = row.getComponent(ToOneRelatedEntityCombobox.class, 3);
368 combobox.reload();
369 }
370 }
371
372 public void doReferenceEditorAdd(SpecimenTypeDesignationDTORow row) {
373
374 ReferencePopupEditor referencePopupEditor = openPopupEditor(ReferencePopupEditor.class, null);
375
376 referencePopupEditor.withReferenceTypes(RegistrationUIDefaults.MEDIA_REFERENCE_TYPES);
377 referencePopupEditor.grantToCurrentUser(COLLECTION_EDITOR_CRUD);
378 referencePopupEditor.withDeleteButton(true);
379 referencePopupEditor.loadInEditor(null);
380
381 referencePopupEditorsRowMap.put(referencePopupEditor, row);
382 }
383
384 public void doReferenceEditorEdit(SpecimenTypeDesignationDTORow row) {
385
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());
391
392 referencePopupEditorsRowMap.put(referencePopupEditor, row);
393 }
394
395 @EventBusListenerMethod(filter = EntityChangeEventFilter.ReferenceFilter.class)
396 public void onReferenceEvent(EntityChangeEvent event){
397
398 Reference newRef = getRepo().getReferenceService().load(event.getEntityUuid(), Arrays.asList(new String[]{"$"}));
399 cache.load(newRef);
400
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());
405
406 } else {
407 for( CollectionRowItemCollection row : popuEditorTypeDesignationSourceRows) {
408 ToOneRelatedEntityCombobox<Reference> combobox = row.getComponent(ToOneRelatedEntityCombobox.class, 7);
409 combobox.reload();
410 }
411 }
412 }
413
414 /**
415 * {@inheritDoc}
416 */
417 @Override
418 public void addRootEntity(CdmBase entity) {
419 rootEntities.add(entity);
420 }
421
422 /**
423 * {@inheritDoc}
424 */
425 @Override
426 public java.util.Collection<CdmBase> getRootEntities() {
427 return rootEntities ;
428 }
429
430 /**
431 * {@inheritDoc}
432 */
433 @Override
434 public void destroy() throws Exception {
435 super.destroy();
436 cache.dispose();
437 }
438
439 }