Project

General

Profile

Download (11 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.config.SpecimenDeleteConfigurator;
26
import eu.etaxonomy.cdm.model.common.VersionableEntity;
27
import eu.etaxonomy.cdm.model.name.Registration;
28
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
29
import eu.etaxonomy.cdm.model.name.TaxonName;
30
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
31
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
32
import eu.etaxonomy.cdm.model.occurrence.DerivationEventType;
33
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
34
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
35
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
36
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
37
import eu.etaxonomy.cdm.model.reference.Reference;
38
import eu.etaxonomy.cdm.vaadin.model.TypedEntityReference;
39
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationDTO;
40
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationWorkingSetDTO;
41
import eu.etaxonomy.cdm.vaadin.util.converter.TypeDesignationSetManager.TypeDesignationWorkingSet;
42
import eu.etaxonomy.cdm.vaadin.view.name.stdDTOs;
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
    public static final List<String> TAXON_NAME_INIT_STRATEGY = Arrays.asList(new String []{
57
            "name.$",
58
            "name.nomenclaturalReference.authorship",
59
            "name.nomenclaturalReference.inReference",
60
            "name.rank",
61
            "name.status.type",
62
            "name.typeDesignations"
63
            }
64
    );
65

    
66
    @Autowired
67
    IRegistrationWorkingSetService registrationWorkingSetService;
68

    
69
    @Qualifier("cdmRepository")
70
    @Autowired
71
    CdmRepository repo;
72

    
73

    
74
    /**
75
     * {@inheritDoc}
76
     */
77
    @Override
78
    public SpecimenTypeDesignationWorkingSetDTO<Registration> create(int registrationId, int publicationId, int typifiedNameId) {
79
        FieldUnit newfieldUnit = FieldUnit.NewInstance();
80
        Registration reg = repo.getRegistrationService().load(registrationId, RegistrationWorkingSetService.REGISTRATION_INIT_STRATEGY);
81
        TaxonName typifiedName = repo.getNameService().load(typifiedNameId, TAXON_NAME_INIT_STRATEGY);
82
        Reference citation = repo.getReferenceService().load(publicationId, Arrays.asList("$"));
83
        SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto = new SpecimenTypeDesignationWorkingSetDTO<Registration>(reg, newfieldUnit, citation, typifiedName);
84
        return workingSetDto;
85
    }
86

    
87
    /**
88
     * {@inheritDoc}
89
     */
90
    @Override
91
    @Transactional
92
    public SpecimenTypeDesignationWorkingSetDTO<Registration> loadDtoByIds(int registrationId, int workingsetId) {
93
        RegistrationDTO regDTO = registrationWorkingSetService.loadDtoById(registrationId);
94
        // find the working set
95
        TypeDesignationWorkingSet typeDesignationWorkingSet = regDTO.getTypeDesignationWorkingSet(workingsetId);
96
        SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto = regDTO.getSpecimenTypeDesignationWorkingSetDTO(typeDesignationWorkingSet.getBaseEntityReference());
97
        return workingSetDto;
98
    }
99

    
100
    @Override
101
    public SpecimenTypeDesignationWorkingSetDTO<Registration> fixMissingFieldUnit(SpecimenTypeDesignationWorkingSetDTO<Registration> bean) {
102

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

    
107
            Registration reg = repo.getRegistrationService().find(bean.getOwner().getId());
108
            RegistrationDTO regDTO = new RegistrationDTO(reg);
109

    
110
            FieldUnit fieldUnit = FieldUnit.NewInstance();
111
            GatheringEvent gatheringEvent = GatheringEvent.NewInstance();
112
            fieldUnit.setGatheringEvent(gatheringEvent);
113
            repo.getOccurrenceService().save(fieldUnit);
114

    
115
            VersionableEntity baseEntity = bean.getBaseEntity();
116
            Set<TypeDesignationBase> typeDesignations = regDTO.getTypeDesignationsInWorkingSet(
117
                    new TypedEntityReference(baseEntity.getClass(), baseEntity.getId(), baseEntity.toString())
118
                    );
119
            for(TypeDesignationBase td : typeDesignations){
120
                DerivationEvent de = DerivationEvent.NewInstance();//
121
                de.addOriginal(fieldUnit);
122
                de.addDerivative(((SpecimenTypeDesignation)td).getTypeSpecimen());
123
                de.setType(DerivationEventType.GATHERING_IN_SITU());
124
            }
125

    
126
            repo.getRegistrationService().saveOrUpdate(reg);
127
        }
128
        return bean;
129
    }
130

    
131
    /**
132
     * {@inheritDoc}
133
     */
134
    @Override
135
    @Transactional(readOnly=false)
