Project

General

Profile

Download (13.6 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.util.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
    @Override
219
    public UUID saveOrUpdate(Registration transientObject) {
220
        transientObject = assureIsPersisted(transientObject);
221
        return super.saveOrUpdate(transientObject);
222
    }
223

    
224
    @Override
225
    public Map<UUID, Registration> save(Collection<? extends Registration> newInstances) {
226
        Map<UUID, Registration> regs = new HashMap<>();
227
        for(Registration newInstance : newInstances) {
228
            Registration reg = save(newInstance);
229
            regs.put(reg.getUuid(), reg);
230
        }
231
        return regs;
232
    }
233

    
234
    @Override
235
    public Map<UUID, Registration> saveOrUpdate(Collection<Registration> transientInstances) {
236
        Map<UUID, Registration> regs = new HashMap<>();
237
        for(Registration transientInstance : transientInstances) {
238
            UUID uuid = saveOrUpdate(transientInstance);
239
            regs.put(uuid, transientInstance);
240
        }
241
        return regs;
242
    }
243

    
244
    // ============= functionality to be moved into a "RegistrationManagerBean" => RegistrationServiceImpl ? ==================
245

    
246

    
247
    /**
248
     * Factory Method
249
     * TODO move into RegistrationFactory
250
     *
251
     * @return a new Registration instance with submitter set to the current authentications principal
252
     */
253
    @Override
254
    public Registration newRegistration() {
255

    
256
        Registration reg = Registration.NewInstance(
257
                null,
258
                null,
259
                null,
260
                null);
261
        Authentication authentication = userHelper.getAuthentication();
262
        reg.setSubmitter((User)authentication.getPrincipal());
263
        return reg;
264
    }
265

    
266
    @Override
267
    @Transactional(readOnly=false)
268
    public Registration createRegistrationForName(UUID taxonNameUuid) {
269

    
270
        Registration reg = Registration.NewInstance(
271
                null,
272
                null,
273
                taxonNameUuid != null ? nameService.load(taxonNameUuid, Arrays.asList("nomenclaturalSource.citation.inReference")) : null,
274
                        null);
275

    
276
        reg = assureIsPersisted(reg);
277

    
278
        return load(reg.getUuid(), Arrays.asList(new String []{"blockedBy"}));
279
    }
280

    
281
    @Override
282
    @Transactional(readOnly=false)
283
    public Registration assureIsPersisted(Registration reg) {
284

    
285
        if(reg.isPersited()){
286
            return reg;
287
        }
288

    
289
        prepareForSave(reg);
290
        reg = super.save(reg);
291
        userHelper.createAuthorityForCurrentUser(reg, Operation.UPDATE, RegistrationStatus.PREPARATION.name());
292

    
293
        return reg;
294
    }
295

    
296
    @Override
297
    @Transactional(readOnly=false)
298
    public void addTypeDesignation(UUID registrationUUID, UUID typeDesignationUuid){
299

    
300
        // load the typeDesignations with the registration so that typified names can not be twice in detached sessions
301
        // otherwise multiple representation problems might occur
302
        Registration registration = load(registrationUUID, Arrays.asList("typeDesignations"));
303
        if(registration == null){
304
            registration = newRegistration();
305
            registration = assureIsPersisted(registration);
306
        }
307
        TypeDesignationBase<?> nameTypeDesignation = nameService.loadTypeDesignation(typeDesignationUuid, Arrays.asList(""));
308
        registration.getTypeDesignations().add(nameTypeDesignation);
309
    }
310

    
311
    @Override
312
    @Transactional(readOnly=false)
313
    public void addTypeDesignation(Registration registration, UUID typeDesignationUuid){
314

    
315
        if(registration == null){
316
            registration = newRegistration();
317
            registration = assureIsPersisted(registration);
318
        } else {
319
            if(registration.isPersited()){
320
                // make sure the the typeDesignations are loaded with the registration so that typified names can not be twice in detached sessions
321
                // otherwise multiple representation problems might occur
322
                registration.getTypeDesignations();
323
            }
324
        }
325
        TypeDesignationBase<?> nameTypeDesignation = nameService.loadTypeDesignation(typeDesignationUuid, Arrays.asList(""));
326
        registration.getTypeDesignations().add(nameTypeDesignation);
327
    }
328

    
329
    /**
330
     * Sets the registration identifier and submitter in case the registration is not yet persisted.
331
     *
332
     * @param reg
333
     *   The Registration to prepare for saving.
334
     */
335
    private void prepareForSave(Registration reg) {
336

    
337
        if(!reg.isPersited()){
338
            if(minter != null){
339
                Identifier<String> identifiers = minter.mint();
340
                if(identifiers.getIdentifier() == null){
341
                    throw new RuntimeException("RegistrationIdentifierMinter configuration incomplete.");
342
                }
343
                reg.setIdentifier(identifiers.getIdentifier());
344
                reg.setSpecificIdentifier(identifiers.getLocalId());
345
            }
346
            Authentication authentication = userHelper.getAuthentication();
347
            reg.setSubmitter((User)authentication.getPrincipal());
348
        }
349
    }
350

    
351
    /**
352
     * @param name
353
     */
354
    @Override
355
    public boolean checkRegistrationExistsFor(TaxonName name) {
356

    
357
        for(Registration reg : name.getRegistrations()){
358
            if(minter != null){
359
                if(minter.isFromOwnRegistration(reg.getIdentifier())){
360
                    return true;
361
                }
362
            } else {
363
                return true; // first registrations wins as we can't distinguish them without a minter.
364
            }
365
        }
366
        return false;
367
    }
368

    
369

    
370

    
371
    // =============================================================================================
372

    
373

    
374
}
(79-79/95)