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

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

    
19
import org.hibernate.Session;
20
import org.jboss.logging.Logger;
21
import org.springframework.beans.factory.annotation.Autowired;
22
import org.springframework.beans.factory.annotation.Qualifier;
23
import org.springframework.stereotype.Service;
24
import org.springframework.transaction.annotation.Transactional;
25

    
26
import eu.etaxonomy.cdm.api.application.CdmRepository;
27
import eu.etaxonomy.cdm.api.service.DeleteResult;
28
import eu.etaxonomy.cdm.api.service.config.SpecimenDeleteConfigurator;
29
import eu.etaxonomy.cdm.api.service.dto.RegistrationDTO;
30
import eu.etaxonomy.cdm.api.service.name.TypeDesignationWorkingSet;
31
import eu.etaxonomy.cdm.api.service.registration.IRegistrationWorkingSetService;
32
import eu.etaxonomy.cdm.api.service.registration.RegistrationWorkingSetService;
33
import eu.etaxonomy.cdm.compare.name.TypeDesignationComparator;
34
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
35
import eu.etaxonomy.cdm.model.common.VersionableEntity;
36
import eu.etaxonomy.cdm.model.name.Registration;
37
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
38
import eu.etaxonomy.cdm.model.name.TaxonName;
39
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
40
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
41
import eu.etaxonomy.cdm.model.occurrence.DerivationEventType;
42
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
43
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
44
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
45
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
46
import eu.etaxonomy.cdm.ref.TypedEntityReference;
47
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationDTO;
48
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationWorkingSetDTO;
49

    
50
/**
51
 * @author a.kohlbecker
52
 * @since Nov 13, 2017
53
 *
54
 */
