Project

General

Profile

Download (12.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.service;
10

    
11
import java.util.ArrayList;
12
import java.util.Arrays;
13
import java.util.Collection;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Optional;
17
import java.util.Set;
18
import java.util.UUID;
19

    
20
import org.apache.log4j.Logger;
21
import org.hibernate.Hibernate;
22
import org.springframework.beans.factory.annotation.Autowired;
23
import org.springframework.beans.factory.annotation.Qualifier;
24
import org.springframework.stereotype.Service;
25
import org.springframework.transaction.annotation.Transactional;
26

    
27
import eu.etaxonomy.cdm.api.application.CdmRepository;
28
import eu.etaxonomy.cdm.api.service.dto.RegistrationDTO;
29
import eu.etaxonomy.cdm.api.service.exception.RegistrationValidationException;
30
import eu.etaxonomy.cdm.api.service.pager.Pager;
31
import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
32
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
33
import eu.etaxonomy.cdm.model.common.User;
34
import eu.etaxonomy.cdm.model.name.Registration;
35
import eu.etaxonomy.cdm.model.name.RegistrationStatus;
36
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
37
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
38
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
39
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
40
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
41
import eu.etaxonomy.cdm.model.reference.Reference;
42
import eu.etaxonomy.cdm.model.reference.ReferenceType;
43
import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer;
44
import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet;
45

    
46
/**
47
 * Provides RegistrationDTOs and RegistrationWorkingsets for Registrations in the database.
48
 *
49
 *
50
 * @author a.kohlbecker
51
 * @since Mar 10, 2017
52
 *
53
 */
54
@Service("registrationWorkingSetService")
55
@Transactional(readOnly=true)
56
public class RegistrationWorkingSetService implements IRegistrationWorkingSetService {
57

    
58
    public static final List<String> REGISTRATION_INIT_STRATEGY = Arrays.asList(new String []{
59
            "blockedBy",
60
            // typeDesignation
61
            "typeDesignations.typeStatus",
62
            "typeDesignations.typifiedNames.typeDesignations", // important !!
63
            "typeDesignations.typeSpecimen",
64
            "typeDesignations.typeName.$",
65
            "typeDesignations.citation",
66
            "typeDesignations.citation.authorship.$",
67
            "typeDesignations.annotations", // needed for AnnotatableEntity.clone() in DerivedUnitConverter.copyPropertiesTo
68
            "typeDesignations.markers", // needed for AnnotatableEntity.clone() in DerivedUnitConverter.copyPropertiesTo
69
            "typeDesignations.registrations", // DerivedUnitConverter.copyPropertiesTo(TARGET n)
70

    
71
            // name
72
            "name.$",
73
            "name.nomenclaturalReference.authorship.$",
74
            "name.nomenclaturalReference.inReference",
75
            "name.rank",
76
            "name.homotypicalGroup.typifiedNames",
77
            "name.status.type",
78
            "name.typeDesignations", // important !!"
79
            // institution
80
            "institution",
81
            }
82
    );
83

    
84
   /**
85
    *
86
    */
87
   private  List<String> DERIVEDUNIT_INIT_STRATEGY = Arrays.asList(new String[]{
88
           "*", // initialize all related entities to allow DerivedUnit conversion, see DerivedUnitConverter.copyPropertiesTo()
89
           "derivedFrom.$",
90
           "derivedFrom.type", // TODO remove?
91
           "derivedFrom.originals.derivationEvents", // important!!
92
           "specimenTypeDesignations.typifiedNames.typeDesignations", // important!!
93
           "mediaSpecimen.sources"
94
   });
95

    
96
   /**
97
   *
98
   */
99
  private List<String> FIELDUNIT_INIT_STRATEGY = Arrays.asList(new String[]{
100
          "$",
101
          "annotations.*", // * is needed as log as we are using a table in FilterableAnnotationsField
102
          "gatheringEvent.$",
103
          "gatheringEvent.country",
104
          "gatheringEvent.collectingAreas",
105
          "gatheringEvent.actor",
106
          "derivationEvents.derivatives" // important, otherwise the DerivedUnits are not included into the graph of initialized entities!!!
107
  });
108

    
109
  public static final List<String> BLOCKING_REGISTRATION_INIT_STRATEGY = Arrays.asList(new String []{
110

    
111
          "blockedBy.blockedBy",
112
          // typeDesignation
113
          "blockedBy.typeDesignations.typeStatus",
114
//          "typeDesignations.typifiedNames.typeDesignations", // important !!
115
//          "typeDesignations.typeSpecimen",
116
//          "typeDesignations.typeName.$",
117
//          "typeDesignations.citation",
118
//          "typeDesignations.citation.authorship.$",
119
          // name
120
//          "blockedBy.name.$",
121
          "blockedBy.name.nomenclaturalReference.authorship",
122
          "blockedBy.name.nomenclaturalReference.inReference",
123
          "blockedBy.name.rank",
124
//          "name.homotypicalGroup.typifiedNames",
125
//          "name.status.type",
126
//          "name.typeDesignations",
127
          // institution
128
          "blockedBy.institution",
129
          }
130
  );
131

    
132
    /**
133
     *
134
     */
135
    private static final int PAGE_SIZE = 50;
136

    
137
    private static final Logger logger = Logger.getLogger(RegistrationWorkingSetService.class);
138

    
139
    @Autowired
140
    @Qualifier("cdmRepository")
141
    private CdmRepository repo;
142

    
143
    @Autowired
144
    protected IBeanInitializer defaultBeanInitializer;
145

    
146
    public RegistrationWorkingSetService() {
147

    
148
    }
149

    
150

    
151
    /**
152
     * @param id the Registration entity id
153
     * @return
154
     */
155
    @Override
156
    public RegistrationDTO loadDtoById(Integer id) {
157
        Registration reg = repo.getRegistrationService().load(id, REGISTRATION_INIT_STRATEGY);
158
        inititializeSpecimen(reg);
159
        return new RegistrationDTO(reg);
160
    }
161

    
162

    
163
    /**
164
     * @param id the Registration entity id
165
     * @return
166
     */
167
    @Override
168
    public RegistrationDTO loadDtoByUuid(UUID uuid) {
169
        Registration reg = repo.getRegistrationService().load(uuid, REGISTRATION_INIT_STRATEGY);
170
        inititializeSpecimen(reg);
171
        return new RegistrationDTO(reg);
172
    }
173

    
174

    
175
    @Override
176
    public Pager<RegistrationDTO> pageDTOs(Integer pageSize, Integer pageIndex) {
177

    
178
        return pageDTOs(null, null, null, null, pageSize, pageIndex);
179
    }
180

    
181
    /**
182
     * {@inheritDoc}
183
     */
184
    @Override
185
    public Pager<RegistrationDTO> pageDTOs(User submitter, Collection<RegistrationStatus> includedStatus,
186
            String identifierFilterPattern, String taxonNameFilterPattern,
187
            Integer pageSize, Integer pageIndex) {
188

    
189
        if(pageSize == null){
190
            pageSize = PAGE_SIZE;
191
        }
192

    
193
        Pager<Registration> pager = repo.getRegistrationService().page(submitter, includedStatus,
194
                identifierFilterPattern, taxonNameFilterPattern,
195
                PAGE_SIZE, 0, null, REGISTRATION_INIT_STRATEGY);
196
        List<Registration> registrations = pager.getRecords();
197
        Pager<RegistrationDTO> dtoPager = new DefaultPagerImpl(pager.getCurrentIndex(), pager.getCount(), pager.getPageSize(), makeDTOs(registrations));
198
        return dtoPager;
199
    }
200

    
201

    
202
    /**
203
     * {@inheritDoc}
204
     * @throws RegistrationValidationException
205
     */
206
    @Override
207
    public RegistrationWorkingSet loadWorkingSetByReferenceUuid(UUID referenceUuid, boolean resolveSections) throws RegistrationValidationException {
208

    
209
        Reference reference = repo.getReferenceService().find(referenceUuid); // needed to use load to avoid the problem described in #7331
210
        if(resolveSections){
211
            reference = resolveSection(reference);
212
        }
213

    
214
        Pager<Registration> pager = repo.getRegistrationService().page(Optional.of(reference), null, null, null, REGISTRATION_INIT_STRATEGY);
215

    
216
        /* for debugging https://dev.e-taxonomy.eu/redmine/issues/7331 */
217
        // debugIssue7331(pager);
218
        return new RegistrationWorkingSet(makeDTOs(pager.getRecords()));
219
    }
220

    
221

    
222
    /**
223
     * @param reference
224
     * @return
225
     */
226
    protected Reference resolveSection(Reference reference) {
227
        repo.getReferenceService().load(reference.getUuid(), Arrays.asList(new String[]{"inReference"})); // needed to avoid the problem described in #7331
228
        if(reference.isOfType(ReferenceType.Section) && reference.getInReference() != null) {
229
            reference = reference.getInReference();
230
        }
231
        return reference;
232
    }
233

    
234
    /**
235
     * {@inheritDoc}
236
     * @throws RegistrationValidationException
237
     */
238
    @Override
239
    public RegistrationWorkingSet loadWorkingSetByReferenceID(Integer referenceID, boolean resolveSections) throws RegistrationValidationException {
240

    
241
        Reference reference = repo.getReferenceService().find(referenceID);
242
        if(resolveSections){
243
            reference = resolveSection(reference);
244
        }
245
        repo.getReferenceService().load(reference.getUuid()); // needed to avoid the problem described in #7331
246

    
247
        Pager<Registration> pager = repo.getRegistrationService().page(Optional.of(reference), null, null, null, REGISTRATION_INIT_STRATEGY);
248

    
249
        /* for debugging https://dev.e-taxonomy.eu/redmine/issues/7331 */
250
        // debugIssue7331(pager);
251

    
252
        return new RegistrationWorkingSet(makeDTOs(pager.getRecords()));
253
    }
254

    
255

    
256
    /**
257
     * @param pager
258
     */
259
    @SuppressWarnings("unused")
260
    private void debugIssue7331(Pager<Registration> pager) {
261
        for(Registration reg : pager.getRecords()){
262
            if(reg.getName() != null && reg.getName().getNomenclaturalReference().getAuthorship() != null){
263
                Reference ref = reg.getName().getNomenclaturalReference();
264
                if(!Hibernate.isInitialized(ref.getAuthorship())){
265
                    logger.error("UNINITIALIZED");
266
                }
267
            } else {
268
                logger.debug("NO AUTHORS");
269
            }
270
        }
271
    }
272

    
273
    @Override
274
    public Set<RegistrationDTO> loadBlockingRegistrations(UUID blockedRegistrationUuid){
275

    
276
        Registration registration = repo.getRegistrationService().load(blockedRegistrationUuid, BLOCKING_REGISTRATION_INIT_STRATEGY);
277
        Set<Registration> registrations = registration.getBlockedBy();
278

    
279
        Set<RegistrationDTO> blockingSet = new HashSet<>();
280
        for(Registration reg : registrations){
281
            blockingSet.add(new RegistrationDTO(reg));
282
        }
283
        return blockingSet;
284
    }
285

    
286
    /**
287
     * @param regs
288
     * @return
289
     */
290
    private List<RegistrationDTO> makeDTOs(List<Registration> regs) {
291
        initializeSpecimens(regs);
292
        List<RegistrationDTO> dtos = new ArrayList<>(regs.size());
293
        regs.forEach(reg -> {dtos.add(new RegistrationDTO(reg));});
294
        return dtos;
295
    }
296

    
297

    
298

    
299
    /**
300
     * @param regs
301
     */
302
    private void initializeSpecimens(List<Registration> regs) {
303
        for(Registration reg : regs){
304
            inititializeSpecimen(reg);
305
        }
306

    
307
    }
308

    
309

    
310
    /**
311
     * @param reg
312
     */
313
    protected void inititializeSpecimen(Registration reg) {
314

    
315
        for(TypeDesignationBase<?> td : reg.getTypeDesignations()){
316
            if(td instanceof SpecimenTypeDesignation){
317

    
318
                DerivedUnit derivedUnit = ((SpecimenTypeDesignation) td).getTypeSpecimen();
319
                @SuppressWarnings("rawtypes")
320
                Set<SpecimenOrObservationBase> sobs = new HashSet<>();
321
                sobs.add(HibernateProxyHelper.deproxy(derivedUnit));
322

    
323
                while(sobs != null && !sobs.isEmpty()){
324
                    @SuppressWarnings("rawtypes")
325
                    Set<SpecimenOrObservationBase> nextSobs = null;
326
                    for(@SuppressWarnings("rawtypes") SpecimenOrObservationBase sob : sobs){
327
                        sob = HibernateProxyHelper.deproxy(sob);
328
                        if(sob == null){
329
                            continue;
330
                        }
331
                        if(DerivedUnit.class.isAssignableFrom(sob.getClass())) {
332
                            defaultBeanInitializer.initialize(sob, DERIVEDUNIT_INIT_STRATEGY);
333
                            nextSobs = ((DerivedUnit)sob).getOriginals();
334
                        }
335
                        if(sob instanceof FieldUnit){
336
                            defaultBeanInitializer.initialize(sob, FIELDUNIT_INIT_STRATEGY);
337
                        }
338
                    }
339
                    sobs = nextSobs;
340
                }
341
            }
342
        }
343
    }
344

    
345

    
346

    
347

    
348

    
349

    
350
}
(7-7/9)