Project

General

Profile

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

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

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

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

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

    
76
    @Autowired
77
    IRegistrationWorkingSetService registrationWorkingSetService;
78

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

    
83

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
170
            Session session = repo.getSession();
171

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

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

    
179
            // ------------------------ perform delete of removed SpecimenTypeDesignations
180
            for(SpecimenTypeDesignation std : dto.deletedSpecimenTypeDesignations()){
181
                deleteSpecimenTypeDesignation(dto, std);
182
            }
183
            session.flush();
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)