Project

General

Profile

Download (13.7 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.name.Registration;
36
import eu.etaxonomy.cdm.model.name.RegistrationStatus;
37
import eu.etaxonomy.cdm.model.name.TaxonName;
38
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
39
import eu.etaxonomy.cdm.model.permission.Operation;
40
import eu.etaxonomy.cdm.model.permission.User;
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.query.MatchMode;
45
import eu.etaxonomy.cdm.persistence.query.OrderHint;
46

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

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

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

    
69
    @Autowired
70
    private UserHelper userHelper;
71

    
72
    @Autowired
73
    private INameService nameService;
74

    
75
    @Autowired
76
    private ITaxonGraphService taxonGraphService;
77

    
78

    
79

    
80

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

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

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

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

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

    
104

    
105

    
106
    @Override
107
    @Transactional(readOnly = true)
108
    public Pager<Registration> page(UUID submitterUuid, Collection<RegistrationStatus> includedStatus,
109
            String identifierFilterPattern, String taxonNameFilterPattern, String referenceFilterPattern,
110
            Collection<UUID> typeDesignationStatusUuids, Integer pageSize, Integer pageIndex, List<OrderHint> orderHints, List<String> propertyPaths) {
111

    
112
        if( !userHelper.userIsAutheticated() || userHelper.userIsAnnonymous() ) {
113
            includedStatus = Arrays.asList(RegistrationStatus.PUBLISHED);
114
        }
115

    
116
        //Logger.getLogger("org.hibernate.SQL").setLevel(Level.DEBUG);
117
        long numberOfResults = dao.count(submitterUuid, includedStatus, identifierFilterPattern, taxonNameFilterPattern, referenceFilterPattern, typeDesignationStatusUuids);
118
        //Logger.getLogger("org.hibernate.SQL").setLevel(Level.WARN);
119

    
120
        List<Registration> results = new ArrayList<>();
121
        if(pageIndex == null){
122
            pageIndex = 0;
123
        }
124
        Integer [] limitStart = AbstractPagerImpl.limitStartforRange(numberOfResults, pageIndex, pageSize);
125
        if(limitStart != null) {
126
            results = dao.list(submitterUuid, includedStatus, identifierFilterPattern, taxonNameFilterPattern, referenceFilterPattern, typeDesignationStatusUuids,
127
                    limitStart[0], limitStart[1], orderHints, propertyPaths);
128
        }
129

    
130
        return new DefaultPagerImpl<>(pageIndex, numberOfResults, pageSize, results);
131
    }
132

    
133
    @Override
134
    @Transactional(readOnly = true)
135
    public Pager<Registration> pageTaxomicInclusion(UUID submitterUuid, Collection<RegistrationStatus> includedStatus,
136
            String taxonNameFilterPattern, MatchMode matchMode,
137
            Integer pageSize, Integer pageIndex, List<OrderHint> orderHints, List<String> propertyPaths) {
138

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

    
142
        if(includedNames.size() > 0){
143
            return page(submitterUuid, includedStatus, includedNamesUuids, pageSize, pageIndex, orderHints, propertyPaths);
144
        } else {
145
            return new DefaultPagerImpl<>(pageIndex, 0l, pageSize, new ArrayList<Registration>());
146
        }
147
    }
148

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

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

    
159
        long numberOfResults = dao.count(submitterUuid, includedStatus, taxonNameUUIDs);
160

    
161
        List<Registration> results = new ArrayList<>();
162
        if(pageIndex == null){
163
            pageIndex = 0;
164
        }
165
        Integer [] limitStart = AbstractPagerImpl.limitStartforRange(numberOfResults, pageIndex, pageSize);
166
        if(limitStart != null) {
167
            results = dao.list(submitterUuid, includedStatus, taxonNameUUIDs, limitStart[0], limitStart[1], orderHints, propertyPaths);
168
        }
169

    
170
        return new DefaultPagerImpl<>(pageIndex, numberOfResults, pageSize, results);
171
    }
