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
    /**
190
     * @param dto
191
     * @param specimenDeleteConfigurer
192
     * @param std
193
     */
194
    protected void deleteSpecimenTypeDesignation(SpecimenTypeDesignationWorkingSetDTO<? extends VersionableEntity> dto, SpecimenTypeDesignation std) {
195

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

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

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

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

    
242
        SpecimenOrObservationBase original = du;
243

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

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

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

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

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

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

    
302
}
(7-7/7)