Project

General

Profile

Download (12.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.Arrays;
12
import java.util.HashSet;
13
import java.util.Iterator;
14
import java.util.List;
15
import java.util.Set;
16

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

    
24
import eu.etaxonomy.cdm.api.application.CdmRepository;
25
import eu.etaxonomy.cdm.api.service.DeleteResult;
26
import eu.etaxonomy.cdm.api.service.config.SpecimenDeleteConfigurator;
27
import eu.etaxonomy.cdm.model.common.VersionableEntity;
28
import eu.etaxonomy.cdm.model.name.Registration;
29
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
30
import eu.etaxonomy.cdm.model.name.TaxonName;
31
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
32
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
33
import eu.etaxonomy.cdm.model.occurrence.DerivationEventType;
34
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
35
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
36
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
37
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
38
import eu.etaxonomy.cdm.model.reference.Reference;
39
import eu.etaxonomy.cdm.vaadin.model.TypedEntityReference;
40
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationDTO;
41
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationWorkingSetDTO;
42
import eu.etaxonomy.cdm.vaadin.util.converter.TypeDesignationSetManager.TypeDesignationWorkingSet;
43
import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationDTO;
44

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

    
54
    private final Logger logger = Logger.getLogger(SpecimenTypeDesignationWorkingSetServiceImpl.class);
55

    
56
    static SpecimenDeleteConfigurator specimenDeleteConfigurer = new SpecimenDeleteConfigurator();
57
    static {
58
        specimenDeleteConfigurer.setDeleteChildren(true);
59
        specimenDeleteConfigurer.setDeleteFromDescription(true);
60
        specimenDeleteConfigurer.setDeleteFromIndividualsAssociation(true);
61
        specimenDeleteConfigurer.setDeleteFromTypeDesignation(true);
62
        specimenDeleteConfigurer.setDeleteMolecularData(true);
63
    }
64

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

    
75
    @Autowired
76
    IRegistrationWorkingSetService registrationWorkingSetService;
77

    
78
    @Qualifier("cdmRepository")
79
    @Autowired
80
    CdmRepository repo;
81

    
82

    
83
    /**
84
     * {@inheritDoc}
85
     */
86
    @Override
87
    public SpecimenTypeDesignationWorkingSetDTO<Registration> create(int registrationId, int publicationId, int typifiedNameId) {
88
        FieldUnit newfieldUnit = FieldUnit.NewInstance();
89
        Registration reg = repo.getRegistrationService().load(registrationId, RegistrationWorkingSetService.REGISTRATION_INIT_STRATEGY);
90
        TaxonName typifiedName = repo.getNameService().load(typifiedNameId, TAXON_NAME_INIT_STRATEGY);
91
        Reference citation = repo.getReferenceService().load(publicationId, Arrays.asList("$"));
92
        SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto = new SpecimenTypeDesignationWorkingSetDTO<Registration>(reg, newfieldUnit, citation, typifiedName);
93
        return workingSetDto;
94
    }
95

    
96
    /**
97
     * {@inheritDoc}
98
     */
99
    @Override
100
    @Transactional
101
    public SpecimenTypeDesignationWorkingSetDTO<Registration> loadDtoByIds(int registrationId, int workingsetId) {
102
        RegistrationDTO regDTO = registrationWorkingSetService.loadDtoById(registrationId);
103
        // find the working set
104
        TypeDesignationWorkingSet typeDesignationWorkingSet = regDTO.getTypeDesignationWorkingSet(workingsetId);
105
        SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto = regDTO.getSpecimenTypeDesignationWorkingSetDTO(typeDesignationWorkingSet.getBaseEntityReference());
106
        return workingSetDto;
107
    }
108

    
109
    @Override
110
    public SpecimenTypeDesignationWorkingSetDTO<Registration> fixMissingFieldUnit(SpecimenTypeDesignationWorkingSetDTO<Registration> bean) {
111

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

    
116
            Registration reg = repo.getRegistrationService().find(bean.getOwner().getId());
117
            RegistrationDTO regDTO = new RegistrationDTO(reg);
118

    
119
            FieldUnit fieldUnit = FieldUnit.NewInstance();
120
            GatheringEvent gatheringEvent = GatheringEvent.NewInstance();
121
            fieldUnit.setGatheringEvent(gatheringEvent);
122
            repo.getOccurrenceService().save(fieldUnit);
123

    
124
            VersionableEntity baseEntity = bean.getBaseEntity();
125
            Set<TypeDesignationBase> typeDesignations = regDTO.getTypeDesignationsInWorkingSet(
126
                    new TypedEntityReference(baseEntity.getClass(), baseEntity.getId(), baseEntity.toString())
127
                    );
128
            for(TypeDesignationBase td : typeDesignations){
129
                DerivationEvent de = DerivationEvent.NewInstance();//
130
                de.addOriginal(fieldUnit);
131
                de.addDerivative(((SpecimenTypeDesignation)td).getTypeSpecimen());
132
                de.setType(DerivationEventType.GATHERING_IN_SITU());
133
            }
134

    
135
            repo.getRegistrationService().saveOrUpdate(reg);
136
        }
137
        return bean;
138
    }