172

    
173
    /**
174
     * @param identifier
175
     * @param validateUniqueness
176
     * @param response
177
     * @return
178
     * @throws IOException
179
     */
180
    @Override
181
    @Transactional(readOnly = true)
182
    public Pager<Registration> pageByIdentifier(String identifier, Integer pageIndex,  Integer pageSize, List<String> propertyPaths) throws IOException {
183

    
184
        List<Restriction<?>> restrictions = new ArrayList<>();
185
        if( !userHelper.userIsAutheticated() || userHelper.userIsAnnonymous() ) {
186
            restrictions.add(new Restriction<>("status", null, RegistrationStatus.PUBLISHED));
187
        }
188

    
189
        Pager<Registration> regPager = pageByParamWithRestrictions(Registration.class, "identifier", identifier, MatchMode.EXACT,
190
                restrictions, pageSize, pageIndex, null, propertyPaths);
191

    
192
        return regPager;
193
    }
194

    
195
    @Override
196
    @Transactional(readOnly = true)
197
    public Map<UUID, RegistrationStatus> statusByIdentifier(String identifier) throws IOException {
198

    
199
        Pager<Registration> regPager = pageByParamWithRestrictions(Registration.class, "identifier", identifier, MatchMode.EXACT,
200
                null, null, null, null, Arrays.asList("status"));
201

    
202
        Map<UUID, RegistrationStatus> map = new HashMap<>();
203
        for(Registration reg : regPager.getRecords()){
204
            map.put(reg.getUuid(), reg.getStatus());
205
        }
206

    
207
        return map;
208
    }
209

    
210
    /**
211
     * {@inheritDoc}
212
     */
213
    @Override
214
    public Registration save(Registration newInstance) {
215
        return assureIsPersisted(newInstance);
216
    }
217

    
218
    /**
219
     * {@inheritDoc}
220
     */
221
    @Override
222
    public UUID saveOrUpdate(Registration transientObject) {
223
        transientObject = assureIsPersisted(transientObject);
224
        return super.saveOrUpdate(transientObject);
225
    }
226

    
227

    
228
    /**
229
     * {@inheritDoc}
230
     */
231
    @Override
232
    public Map<UUID, Registration> save(Collection<Registration> newInstances) {
233
        Map<UUID, Registration> regs = new HashMap<>();
234
        for(Registration newInstance : newInstances) {
235
            Registration reg = save(newInstance);
236
            regs.put(reg.getUuid(), reg);
237
        }
238
        return regs;
239
    }
240

    
241
    /**
242
     * {@inheritDoc}
243
     */
244
    @Override
245
    public Map<UUID, Registration> saveOrUpdate(Collection<Registration> transientInstances) {
246
        Map<UUID, Registration> regs = new HashMap<>();
247
        for(Registration transientInstance : transientInstances) {
248
            UUID uuid = saveOrUpdate(transientInstance);
249
            regs.put(uuid, transientInstance);
250
        }
251
        return regs;
252
    }
253

    
254
    // ============= functionality to be moved into a "RegistrationManagerBean" => RegistrationServiceImpl ? ==================
255

    
256

    
257
    /**
258
     * Factory Method
259
     * TODO move into RegistrationFactory
260
     *
261
     * @return a new Registration instance with submitter set to the current authentications principal
262
     */
263
    @Override
264
    public Registration newRegistration() {
265

    
266
        Registration reg = Registration.NewInstance(
267
                null,
268
                null,
269
                null,
270
                null);
271
        Authentication authentication = userHelper.getAuthentication();
272
        reg.setSubmitter((User)authentication.getPrincipal());
273
        return reg;
274
    }
275

    
276
    @Override
277
    @Transactional(readOnly=false)
