Project

General

Profile

Download (16.2 KB) Statistics
| Branch: | Tag: | Revision:
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.api.service;
10

    
11
import java.io.IOException;
12
import java.util.ArrayList;
13
import java.util.Arrays;
14
import java.util.Collection;
15
import java.util.HashMap;
16
import java.util.List;
17
import java.util.Map;
18
import java.util.Optional;
19
import java.util.Set;
20
import java.util.UUID;
21
import java.util.stream.Collectors;
22

    
23
import org.springframework.beans.factory.annotation.Autowired;
24
import org.springframework.security.core.Authentication;
25
import org.springframework.stereotype.Service;
26
import org.springframework.transaction.annotation.Transactional;
27

    
28
import eu.etaxonomy.cdm.api.service.idminter.IdentifierMinter.Identifier;
29
import eu.etaxonomy.cdm.api.service.idminter.RegistrationIdentifierMinter;
30
import eu.etaxonomy.cdm.api.service.pager.Pager;
31
import eu.etaxonomy.cdm.api.service.pager.impl.AbstractPagerImpl;
32
import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
33
import eu.etaxonomy.cdm.api.service.taxonGraph.ITaxonGraphService;
34
import eu.etaxonomy.cdm.api.utility.UserHelper;
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.TaxonName;
39
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
40
import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;
41
import eu.etaxonomy.cdm.model.reference.Reference;
42
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
43
import eu.etaxonomy.cdm.persistence.dao.name.IRegistrationDao;
44
import eu.etaxonomy.cdm.persistence.hibernate.permission.Operation;
45
import eu.etaxonomy.cdm.persistence.query.MatchMode;
46
import eu.etaxonomy.cdm.persistence.query.OrderHint;
47

    
48
/**
49
 * @author a.kohlbecker
50
 * @since May 2, 2017
51
 *
52
 */
