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
.service
;
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
;
18 import java
.util
.UUID
;
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
;
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
;
47 * Provides RegistrationDTOs and RegistrationWorkingsets for Registrations in the database.
50 * @author a.kohlbecker
54 @Service("registrationWorkingSetService")
55 @Transactional(readOnly
=true)
56 public class RegistrationWorkingSetService
implements IRegistrationWorkingSetService
{
58 public static final List
<String
> REGISTRATION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
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)
73 "name.nomenclaturalReference.authorship.$",
74 "name.nomenclaturalReference.inReference",
76 "name.homotypicalGroup.typifiedNames",
78 "name.typeDesignations", // important !!"
87 private List
<String
> DERIVEDUNIT_INIT_STRATEGY
= Arrays
.asList(new String
[]{
88 "*", // initialize all related entities to allow DerivedUnit conversion, see DerivedUnitConverter.copyPropertiesTo()
90 "derivedFrom.type", // TODO remove?
91 "derivedFrom.originals.derivationEvents", // important!!
92 "specimenTypeDesignations.typifiedNames.typeDesignations", // important!!
93 "mediaSpecimen.sources"
99 private List
<String
> FIELDUNIT_INIT_STRATEGY
= Arrays
.asList(new String
[]{
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!!!
108 public static final List
<String
> BLOCKING_REGISTRATION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
110 "blockedBy.blockedBy",
112 "blockedBy.typeDesignations.typeStatus",
113 // "typeDesignations.typifiedNames.typeDesignations", // important !!
114 // "typeDesignations.typeSpecimen",
115 // "typeDesignations.typeName.$",
116 // "typeDesignations.citation",
117 // "typeDesignations.citation.authorship.$",
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",
127 "blockedBy.institution",
134 private static final int PAGE_SIZE
= 50;
136 private static final Logger logger
= Logger
.getLogger(RegistrationWorkingSetService
.class);
139 @Qualifier("cdmRepository")
140 private CdmRepository repo
;
143 protected IBeanInitializer defaultBeanInitializer
;
145 public RegistrationWorkingSetService() {
151 * @param id the Registration entity id
155 public RegistrationDTO
loadDtoById(Integer id
) {
156 Registration reg
= repo
.getRegistrationService().load(id
, REGISTRATION_INIT_STRATEGY
);
157 inititializeSpecimen(reg
);
158 return new RegistrationDTO(reg
);
163 * @param id the Registration entity id
167 public RegistrationDTO
loadDtoByUuid(UUID uuid
) {
168 Registration reg
= repo
.getRegistrationService().load(uuid
, REGISTRATION_INIT_STRATEGY
);
169 inititializeSpecimen(reg
);
170 return new RegistrationDTO(reg
);
175 public Pager
<RegistrationDTO
> pageDTOs(Integer pageSize
, Integer pageIndex
) {
177 return pageDTOs(null, null, null, null, pageSize
, pageIndex
);
184 public Pager
<RegistrationDTO
> pageDTOs(User submitter
, Collection
<RegistrationStatus
> includedStatus
,
185 String identifierFilterPattern
, String taxonNameFilterPattern
,
186 Integer pageSize
, Integer pageIndex
) {
188 if(pageSize
== null){
189 pageSize
= PAGE_SIZE
;
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
));
203 * @throws RegistrationValidationException
206 public RegistrationWorkingSet
loadWorkingSetByReferenceUuid(UUID referenceUuid
, boolean resolveSections
) throws RegistrationValidationException
{
208 Reference reference
= repo
.getReferenceService().find(referenceUuid
); // needed to use load to avoid the problem described in #7331
210 reference
= resolveSection(reference
);
213 Pager
<Registration
> pager
= repo
.getRegistrationService().page(Optional
.of(reference
), null, null, null, REGISTRATION_INIT_STRATEGY
);
215 /* for debugging https://dev.e-taxonomy.eu/redmine/issues/7331 */
216 // debugIssue7331(pager);
217 return new RegistrationWorkingSet(makeDTOs(pager
.getRecords()));
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();
235 * @throws RegistrationValidationException
238 public RegistrationWorkingSet
loadWorkingSetByReferenceID(Integer referenceID
, boolean resolveSections
) throws RegistrationValidationException
{
240 Reference reference
= repo
.getReferenceService().find(referenceID
);
242 reference
= resolveSection(reference
);
244 repo
.getReferenceService().load(reference
.getUuid()); // needed to avoid the problem described in #7331
246 Pager
<Registration
> pager
= repo
.getRegistrationService().page(Optional
.of(reference
), null, null, null, REGISTRATION_INIT_STRATEGY
);
248 /* for debugging https://dev.e-taxonomy.eu/redmine/issues/7331 */
249 // debugIssue7331(pager);
251 return new RegistrationWorkingSet(makeDTOs(pager
.getRecords()));
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");
267 logger
.debug("NO AUTHORS");
273 public Set
<RegistrationDTO
> loadBlockingRegistrations(UUID blockedRegistrationUuid
){
275 Registration registration
= repo
.getRegistrationService().load(blockedRegistrationUuid
, BLOCKING_REGISTRATION_INIT_STRATEGY
);
276 Set
<Registration
> registrations
= registration
.getBlockedBy();
278 Set
<RegistrationDTO
> blockingSet
= new HashSet
<>();
279 for(Registration reg
: registrations
){
280 blockingSet
.add(new RegistrationDTO(reg
));
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
));});
301 private void initializeSpecimens(List
<Registration
> regs
) {
302 for(Registration reg
: regs
){
303 inititializeSpecimen(reg
);
312 protected void inititializeSpecimen(Registration reg
) {
314 for(TypeDesignationBase
<?
> td
: reg
.getTypeDesignations()){
315 if(td
instanceof SpecimenTypeDesignation
){
317 DerivedUnit derivedUnit
= ((SpecimenTypeDesignation
) td
).getTypeSpecimen();
318 @SuppressWarnings("rawtypes")
319 Set
<SpecimenOrObservationBase
> sobs
= new HashSet
<>();
320 sobs
.add(HibernateProxyHelper
.deproxy(derivedUnit
));
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
);
330 if(DerivedUnit
.class.isAssignableFrom(sob
.getClass())) {
331 defaultBeanInitializer
.initialize(sob
, DERIVEDUNIT_INIT_STRATEGY
);
332 nextSobs
= ((DerivedUnit
)sob
).getOriginals();
334 if(sob
instanceof FieldUnit
){
335 defaultBeanInitializer
.initialize(sob
, FIELDUNIT_INIT_STRATEGY
);