278
    public Registration createRegistrationForName(UUID taxonNameUuid) {
279

    
280
        Registration reg = Registration.NewInstance(
281
                null,
282
                null,
283
                taxonNameUuid != null ? nameService.load(taxonNameUuid, Arrays.asList("nomenclaturalSource.citation.inReference")) : null,
284
                        null);
285

    
286
        reg = assureIsPersisted(reg);
287

    
288
        return load(reg.getUuid(), Arrays.asList(new String []{"blockedBy"}));
289
    }
290

    
291
    @Override
292
    @Transactional(readOnly=false)
293
    public Registration assureIsPersisted(Registration reg) {
294

    
295
        if(reg.isPersited()){
296
            return reg;
297
        }
298

    
299
        prepareForSave(reg);
300
        reg = super.save(reg);
301
        userHelper.createAuthorityForCurrentUser(reg, Operation.UPDATE, RegistrationStatus.PREPARATION.name());
302

    
303
        return reg;
304
    }
305

    
306
    @Override
307
    @Transactional(readOnly=false)
308
    public void addTypeDesignation(UUID registrationUUID, UUID typeDesignationUuid){
309

    
310
        // load the typeDesignations with the registration so that typified names can not be twice in detached sessions
311
        // otherwise multiple representation problems might occur
312
        Registration registration = load(registrationUUID, Arrays.asList("typeDesignations"));
313
        if(registration == null){
314
            registration = newRegistration();
315
            registration = assureIsPersisted(registration);
316
        }
317
        TypeDesignationBase<?> nameTypeDesignation = nameService.loadTypeDesignation(typeDesignationUuid, Arrays.asList(""));
318
        registration.getTypeDesignations().add(nameTypeDesignation);
319
    }
320

    
321
    @Override
322
    @Transactional(readOnly=false)
323
    public void addTypeDesignation(Registration registration, UUID typeDesignationUuid){
324

    
325
        if(registration == null){
326
            registration = newRegistration();
327
            registration = assureIsPersisted(registration);
328
        } else {
329
            if(registration.isPersited()){
330
                // make sure the the typeDesignations are loaded with the registration so that typified names can not be twice in detached sessions
331
                // otherwise multiple representation problems might occur
332
                registration.getTypeDesignations();
333
            }
334
        }
335
        TypeDesignationBase<?> nameTypeDesignation = nameService.loadTypeDesignation(typeDesignationUuid, Arrays.asList(""));
336
        registration.getTypeDesignations().add(nameTypeDesignation);
337
    }
338

    
339
    /**
340
     * Sets the registration identifier and submitter in case the registration is not yet persisted.
341
     *
342
     * @param reg
343
     *   The Registration to prepare for saving.
344
     */
345
    private void prepareForSave(Registration reg) {
346

    
347
        if(!reg.isPersited()){
348
            if(minter != null){
349
                Identifier<String> identifiers = minter.mint();
350
                if(identifiers.getIdentifier() == null){
351
                    throw new RuntimeException("RegistrationIdentifierMinter configuration incomplete.");
352
                }
353
                reg.setIdentifier(identifiers.getIdentifier());
354
                reg.setSpecificIdentifier(identifiers.getLocalId());
355
            }
356
            Authentication authentication = userHelper.getAuthentication();
357
            reg.setSubmitter((User)authentication.getPrincipal());
358
        }
359
    }
360

    
361
    /**
362
     * @param name
363
     */
364
    @Override
365
    public boolean checkRegistrationExistsFor(TaxonName name) {
366

    
367
        for(Registration reg : name.getRegistrations()){
368
            if(minter != null){
369
                if(minter.isFromOwnRegistration(reg.getIdentifier())){
370
                    return true;
371
                }
372
            } else {
373
                return true; // first registrations wins as we can't distinguish them without a minter.
374
            }
375
        }
376
        return false;
377
    }
378

    
379

    
380

    
381
    // =============================================================================================
382

    
383

    
384
}
(83-83/100)