55
@Service("specimenTypeDesignationWorkingSetService")
56
@Transactional(readOnly=true)
57
public class SpecimenTypeDesignationWorkingSetServiceImpl implements ISpecimenTypeDesignationWorkingSetService {
58

    
59
    private final Logger logger = Logger.getLogger(SpecimenTypeDesignationWorkingSetServiceImpl.class);
60

    
61
    static SpecimenDeleteConfigurator specimenDeleteConfigurer = new SpecimenDeleteConfigurator();
62
    static {
63
        specimenDeleteConfigurer.setDeleteChildren(true);
64
        specimenDeleteConfigurer.setDeleteFromDescription(true);
65
        specimenDeleteConfigurer.setDeleteFromIndividualsAssociation(true);
66
        specimenDeleteConfigurer.setDeleteFromTypeDesignation(true);
67
        specimenDeleteConfigurer.setDeleteMolecularData(true);
68
    }
69

    
70
    public static final List<String> TAXON_NAME_INIT_STRATEGY = Arrays.asList(new String []{
71
            "$",
72
            "nomenclaturalSource.citation.authorship.$",
73
            "nomenclaturalSource.citation.inReference.authorship.$",
74
            "nomenclaturalSource.citation.inReference.inReference.authorship.$",
75
            "status.type",
76
            "typeDesignations"
77
            }
78
    );
79

    
80
    @Autowired
81
    IRegistrationWorkingSetService registrationWorkingSetService;
82

    
83
    @Qualifier("cdmRepository")
84
    @Autowired
85
    CdmRepository repo;
86

    
87
    @Override
88
    public SpecimenTypeDesignationWorkingSetDTO<Registration> create(UUID registrationUuid, UUID typifiedNameUuid) {
89
        FieldUnit newfieldUnit = FieldUnit.NewInstance();
90
        Registration reg = repo.getRegistrationService().load(registrationUuid, RegistrationWorkingSetService.REGISTRATION_DTO_INIT_STRATEGY.getPropertyPaths());
91
        if(reg == null){
92
            reg = repo.getRegistrationService().newRegistration();
93
            reg.setUuid(registrationUuid);
94
        }
95
        TaxonName typifiedName = repo.getNameService().load(typifiedNameUuid, TAXON_NAME_INIT_STRATEGY);
96
        SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto = new SpecimenTypeDesignationWorkingSetDTO<>(reg, newfieldUnit, typifiedName);
97
        return workingSetDto;
98
    }
99

    
100
    @Override
101
    @Transactional(readOnly=true)
102
    public SpecimenTypeDesignationWorkingSetDTO<Registration> load(UUID registrationUuid, TypedEntityReference<? extends IdentifiableEntity<?>> baseEntityRef) {
103

    
104
        RegistrationDTO regDTO = registrationWorkingSetService.loadDtoByUuid(registrationUuid);
105
        // find the working set
106
        TypeDesignationWorkingSet typeDesignationWorkingSet = regDTO.getTypeDesignationWorkingSet(baseEntityRef);
107
        SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto = specimenTypeDesignationWorkingSetDTO(regDTO, typeDesignationWorkingSet.getBaseEntityReference());
108
        return workingSetDto;
109
    }
110

    
111
    protected SpecimenTypeDesignationWorkingSetDTO<Registration> specimenTypeDesignationWorkingSetDTO(
112
            RegistrationDTO regDTO, TypedEntityReference baseEntityReference) {
113

    
114
        Set<TypeDesignationBase> typeDesignations = regDTO.getTypeDesignationsInWorkingSet(baseEntityReference);
115
        List<SpecimenTypeDesignation> specimenTypeDesignations = new ArrayList<>(typeDesignations.size());
116
        typeDesignations.forEach(td -> specimenTypeDesignations.add((SpecimenTypeDesignation)td));
117
        specimenTypeDesignations.sort(new TypeDesignationComparator());
118
        VersionableEntity baseEntity = regDTO.getTypeDesignationWorkingSet(baseEntityReference).getBaseEntity();
119

    
120
        SpecimenTypeDesignationWorkingSetDTO<Registration> dto = new SpecimenTypeDesignationWorkingSetDTO<Registration>(regDTO.registration(),
121
                baseEntity, specimenTypeDesignations, regDTO.typifiedName());
122
        return dto;
123
    }
124

    
125
    @Override
126
    public SpecimenTypeDesignationWorkingSetDTO<Registration> fixMissingFieldUnit(SpecimenTypeDesignationWorkingSetDTO<Registration> bean) {
127

    
128
        if(bean.getFieldUnit() == null){
129
            // in case the base unit of the working set is not a FieldUnit all contained TypeDesignations must be modified
130
            // so that they are based on an empty FieldUnit with an associated Gathering Event
131

    
132
            Registration reg = repo.getRegistrationService().find(bean.getOwner().getUuid());
133
            RegistrationDTO regDTO = new RegistrationDTO(reg);
134

    
135
            FieldUnit fieldUnit = FieldUnit.NewInstance();
136
            GatheringEvent gatheringEvent = GatheringEvent.NewInstance();
137
            fieldUnit.setGatheringEvent(gatheringEvent);
138
            fieldUnit = repo.getOccurrenceService().save(fieldUnit);
139

    
140
            VersionableEntity baseEntity = bean.getBaseEntity();
141
            Set<TypeDesignationBase> typeDesignations = regDTO.getTypeDesignationsInWorkingSet(
142
                    new TypedEntityReference(baseEntity.getClass(), baseEntity.getUuid(), baseEntity.toString())
143
                    );
144
            for(TypeDesignationBase td : typeDesignations){
145
                DerivationEvent de = DerivationEvent.NewInstance();//
146
                de.addOriginal(fieldUnit);
147
                de.addDerivative(((SpecimenTypeDesignation)td).getTypeSpecimen());
148
                de.setType(DerivationEventType.GATHERING_IN_SITU());
149
            }
150

    
151
            repo.getRegistrationService().saveOrUpdate(reg);
152
        }
153
        return bean;
154
    }
155

    
156
    @Override
157
    @Transactional(readOnly=false)
158
    public void save(SpecimenTypeDesignationWorkingSetDTO<? extends VersionableEntity> dto) {
159

    
160
        if(dto.getOwner() instanceof Registration){
161
            Registration regPremerge = (Registration) dto.getOwner();
162

    
163
            regPremerge = repo.getRegistrationService().assureIsPersisted(regPremerge);
164

    
165
            // find the newly created type designations
166
            Set<SpecimenTypeDesignation> newTypeDesignations = findNewTypeDesignations((SpecimenTypeDesignationWorkingSetDTO<Registration>) dto);
167

    
168
            FieldUnit fieldUnit = (FieldUnit) dto.getBaseEntity();
169

    
170
            // associate the new typeDesignations with the registration
171
            for(SpecimenTypeDesignation std : newTypeDesignations){
172
                assureFieldUnit(fieldUnit, std);
173
                // here the TypeDesignation.typifiedName is also set internally
174
                dto.getTypifiedName().addTypeDesignation(std, false);
175
                regPremerge.addTypeDesignation(std);
176
            }
177

    
178
            for(SpecimenTypeDesignationDTO stdDTO : dto.getSpecimenTypeDesignationDTOs()){
179
                SpecimenTypeDesignation specimenTypeDesignation = stdDTO.asSpecimenTypeDesignation();
180
                // associate all type designations with the fieldUnit
181
                assureFieldUnit(fieldUnit, specimenTypeDesignation);
182
            }
183

    
184
            Session session = repo.getSession();
185

    
186
            session.merge(regPremerge);
187
            session.flush();
188

    
189
            // ------------------------ perform delete of removed SpecimenTypeDesignations
190
            // this step also includes the deletion of DerivedUnits which have been converted by
191
            // the DerivedUnitConverter in turn of a kindOfUnit change
192
            for(SpecimenTypeDesignation std : dto.deletedSpecimenTypeDesignations()){
193
                deleteSpecimenTypeDesignation(dto, std);
194
            }
195
        }
196

    
197

    
198
    }
199

    
200
    /**
201
     * @param dto
202
     * @param specimenDeleteConfigurer
203
     * @param std
204
     */
205
    protected void deleteSpecimenTypeDesignation(SpecimenTypeDesignationWorkingSetDTO<? extends VersionableEntity> dto, SpecimenTypeDesignation std) {
206

    
207
//        if(dto.getOwner() instanceof Registration){
208
//            Registration registration = (Registration) dto.getOwner();
209
//            registration.getTypeDesignations().clear();
210
//            repo.getRegistrationService().save(registration);
211
//        } else {
212
//            throw new RuntimeException("Unimplemented owner type");
213
//        }
214
        DerivedUnit du = std.getTypeSpecimen();
215
//        DerivationEvent derivationEvent = du.getDerivedFrom();
216

    
217
        //du.removeSpecimenTypeDesignation(std);
218
        //derivationEvent.removeDerivative(du);
219
        std.setTypeSpecimen(null);
220
        repo.getOccurrenceService().delete(du, specimenDeleteConfigurer);
221
        repo.getNameService().deleteTypeDesignation(dto.getTypifiedName(), std);
222
//        if(derivationEvent.getDerivatives().size() == 0){
223
//          getRepo().getEventBaseService().delete(derivationEvent);
224
//      }
225
    }
226

    
227
    /**
228
     * @param session
229
     * @param fieldUnit
230
     * @param specimenTypeDesignation
231
     */
232
    protected void assureFieldUnit(FieldUnit fieldUnit,
233
            SpecimenTypeDesignation specimenTypeDesignation) {
234
        try {
235
            SpecimenOrObservationBase<?> original = findEarliestOriginal(specimenTypeDesignation.getTypeSpecimen());
236
            if(original instanceof DerivedUnit){
237
                DerivedUnit du = (DerivedUnit)original;
238
                du.getDerivedFrom().addOriginal(fieldUnit);
239
            }
240
        } catch (Exception e) {
241
            // has more than one originals !!!
242
            logger.error(e);
243
        }
244
    }
245

    
246
    /**
247
     * @param std
248
     * @return
249
     * @throws Exception
250
     */
251
    private SpecimenOrObservationBase<?> findEarliestOriginal(DerivedUnit du) throws Exception {
252

    
253
        SpecimenOrObservationBase original = du;
254

    
255
        while(du != null && du.getDerivedFrom() != null && !du.getDerivedFrom().getOriginals().isEmpty()) {
256
            Iterator<SpecimenOrObservationBase> it = du.getDerivedFrom().getOriginals().iterator();
257
            SpecimenOrObservationBase nextOriginal = it.next();
258
            if(nextOriginal == null){
259
                break;
260
            }
261
            original = nextOriginal;
262
            if(original instanceof DerivedUnit){
263
                du = (DerivedUnit)original;
264
            } else {
265
                // so this must be a FieldUnit,
266
               break;
267
            }
268
            if(it.hasNext()){
269
                throw new Exception(String.format("%s has more than one originals", du.toString()));
270
            }
271
        }
272
        return original;
273
    }
274

    
275
    private Set<SpecimenTypeDesignation> findNewTypeDesignations(SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto) {
276

    
277
        Registration reg = workingSetDto.getOwner();
278
        Set<SpecimenTypeDesignation> addCandidates = new HashSet<>();
279
        for(SpecimenTypeDesignationDTO stdDTO : workingSetDto.getSpecimenTypeDesignationDTOs()){
280
            SpecimenTypeDesignation std = stdDTO.asSpecimenTypeDesignation();
281
            if(reg.getTypeDesignations().isEmpty() || !reg.getTypeDesignations().stream().filter(td -> td.equals(std)).findFirst().isPresent()){
282
                addCandidates.add(std);
283
            }
284
        }
285
        return addCandidates;
286
    }
287

    
288
    /**
289
     * {@inheritDoc}
290
     */
291
    @Override
292
    @Transactional(readOnly=false)
293
    public void delete(SpecimenTypeDesignationWorkingSetDTO bean, boolean deleteFieldUnit) {
294

    
295
        @SuppressWarnings("unchecked")
296
        List<SpecimenTypeDesignationDTO> specimenTypeDesignationDTOs = bean.getSpecimenTypeDesignationDTOs();
297
        for(SpecimenTypeDesignationDTO stdDTO : specimenTypeDesignationDTOs){
298
          SpecimenTypeDesignation std =  stdDTO.asSpecimenTypeDesignation();
299
          deleteSpecimenTypeDesignation(bean, std);
300
          if(bean.getOwner() instanceof Registration){
301
              ((Registration)bean.getOwner()).getTypeDesignations().remove(std);
302
          }
303
        }
304

    
305
        if(deleteFieldUnit){
306
            FieldUnit fu = bean.getFieldUnit();
307
            // delete the fieldunit and all derivatives
308
            DeleteResult result = repo.getOccurrenceService().delete(fu.getUuid(), specimenDeleteConfigurer);
309
            String msg = result.toString();
310
        }
311
    }
312

    
313
}
(11-11/14)