139

    
140
    /**
141
     * {@inheritDoc}
142
     */
143
    @Override
144
    @Transactional(readOnly=false)
145
    public void save(SpecimenTypeDesignationWorkingSetDTO<? extends VersionableEntity> dto) {
146

    
147
        if(dto.getOwner() instanceof Registration){
148
            Registration regPremerge = (Registration) dto.getOwner();
149

    
150
            // find the newly created type designations
151
            Set<SpecimenTypeDesignation> newTypeDesignations = findNewTypeDesignations((SpecimenTypeDesignationWorkingSetDTO<Registration>) dto);
152

    
153
            FieldUnit fieldUnit = (FieldUnit) dto.getBaseEntity();
154

    
155
            // associate the new typeDesignations with the registration
156
            for(SpecimenTypeDesignation std : newTypeDesignations){
157
                assureFieldUnit(fieldUnit, std);
158
                std.setCitation(dto.getCitation());
159
                dto.getTypifiedName().addTypeDesignation(std, false);
160
                regPremerge.addTypeDesignation(std);
161
            }
162

    
163
            for(SpecimenTypeDesignationDTO stdDTO : dto.getSpecimenTypeDesignationDTOs()){
164
                SpecimenTypeDesignation specimenTypeDesignation = stdDTO.asSpecimenTypeDesignation();
165
                // associate all type designations with the fieldUnit
166
                assureFieldUnit(fieldUnit, specimenTypeDesignation);
167
            }
168

    
169
            Session session = repo.getSession();
170

    
171
//            PersistentContextAnalyzer regAnalyzer = new PersistentContextAnalyzer(dto.getOwner(), session);
172
//            regAnalyzer.printEntityGraph(System.out);
173
//            regAnalyzer.printCopyEntities(System.out);
174

    
175
            session.merge(dto.getOwner());
176
            session.flush();
177

    
178
            // ------------------------ perform delete of removed SpecimenTypeDesignations
179
            for(SpecimenTypeDesignation std : dto.deletedSpecimenTypeDesignations()){
180
                deleteSpecimenTypeDesignation(dto, std);
181
            }
182
            session.flush();
183
        }
184

    
185

    
186
    }
187

    
188
    /**
189
     * @param dto
190
     * @param specimenDeleteConfigurer
191
     * @param std
192
     */
193
    protected void deleteSpecimenTypeDesignation(SpecimenTypeDesignationWorkingSetDTO<? extends VersionableEntity> dto, SpecimenTypeDesignation std) {
194

    
195
//        if(dto.getOwner() instanceof Registration){
196
//            Registration registration = (Registration) dto.getOwner();
197
//            registration.getTypeDesignations().clear();
198
//            repo.getRegistrationService().save(registration);
199
//        } else {
200
//            throw new RuntimeException("Unimplemented owner type");
201
//        }
202
        DerivedUnit du = std.getTypeSpecimen();
203
//        DerivationEvent derivationEvent = du.getDerivedFrom();
204

    
205
        //du.removeSpecimenTypeDesignation(std);
206
        //derivationEvent.removeDerivative(du);
207
        std.setTypeSpecimen(null);
208
        repo.getOccurrenceService().delete(du, specimenDeleteConfigurer);
209
        repo.getNameService().deleteTypeDesignation(dto.getTypifiedName(), std);
210
//        if(derivationEvent.getDerivatives().size() == 0){
211
//          getRepo().getEventBaseService().delete(derivationEvent);
212
//      }
213
    }
