ref #7458 solving generic type parameter problem in FilterableAnnotationsField
[cdm-vaadin.git] / src / main / java / eu / etaxonomy / cdm / service / RegistrationWorkingSetService.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.service;
10
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.Collection;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Optional;
17 import java.util.Set;
18 import java.util.UUID;
19
20 import org.apache.log4j.Logger;
21 import org.hibernate.Hibernate;
22 import org.springframework.beans.factory.annotation.Autowired;
23 import org.springframework.beans.factory.annotation.Qualifier;
24 import org.springframework.stereotype.Service;
25 import org.springframework.transaction.annotation.Transactional;
26
27 import eu.etaxonomy.cdm.api.application.CdmRepository;
28 import eu.etaxonomy.cdm.api.service.dto.RegistrationDTO;
29 import eu.etaxonomy.cdm.api.service.exception.RegistrationValidationException;
30 import eu.etaxonomy.cdm.api.service.pager.Pager;
31 import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
32 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
33 import eu.etaxonomy.cdm.model.common.User;
34 import eu.etaxonomy.cdm.model.name.Registration;
35 import eu.etaxonomy.cdm.model.name.RegistrationStatus;
36 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
37 import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
38 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
39 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
40 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
41 import eu.etaxonomy.cdm.model.reference.Reference;
42 import eu.etaxonomy.cdm.model.reference.ReferenceType;
43 import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer;
44 import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet;
45
46 /**
47 * Provides RegistrationDTOs and RegistrationWorkingsets for Registrations in the database.
48 *
49 *
50 * @author a.kohlbecker
51 * @since Mar 10, 2017
52 *
53 */
54 @Service("registrationWorkingSetService")
55 @Transactional(readOnly=true)
56 public class RegistrationWorkingSetService implements IRegistrationWorkingSetService {
57
58 public static final List<String> REGISTRATION_INIT_STRATEGY = Arrays.asList(new String []{
59 "blockedBy",
60 // typeDesignation
61 "typeDesignations.typeStatus",
62 "typeDesignations.typifiedNames.typeDesignations", // important !!
63 "typeDesignations.typeSpecimen",
64 "typeDesignations.typeName.$",
65 "typeDesignations.citation",
66 "typeDesignations.citation.authorship.$",
67 "typeDesignations.annotations", // needed for AnnotatableEntity.clone() in DerivedUnitConverter.copyPropertiesTo
68 "typeDesignations.markers", // needed for AnnotatableEntity.clone() in DerivedUnitConverter.copyPropertiesTo
69 "typeDesignations.registrations", // DerivedUnitConverter.copyPropertiesTo(TARGET n)
70
71 // name
72 "name.$",
73 "name.nomenclaturalReference.authorship.$",
74 "name.nomenclaturalReference.inReference",
75 "name.rank",
76 "name.homotypicalGroup.typifiedNames",
77 "name.status.type",
78 "name.typeDesignations", // important !!"
79 // institution
80 "institution",
81 }
82 );
83
84 /**
85 *
86 */
87 private List<String> DERIVEDUNIT_INIT_STRATEGY = Arrays.asList(new String[]{
88 "*", // initialize all related entities to allow DerivedUnit conversion, see DerivedUnitConverter.copyPropertiesTo()
89 "derivedFrom.$",
90 "derivedFrom.type", // TODO remove?
91 "derivedFrom.originals.derivationEvents", // important!!
92 "specimenTypeDesignations.typifiedNames.typeDesignations", // important!!
93 "mediaSpecimen.sources"
94 });
95
96 /**
97 *
98 */
99 private List<String> FIELDUNIT_INIT_STRATEGY = Arrays.asList(new String[]{
100 "$",
101 "gatheringEvent.$",
102 "gatheringEvent.country",
103 "gatheringEvent.collectingAreas",
104 "gatheringEvent.actor",
105 "derivationEvents.derivatives" // important, otherwise the DerivedUnits are not included into the graph of initialized entities!!!
106 });
107
108 public static final List<String> BLOCKING_REGISTRATION_INIT_STRATEGY = Arrays.asList(new String []{
109
110 "blockedBy.blockedBy",
111 // typeDesignation
112 "blockedBy.typeDesignations.typeStatus",
113 // "typeDesignations.typifiedNames.typeDesignations", // important !!
114 // "typeDesignations.typeSpecimen",
115 // "typeDesignations.typeName.$",
116 // "typeDesignations.citation",
117 // "typeDesignations.citation.authorship.$",
118 // name
119 // "blockedBy.name.$",
120 "blockedBy.name.nomenclaturalReference.authorship",
121 "blockedBy.name.nomenclaturalReference.inReference",
122 "blockedBy.name.rank",
123 // "name.homotypicalGroup.typifiedNames",
124 // "name.status.type",
125 // "name.typeDesignations",
126 // institution
127 "blockedBy.institution",
128 }
129 );
130
131 /**
132 *
133 */
134 private static final int PAGE_SIZE = 50;
135
136 private static final Logger logger = Logger.getLogger(RegistrationWorkingSetService.class);
137
138 @Autowired
139 @Qualifier("cdmRepository")
140 private CdmRepository repo;
141
142 @Autowired
143 protected IBeanInitializer defaultBeanInitializer;
144
145 public RegistrationWorkingSetService() {
146
147 }
148
149
150 /**
151 * @param id the Registration entity id
152 * @return
153 */
154 @Override
155 public RegistrationDTO loadDtoById(Integer id) {
156 Registration reg = repo.getRegistrationService().load(id, REGISTRATION_INIT_STRATEGY);
157 inititializeSpecimen(reg);
158 return new RegistrationDTO(reg);
159 }
160
161
162 /**
163 * @param id the Registration entity id
164 * @return
165 */
166 @Override
167 public RegistrationDTO loadDtoByUuid(UUID uuid) {
168 Registration reg = repo.getRegistrationService().load(uuid, REGISTRATION_INIT_STRATEGY);
169 inititializeSpecimen(reg);
170 return new RegistrationDTO(reg);
171 }
172
173
174 @Override
175 public Pager<RegistrationDTO> pageDTOs(Integer pageSize, Integer pageIndex) {
176
177 return pageDTOs(null, null, null, null, pageSize, pageIndex);
178 }
179
180 /**
181 * {@inheritDoc}
182 */
183 @Override
184 public Pager<RegistrationDTO> pageDTOs(User submitter, Collection<RegistrationStatus> includedStatus,
185 String identifierFilterPattern, String taxonNameFilterPattern,
186 Integer pageSize, Integer pageIndex) {
187
188 if(pageSize == null){
189 pageSize = PAGE_SIZE;
190 }
191
192 Pager<Registration> pager = repo.getRegistrationService().page(submitter, includedStatus,
193 identifierFilterPattern, taxonNameFilterPattern,
194 PAGE_SIZE, 0, null, REGISTRATION_INIT_STRATEGY);
195 List<Registration> registrations = pager.getRecords();
196 Pager<RegistrationDTO> dtoPager = new DefaultPagerImpl(pager.getCurrentIndex(), pager.getCount(), pager.getPageSize(), makeDTOs(registrations));
197 return dtoPager;
198 }
199
200
201 /**
202 * {@inheritDoc}
203 * @throws RegistrationValidationException
204 */
205 @Override
206 public RegistrationWorkingSet loadWorkingSetByReferenceUuid(UUID referenceUuid, boolean resolveSections) throws RegistrationValidationException {
207
208 Reference reference = repo.getReferenceService().find(referenceUuid); // needed to use load to avoid the problem described in #7331
209 if(resolveSections){
210 reference = resolveSection(reference);
211 }
212
213 Pager<Registration> pager = repo.getRegistrationService().page(Optional.of(reference), null, null, null, REGISTRATION_INIT_STRATEGY);
214
215 /* for debugging https://dev.e-taxonomy.eu/redmine/issues/7331 */
216 // debugIssue7331(pager);
217 return new RegistrationWorkingSet(makeDTOs(pager.getRecords()));
218 }
219
220
221 /**
222 * @param reference
223 * @return
224 */
225 protected Reference resolveSection(Reference reference) {
226 repo.getReferenceService().load(reference.getUuid(), Arrays.asList(new String[]{"inReference"})); // needed to avoid the problem described in #7331
227 if(reference.isOfType(ReferenceType.Section) && reference.getInReference() != null) {
228 reference = reference.getInReference();
229 }
230 return reference;
231 }
232
233 /**
234 * {@inheritDoc}
235 * @throws RegistrationValidationException
236 */
237 @Override
238 public RegistrationWorkingSet loadWorkingSetByReferenceID(Integer referenceID, boolean resolveSections) throws RegistrationValidationException {
239
240 Reference reference = repo.getReferenceService().find(referenceID);
241 if(resolveSections){
242 reference = resolveSection(reference);
243 }
244 repo.getReferenceService().load(reference.getUuid()); // needed to avoid the problem described in #7331
245
246 Pager<Registration> pager = repo.getRegistrationService().page(Optional.of(reference), null, null, null, REGISTRATION_INIT_STRATEGY);
247
248 /* for debugging https://dev.e-taxonomy.eu/redmine/issues/7331 */
249 // debugIssue7331(pager);
250
251 return new RegistrationWorkingSet(makeDTOs(pager.getRecords()));
252 }
253
254
255 /**
256 * @param pager
257 */
258 @SuppressWarnings("unused")
259 private void debugIssue7331(Pager<Registration> pager) {
260 for(Registration reg : pager.getRecords()){
261 if(reg.getName() != null && reg.getName().getNomenclaturalReference().getAuthorship() != null){
262 Reference ref = reg.getName().getNomenclaturalReference();
263 if(!Hibernate.isInitialized(ref.getAuthorship())){
264 logger.error("UNINITIALIZED");
265 }
266 } else {
267 logger.debug("NO AUTHORS");
268 }
269 }
270 }
271
272 @Override
273 public Set<RegistrationDTO> loadBlockingRegistrations(UUID blockedRegistrationUuid){
274
275 Registration registration = repo.getRegistrationService().load(blockedRegistrationUuid, BLOCKING_REGISTRATION_INIT_STRATEGY);
276 Set<Registration> registrations = registration.getBlockedBy();
277
278 Set<RegistrationDTO> blockingSet = new HashSet<>();
279 for(Registration reg : registrations){
280 blockingSet.add(new RegistrationDTO(reg));
281 }
282 return blockingSet;
283 }
284
285 /**
286 * @param regs
287 * @return
288 */
289 private List<RegistrationDTO> makeDTOs(List<Registration> regs) {
290 initializeSpecimens(regs);
291 List<RegistrationDTO> dtos = new ArrayList<>(regs.size());
292 regs.forEach(reg -> {dtos.add(new RegistrationDTO(reg));});
293 return dtos;
294 }
295
296
297
298 /**
299 * @param regs
300 */
301 private void initializeSpecimens(List<Registration> regs) {
302 for(Registration reg : regs){
303 inititializeSpecimen(reg);
304 }
305
306 }
307
308
309 /**
310 * @param reg
311 */
312 protected void inititializeSpecimen(Registration reg) {
313
314 for(TypeDesignationBase<?> td : reg.getTypeDesignations()){
315 if(td instanceof SpecimenTypeDesignation){
316
317 DerivedUnit derivedUnit = ((SpecimenTypeDesignation) td).getTypeSpecimen();
318 @SuppressWarnings("rawtypes")
319 Set<SpecimenOrObservationBase> sobs = new HashSet<>();
320 sobs.add(HibernateProxyHelper.deproxy(derivedUnit));
321
322 while(sobs != null && !sobs.isEmpty()){
323 @SuppressWarnings("rawtypes")
324 Set<SpecimenOrObservationBase> nextSobs = null;
325 for(@SuppressWarnings("rawtypes") SpecimenOrObservationBase sob : sobs){
326 sob = HibernateProxyHelper.deproxy(sob);
327 if(sob == null){
328 continue;
329 }
330 if(DerivedUnit.class.isAssignableFrom(sob.getClass())) {
331 defaultBeanInitializer.initialize(sob, DERIVEDUNIT_INIT_STRATEGY);
332 nextSobs = ((DerivedUnit)sob).getOriginals();
333 }
334 if(sob instanceof FieldUnit){
335 defaultBeanInitializer.initialize(sob, FIELDUNIT_INIT_STRATEGY);
336 }
337 }
338 sobs = nextSobs;
339 }
340 }
341 }
342 }
343
344
345
346
347
348
349 }