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
.api
.service
.registration
;
11 import java
.io
.IOException
;
12 import java
.util
.ArrayList
;
13 import java
.util
.Arrays
;
14 import java
.util
.Collection
;
15 import java
.util
.HashSet
;
16 import java
.util
.List
;
17 import java
.util
.Optional
;
19 import java
.util
.UUID
;
21 import org
.apache
.log4j
.Logger
;
22 import org
.hibernate
.Hibernate
;
23 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
24 import org
.springframework
.beans
.factory
.annotation
.Qualifier
;
25 import org
.springframework
.stereotype
.Service
;
26 import org
.springframework
.transaction
.annotation
.Transactional
;
28 import eu
.etaxonomy
.cdm
.api
.application
.CdmRepository
;
29 import eu
.etaxonomy
.cdm
.api
.service
.dto
.RegistrationDTO
;
30 import eu
.etaxonomy
.cdm
.api
.service
.dto
.RegistrationWorkingSet
;
31 import eu
.etaxonomy
.cdm
.api
.service
.exception
.RegistrationValidationException
;
32 import eu
.etaxonomy
.cdm
.api
.service
.pager
.Pager
;
33 import eu
.etaxonomy
.cdm
.api
.service
.pager
.impl
.DefaultPagerImpl
;
34 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
35 import eu
.etaxonomy
.cdm
.model
.common
.User
;
36 import eu
.etaxonomy
.cdm
.model
.name
.Registration
;
37 import eu
.etaxonomy
.cdm
.model
.name
.RegistrationStatus
;
38 import eu
.etaxonomy
.cdm
.model
.name
.SpecimenTypeDesignation
;
39 import eu
.etaxonomy
.cdm
.model
.name
.TypeDesignationBase
;
40 import eu
.etaxonomy
.cdm
.model
.name
.TypeDesignationStatusBase
;
41 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivedUnit
;
42 import eu
.etaxonomy
.cdm
.model
.occurrence
.FieldUnit
;
43 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
44 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
45 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceType
;
46 import eu
.etaxonomy
.cdm
.persistence
.dao
.initializer
.IBeanInitializer
;
47 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
48 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
.SortOrder
;
51 * Provides RegistrationDTOs and RegistrationWorkingsets for Registrations in the database.
54 * @author a.kohlbecker
58 @Service("registrationWorkingSetService")
59 @Transactional(readOnly
=true)
60 public class RegistrationWorkingSetService
implements IRegistrationWorkingSetService
{
62 public static final List
<String
> REGISTRATION_DTO_INIT_STRATEGY
= Arrays
.asList(new String
[]{
65 "typeDesignations.typeStatus",
66 "typeDesignations.typifiedNames.typeDesignations", // important !!
67 "typeDesignations.typeSpecimen",
68 "typeDesignations.typeName.$",
69 "typeDesignations.citation",
70 "typeDesignations.citation.authorship.$",
71 "typeDesignations.annotations", // needed for AnnotatableEntity.clone() in DerivedUnitConverter.copyPropertiesTo
72 "typeDesignations.markers", // needed for AnnotatableEntity.clone() in DerivedUnitConverter.copyPropertiesTo
73 "typeDesignations.registrations", // DerivedUnitConverter.copyPropertiesTo(TARGET n)
77 "name.nomenclaturalReference.authorship.$",
78 "name.nomenclaturalReference.inReference",
80 "name.homotypicalGroup.typifiedNames",
82 "name.typeDesignations", // important !!"
91 public List
<String
> DERIVEDUNIT_INIT_STRATEGY
= Arrays
.asList(new String
[]{
92 "*", // initialize all related entities to allow DerivedUnit conversion, see DerivedUnitConverter.copyPropertiesTo()
94 "derivedFrom.type", // TODO remove?
95 "derivedFrom.originals.derivationEvents", // important!!
96 "specimenTypeDesignations.typifiedNames.typeDesignations", // important!!
97 "mediaSpecimen.sources"
103 public List
<String
> FIELDUNIT_INIT_STRATEGY
= Arrays
.asList(new String
[]{
105 "annotations.*", // * is needed as log as we are using a table in FilterableAnnotationsField
107 "gatheringEvent.country",
108 "gatheringEvent.collectingAreas",
109 "gatheringEvent.actor",
110 "derivationEvents.derivatives" // important, otherwise the DerivedUnits are not included into the graph of initialized entities!!!
113 public static final List
<String
> BLOCKING_REGISTRATION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
115 "blockedBy.blockedBy",
117 "blockedBy.typeDesignations.typeStatus",
118 // "typeDesignations.typifiedNames.typeDesignations", // important !!
119 // "typeDesignations.typeSpecimen",
120 // "typeDesignations.typeName.$",
121 // "typeDesignations.citation",
122 // "typeDesignations.citation.authorship.$",
124 // "blockedBy.name.$",
125 "blockedBy.name.nomenclaturalReference.authorship",
126 "blockedBy.name.nomenclaturalReference.inReference",
127 "blockedBy.name.rank",
128 // "name.homotypicalGroup.typifiedNames",
129 // "name.status.type",
130 // "name.typeDesignations",
132 "blockedBy.institution",
139 private static final int PAGE_SIZE
= 50;
141 private static final Logger logger
= Logger
.getLogger(RegistrationWorkingSetService
.class);
144 @Qualifier("cdmRepository")
145 private CdmRepository repo
;
148 protected IBeanInitializer defaultBeanInitializer
;
150 public RegistrationWorkingSetService() {
156 * @param id the Registration entity id
160 public RegistrationDTO
loadDtoById(Integer id
) {
161 Registration reg
= repo
.getRegistrationService().load(id
, REGISTRATION_DTO_INIT_STRATEGY
);
162 inititializeSpecimen(reg
);
163 return new RegistrationDTO(reg
);
168 * @param id the Registration entity id
172 @Transactional(readOnly
=true)
173 public RegistrationDTO
loadDtoByUuid(UUID uuid
) {
174 Registration reg
= repo
.getRegistrationService().load(uuid
, REGISTRATION_DTO_INIT_STRATEGY
);
175 inititializeSpecimen(reg
);
176 return new RegistrationDTO(reg
);
180 @Transactional(readOnly
=true)
181 public Pager
<RegistrationDTO
> pageDTOs(String identifier
, Integer pageIndex
, Integer pageSize
) throws IOException
{
183 Pager
<Registration
> regPager
= repo
.getRegistrationService().pageByIdentifier(identifier
, pageIndex
, pageSize
, REGISTRATION_DTO_INIT_STRATEGY
);
184 return convertToDTOPager(regPager
);
193 public Pager
<RegistrationDTO
> convertToDTOPager(Pager
<Registration
> regPager
) {
194 return new DefaultPagerImpl
<RegistrationDTO
>(regPager
.getCurrentIndex(), regPager
.getCount(), regPager
.getPageSize(), makeDTOs(regPager
.getRecords()));
199 public Pager
<RegistrationDTO
> pageDTOs(Integer pageSize
, Integer pageIndex
) {
201 return pageDTOs((User
)null, null, null, null, null, pageSize
, pageIndex
, null);
208 public Pager
<RegistrationDTO
> pageDTOs(User submitter
, Collection
<RegistrationStatus
> includedStatus
,
209 String identifierFilterPattern
, String taxonNameFilterPattern
, Set
<TypeDesignationStatusBase
> typeStatusFilter
,
210 Integer pageSize
, Integer pageIndex
, List
<OrderHint
> orderHints
) {
212 if(pageSize
== null){
213 pageSize
= PAGE_SIZE
;
216 if(orderHints
== null){
217 orderHints
= Arrays
.asList(new OrderHint("identifier", SortOrder
.ASCENDING
));
220 Pager
<Registration
> pager
= repo
.getRegistrationService().page(submitter
, includedStatus
, identifierFilterPattern
, taxonNameFilterPattern
,
221 typeStatusFilter
, PAGE_SIZE
, pageIndex
, orderHints
, REGISTRATION_DTO_INIT_STRATEGY
);
223 Pager
<RegistrationDTO
> dtoPager
= convertToDTOPager(pager
);
224 if(logger
.isDebugEnabled()){
225 logger
.debug(String
.format("pageDTOs() pageIndex: $1%d, pageSize: $2%d, includedStatus: $3%s, identifierFilterPattern: $4%s, taxonNameFilterPattern: $5%s, submitter: $6%s",
226 pageIndex
, pageSize
, includedStatus
, identifierFilterPattern
, taxonNameFilterPattern
, submitter
));
227 logger
.debug("pageDTOs() result: " + pager
.toString());
233 public Pager
<RegistrationDTO
> pageDTOs(UUID submitterUuid
, Collection
<RegistrationStatus
> includedStatus
, String identifierFilterPattern
,
234 String taxonNameFilterPattern
, Collection
<UUID
> typeDesignationStatusUuids
, Integer pageSize
,
235 Integer pageIndex
, List
<OrderHint
> orderHints
){
237 if(pageSize
== null){
238 pageSize
= PAGE_SIZE
;
241 if(orderHints
== null){
242 orderHints
= Arrays
.asList(new OrderHint("identifier", SortOrder
.ASCENDING
));
245 Pager
<Registration
> pager
= repo
.getRegistrationService().page(submitterUuid
, includedStatus
,
246 identifierFilterPattern
, taxonNameFilterPattern
,
247 typeDesignationStatusUuids
, PAGE_SIZE
, pageIndex
, orderHints
, REGISTRATION_DTO_INIT_STRATEGY
);
249 Pager
<RegistrationDTO
> dtoPager
= convertToDTOPager(pager
);
250 if(logger
.isDebugEnabled()){
251 logger
.debug(String
.format("pageDTOs() pageIndex: $1%d, pageSize: $2%d, includedStatusUuids: $3%s, typeDesignationStatusUuids: $4%s, taxonNameFilterPattern: $5%s, submitterUuid: $6%s",
252 pageIndex
, pageSize
, includedStatus
, identifierFilterPattern
, taxonNameFilterPattern
, submitterUuid
));
253 logger
.debug("pageDTOs() result: " + pager
.toString());
262 * @throws RegistrationValidationException
265 public RegistrationWorkingSet
loadWorkingSetByReferenceUuid(UUID referenceUuid
, boolean resolveSections
) throws RegistrationValidationException
{
267 Reference reference
= repo
.getReferenceService().load(referenceUuid
); // needed to use load to avoid the problem described in #7331
269 reference
= resolveSection(reference
);
272 Pager
<Registration
> pager
= repo
.getRegistrationService().page(Optional
.of(reference
), null, null, null, REGISTRATION_DTO_INIT_STRATEGY
);
274 /* for debugging https://dev.e-taxonomy.eu/redmine/issues/7331 */
275 // debugIssue7331(pager);
276 return new RegistrationWorkingSet(makeDTOs(pager
.getRecords()));
284 protected Reference
resolveSection(Reference reference
) {
285 repo
.getReferenceService().load(reference
.getUuid(), Arrays
.asList(new String
[]{"inReference"})); // needed to avoid the problem described in #7331
286 if(reference
.isOfType(ReferenceType
.Section
) && reference
.getInReference() != null) {
287 reference
= reference
.getInReference();
294 * @throws RegistrationValidationException
297 public RegistrationWorkingSet
loadWorkingSetByReferenceID(Integer referenceID
, boolean resolveSections
) throws RegistrationValidationException
{
299 Reference reference
= repo
.getReferenceService().find(referenceID
);
301 reference
= resolveSection(reference
);
303 repo
.getReferenceService().load(reference
.getUuid()); // needed to avoid the problem described in #7331
305 Pager
<Registration
> pager
= repo
.getRegistrationService().page(Optional
.of(reference
), null, null, null, REGISTRATION_DTO_INIT_STRATEGY
);
307 /* for debugging https://dev.e-taxonomy.eu/redmine/issues/7331 */
308 // debugIssue7331(pager);
310 return new RegistrationWorkingSet(makeDTOs(pager
.getRecords()));
317 @SuppressWarnings("unused")
318 private void debugIssue7331(Pager
<Registration
> pager
) {
319 for(Registration reg
: pager
.getRecords()){
320 if(reg
.getName() != null && reg
.getName().getNomenclaturalReference().getAuthorship() != null){
321 Reference ref
= reg
.getName().getNomenclaturalReference();
322 if(!Hibernate
.isInitialized(ref
.getAuthorship())){
323 logger
.error("UNINITIALIZED");
326 logger
.debug("NO AUTHORS");
332 public Set
<RegistrationDTO
> loadBlockingRegistrations(UUID blockedRegistrationUuid
){
334 Registration registration
= repo
.getRegistrationService().load(blockedRegistrationUuid
, BLOCKING_REGISTRATION_INIT_STRATEGY
);
335 Set
<Registration
> registrations
= registration
.getBlockedBy();
337 Set
<RegistrationDTO
> blockingSet
= new HashSet
<>();
338 for(Registration reg
: registrations
){
339 blockingSet
.add(new RegistrationDTO(reg
));
348 private List
<RegistrationDTO
> makeDTOs(List
<Registration
> regs
) {
349 initializeSpecimens(regs
);
350 List
<RegistrationDTO
> dtos
= new ArrayList
<>(regs
.size());
351 regs
.forEach(reg
-> {dtos
.add(new RegistrationDTO(reg
));});
359 public void initializeSpecimens(List
<Registration
> regs
) {
360 for(Registration reg
: regs
){
361 inititializeSpecimen(reg
);
370 public void inititializeSpecimen(Registration reg
) {
372 for(TypeDesignationBase
<?
> td
: reg
.getTypeDesignations()){
373 if(td
instanceof SpecimenTypeDesignation
){
375 DerivedUnit derivedUnit
= ((SpecimenTypeDesignation
) td
).getTypeSpecimen();
376 @SuppressWarnings("rawtypes")
377 Set
<SpecimenOrObservationBase
> sobs
= new HashSet
<>();
378 sobs
.add(HibernateProxyHelper
.deproxy(derivedUnit
));
380 while(sobs
!= null && !sobs
.isEmpty()){
381 @SuppressWarnings("rawtypes")
382 Set
<SpecimenOrObservationBase
> nextSobs
= null;
383 for(@SuppressWarnings("rawtypes") SpecimenOrObservationBase sob
: sobs
){
384 sob
= HibernateProxyHelper
.deproxy(sob
);
388 if(DerivedUnit
.class.isAssignableFrom(sob
.getClass())) {
389 defaultBeanInitializer
.initialize(sob
, DERIVEDUNIT_INIT_STRATEGY
);
390 nextSobs
= ((DerivedUnit
)sob
).getOriginals();
392 if(sob
instanceof FieldUnit
){
393 defaultBeanInitializer
.initialize(sob
, FIELDUNIT_INIT_STRATEGY
);