214

    
215
    /**
216
     * @param session
217
     * @param fieldUnit
218
     * @param specimenTypeDesignation
219
     */
220
    protected void assureFieldUnit(FieldUnit fieldUnit,
221
            SpecimenTypeDesignation specimenTypeDesignation) {
222
        try {
223
            SpecimenOrObservationBase<?> original = findEarliestOriginal(specimenTypeDesignation.getTypeSpecimen());
224
            if(original instanceof DerivedUnit){
225
                DerivedUnit du = (DerivedUnit)original;
226
                du.getDerivedFrom().addOriginal(fieldUnit);
227
            }
228
        } catch (Exception e) {
229
            // has more than one originals !!!
230
            logger.error(e);
231
        }
232
    }
233

    
234
    /**
235
     * @param std
236
     * @return
237
     * @throws Exception
238
     */
239
    private SpecimenOrObservationBase<?> findEarliestOriginal(DerivedUnit du) throws Exception {
240

    
241
        SpecimenOrObservationBase original = du;
242

    
243
        while(du != null && du.getDerivedFrom() != null && !du.getDerivedFrom().getOriginals().isEmpty()) {
244
            Iterator<SpecimenOrObservationBase> it = du.getDerivedFrom().getOriginals().iterator();
245
            SpecimenOrObservationBase nextOriginal = it.next();
246
            if(nextOriginal == null){
247
                break;
248
            }
249
            original = nextOriginal;
250
            if(original instanceof DerivedUnit){
251
                du = (DerivedUnit)original;
252
            } else {
253
                // so this must be a FieldUnit,
254
               break;
255
            }
256
            if(it.hasNext()){
257
                throw new Exception(String.format("%s has more than one originals", du.toString()));
258
            }
259
        }
260
        return original;
261
    }
262

    
263
    private Set<SpecimenTypeDesignation> findNewTypeDesignations(SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto) {
264

    
265
        Registration reg = workingSetDto.getOwner();
266
        Set<SpecimenTypeDesignation> addCandidates = new HashSet<>();
267
        for(SpecimenTypeDesignationDTO stdDTO : workingSetDto.getSpecimenTypeDesignationDTOs()){
268
            SpecimenTypeDesignation std = stdDTO.asSpecimenTypeDesignation();
269
            if(reg.getTypeDesignations().isEmpty() || !reg.getTypeDesignations().stream().filter(td -> td.equals(std)).findFirst().isPresent()){
270
                addCandidates.add(std);
271
            }
272
        }
273
        return addCandidates;
274
    }
275

    
276
    /**
277
     * {@inheritDoc}
278
     */
279
    @Override
280
    @Transactional(readOnly=false)
281
    public void delete(SpecimenTypeDesignationWorkingSetDTO bean, boolean deleteFieldUnit) {
282

    
283
        @SuppressWarnings("unchecked")
284
        List<SpecimenTypeDesignationDTO> specimenTypeDesignationDTOs = bean.getSpecimenTypeDesignationDTOs();
285
        for(SpecimenTypeDesignationDTO stdDTO : specimenTypeDesignationDTOs){
286
          SpecimenTypeDesignation std =  stdDTO.asSpecimenTypeDesignation();
287
          deleteSpecimenTypeDesignation(bean, std);
288
          if(bean.getOwner() instanceof Registration){
289
              ((Registration)bean.getOwner()).getTypeDesignations().remove(std);
290
          }
291
        }
292

    
293
        if(deleteFieldUnit){
294
            FieldUnit fu = bean.getFieldUnit();
295
            // delete the fieldunit and all derivatives
296
            DeleteResult result = repo.getOccurrenceService().delete(fu.getUuid(), specimenDeleteConfigurer);
297
            String msg = result.toString();
298
        }
299
    }
300

    
301
}
(7-7/7)