Project

General

Profile

Download (8.41 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.api.util;
10

    
11
import java.lang.reflect.InvocationTargetException;
12
import java.lang.reflect.Method;
13

    
14
import org.apache.log4j.Logger;
15

    
16
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
17
import eu.etaxonomy.cdm.model.media.Media;
18
import eu.etaxonomy.cdm.model.name.Registration;
19
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
20
import eu.etaxonomy.cdm.model.name.TaxonName;
21
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
22
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
23
import eu.etaxonomy.cdm.model.occurrence.MediaSpecimen;
24
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
25

    
26
/**
27
 * @author a.kohlbecker
28
 * @since Jun 23, 2017
29
 */
30
public class DerivedUnitConverter<TARGET extends DerivedUnit> {
31

    
32
    private DerivedUnit source;
33

    
34
    private SpecimenTypeDesignation specimenTypeDesignation;
35

    
36
    private SpecimenTypeDesignation newSpecimenTypeDesignation;
37

    
38
    private static final Logger logger = Logger.getLogger(DerivedUnitConverter.class);
39

    
40
    /**
41
     * @param specimenTypeDesignation
42
     */
43
    public DerivedUnitConverter(DerivedUnit source) throws Exception {
44
        if(source == null){
45
            throw new NullPointerException();
46
        }
47
        this.source = HibernateProxyHelper.deproxy(source, DerivedUnit.class);
48
        if(source.getSpecimenTypeDesignations().size() == 1){
49
            specimenTypeDesignation = source.getSpecimenTypeDesignations().iterator().next();
50
        } else if (source.getSpecimenDescriptions().size() > 1){
51
            throw new Exception("can not convert derived unit with multipe type designations");
52
        }
53
    }
54

    
55
    /**
56
     * @param specimenTypeDesignation
57
     */
58
    public DerivedUnitConverter(SpecimenTypeDesignation specimenTypeDesignation) {
59
        if(specimenTypeDesignation == null){
60
            throw new NullPointerException();
61
        }
62
        this.specimenTypeDesignation = HibernateProxyHelper.deproxy(specimenTypeDesignation);
63
        this.source = HibernateProxyHelper.deproxy(specimenTypeDesignation.getTypeSpecimen(), DerivedUnit.class);
64
    }
65

    
66
    /**
67
     * converts the <code>source</code> <code>DerivedUnit</code> this converter has been created
68
     * for into a <code>DerivedUnit</code> of the type <code>TARGET</code>.
69
     * If the <code>source</code> instance was persisted the target instance will also be written
70
     * into data base and the source is deleted from there.
71
     *
72
     * @param targetType
73
     * @param recordBasis
74
     * @throws DerivedUnitConversionException
75
     */
76
    @SuppressWarnings("unchecked")
77
    public SpecimenTypeDesignation convertTo(Class<TARGET> targetType, SpecimenOrObservationType recordBasis) throws DerivedUnitConversionException {
78

    
79
        if(source.getClass().equals(targetType)){
80
            // nothing to do
81
            return specimenTypeDesignation;
82
        }
83

    
84
        if(!isSuppoprtedType(targetType)){
85
            throw new DerivedUnitConversionException(
86
                    String.format("Unsupported convertion target type: %s",
87
                            targetType.getName())
88
                    );
89
        }
90

    
91
        if(!canConvert()){
92
            throw new DerivedUnitConversionException(
93
                    String.format("%s can not be converted into %s as long it contains unconvertable non null properties",
94
                            source.toString(),
95
                            targetType.getName())
96
                    );
97
        }
98

    
99
        TARGET newInstance = null;
100
        try {
101
            Method newInstanceMethod = targetType.getDeclaredMethod("NewInstance", SpecimenOrObservationType.class);
102
            newInstance = (TARGET) newInstanceMethod.invoke(SpecimenOrObservationType.class, recordBasis);
103

    
104
            copyPropertiesTo(newInstance);
105

    
106
        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
107
                | InvocationTargetException e) {
108
            throw new DerivedUnitConversionException("Error during intantiation of " + targetType.getName(), e);
109
        }
110

    
111
        logger.debug("convertion of " + source.instanceToString() + "<--" + specimenTypeDesignation.instanceToString()
112
                + " to "
113
                + newSpecimenTypeDesignation.getTypeSpecimen().instanceToString() +  "<--" + newSpecimenTypeDesignation.instanceToString() );
114
        return newSpecimenTypeDesignation;
115

    
116
    }
117

    
118
    /**
119
     * @param newInstance
120
     */
121
    private void copyPropertiesTo(TARGET target) {
122
        target.setAccessionNumber(source.getAccessionNumber());
123
        target.setBarcode(source.getBarcode());
124
        target.setCatalogNumber(source.getCatalogNumber());
125
        target.setCollection(source.getCollection());
126
        DerivationEvent derivationEvent = source.getDerivedFrom();
127
        if(derivationEvent != null){
128
            derivationEvent.getDerivatives().remove(source);
129
        }
130
        target.setDerivedFrom(source.getDerivedFrom());
131
        source.setDerivedFrom(null);
132
        target.setExsiccatum(source.getExsiccatum());
133
        target.setIndividualCount(source.getIndividualCount());
134
        target.setKindOfUnit(source.getKindOfUnit());
135
        target.setLifeStage(source.getLifeStage());
136
        target.setLsid(source.getLsid());
137
        target.setOriginalLabelInfo(source.getOriginalLabelInfo());
138
        target.setPreferredStableUri(source.getPreferredStableUri());
139
        target.setPreservation(source.getPreservation());
140
        target.setPublish(source.isPublish());
141
        target.setProtectedIdentityCache(source.isProtectedIdentityCache());
142
        target.setProtectedTitleCache(source.isProtectedTitleCache());
143
        // n.setRecordBasis(source.getRecordBasis()); // not to copy, this it is set for the new instance explicitly
144
        target.setSex(source.getSex());
145
        target.setStoredUnder(source.getStoredUnder());
146
        target.setTitleCache(source.getTitleCache(), target.isProtectedTitleCache());
147
        source.getSources().forEach(s -> target.addSource(s));
148
        source.getAnnotations().forEach(a -> target.addAnnotation(a));
149
        source.getCredits().forEach(c -> target.addCredit(c));
150
        source.getDerivationEvents().forEach(de -> target.addDerivationEvent(de));
151
        source.getDerivationEvents().clear();
152
        source.getDescriptions().forEach(d -> target.addDescription(d));
153
        source.getDeterminations().forEach(det -> target.addDetermination(det));
154
        source.getDeterminations().clear();
155
        source.getExtensions().forEach(e -> target.addExtension(e));
156
        source.getIdentifiers().forEach(i -> target.addIdentifier(i));
157
        source.getMarkers().forEach(m -> target.addMarker(m));
158
        source.getRights().forEach(r -> target.addRights(r));
159
        target.addSources(source.getSources());
160
        // need to clone the SpecimenTypeDesignation, since the SpecimenTypeDesignations are being deleted by the hibernate delete cascade
161
        newSpecimenTypeDesignation = specimenTypeDesignation.clone();
162
        for(Registration reg : specimenTypeDesignation.getRegistrations()){
163
            reg.removeTypeDesignation(specimenTypeDesignation);
164
        }
165
        for(TaxonName name : specimenTypeDesignation.getTypifiedNames()){
166
            name.removeTypeDesignation(specimenTypeDesignation);
167
        }
168
        target.addSpecimenTypeDesignation(newSpecimenTypeDesignation);
169

    
170
    }
171

    
172
    /**
173
     * @param targetType
174
     * @return
175
     */
176
    public boolean isSuppoprtedType(Class<TARGET> targetType) {
177
        return targetType.equals(MediaSpecimen.class) || targetType.equals(DerivedUnit.class);
178
    }
179

    
180
    /**
181
     * @return
182
     */
183
    private boolean canConvert() {
184

    
185
        if(source.getClass().equals(DerivedUnit.class)) {
186
            return true;
187
        }
188
        if(source.getClass().equals(MediaSpecimen.class)){
189
            MediaSpecimen ms = (MediaSpecimen)source;
190
            Media media = ms.getMediaSpecimen();
191
            return media == null;
192
        }
193

    
194
        return false;
195
    }
196

    
197
    /**
198
     * Returns the derived unit which was the source entity for the conversion.
199
     * You may want to delete this entity after the conversion if this makes sense
200
     * in the context of the actual use case. By this you can
201
     * avoid orphan derived units and type designations.
202
     */
203
    public DerivedUnit oldDerivedUnit(){
204
        return source;
205
    }
206

    
207
}
(4-4/15)