Project

General

Profile

Download (13.3 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.dto.TypedEntityReference;
31
import eu.etaxonomy.cdm.api.service.name.TypeDesignationSetManager.TypeDesignationWorkingSet;
32
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
33
import eu.etaxonomy.cdm.model.common.VersionableEntity;
34
import eu.etaxonomy.cdm.model.name.Registration;
35
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
36
import eu.etaxonomy.cdm.model.name.TaxonName;
37
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
38
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
39
import eu.etaxonomy.cdm.model.occurrence.DerivationEventType;
40
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
41
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
42
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
43
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
44
import eu.etaxonomy.cdm.model.reference.Reference;
45
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationDTO;
46
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationWorkingSetDTO;
47

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

    
57
    private final Logger logger = Logger.getLogger(SpecimenTypeDesignationWorkingSetServiceImpl.class);
58

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

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

    
78
    @Autowired
79
    IRegistrationWorkingSetService registrationWorkingSetService;
80

    
81
    @Qualifier("cdmRepository")
82
    @Autowired
83
    CdmRepository repo;
84

    
85

    
86
    /**
87
     * {@inheritDoc}
88
     */
89
    @Override
90
    public SpecimenTypeDesignationWorkingSetDTO<Registration> create(UUID registrationUuid, UUID publicationUuid, UUID typifiedNameUuid) {
91
        FieldUnit newfieldUnit = FieldUnit.NewInstance();
92
        Registration reg = repo.getRegistrationService().load(registrationUuid, RegistrationWorkingSetService.REGISTRATION_INIT_STRATEGY);
93
        TaxonName typifiedName = repo.getNameService().load(typifiedNameUuid, TAXON_NAME_INIT_STRATEGY);
94
        Reference citation = repo.getReferenceService().load(publicationUuid, Arrays.asList("$"));
95
        SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto = new SpecimenTypeDesignationWorkingSetDTO<Registration>(reg, newfieldUnit, citation, typifiedName);
96
        return workingSetDto;
97
    }
98

    
99
    /**
100
     * {@inheritDoc}
101
     */
102
    @Override
103
    @Transactional
104
    public SpecimenTypeDesignationWorkingSetDTO<Registration> load(UUID registrationUuid, TypedEntityReference<? extends IdentifiableEntity<?>> baseEntityRef) {
105
        RegistrationDTO regDTO = registrationWorkingSetService.loadDtoByUuid(registrationUuid);
106
        // find the working set
107
        TypeDesignationWorkingSet typeDesignationWorkingSet = regDTO.getTypeDesignationWorkingSet(baseEntityRef);
108
        SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto = specimenTypeDesignationWorkingSetDTO(regDTO, typeDesignationWorkingSet.getBaseEntityReference());
109
        return workingSetDto;
110
    }
111

    
112
    protected SpecimenTypeDesignationWorkingSetDTO<Registration> specimenTypeDesignationWorkingSetDTO(RegistrationDTO regDTO, TypedEntityReference baseEntityReference) {
113
        Set<TypeDesignationBase> typeDesignations = regDTO.getTypeDesignationsInWorkingSet(baseEntityReference);
114
        List<SpecimenTypeDesignation> specimenTypeDesignations = new ArrayList<>(typeDesignations.size());
115
        typeDesignations.forEach(td -> specimenTypeDesignations.add((SpecimenTypeDesignation)td));
116
        VersionableEntity baseEntity = regDTO.getTypeDesignationWorkingSet(baseEntityReference).getBaseEntity();
117

    
118
        SpecimenTypeDesignationWorkingSetDTO<Registration> dto = new SpecimenTypeDesignationWorkingSetDTO<Registration>(regDTO.registration(),
119
                baseEntity, specimenTypeDesignations, regDTO.getCitation(), regDTO.getTypifiedName());
120
        return dto;
121
    }
122

    
123
    @Override
124
    public SpecimenTypeDesignationWorkingSetDTO<Registration> fixMissingFieldUnit(SpecimenTypeDesignationWorkingSetDTO<Registration> bean) {
125

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

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

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

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

    
149
            repo.getRegistrationService().saveOrUpdate(reg);
150
        }
151
        return bean;
152
    }
153

    
154
    /**
155
     * {@inheritDoc}
156
     */
157
    @Override
158
    @Transactional(readOnly=false)
159
    public void save(SpecimenTypeDesignationWorkingSetDTO<? extends VersionableEntity> dto) {
160

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

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

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

    
169
            // associate the new typeDesignations with the registration
170
            for(SpecimenTypeDesignation std : newTypeDesignations){
171
                assureFieldUnit(fieldUnit, std);
172
                std.setCitation(dto.getCitation());
173
                dto.getTypifiedName().addTypeDesignation(std, false);
174
                regPremerge.addTypeDesignation(std);
175
            }
176

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

    
183
            Session session = repo.getSession();
184

    
185
            session.merge(dto.getOwner());
186
            session.flush();
187

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

    
196

    
197
    }
198

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

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

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

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

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

    
252
        SpecimenOrObservationBase original = du;
253

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

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

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

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

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

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

    
312
}
(7-7/7)