Project

General

Profile

Download (12.8 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.persistence.query.OrderHint;
45
import eu.etaxonomy.cdm.persistence.query.OrderHint.SortOrder;
46
import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet;
47

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

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

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

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

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

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

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

    
134
    /**
135
     *
136
     */
137
    private static final int PAGE_SIZE = 50;
138

    
139
    private static final Logger logger = Logger.getLogger(RegistrationWorkingSetService.class);
140

    
141
    @Autowired
142
    @Qualifier("cdmRepository")
143
    private CdmRepository repo;
144

    
145
    @Autowired
146
    protected IBeanInitializer defaultBeanInitializer;
147

    
148
    public RegistrationWorkingSetService() {
149

    
150
    }
151

    
152

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

    
164

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

    
176

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

    
180
        return pageDTOs(null, null, null, null, pageSize, pageIndex);
181
    }
182

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

    
191
        if(pageSize == null){
192
            pageSize = PAGE_SIZE;
193
        }
194

    
195
        List<OrderHint> orderHints = Arrays.asList(new OrderHint("identifier", SortOrder.ASCENDING));
196

    
197
        Pager<Registration> pager = repo.getRegistrationService().page(submitter, includedStatus, identifierFilterPattern, taxonNameFilterPattern,
198
                PAGE_SIZE, pageIndex, orderHints , REGISTRATION_INIT_STRATEGY);
199
        List<Registration> registrations = pager.getRecords();
200
        Pager<RegistrationDTO> dtoPager = new DefaultPagerImpl(pager.getCurrentIndex(), pager.getCount(), pager.getPageSize(), makeDTOs(registrations));
201
        if(logger.isDebugEnabled()){
202
            logger.debug(String.format("pageDTOs() pageIndex: $1%d, pageSize: $2%d, includedStatus: $3%s, identifierFilterPattern: $4%s, taxonNameFilterPattern: $5%s",
203
                    pageIndex, pageSize, includedStatus, identifierFilterPattern, taxonNameFilterPattern));
204
            logger.debug("pageDTOs() result: " + pager.toString());
205
        }
206
        return dtoPager;
207
    }
208

    
209

    
210
    /**
211
     * {@inheritDoc}
212
     * @throws RegistrationValidationException
213
     */
214
    @Override
215
    public RegistrationWorkingSet loadWorkingSetByReferenceUuid(UUID referenceUuid, boolean resolveSections) throws RegistrationValidationException {
216

    
217
        Reference reference = repo.getReferenceService().find(referenceUuid); // needed to use load to avoid the problem described in #7331
218
        if(resolveSections){
219
            reference = resolveSection(reference);
220
        }
221

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

    
224
        /* for debugging https://dev.e-taxonomy.eu/redmine/issues/7331 */
225
        // debugIssue7331(pager);
226
        return new RegistrationWorkingSet(makeDTOs(pager.getRecords()));
227
    }
228

    
229

    
230
    /**
231
     * @param reference
232
     * @return
233
     */
234
    protected Reference resolveSection(Reference reference) {
235
        repo.getReferenceService().load(reference.getUuid(), Arrays.asList(new String[]{"inReference"})); // needed to avoid the problem described in #7331
236
        if(reference.isOfType(ReferenceType.Section) && reference.getInReference() != null) {
237
            reference = reference.getInReference();
238
        }
239
        return reference;
240
    }
241

    
242
    /**
243
     * {@inheritDoc}
244
     * @throws RegistrationValidationException
245
     */
246
    @Override
247
    public RegistrationWorkingSet loadWorkingSetByReferenceID(Integer referenceID, boolean resolveSections) throws RegistrationValidationException {
248

    
249
        Reference reference = repo.getReferenceService().find(referenceID);
250
        if(resolveSections){
251
            reference = resolveSection(reference);
252
        }
253
        repo.getReferenceService().load(reference.getUuid()); // needed to avoid the problem described in #7331
254

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

    
257
        /* for debugging https://dev.e-taxonomy.eu/redmine/issues/7331 */
258
        // debugIssue7331(pager);
259

    
260
        return new RegistrationWorkingSet(makeDTOs(pager.getRecords()));
261
    }