136
    public void save(SpecimenTypeDesignationWorkingSetDTO<? extends VersionableEntity> dto) {
137

    
138
        if(dto.getOwner() instanceof Registration){
139
            Registration regPremerge = (Registration) dto.getOwner();
140

    
141
            // find the newly created type designations
142
            Set<SpecimenTypeDesignation> newTypeDesignations = findNewTypeDesignations((SpecimenTypeDesignationWorkingSetDTO<Registration>) dto);
143

    
144
            FieldUnit fieldUnit = (FieldUnit) dto.getBaseEntity();
145

    
146
            // associate the new typeDesignations with the registration
147
            for(SpecimenTypeDesignation std : newTypeDesignations){
148
                assureFieldUnit(fieldUnit, std);
149
                std.setCitation(dto.getCitation());
150
                dto.getTypifiedName().addTypeDesignation(std, false);
151
                regPremerge.addTypeDesignation(std);
152
            }
153

    
154
            for(SpecimenTypeDesignationDTO stdDTO : dto.getSpecimenTypeDesignationDTOs()){
155
                SpecimenTypeDesignation specimenTypeDesignation = stdDTO.asSpecimenTypeDesignation();
156
                // associate all type designations with the fieldUnit
157
                assureFieldUnit(fieldUnit, specimenTypeDesignation);
158
            }
159

    
160
            Session session = repo.getSession();
161

    
162
//            PersistentContextAnalyzer regAnalyzer = new PersistentContextAnalyzer(dto.getOwner(), session);
163
//            regAnalyzer.printEntityGraph(System.out);
164
//            regAnalyzer.printCopyEntities(System.out);
165

    
166
            session.merge(dto.getOwner());
167
            session.flush();
168

    
169
            // ------------------------ perform delete of removed SpecimenTypeDesignations
170
            SpecimenDeleteConfigurator specimenDeleteConfigurer = new SpecimenDeleteConfigurator();
171
            specimenDeleteConfigurer.setDeleteChildren(false);
172
            specimenDeleteConfigurer.setDeleteFromDescription(true);
173
            specimenDeleteConfigurer.setDeleteFromIndividualsAssociation(true);
174
            specimenDeleteConfigurer.setDeleteFromTypeDesignation(true);
175
            specimenDeleteConfigurer.setDeleteMolecularData(true);
176

    
177
            for(SpecimenTypeDesignation std : dto.deletedSpecimenTypeDesignations()){
178
                DerivedUnit du = std.getTypeSpecimen();
179
                du.removeSpecimenTypeDesignation(std);
180
                DerivationEvent derivationEvent = du.getDerivedFrom();
181
                derivationEvent.removeDerivative(du);
182
                repo.getNameService().deleteTypeDesignation(dto.getTypifiedName(), std);
183
                repo.getOccurrenceService().delete(du, specimenDeleteConfigurer);
184
//                if(derivationEvent.getDerivatives().size() == 0){
185
//                    getRepo().getEventBaseService().delete(derivationEvent);
186
//                }
187
            }
188
            // -------------------------
189

    
190

    
191
        }
192

    
193

    
194
    }
195

    
196
    /**
197
     * @param session
198
     * @param fieldUnit
199
     * @param specimenTypeDesignation
200
     */
201
    protected void assureFieldUnit(FieldUnit fieldUnit,
202
            SpecimenTypeDesignation specimenTypeDesignation) {
203
        try {
204
            SpecimenOrObservationBase<?> original = findEarliestOriginal(specimenTypeDesignation.getTypeSpecimen());
205
            if(original instanceof DerivedUnit){
206
                DerivedUnit du = (DerivedUnit)original;
207
                du.getDerivedFrom().addOriginal(fieldUnit);
208
            }
209
        } catch (Exception e) {
210
            // has more than one originals !!!
211
            logger.error(e);
212
        }
213
    }
214

    
215
    /**
216
     * @param std
217
     * @return
218
     * @throws Exception
219
     */
220
    private SpecimenOrObservationBase<?> findEarliestOriginal(DerivedUnit du) throws Exception {
221

    
222
        SpecimenOrObservationBase original = du;
223

    
224
        while(du != null && du.getDerivedFrom() != null && !du.getDerivedFrom().getOriginals().isEmpty()) {
225
            Iterator<SpecimenOrObservationBase> it = du.getDerivedFrom().getOriginals().iterator();
226
            SpecimenOrObservationBase nextOriginal = it.next();
227
            if(nextOriginal == null){
228
                break;
229
            }
230
            original = nextOriginal;
231
            if(original instanceof DerivedUnit){
232
                du = (DerivedUnit)original;
233
            } else {
234
                // so this must be a FieldUnit,
235
               break;
236
            }
237
            if(it.hasNext()){
238
                throw new Exception(String.format("%s has more than one originals", du.toString()));
239
            }
240
        }
241
        return original;
242
    }
243

    
244
    private Set<SpecimenTypeDesignation> findNewTypeDesignations(SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto) {
245

    
246
        Registration reg = workingSetDto.getOwner();
247
        Set<SpecimenTypeDesignation> addCandidates = new HashSet<>();
248
        for(SpecimenTypeDesignationDTO stdDTO : workingSetDto.getSpecimenTypeDesignationDTOs()){
249
            SpecimenTypeDesignation std = stdDTO.asSpecimenTypeDesignation();
250
            if(reg.getTypeDesignations().isEmpty() || !reg.getTypeDesignations().stream().filter(td -> td.equals(std)).findFirst().isPresent()){
251
                addCandidates.add(std);
252
            }
253
        }
254
        return addCandidates;
255
    }
256

    
257
    /**
258
     * {@inheritDoc}
259
     */
260
    @Override
261
    public void delete(SpecimenTypeDesignationWorkingSetDTO bean) {
262
        for(stdDTOs : bean.getSpecimenTypeDesignationDTOs()){
263

    
264
                }
265

    
266
    }
267

    
268
}
(7-7/7)