Project

General

Profile

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

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

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

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

    
50
    private final Logger logger = Logger.getLogger(SpecimenTypeDesignationWorkingSetServiceImpl.class);
51

    
52
    @Autowired
53
    IRegistrationWorkingSetService registrationWorkingSetService;
54

    
55
    @Qualifier("cdmRepository")
56
    @Autowired
57
    CdmRepository repo;
58

    
59

    
60
    /**
61
     * {@inheritDoc}
62
     */
63
    @Override
64
    public SpecimenTypeDesignationWorkingSetDTO<Registration> create(int registrationId, int publicationId, int typifiedNameId) {
65
        FieldUnit newfieldUnit = FieldUnit.NewInstance();
66
        Registration reg = repo.getRegistrationService().load(registrationId, RegistrationWorkingSetService.REGISTRATION_INIT_STRATEGY);
67
        SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto = new SpecimenTypeDesignationWorkingSetDTO<Registration>(reg, newfieldUnit, publicationId, typifiedNameId);
68
        return workingSetDto;
69
    }
70

    
71
    /**
72
     * {@inheritDoc}
73
     */
74
    @Override
75
    @Transactional
76
    public SpecimenTypeDesignationWorkingSetDTO<Registration> loadDtoByIds(int registrationId, int workingsetId) {
77
        RegistrationDTO regDTO = registrationWorkingSetService.loadDtoById(registrationId);
78
        // find the working set
79
        TypeDesignationWorkingSet typeDesignationWorkingSet = regDTO.getTypeDesignationWorkingSet(workingsetId);
80
        SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto = regDTO.getSpecimenTypeDesignationWorkingSetDTO(typeDesignationWorkingSet.getBaseEntityReference());
81
        workingSetDto.setCitationEntityID(regDTO.getCitation().getId());
82
        workingSetDto.setTypifiedNameEntityID(regDTO.getTypifiedName().getId());
83
        return workingSetDto;
84
    }
85

    
86
    @Override
87
    public SpecimenTypeDesignationWorkingSetDTO<Registration> fixMissingFieldUnit(SpecimenTypeDesignationWorkingSetDTO<Registration> bean) {
88

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

    
93
            Registration reg = repo.getRegistrationService().find(bean.getOwner().getId());
94
            RegistrationDTO regDTO = new RegistrationDTO(reg);
95

    
96
            FieldUnit fieldUnit = FieldUnit.NewInstance();
97
            GatheringEvent gatheringEvent = GatheringEvent.NewInstance();
98
            fieldUnit.setGatheringEvent(gatheringEvent);
99
            repo.getOccurrenceService().save(fieldUnit);
100

    
101
            VersionableEntity baseEntity = bean.getBaseEntity();
102
            Set<TypeDesignationBase> typeDesignations = regDTO.getTypeDesignationsInWorkingSet(
103
                    new TypedEntityReference(baseEntity.getClass(), baseEntity.getId(), baseEntity.toString())
104
                    );
105
            for(TypeDesignationBase td : typeDesignations){
106
                DerivationEvent de = DerivationEvent.NewInstance();//
107
                de.addOriginal(fieldUnit);
108
                de.addDerivative(((SpecimenTypeDesignation)td).getTypeSpecimen());
109
                de.setType(DerivationEventType.GATHERING_IN_SITU());
110
            }
111

    
112
            repo.getRegistrationService().saveOrUpdate(reg);
113
        }
114
        return bean;
115
    }
116

    
117
    /**
118
     * {@inheritDoc}
119
     */
120
    @Override
121
    @Transactional(readOnly=false)
122
    public void save(SpecimenTypeDesignationWorkingSetDTO<? extends VersionableEntity> dto, Reference citation, TaxonName typifiedName) {
123

    
124
        if(dto.getOwner() instanceof Registration){
125
            Registration regPremerge = (Registration) dto.getOwner();
126

    
127
            // find the newly created type designations
128
            Set<SpecimenTypeDesignation> newTypeDesignations = findNewTypeDesignations((SpecimenTypeDesignationWorkingSetDTO<Registration>) dto);
129

    
130
            FieldUnit fieldUnit = (FieldUnit) dto.getBaseEntity();
131

    
132
            // associate the new typeDesignations with the registration
133
            for(SpecimenTypeDesignation std : newTypeDesignations){
134
                assureFieldUnit(fieldUnit, std);
135
                std.setCitation(citation);
136
                typifiedName.addTypeDesignation(std, false);
137
                regPremerge.addTypeDesignation(std);
138
            }
139

    
140
            for(SpecimenTypeDesignationDTO stdDTO : dto.getSpecimenTypeDesignationDTOs()){
141
                SpecimenTypeDesignation specimenTypeDesignation = stdDTO.asSpecimenTypeDesignation();
142
                // associate all type designations with the fieldUnit
143
                assureFieldUnit(fieldUnit, specimenTypeDesignation);
144
            }
145

    
146
            Session session = repo.getSession();
147

    
148
            session.merge(dto.getOwner());
149

    
150
            session.flush();
151
        }
152

    
153

    
154
    }
155

    
156
    /**
157
     * @param session
158
     * @param fieldUnit
159
     * @param specimenTypeDesignation
160
     */
161
    protected void assureFieldUnit(FieldUnit fieldUnit,
162
            SpecimenTypeDesignation specimenTypeDesignation) {
163
        try {
164
            SpecimenOrObservationBase<?> original = findEarliestOriginal(specimenTypeDesignation.getTypeSpecimen());
165
            if(original instanceof DerivedUnit){
166
                DerivedUnit du = (DerivedUnit)original;
167
                du.getDerivedFrom().addOriginal(fieldUnit);
168
            }
169
        } catch (Exception e) {
170
            // has more than one originals !!!
171
            logger.error(e);
172
        }
173
    }
174

    
175
    /**
176
     * @param std
177
     * @return
178
     * @throws Exception
179
     */
180
    private SpecimenOrObservationBase<?> findEarliestOriginal(DerivedUnit du) throws Exception {
181

    
182
        SpecimenOrObservationBase original = du;
183

    
184
        while(du != null && du.getDerivedFrom() != null && !du.getDerivedFrom().getOriginals().isEmpty()) {
185
            Iterator<SpecimenOrObservationBase> it = du.getDerivedFrom().getOriginals().iterator();
186
            SpecimenOrObservationBase nextOriginal = it.next();
187
            if(nextOriginal == null){
188
                break;
189
            }
190
            original = nextOriginal;
191
            if(original instanceof DerivedUnit){
192
                du = (DerivedUnit)original;
193
            } else {
194
                // so this must be a FieldUnit,
195
               break;
196
            }
197
            if(it.hasNext()){
198
                throw new Exception(String.format("%s has more than one originals", du.toString()));
199
            }
200
        }
201
        return original;
202
    }
203

    
204
    private Set<SpecimenTypeDesignation> findNewTypeDesignations(SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto) {
205

    
206
        Registration reg = workingSetDto.getOwner();
207
        Set<SpecimenTypeDesignation> addCandidates = new HashSet<>();
208
        for(SpecimenTypeDesignationDTO stdDTO : workingSetDto.getSpecimenTypeDesignationDTOs()){
209
            SpecimenTypeDesignation std = stdDTO.asSpecimenTypeDesignation();
210
            if(reg.getTypeDesignations().isEmpty() || !reg.getTypeDesignations().stream().filter(td -> td.equals(std)).findFirst().isPresent()){
211
                addCandidates.add(std);
212
            }
213
        }
214
        return addCandidates;
215
    }
216

    
217
}
(7-7/7)