262

    
263

    
264
    /**
265
     * @param pager
266
     */
267
    @SuppressWarnings("unused")
268
    private void debugIssue7331(Pager<Registration> pager) {
269
        for(Registration reg : pager.getRecords()){
270
            if(reg.getName() != null && reg.getName().getNomenclaturalReference().getAuthorship() != null){
271
                Reference ref = reg.getName().getNomenclaturalReference();
272
                if(!Hibernate.isInitialized(ref.getAuthorship())){
273
                    logger.error("UNINITIALIZED");
274
                }
275
            } else {
276
                logger.debug("NO AUTHORS");
277
            }
278
        }
279
    }
280

    
281
    @Override
282
    public Set<RegistrationDTO> loadBlockingRegistrations(UUID blockedRegistrationUuid){
283

    
284
        Registration registration = repo.getRegistrationService().load(blockedRegistrationUuid, BLOCKING_REGISTRATION_INIT_STRATEGY);
285
        Set<Registration> registrations = registration.getBlockedBy();
286

    
287
        Set<RegistrationDTO> blockingSet = new HashSet<>();
288
        for(Registration reg : registrations){
289
            blockingSet.add(new RegistrationDTO(reg));
290
        }
291
        return blockingSet;
292
    }
293

    
294
    /**
295
     * @param regs
296
     * @return
297
     */
298
    private List<RegistrationDTO> makeDTOs(List<Registration> regs) {
299
        initializeSpecimens(regs);
300
        List<RegistrationDTO> dtos = new ArrayList<>(regs.size());
301
        regs.forEach(reg -> {dtos.add(new RegistrationDTO(reg));});
302
        return dtos;
303
    }
304

    
305

    
306

    
307
    /**
308
     * @param regs
309
     */
310
    private void initializeSpecimens(List<Registration> regs) {
311
        for(Registration reg : regs){
312
            inititializeSpecimen(reg);
313
        }
314

    
315
    }
316

    
317

    
318
    /**
319
     * @param reg
320
     */
321
    protected void inititializeSpecimen(Registration reg) {
322

    
323
        for(TypeDesignationBase<?> td : reg.getTypeDesignations()){
324
            if(td instanceof SpecimenTypeDesignation){
325

    
326
                DerivedUnit derivedUnit = ((SpecimenTypeDesignation) td).getTypeSpecimen();
327
                @SuppressWarnings("rawtypes")
328
                Set<SpecimenOrObservationBase> sobs = new HashSet<>();
329
                sobs.add(HibernateProxyHelper.deproxy(derivedUnit));
330

    
331
                while(sobs != null && !sobs.isEmpty()){
332
                    @SuppressWarnings("rawtypes")
333
                    Set<SpecimenOrObservationBase> nextSobs = null;
334
                    for(@SuppressWarnings("rawtypes") SpecimenOrObservationBase sob : sobs){
335
                        sob = HibernateProxyHelper.deproxy(sob);
336
                        if(sob == null){
337
                            continue;
338
                        }
339
                        if(DerivedUnit.class.isAssignableFrom(sob.getClass())) {
340
                            defaultBeanInitializer.initialize(sob, DERIVEDUNIT_INIT_STRATEGY);
341
                            nextSobs = ((DerivedUnit)sob).getOriginals();
342
                        }
343
                        if(sob instanceof FieldUnit){
344
                            defaultBeanInitializer.initialize(sob, FIELDUNIT_INIT_STRATEGY);
345
                        }
346
                    }
347
                    sobs = nextSobs;
348
                }
349
            }
350
        }
351
    }
352

    
353

    
354

    
355

    
356

    
357

    
358
}
(7-7/9)