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
;
11 import java
.io
.IOException
;
12 import java
.util
.ArrayList
;
13 import java
.util
.Arrays
;
14 import java
.util
.Collection
;
15 import java
.util
.List
;
16 import java
.util
.Optional
;
18 import java
.util
.UUID
;
20 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
21 import org
.springframework
.security
.core
.Authentication
;
22 import org
.springframework
.stereotype
.Service
;
23 import org
.springframework
.transaction
.annotation
.Transactional
;
25 import eu
.etaxonomy
.cdm
.api
.service
.idminter
.IdentifierMinter
.Identifier
;
26 import eu
.etaxonomy
.cdm
.api
.service
.idminter
.RegistrationIdentifierMinter
;
27 import eu
.etaxonomy
.cdm
.api
.service
.pager
.Pager
;
28 import eu
.etaxonomy
.cdm
.api
.service
.pager
.impl
.AbstractPagerImpl
;
29 import eu
.etaxonomy
.cdm
.api
.service
.pager
.impl
.DefaultPagerImpl
;
30 import eu
.etaxonomy
.cdm
.api
.utility
.UserHelper
;
31 import eu
.etaxonomy
.cdm
.model
.common
.User
;
32 import eu
.etaxonomy
.cdm
.model
.name
.Registration
;
33 import eu
.etaxonomy
.cdm
.model
.name
.RegistrationStatus
;
34 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
35 import eu
.etaxonomy
.cdm
.model
.name
.TypeDesignationBase
;
36 import eu
.etaxonomy
.cdm
.model
.name
.TypeDesignationStatusBase
;
37 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
38 import eu
.etaxonomy
.cdm
.persistence
.dao
.common
.Restriction
;
39 import eu
.etaxonomy
.cdm
.persistence
.dao
.name
.IRegistrationDao
;
40 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.Operation
;
41 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
42 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
45 * @author a.kohlbecker
50 @Transactional(readOnly
= true)
51 public class RegistrationServiceImpl
extends AnnotatableServiceBase
<Registration
, IRegistrationDao
> implements IRegistrationService
{
58 protected void setDao(IRegistrationDao dao
) {
62 @Autowired(required
=false)
63 private RegistrationIdentifierMinter minter
;
66 private UserHelper userHelper
;
70 private INameService nameService
;
77 @Transactional(readOnly
= true)
78 public Pager
<Registration
> page(Optional
<Reference
> reference
, Collection
<RegistrationStatus
> includedStatus
,
79 Integer pageSize
, Integer pageIndex
, List
<String
> propertyPaths
) {
81 long numberOfResults
= dao
.count(reference
, includedStatus
);
83 List
<Registration
> results
= new ArrayList
<>();
84 Integer
[] limitStart
= AbstractPagerImpl
.limitStartforRange(numberOfResults
, pageIndex
, pageSize
);
85 if(limitStart
!= null) {
86 results
= dao
.list(reference
, includedStatus
, limitStart
[0], limitStart
[1], propertyPaths
);
89 return new DefaultPagerImpl
<>(pageIndex
, numberOfResults
, pageSize
, results
);
96 @Transactional(readOnly
= true)
97 public Pager
<Registration
> page(User submitter
, Collection
<RegistrationStatus
> includedStatus
,
98 String identifierFilterPattern
, String taxonNameFilterPattern
, Set
<TypeDesignationStatusBase
> typeDesignationStatus
,
99 Integer pageSize
, Integer pageIndex
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
101 List
<Restriction
<?
extends Object
>> restrictions
= new ArrayList
<>();
103 if( !userHelper
.userIsAutheticated() || userHelper
.userIsAnnonymous() ) {
104 includedStatus
= Arrays
.asList(RegistrationStatus
.PUBLISHED
);
107 if(submitter
!= null){
108 restrictions
.add(new Restriction
<>("submitter", MatchMode
.EXACT
, submitter
));
110 if(includedStatus
!= null && !includedStatus
.isEmpty()){
111 restrictions
.add(new Restriction
<>("status", MatchMode
.EXACT
, includedStatus
.toArray(new RegistrationStatus
[includedStatus
.size()])));
113 if(identifierFilterPattern
!= null){
114 restrictions
.add(new Restriction
<>("identifier", MatchMode
.LIKE
, identifierFilterPattern
));
116 if(taxonNameFilterPattern
!= null){
117 restrictions
.add(new Restriction
<>("name.titleCache", MatchMode
.LIKE
, taxonNameFilterPattern
));
119 if(typeDesignationStatus
!= null){
120 restrictions
.add(new Restriction
<>("typeDesignations.typeStatus", null, typeDesignationStatus
.toArray(new TypeDesignationStatusBase
[typeDesignationStatus
.size()])));
123 long numberOfResults
= dao
.count(Registration
.class, restrictions
);
125 List
<Registration
> results
= new ArrayList
<>();
126 Integer
[] limitStart
= AbstractPagerImpl
.limitStartforRange(numberOfResults
, pageIndex
, pageSize
);
127 if(limitStart
!= null) {
128 results
= dao
.list(Registration
.class, restrictions
, limitStart
[0], limitStart
[1], orderHints
, propertyPaths
);
131 return new DefaultPagerImpl
<>(pageIndex
, numberOfResults
, pageSize
, results
);
135 @Transactional(readOnly
= true)
136 public Pager
<Registration
> page(UUID submitterUuid
, Collection
<RegistrationStatus
> includedStatus
,
137 String identifierFilterPattern
, String taxonNameFilterPattern
, Collection
<UUID
> typeDesignationStatusUuids
,
138 Integer pageSize
, Integer pageIndex
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
140 List
<Restriction
<?
extends Object
>> restrictions
= new ArrayList
<>();
142 if( !userHelper
.userIsAutheticated() || userHelper
.userIsAnnonymous() ) {
143 includedStatus
= Arrays
.asList(RegistrationStatus
.PUBLISHED
);
146 if(submitterUuid
!= null){
147 restrictions
.add(new Restriction
<>("submitter.uuid", null, submitterUuid
));
149 if(includedStatus
!= null && !includedStatus
.isEmpty()){
150 restrictions
.add(new Restriction
<>("status", null, includedStatus
.toArray(new RegistrationStatus
[includedStatus
.size()])));
152 if(identifierFilterPattern
!= null){
153 restrictions
.add(new Restriction
<>("identifier", MatchMode
.LIKE
, identifierFilterPattern
));
155 if(taxonNameFilterPattern
!= null){
156 restrictions
.add(new Restriction
<>("name.titleCache", MatchMode
.LIKE
, taxonNameFilterPattern
));
158 if(typeDesignationStatusUuids
!= null){
159 restrictions
.add(new Restriction
<>("typeDesignations.typeStatus.uuid", null, typeDesignationStatusUuids
.toArray(new UUID
[typeDesignationStatusUuids
.size()])));
162 long numberOfResults
= dao
.count(Registration
.class, restrictions
);
164 List
<Registration
> results
= new ArrayList
<>();
165 if(pageIndex
== null){
168 Integer
[] limitStart
= AbstractPagerImpl
.limitStartforRange(numberOfResults
, pageIndex
, pageSize
);
169 if(limitStart
!= null) {
170 results
= dao
.list(Registration
.class, restrictions
, limitStart
[0], limitStart
[1], orderHints
, propertyPaths
);
173 return new DefaultPagerImpl
<>(pageIndex
, numberOfResults
, pageSize
, results
);
178 * @param validateUniqueness
181 * @throws IOException
184 @Transactional(readOnly
= true)
185 public Pager
<Registration
> pageByIdentifier(String identifier
, Integer pageIndex
, Integer pageSize
, List
<String
> propertyPaths
) throws IOException
{
187 List
<Restriction
<?
>> restrictions
= new ArrayList
<>();
188 if( !userHelper
.userIsAutheticated() || userHelper
.userIsAnnonymous() ) {
189 restrictions
.add(new Restriction
<>("status", null, RegistrationStatus
.PUBLISHED
));
192 Pager
<Registration
> regPager
= pageByRestrictions(Registration
.class, "identifier", identifier
, MatchMode
.EXACT
,
193 restrictions
, pageSize
, pageIndex
, null, propertyPaths
);
199 // ============= functionality to be moved into a "RegistrationManagerBean" ==================
204 * TODO move into RegistrationFactory
206 * @return a new Registration instance with submitter set to the current authentications principal
209 public Registration
newRegistration() {
211 Registration reg
= Registration
.NewInstance(
216 Authentication authentication
= userHelper
.getAuthentication();
217 reg
.setSubmitter((User
)authentication
.getPrincipal());
226 @Transactional(readOnly
=false)
227 public Registration
createRegistrationForName(UUID taxonNameUuid
) {
229 Registration reg
= Registration
.NewInstance(
232 taxonNameUuid
!= null ? nameService
.load(taxonNameUuid
, Arrays
.asList("nomenclaturalReference.inReference")) : null,
235 reg
= assureIsPersisted(reg
);
237 return load(reg
.getUuid(), Arrays
.asList(new String
[]{"blockedBy"}));
241 * @param typeDesignationTarget
244 @Transactional(readOnly
=false)
245 public Registration
assureIsPersisted(Registration reg
) {
247 if(reg
.isPersited()){
253 userHelper
.createAuthorityForCurrentUser(Registration
.class, reg
.getUuid(), Operation
.UPDATE
, RegistrationStatus
.PREPARATION
.name());
259 @Transactional(readOnly
=false)
260 public void addTypeDesignation(UUID registrationUUID
, UUID typeDesignationUuid
){
262 // load the typeDesignations with the registration so that typified names can not be twice in detached sessions
263 // otherwise multiple representation problems might occur
264 Registration registration
= load(registrationUUID
, Arrays
.asList("typeDesignations"));
265 if(registration
== null){
266 registration
= newRegistration();
267 registration
= assureIsPersisted(registration
);
269 TypeDesignationBase
<?
> nameTypeDesignation
= nameService
.loadTypeDesignation(typeDesignationUuid
, Arrays
.asList(""));
270 registration
.getTypeDesignations().add(nameTypeDesignation
);
274 * Sets the registration identifier and submitter in case the registration is not yet persisted.
277 * The Registration to prepare for saving.
279 private void prepareForSave(Registration reg
) {
281 if(!reg
.isPersited()){
283 Identifier
<String
> identifiers
= minter
.mint();
284 if(identifiers
.getIdentifier() == null){
285 throw new RuntimeException("RegistrationIdentifierMinter configuration incomplete.");
287 reg
.setIdentifier(identifiers
.getIdentifier());
288 reg
.setSpecificIdentifier(identifiers
.getLocalId());
290 Authentication authentication
= userHelper
.getAuthentication();
291 reg
.setSubmitter((User
)authentication
.getPrincipal());
299 public boolean checkRegistrationExistsFor(TaxonName name
) {
301 for(Registration reg
: name
.getRegistrations()){
303 if(minter
.isFromOwnRegistration(reg
.getIdentifier())){
307 return true; // first registrations wins as we can't distinguish them without a minter.
313 // =============================================================================================