53
@Service
54
@Transactional(readOnly = true)
55
public class RegistrationServiceImpl extends AnnotatableServiceBase<Registration, IRegistrationDao>
56
    implements IRegistrationService {
57

    
58
    /**
59
     * {@inheritDoc}
60
     */
61
    @Autowired
62
    @Override
63
    protected void setDao(IRegistrationDao dao) {
64
        this.dao = dao;
65
    }
66

    
67
    @Autowired(required=false)
68
    private RegistrationIdentifierMinter minter;
69

    
70
    @Autowired
71
    private UserHelper userHelper;
72

    
73
    @Autowired
74
    private INameService nameService;
75

    
76
    @Autowired
77
    private ITaxonGraphService taxonGraphService;
78

    
79

    
80

    
81

    
82
    /**
83
     * {@inheritDoc}
84
     */
85
    @Override
86
    @Transactional(readOnly = true)
87
    public Pager<Registration> page(Optional<Reference> reference, Collection<RegistrationStatus> includedStatus,
88
            Integer pageSize, Integer pageIndex, List<String> propertyPaths) {
89

    
90
        if( !userHelper.userIsAutheticated() || userHelper.userIsAnnonymous() ) {
91
            includedStatus = Arrays.asList(RegistrationStatus.PUBLISHED);
92
        }
93

    
94
        long numberOfResults = dao.count(reference, includedStatus);
95

    
96
        List<Registration> results = new ArrayList<>();
97
        Integer [] limitStart = AbstractPagerImpl.limitStartforRange(numberOfResults, pageIndex, pageSize);
98
        if(limitStart != null) {
99
            results = dao.list(reference, includedStatus, limitStart[0], limitStart[1], propertyPaths);
100
        }
101

    
102
        return new DefaultPagerImpl<>(pageIndex, numberOfResults, pageSize, results);
103
    }
104

    
105
    /**
106
     * {@inheritDoc}
107
     */
108
    @Override
109
    @Transactional(readOnly = true)
110
    public Pager<Registration> page(User submitter, Collection<RegistrationStatus> includedStatus,
111
            String identifierFilterPattern, String taxonNameFilterPattern, Set<TypeDesignationStatusBase> typeDesignationStatus,
112
            Integer pageSize, Integer pageIndex, List<OrderHint> orderHints, List<String> propertyPaths) {
113

    
114
        List<Restriction<? extends Object>> restrictions = new ArrayList<>();
115

    
116
        if( !userHelper.userIsAutheticated() || userHelper.userIsAnnonymous() ) {
117
            includedStatus = Arrays.asList(RegistrationStatus.PUBLISHED);
118
        }
119

    
120
        if(submitter != null){
121
            restrictions.add(new Restriction<>("submitter", MatchMode.EXACT, submitter));
122
        }
123
        if(includedStatus != null && !includedStatus.isEmpty()){
124
            restrictions.add(new Restriction<>("status", MatchMode.EXACT, includedStatus.toArray(new RegistrationStatus[includedStatus.size()])));
125
        }
126
        if(identifierFilterPattern != null){
127
            restrictions.add(new Restriction<>("identifier", MatchMode.LIKE, identifierFilterPattern));
128
        }
129
        if(taxonNameFilterPattern != null){
130
            restrictions.add(new Restriction<>("name.titleCache", MatchMode.LIKE, taxonNameFilterPattern));
131
        }
132
        if(typeDesignationStatus != null){
133
            restrictions.add(new Restriction<>("typeDesignations.typeStatus", null, typeDesignationStatus.toArray(new TypeDesignationStatusBase[typeDesignationStatus.size()])));
134
        }
135

    
136
        long numberOfResults = dao.count(Registration.class, restrictions);
137

    
138
        List<Registration> results = new ArrayList<>();
139
        Integer [] limitStart = AbstractPagerImpl.limitStartforRange(numberOfResults, pageIndex, pageSize);
140
        if(limitStart != null) {
141
            results = dao.list(Registration.class, restrictions, limitStart[0], limitStart[1], orderHints, propertyPaths);
142
        }
143

    
144
        return new DefaultPagerImpl<>(pageIndex, numberOfResults, pageSize, results);
145
    }
146

    
147
    @Override
148
    @Transactional(readOnly = true)
149
    public Pager<Registration> page(UUID submitterUuid, Collection<RegistrationStatus> includedStatus,
150
            String identifierFilterPattern, String taxonNameFilterPattern, Collection<UUID> typeDesignationStatusUuids,
151
            Integer pageSize, Integer pageIndex, List<OrderHint> orderHints, List<String> propertyPaths) {
152

    
153
        List<Restriction<? extends Object>> restrictions = new ArrayList<>();
154

    
155
        if( !userHelper.userIsAutheticated() || userHelper.userIsAnnonymous() ) {
156
            includedStatus = Arrays.asList(RegistrationStatus.PUBLISHED);
157
        }
158

    
159
        if(submitterUuid != null){
160
            restrictions.add(new Restriction<>("submitter.uuid", null, submitterUuid));
161
        }
162
        if(includedStatus != null && !includedStatus.isEmpty()){
163
            restrictions.add(new Restriction<>("status", null, includedStatus.toArray(new RegistrationStatus[includedStatus.size()])));
164
        }
165
        if(identifierFilterPattern != null){
166
            restrictions.add(new Restriction<>("identifier", MatchMode.LIKE, identifierFilterPattern));
167
        }
168
        if(taxonNameFilterPattern != null){
169
            restrictions.add(new Restriction<>("name.titleCache", MatchMode.LIKE, taxonNameFilterPattern));
170
        }
171
        if(typeDesignationStatusUuids != null){
172
            restrictions.add(new Restriction<>("typeDesignations.typeStatus.uuid", null, typeDesignationStatusUuids.toArray(new UUID[typeDesignationStatusUuids.size()])));
173
        }
174

    
175
        long numberOfResults = dao.count(Registration.class, restrictions);
176

    
177
        List<Registration> results = new ArrayList<>();
178
        if(pageIndex == null){
179
            pageIndex = 0;
180
        }
181
        Integer [] limitStart = AbstractPagerImpl.limitStartforRange(numberOfResults, pageIndex, pageSize);
182
        if(limitStart != null) {
183
            results = dao.list(Registration.class, restrictions, limitStart[0], limitStart[1], orderHints, propertyPaths);
184
        }
185

    
186
        return new DefaultPagerImpl<>(pageIndex, numberOfResults, pageSize, results);
187
    }
188

    
189
    @Override
190
    @Transactional(readOnly = true)
191
    public Pager<Registration> pageTaxomicInclusion(UUID submitterUuid, Collection<RegistrationStatus> includedStatus,
192
            String taxonNameFilterPattern, MatchMode matchMode,
193
            Integer pageSize, Integer pageIndex, List<OrderHint> orderHints, List<String> propertyPaths) {
194

    
195
        List<TaxonName> includedNames = taxonGraphService.listIncludedNames(taxonNameFilterPattern, matchMode);
196
        Set<UUID> includedNamesUuids = includedNames.stream().map(TaxonName::getUuid).collect(Collectors.toSet());
197

    
198
        if(includedNames.size() > 0){
199
            return page(submitterUuid, includedStatus, includedNamesUuids, pageSize, pageIndex, orderHints, propertyPaths);
200
        } else {
201
            return new DefaultPagerImpl<>(pageIndex, 0l, pageSize, new ArrayList<Registration>());
202
        }
203
    }
204

    
205
    @Override
206
    @Transactional(readOnly = true)
207
    public Pager<Registration> page(UUID submitterUuid, Collection<RegistrationStatus> includedStatus,
208
            Collection<UUID> taxonNameUUIDs,
209
            Integer pageSize, Integer pageIndex, List<OrderHint> orderHints, List<String> propertyPaths) {
210

    
211
        List<Restriction<? extends Object>> restrictions = new ArrayList<>();
212

    
213
        if( !userHelper.userIsAutheticated() || userHelper.userIsAnnonymous() ) {
214
            includedStatus = Arrays.asList(RegistrationStatus.PUBLISHED);
215
        }
216

    
217
        if(submitterUuid != null){
218
            restrictions.add(new Restriction<>("submitter.uuid", null, submitterUuid));
219
        }
220
        if(includedStatus != null && !includedStatus.isEmpty()){
221
            restrictions.add(new Restriction<>("status", null, includedStatus.toArray(new RegistrationStatus[includedStatus.size()])));
222
        }
223

    
224
        if(taxonNameUUIDs != null){
225
            restrictions.add(new Restriction<>("name.uuid", null , taxonNameUUIDs.toArray(new UUID[taxonNameUUIDs.size()])));
226
        }
227

    
228
        long numberOfResults = dao.count(Registration.class, restrictions);
229

    
230
        List<Registration> results = new ArrayList<>();
231
        if(pageIndex == null){
232
            pageIndex = 0;
233
        }
234
        Integer [] limitStart = AbstractPagerImpl.limitStartforRange(numberOfResults, pageIndex, pageSize);
235
        if(limitStart != null) {
236
            results = dao.list(Registration.class, restrictions, limitStart[0], limitStart[1], orderHints, propertyPaths);
237
        }
238

    
239
        return new DefaultPagerImpl<>(pageIndex, numberOfResults, pageSize, results);
240
    }
241

    
242
    /**
243
     * @param identifier
244
     * @param validateUniqueness
245
     * @param response
246
     * @return
247
     * @throws IOException
248
     */
249
    @Override
250
    @Transactional(readOnly = true)
251
    public Pager<Registration> pageByIdentifier(String identifier, Integer pageIndex,  Integer pageSize, List<String> propertyPaths) throws IOException {
252

    
253
        List<Restriction<?>> restrictions = new ArrayList<>();
254
        if( !userHelper.userIsAutheticated() || userHelper.userIsAnnonymous() ) {
255
            restrictions.add(new Restriction<>("status", null, RegistrationStatus.PUBLISHED));
256
        }
257

    
258
        Pager<Registration> regPager = pageByRestrictions(Registration.class, "identifier", identifier, MatchMode.EXACT,
259
                restrictions, pageSize, pageIndex, null, propertyPaths);
260

    
261

    
262
        return regPager;
263
    }
264

    
265
    @Override
266
    @Transactional(readOnly = true)
267
    public Map<UUID, RegistrationStatus> statusByIdentifier(String identifier) throws IOException {
268

    
269
        Pager<Registration> regPager = pageByRestrictions(Registration.class, "identifier", identifier, MatchMode.EXACT,
270
                null, null, null, null, Arrays.asList("status"));
271

    
272
        Map<UUID, RegistrationStatus> map = new HashMap<>();
273
        for(Registration reg : regPager.getRecords()){
274
            map.put(reg.getUuid(), reg.getStatus());
275
        }
276

    
277
        return map;
278
    }
279

    
280
    /**
281
     * {@inheritDoc}
282
     */
283
    @Override
284
    public Registration save(Registration newInstance) {
285
        return assureIsPersisted(newInstance);
286
    }
287

    
288
    /**
289
     * {@inheritDoc}
290
     */
291
    @Override
292
    public UUID saveOrUpdate(Registration transientObject) {
293
        transientObject = assureIsPersisted(transientObject);
294
        return super.saveOrUpdate(transientObject);
295
    }
296

    
297

    
298
    /**
299
     * {@inheritDoc}
300
     */
301
    @Override
302
    public Map<UUID, Registration> save(Collection<Registration> newInstances) {
303
        Map<UUID, Registration> regs = new HashMap<>();
304
        for(Registration newInstance : newInstances) {
305
            Registration reg = save(newInstance);
306
            regs.put(reg.getUuid(), reg);
307
        }
308
        return regs;
309
    }
310

    
311
    /**
312
     * {@inheritDoc}
313
     */
314
    @Override
315
    public Map<UUID, Registration> saveOrUpdate(Collection<Registration> transientInstances) {
316
        Map<UUID, Registration> regs = new HashMap<>();
317
        for(Registration transientInstance : transientInstances) {
318
            UUID uuid = saveOrUpdate(transientInstance);
319
            regs.put(uuid, transientInstance);
320
        }
321
        return regs;
322
    }
323

    
324
    // ============= functionality to be moved into a "RegistrationManagerBean" ==================
325

    
326

    
327
    /**
328
     * Factory Method
329
     * TODO move into RegistrationFactory
330
     *
331
     * @return a new Registration instance with submitter set to the current authentications principal
332
     */
333
    @Override
334
    public Registration newRegistration() {
335

    
336
        Registration reg = Registration.NewInstance(
337
                null,
338
                null,
339
                null,
340
                null);
341
        Authentication authentication = userHelper.getAuthentication();
342
        reg.setSubmitter((User)authentication.getPrincipal());
343
        return reg;
344
    }
345

    
346
    /**
347
     * @param taxonNameId
348
     * @return
349
     */
350
    @Override
351
    @Transactional(readOnly=false)
352
    public Registration createRegistrationForName(UUID taxonNameUuid) {
353

    
354
        Registration reg = Registration.NewInstance(
355
                null,
356
                null,
357
                taxonNameUuid != null ? nameService.load(taxonNameUuid, Arrays.asList("nomenclaturalReference.inReference")) : null,
358
                        null);
359

    
360
        reg = assureIsPersisted(reg);
361

    
362
        return load(reg.getUuid(), Arrays.asList(new String []{"blockedBy"}));
363
    }
364

    
365
    /**
366
     * @param typeDesignationTarget
367
     */
368
    @Override
369
    @Transactional(readOnly=false)
370
    public Registration assureIsPersisted(Registration reg) {
371

    
372
        if(reg.isPersited()){
373
            return reg;
374
        }
375

    
376
        prepareForSave(reg);
377
        reg = super.save(reg);
378
        userHelper.createAuthorityForCurrentUser(Registration.class, reg.getUuid(), Operation.UPDATE, RegistrationStatus.PREPARATION.name());
379

    
380
        return reg;
381
    }
382

    
383
    @Override
384
    @Transactional(readOnly=false)
385
    public void addTypeDesignation(UUID registrationUUID, UUID typeDesignationUuid){
386

    
387
        // load the typeDesignations with the registration so that typified names can not be twice in detached sessions
388
        // otherwise multiple representation problems might occur
389
        Registration registration = load(registrationUUID, Arrays.asList("typeDesignations"));
390
        if(registration == null){
391
            registration = newRegistration();
392
            registration = assureIsPersisted(registration);
393
        }
394
        TypeDesignationBase<?> nameTypeDesignation = nameService.loadTypeDesignation(typeDesignationUuid, Arrays.asList(""));
395
        registration.getTypeDesignations().add(nameTypeDesignation);
396
    }
397

    
398
    /**
399
     * Sets the registration identifier and submitter in case the registration is not yet persisted.
400
     *
401
     * @param reg
402
     *   The Registration to prepare for saving.
403
     */
404
    private void prepareForSave(Registration reg) {
405

    
406
        if(!reg.isPersited()){
407
            if(minter != null){
408
                Identifier<String> identifiers = minter.mint();
409
                if(identifiers.getIdentifier() == null){
410
                    throw new RuntimeException("RegistrationIdentifierMinter configuration incomplete.");
411
                }
412
                reg.setIdentifier(identifiers.getIdentifier());
413
                reg.setSpecificIdentifier(identifiers.getLocalId());
414
            }
415
            Authentication authentication = userHelper.getAuthentication();
416
            reg.setSubmitter((User)authentication.getPrincipal());
417
        }
418
    }
419

    
420
    /**
421
     * @param name
422
     */
423
    @Override
424
    public boolean checkRegistrationExistsFor(TaxonName name) {
425

    
426
        for(Registration reg : name.getRegistrations()){
427
            if(minter != null){
428
                if(minter.isFromOwnRegistration(reg.getIdentifier())){
429
                    return true;
430
                }
431
            } else {
432
                return true; // first registrations wins as we can't distinguish them without a minter.
433
            }
434
        }
435
        return false;
436
    }
437

    
438

    
439

    
440
    // =============================================================================================
441

    
442

    
443
}
(90-90/103)