Project

General

Profile

Download (8.44 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.utility;
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
 *
28
 * @author a.kohlbecker
29
 * @since Jun 23, 2017
30
 *
31
 */
32
public class DerivedUnitConverter<TARGET extends DerivedUnit> {
33

    
34
    private DerivedUnit source;
35

    
36
    private SpecimenTypeDesignation specimenTypeDesignation;
37

    
38
    private SpecimenTypeDesignation newSpecimenTypeDesignation;
39

    
40
    private static final Logger logger = Logger.getLogger(DerivedUnitConverter.class);
41

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

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

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

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

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

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

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

    
106
            copyPropertiesTo(newInstance);
107

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

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

    
118
    }
119

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

    
172
    }
173

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

    
182
    /**
183
     * @return
184
     */
185
    private boolean canConvert() {
186

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

    
196
        return false;
197
    }
198

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

    
209
}
(2-2/6)