Project

General

Profile

Download (65.7 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2019 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.io.cdm2cdm;
10

    
11
import java.lang.reflect.Field;
12
import java.lang.reflect.InvocationTargetException;
13
import java.lang.reflect.Method;
14
import java.util.ArrayList;
15
import java.util.Collection;
16
import java.util.HashMap;
17
import java.util.HashSet;
18
import java.util.List;
19
import java.util.Map;
20
import java.util.Set;
21
import java.util.UUID;
22

    
23
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
24

    
25
import eu.etaxonomy.cdm.api.application.CdmApplicationController;
26
import eu.etaxonomy.cdm.api.application.ICdmRepository;
27
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
28
import eu.etaxonomy.cdm.database.DbSchemaValidation;
29
import eu.etaxonomy.cdm.database.ICdmDataSource;
30
import eu.etaxonomy.cdm.database.ICdmImportSource;
31
import eu.etaxonomy.cdm.io.common.CdmImportBase;
32
import eu.etaxonomy.cdm.io.common.ITaxonNodeOutStreamPartitioner;
33
import eu.etaxonomy.cdm.io.common.TaxonNodeOutStreamPartitioner;
34
import eu.etaxonomy.cdm.io.common.TaxonNodeOutStreamPartitionerConcurrent;
35
import eu.etaxonomy.cdm.model.agent.AgentBase;
36
import eu.etaxonomy.cdm.model.agent.Contact;
37
import eu.etaxonomy.cdm.model.agent.Institution;
38
import eu.etaxonomy.cdm.model.agent.InstitutionalMembership;
39
import eu.etaxonomy.cdm.model.agent.Person;
40
import eu.etaxonomy.cdm.model.agent.Team;
41
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
42
import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
43
import eu.etaxonomy.cdm.model.common.Annotation;
44
import eu.etaxonomy.cdm.model.common.CdmBase;
45
import eu.etaxonomy.cdm.model.common.Credit;
46
import eu.etaxonomy.cdm.model.common.Extension;
47
import eu.etaxonomy.cdm.model.common.ExtensionType;
48
import eu.etaxonomy.cdm.model.common.IIntextReferencable;
49
import eu.etaxonomy.cdm.model.common.IIntextReferenceTarget;
50
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
51
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
52
import eu.etaxonomy.cdm.model.common.Identifier;
53
import eu.etaxonomy.cdm.model.common.IntextReference;
54
import eu.etaxonomy.cdm.model.common.Language;
55
import eu.etaxonomy.cdm.model.common.LanguageString;
56
import eu.etaxonomy.cdm.model.common.LanguageStringBase;
57
import eu.etaxonomy.cdm.model.common.Marker;
58
import eu.etaxonomy.cdm.model.common.MarkerType;
59
import eu.etaxonomy.cdm.model.common.RelationshipBase;
60
import eu.etaxonomy.cdm.model.common.SingleSourcedEntityBase;
61
import eu.etaxonomy.cdm.model.common.SourcedEntityBase;
62
import eu.etaxonomy.cdm.model.common.VersionableEntity;
63
import eu.etaxonomy.cdm.model.description.CommonTaxonName;
64
import eu.etaxonomy.cdm.model.description.DescriptionBase;
65
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
66
import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
67
import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
68
import eu.etaxonomy.cdm.model.description.Distribution;
69
import eu.etaxonomy.cdm.model.description.FeatureState;
70
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
71
import eu.etaxonomy.cdm.model.description.TaxonDescription;
72
import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
73
import eu.etaxonomy.cdm.model.description.TextData;
74
import eu.etaxonomy.cdm.model.location.Country;
75
import eu.etaxonomy.cdm.model.location.NamedArea;
76
import eu.etaxonomy.cdm.model.media.ExternalLink;
77
import eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity;
78
import eu.etaxonomy.cdm.model.media.Media;
79
import eu.etaxonomy.cdm.model.media.Rights;
80
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
81
import eu.etaxonomy.cdm.model.name.HybridRelationship;
82
import eu.etaxonomy.cdm.model.name.NameRelationship;
83
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
84
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
85
import eu.etaxonomy.cdm.model.name.Registration;
86
import eu.etaxonomy.cdm.model.name.TaxonName;
87
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
88
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
89
import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
90
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
91
import eu.etaxonomy.cdm.model.permission.User;
92
import eu.etaxonomy.cdm.model.reference.NamedSource;
93
import eu.etaxonomy.cdm.model.reference.NamedSourceBase;
94
import eu.etaxonomy.cdm.model.reference.OriginalSourceBase;
95
import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
96
import eu.etaxonomy.cdm.model.reference.Reference;
97
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
98
import eu.etaxonomy.cdm.model.taxon.Classification;
99
import eu.etaxonomy.cdm.model.taxon.SecundumSource;
100
import eu.etaxonomy.cdm.model.taxon.Synonym;
101
import eu.etaxonomy.cdm.model.taxon.Taxon;
102
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
103
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
104
import eu.etaxonomy.cdm.model.taxon.TaxonNodeAgentRelation;
105
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
106
import eu.etaxonomy.cdm.model.term.DefinedTerm;
107
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
108
import eu.etaxonomy.cdm.model.term.OrderedTermBase;
109
import eu.etaxonomy.cdm.model.term.Representation;
110
import eu.etaxonomy.cdm.model.term.TermBase;
111
import eu.etaxonomy.cdm.model.term.TermCollection;
112
import eu.etaxonomy.cdm.model.term.TermNode;
113
import eu.etaxonomy.cdm.model.term.TermRelationBase;
114
import eu.etaxonomy.cdm.model.term.TermTree;
115
import eu.etaxonomy.cdm.model.term.TermVocabulary;
116
import eu.etaxonomy.cdm.persistence.query.MatchMode;
117

    
118
/**
119
 * Base class for migrating data from one CDM instance to another.
120
 *
121
 * @author a.mueller
122
 * @since 17.08.2019
123
 */
124
public abstract class Cdm2CdmImportBase
125
        extends CdmImportBase<Cdm2CdmImportConfigurator, Cdm2CdmImportState> {
126

    
127
    private static final long serialVersionUID = 1344722304369624443L;
128
    private static final Logger logger = LogManager.getLogger(Cdm2CdmImportBase.class);
129

    
130
    //quick and dirty
131
    private Cdm2CdmImportState stateX;
132

    
133
    protected ICdmRepository sourceRepo(Cdm2CdmImportState state){
134
        ICdmRepository repo = state.getSourceRepository();
135
        if (repo == null){
136
            ICdmImportSource source = state.getConfig().getSource();
137
            if (source instanceof ICdmRepository){
138
                repo = (ICdmRepository)source;
139
            }else if (source instanceof ICdmDataSource){
140
                System.out.println("start source repo");
141
                boolean omitTermLoading = true;
142
                repo = CdmApplicationController.NewInstance((ICdmDataSource)source,
143
                        DbSchemaValidation.VALIDATE, omitTermLoading);
144
                state.setSourceRepository(repo);
145
                System.out.println("end source repo");
146
            }else{
147
                throw new IllegalStateException("Unsupported ICdmImportSource type");
148
            }
149
        }
150
        return repo;
151
    }
152

    
153
    protected  Contact detache(Contact contact, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
154
        contact = CdmBase.deproxy(contact);
155
        if (contact == null){
156
            return contact;
157
        }else{
158
            return handlePersistedContact(contact, state);
159
        }
160
    }
161

    
162
    protected  IIntextReferencable detache(IIntextReferencable cdmBase, boolean onlyForDefinedSignature, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
163
        return (IIntextReferencable)detache((CdmBase)cdmBase, state);
164
    }
165
    protected  IIntextReferenceTarget detache(IIntextReferenceTarget cdmBase, boolean onlyForDefinedSignature, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
166
        return (IIntextReferenceTarget)detache((CdmBase)cdmBase, state);
167
    }
168

    
169
    protected <T extends CdmBase> T detache(T cdmBase, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
170
        return detache(cdmBase, false, state);
171
    }
172

    
173
    protected <T extends CdmBase> T detache(T cdmBase, boolean notFromSource, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
174
        cdmBase = CdmBase.deproxy(cdmBase);
175
        if (cdmBase == null ){
176
            return cdmBase;
177
        }else if(isInCache(cdmBase, state)){
178
            return getCached(cdmBase, state);
179
        }else {
180
            if (state.getExistingObjects(cdmBase.getClass()) == null){
181
                loadExistingUuids(cdmBase.getClass(), state);
182
            }
183
            boolean exists = state.getExistingObjects(cdmBase.getClass()).contains(cdmBase.getUuid());
184
            if (exists){
185
                Class<T> clazz = (Class<T>)cdmBase.getClass();
186
                T existingObj = getCommonService().find(clazz, cdmBase.getUuid());
187
                if (existingObj != null){
188
                    cache(existingObj, state);
189
                    return existingObj;
190
                }else{
191
                    logger.warn("Object should exist already but does not exist in target. This should not happen: " + cdmBase.getClass().getSimpleName() + "/" + cdmBase.getUuid());
192
                }
193
            }
194
        }
195
        if ( !cdmBase.isPersited()){
196
            logger.warn("Non persisted object not in cache and not in target DB. This should not happen: " + cdmBase.getUuid());
197
            return cdmBase; //should not happen anymore; either in cache or in target or persisted in source
198
        }else{
199
            return notFromSource? null : (T)handlePersisted(cdmBase, state);
200
        }
201
    }
202

    
203
    private Set<UUID> loadExistingUuids(Class<? extends CdmBase> clazz, Cdm2CdmImportState state) {
204
        List<UUID> list = getCommonService().listUuid(clazz);
205
        Set<UUID> result = new HashSet<>(list);
206
        state.putExistingObjects(clazz, result);
207
        return result;
208
    }
209

    
210
    protected <A extends CdmBase> CdmBase handlePersisted(A cdmBase, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
211
        if(cdmBase instanceof TaxonNode){
212
            return handlePersistedTaxonNode((TaxonNode)cdmBase, state);
213
        }else if(cdmBase instanceof Taxon){
214
            return handlePersistedTaxon((Taxon)cdmBase, state);
215
        }else if(cdmBase instanceof Synonym){
216
            return handlePersistedSynonym((Synonym)cdmBase, state);
217
        }else if(cdmBase instanceof TaxonName){
218
            return handlePersistedTaxonName((TaxonName)cdmBase, state);
219
        }else if(cdmBase instanceof Team){
220
            return handlePersistedTeam((Team)cdmBase, state);
221
        }else if(cdmBase instanceof Person){
222
            return handlePersistedPerson((Person)cdmBase, state);
223
        }else if(cdmBase instanceof Classification){
224
            return handlePersistedClassification((Classification)cdmBase, state);
225
        }else if(cdmBase instanceof Reference){
226
            return handlePersistedReference((Reference)cdmBase, state);
227
        }else if(cdmBase instanceof SpecimenOrObservationBase){
228
            return handlePersistedSpecimenOrObservationBase((SpecimenOrObservationBase)cdmBase, state);
229
        }else if(cdmBase instanceof IdentifiableSource){
230
            return handlePersistedIdentifiableSource((IdentifiableSource)cdmBase, state);
231
        }else if(cdmBase instanceof DescriptionElementSource){
232
            return handlePersistedDescriptionElementSource((DescriptionElementSource)cdmBase, state);
233
        }else if(cdmBase instanceof CommonTaxonName){
234
            return handlePersistedCommonTaxonName((CommonTaxonName)cdmBase, state);
235
        }else if(cdmBase instanceof Distribution){
236
            return handlePersistedDistribution((Distribution)cdmBase, state);
237
        }else if(cdmBase instanceof TextData){
238
            return handlePersistedTextData((TextData)cdmBase, state);
239
        }else if(cdmBase instanceof HomotypicalGroup){
240
            return handlePersistedHomotypicalGroup((HomotypicalGroup)cdmBase, state);
241
        }else if(cdmBase instanceof TypeDesignationBase){
242
            return handlePersistedTypeDesignationBase((TypeDesignationBase)cdmBase, state);
243
        }else if(cdmBase instanceof TaxonDescription){
244
            return handlePersistedTaxonDescription((TaxonDescription)cdmBase, state);
245
        }else if(cdmBase instanceof NomenclaturalStatus){
246
            return handlePersistedNomenclaturalStatus((NomenclaturalStatus)cdmBase, state);
247
        }else if(cdmBase instanceof TaxonNameDescription){
248
            return handlePersistedTaxonNameDescription((TaxonNameDescription)cdmBase, state);
249
        }else if(cdmBase instanceof TaxonRelationship){
250
            return handlePersistedTaxonRelationship((TaxonRelationship)cdmBase, state);
251
        }else if(cdmBase instanceof HybridRelationship){
252
            return handlePersistedHybridRelationship((HybridRelationship)cdmBase, state);
253
        }else if(cdmBase instanceof NameRelationship){
254
            return handlePersistedNameRelationship((NameRelationship)cdmBase, state);
255
        }else if(cdmBase instanceof TaxonNodeAgentRelation){
256
            return handlePersistedTaxonNodeAgentRelation((TaxonNodeAgentRelation)cdmBase, state);
257
        }else if(cdmBase instanceof User){
258
            return handlePersistedUser((User)cdmBase, state);
259
        }else if(cdmBase instanceof Extension){
260
            return handlePersistedExtension((Extension)cdmBase, state);
261
        }else if(cdmBase instanceof Marker){
262
            return handlePersistedMarker((Marker)cdmBase, state);
263
        }else if(cdmBase instanceof Annotation){
264
            return handlePersistedAnnotation((Annotation)cdmBase, state);
265
        }else if(cdmBase instanceof LanguageString){
266
            return handlePersistedLanguageString((LanguageString)cdmBase, state);
267
        }else if(cdmBase instanceof TermVocabulary){
268
            return handlePersistedVocabulary((TermVocabulary<?>)cdmBase, state);
269
        }else if(cdmBase instanceof TermTree){
270
            return handlePersistedTermTree((TermTree<?>)cdmBase, state);
271
        }else if(cdmBase instanceof NamedArea){
272
            return handlePersistedNamedArea((NamedArea)cdmBase, state);
273
        }else if(cdmBase instanceof TermNode){
274
            return handlePersistedTermNode((TermNode)cdmBase, state);
275
        }else if(cdmBase instanceof Representation){
276
            return handlePersistedRepresentation((Representation)cdmBase, state);
277
        }else if(cdmBase instanceof InstitutionalMembership){
278
            return handlePersistedInstitutionalMembership((InstitutionalMembership)cdmBase, state);
279
        }else if(cdmBase instanceof Institution){
280
            return handlePersistedInstitution((Institution)cdmBase, state);
281
        }else if(cdmBase instanceof IntextReference){
282
            return handlePersistedIntextReference((IntextReference)cdmBase, state);
283
        }else if(cdmBase instanceof ExtensionType){
284
            return handlePersistedExtensionType((ExtensionType)cdmBase, state);
285
        }else if(cdmBase instanceof NomenclaturalStatusType){
286
            return handlePersistedNomenclaturalStatusType((NomenclaturalStatusType)cdmBase, state);
287
        }else if(cdmBase instanceof MarkerType){
288
            return handlePersistedMarkerType((MarkerType)cdmBase, state);
289
        }else if(cdmBase instanceof Rights){
290
            return handlePersistedRights((Rights)cdmBase, state);
291
        }else if(cdmBase instanceof DefinedTerm){
292
            return handlePersistedDefinedTerm((DefinedTerm)cdmBase, state);
293
        }else if(cdmBase instanceof DefinedTermBase){
294
            return handlePersistedTerm((DefinedTermBase<?>)cdmBase, state);
295
        }else {
296
            throw new RuntimeException("Type not yet supported: " + cdmBase.getClass().getCanonicalName());
297
        }
298
    }
299

    
300

    
301
    protected TaxonNode handlePersistedTaxonNode(TaxonNode node, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
302

    
303
        TaxonNode result = handlePersisted((AnnotatableEntity)node, state);
304
        if (result ==null){
305
            return result;
306
        }
307
        //complete
308
        handleCollection(result, TaxonNode.class, "agentRelations", TaxonNodeAgentRelation.class, state);
309
        result.setTaxon(detache(result.getTaxon(), state));
310
        result.setCitation(detache(node.getReference(), state));
311
        result.setSynonymToBeUsed(detache(result.getSynonymToBeUsed(), state));
312
        handleMap(result, TaxonNode.class, "excludedNote", Language.class, LanguageString.class, state);
313
        //classification, parent, children
314
        this.setInvisible(node, "classification", detache(node.getClassification(), state));
315
        handleParentTaxonNode(result, state);
316
        setNewCollection(node, TaxonNode.class, "childNodes", TaxonNode.class);
317
        return result;
318
    }
319

    
320
    private void handleParentTaxonNode(TaxonNode childNode, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
321
        TaxonNode parent = detache(childNode.getParent(), true, state);
322
        //TODO
323
        String microReference = null;
324
        Reference reference = null;
325
        if (parent == null && childNode.getClassification().getRootNode().equals(childNode)){
326
            //do nothing
327
        }else if (parent == null ){
328
            childNode.getClassification().addChildNode(childNode, reference, microReference) ;
329
        }else{
330
            parent.addChildNode(childNode, reference, microReference);
331
        }
332
    }
333

    
334
    protected Taxon handlePersistedTaxon(Taxon taxon, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
335
        Taxon result = handlePersisted((TaxonBase)taxon, state);
336
        //complete
337
        handleCollection(result, Taxon.class, "synonyms", Synonym.class, state);
338
//        handleCollection(result, Taxon.class, "taxonNodes", TaxonNode.class);
339
        setNewCollection(result, Taxon.class, "taxonNodes", TaxonNode.class);
340
        handleCollection(result, Taxon.class, "relationsFromThisTaxon", TaxonRelationship.class, state);
341
        handleCollection(result, Taxon.class, "relationsToThisTaxon", TaxonRelationship.class, state);
342
        if (this.doDescriptions(state)){
343
            handleCollection(result, Taxon.class, "descriptions", TaxonDescription.class, state);
344
        }else{
345
            setNewCollection(result, Taxon.class, "descriptions", TaxonDescription.class);
346
        }
347
        return result;
348
    }
349

    
350
    protected boolean doDescriptions(Cdm2CdmImportState state) {
351
        return false;
352
    }
353

    
354
    protected Synonym handlePersistedSynonym(Synonym synonym, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
355
        Synonym result = handlePersisted((TaxonBase)synonym, state);
356
        //complete
357
        setInvisible(result, "acceptedTaxon", detache(result.getAcceptedTaxon(), state));
358
        result.setType(detache(result.getType(), state));
359
        return result;
360
    }
361

    
362
    protected TaxonRelationship handlePersistedTaxonRelationship(TaxonRelationship taxRel, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
363
        TaxonRelationship result = handlePersisted((RelationshipBase)taxRel, state);
364
        //complete
365
        result.setFromTaxon(detache(result.getFromTaxon(), state));
366
        result.setToTaxon(detache(result.getToTaxon(), state));
367
        result.setType(detache(result.getType(), state));
368
        return result;
369
    }
370

    
371
    protected NameRelationship handlePersistedNameRelationship(NameRelationship rel, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
372
        NameRelationship result = handlePersisted((RelationshipBase)rel, state);
373
        //complete
374
        setInvisible(result, "relatedFrom", detache(result.getFromName(), state));
375
        setInvisible(result, "relatedTo", detache(result.getToName(), state));
376
//        result.setFromName(detache(result.getFromName(), state));
377
//        result.setToName(detache(result.getToName(), state));
378
        result.setType(detache(result.getType(), state));
379
        return result;
380
    }
381

    
382
    protected HybridRelationship handlePersistedHybridRelationship(HybridRelationship rel, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
383
        HybridRelationship result = handlePersisted((RelationshipBase)rel, state);
384
        //complete
385
        setInvisible(result, "relatedFrom", detache(result.getParentName(), state));
386
        setInvisible(result, "relatedTo", detache(result.getHybridName(), state));
387
//        result.setFromName(detache(result.getFromName()));
388
//        result.setToName(detache(result.getToName()));
389
        result.setType(detache(result.getType(), state));
390
        return result;
391
    }
392

    
393
    protected NomenclaturalStatus handlePersistedNomenclaturalStatus(NomenclaturalStatus status, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
394
        NomenclaturalStatus result = handlePersisted((SingleSourcedEntityBase)status, state);
395
        //complete
396
        result.setType(detache(result.getType(), state));
397
        return result;
398
    }
399

    
400
    protected TypeDesignationBase handlePersistedTypeDesignationBase(TypeDesignationBase<?> designation, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
401
        TypeDesignationBase result = handlePersisted((SourcedEntityBase)designation, state);
402
        //complete
403
        result.setCitation(detache(result.getCitation(), state));
404
        handleCollection(result, TypeDesignationBase.class, "registrations", Registration.class, state);
405
        handleCollection(result, TypeDesignationBase.class, "typifiedNames", TaxonName.class, state);
406
        result.setTypeStatus(detache(result.getTypeStatus(), state));
407
        return result;
408
    }
409

    
410
    protected InstitutionalMembership handlePersistedInstitutionalMembership(InstitutionalMembership institutionalMembership, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
411
        InstitutionalMembership result = handlePersisted((VersionableEntity)institutionalMembership, state);
412
        //complete
413
//        result.setPerson(detache(result.getPerson()));
414
        setInvisible(result, "person", detache(result.getPerson(), state));
415
        result.setInstitute(detache(result.getInstitute(), state));
416
        return result;
417
    }
418

    
419
    protected Institution handlePersistedInstitution(Institution institution, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
420
        Institution result = handlePersisted((AgentBase)institution, state);
421
        //complete
422
        result.setIsPartOf(detache(result.getIsPartOf(), state));
423
        handleCollection(result, Institution.class, "types", DefinedTerm.class, state);
424
        return result;
425
    }
426

    
427
    protected TaxonNodeAgentRelation handlePersistedTaxonNodeAgentRelation(TaxonNodeAgentRelation nodeAgentRel, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
428
        TaxonNodeAgentRelation result = handlePersisted((AnnotatableEntity)nodeAgentRel, state);
429
        //complete
430
        result.setAgent(detache(result.getAgent(), state));
431
        result.setType(detache(result.getType(), state));
432
        setInvisible(result, "taxonNode", detache(result.getTaxonNode(), state));
433
        return result;
434
    }
435

    
436

    
437
    protected TaxonName handlePersistedTaxonName(TaxonName taxonName, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
438
        @SuppressWarnings("rawtypes")
439
        TaxonName result = handlePersisted((IdentifiableEntity)taxonName, state);
440
        //complete
441
        result.setRank(detache(result.getRank(), state));
442
        result.setCombinationAuthorship(detache(result.getCombinationAuthorship(), state));
443
        result.setExCombinationAuthorship(detache(result.getExCombinationAuthorship(), state));
444
        result.setBasionymAuthorship(detache(result.getBasionymAuthorship(), state));
445
        result.setExBasionymAuthorship(detache(result.getExBasionymAuthorship(), state));
446
        result.setInBasionymAuthorship(detache(result.getInBasionymAuthorship(), state));
447
        result.setInCombinationAuthorship(detache(result.getInCombinationAuthorship(), state));
448

    
449
        result.setNomenclaturalReference(detache(result.getNomenclaturalReference(), state));
450
        result.setNomenclaturalSource(detache(result.getNomenclaturalSource(), state));
451
        result.setHomotypicalGroup(detache(result.getHomotypicalGroup(), state));
452
        handleCollection(result, TaxonName.class, "descriptions", TaxonNameDescription.class, state);
453
        handleCollection(result, TaxonName.class, "hybridChildRelations", HybridRelationship.class, state);
454
        handleCollection(result, TaxonName.class, "hybridParentRelations", HybridRelationship.class, state);
455
        handleCollection(result, TaxonName.class, "relationsFromThisName", NameRelationship.class, state);
456
        handleCollection(result, TaxonName.class, "relationsToThisName", NameRelationship.class, state);
457
        handleCollection(result, TaxonName.class, "status", NomenclaturalStatus.class, state);
458

    
459
        handleCollection(result, TaxonName.class, "registrations", Registration.class, state);
460
        handleCollection(result, TaxonName.class, "typeDesignations", TypeDesignationBase.class, state);
461

    
462
        handleCollection(result, TaxonName.class, "taxonBases", TaxonBase.class, state);
463

    
464
        return result;
465
    }
466

    
467
    protected HomotypicalGroup handlePersistedHomotypicalGroup(HomotypicalGroup group, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
468
        HomotypicalGroup result = handlePersisted((AnnotatableEntity)group, state);
469
        //complete
470
        handleCollection(result, HomotypicalGroup.class, "typifiedNames", TaxonName.class, state);
471
        return result;
472
    }
473

    
474
    protected Annotation handlePersistedAnnotation(Annotation annotation, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
475
        Annotation result = handlePersisted((AnnotatableEntity)annotation, state);
476
        //complete
477
        result.setAnnotationType(detache(annotation.getAnnotationType(), state));
478
        result.setCommentator(detache(result.getCommentator(), state));
479
        handleCollection(result, Annotation.class, "intextReferences", IntextReference.class, state);
480
        return result;
481
    }
482

    
483
    protected Extension handlePersistedExtension(Extension extension, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
484
        Extension result = handlePersisted((VersionableEntity)extension, state);
485
        //complete
486
        result.setType(detache(extension.getType(), state));
487
        return result;
488
    }
489

    
490
    protected Marker handlePersistedMarker(Marker marker, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
491
        Marker result = handlePersisted((VersionableEntity)marker, state);
492
        //complete
493
        result.setMarkerType(detache(marker.getMarkerType(), state));
494
        return result;
495
    }
496

    
497
    protected Team handlePersistedTeam(Team team, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
498
        Team result = handlePersisted((TeamOrPersonBase)team, state);
499
        //complete
500
        handleCollection(result, Team.class, "teamMembers", Person.class, state);
501
        return result;
502
    }
503

    
504
    protected Contact handlePersistedContact(Contact contact, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
505
        Contact result = contact; // getTarget(contact);
506
        if (result ==null){
507
            return result;
508
        }
509
        if (!contact.getAddresses().isEmpty() || !contact.getEmailAddresses().isEmpty()
510
               || !contact.getFaxNumbers().isEmpty() ||!contact.getPhoneNumbers().isEmpty()
511
               ||!contact.getUrls().isEmpty()){
512
            logger.warn("Addresses not yet implemented");
513
        }
514
        setInvisible(result, "addresses", new HashSet<>());
515
//        handleCollection(result, Contact.class, "", Address.class);
516
        setInvisible(result, "faxNumbers", new ArrayList<>());
517
        setInvisible(result, "phoneNumbers", new ArrayList<>());
518
        setInvisible(result, "emailAddresses", new ArrayList<>());
519
        setInvisible(result, "urls", new ArrayList<>());
520
        return result;
521
    }
522

    
523
    protected Person handlePersistedPerson(Person person, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
524
        Person result = handlePersisted((TeamOrPersonBase)person, state);
525
        //complete
526
        handleCollection(result, Person.class, "institutionalMemberships", InstitutionalMembership.class, state);
527
        return result;
528
    }
529

    
530
    protected NamedArea handlePersistedNamedArea(NamedArea area, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
531
        NamedArea result = handlePersisted((OrderedTermBase)area, state);
532
        //complete
533
        handleCollection(result, NamedArea.class, "countries", Country.class, state);
534
        result.setLevel(detache(result.getLevel(), state));
535
        result.setType(detache(result.getType(), state));
536
        result.setShape(detache(result.getShape(), state));
537
        return result;
538
    }
539

    
540
    protected Classification handlePersistedClassification(Classification classification, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
541
        Classification result = handlePersisted((IdentifiableEntity)classification, state);
542
        //complete
543
        result.setName(detache(classification.getName(), state));
544
        result.setReference(detache(classification.getReference(), state));
545
        result.setRootNode(detache(classification.getRootNode(), state));
546
        handleCollection(result, Classification.class, "geoScopes", NamedArea.class, state);
547
        handleMap(result, Classification.class, "description", Language.class, LanguageString.class, state);
548
        return result;
549
    }
550

    
551
    protected Reference handlePersistedReference(Reference reference, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
552
        Reference result = handlePersisted((IdentifiableMediaEntity)reference, state);
553
        result.setAuthorship(detache(result.getAuthorship(), state));
554
        result.setInstitution(detache(result.getInstitution(), state));
555
        result.setSchool(detache(result.getSchool(), state));
556
        result.setInReference(detache(result.getInReference(), state));
557
        return result;
558
    }
559

    
560
    protected SpecimenOrObservationBase<?> handlePersistedSpecimenOrObservationBase(SpecimenOrObservationBase specimen, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
561
        //TODO implement for classes
562
        SpecimenOrObservationBase<?> result = handlePersisted((IdentifiableEntity)specimen, state);
563
        //complete
564
        result.setSex(detache(result.getSex(), state));
565
        result.setLifeStage(detache(result.getLifeStage(), state));
566
        result.setKindOfUnit(detache(result.getKindOfUnit(), state));
567
        handleCollection(result, SpecimenOrObservationBase.class, "determinations", DeterminationEvent.class, state);
568
        handleCollection(result, SpecimenOrObservationBase.class, "descriptions", SpecimenDescription.class, state);
569
        handleCollection(result, SpecimenOrObservationBase.class, "derivationEvents", DerivationEvent.class, state);
570
        handleMap(result, SpecimenOrObservationBase.class, "definition", Language.class, LanguageString.class, state);
571
        return result;
572
    }
573

    
574
    protected IdentifiableSource handlePersistedIdentifiableSource(IdentifiableSource source, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
575
        IdentifiableSource result = handlePersisted((OriginalSourceBase)source, state);
576
        //complete
577
        return result;
578
    }
579

    
580
    protected <T extends NamedSourceBase> T handlePersisted(NamedSourceBase source, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
581
        T result = handlePersisted((OriginalSourceBase)source, state);
582
        //complete
583
        result.setNameUsedInSource(detache(result.getNameUsedInSource(), state));
584
        return result;
585
    }
586

    
587
    protected NamedSource handlePersistedNamedSource(NamedSource source, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
588
        NamedSource result = handlePersisted((NamedSourceBase)source, state);
589
        //complete
590
        return result;
591
    }
592

    
593
    protected SecundumSource handlePersistedSecundumSource(DescriptionElementSource source, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
594
        SecundumSource result = handlePersisted((NamedSourceBase)source, state);
595
        //TODO correct?
596
        result.setSourcedTaxon(detache(result.getSourcedTaxon(), state));
597
        return result;
598
    }
599

    
600
    protected DescriptionElementSource handlePersistedDescriptionElementSource(DescriptionElementSource source, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
601
        DescriptionElementSource result = handlePersisted((NamedSourceBase)source, state);
602
        //TODO correct?
603
        detache(result.getSourcedElement(), state).addSource(result);
604
        return result;
605
    }
606

    
607
    protected <T extends CommonTaxonName> T  handlePersistedCommonTaxonName(CommonTaxonName element, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
608
        T result = handlePersisted((DescriptionElementBase)element, state);
609
        //complete
610
        result.setLanguage(detache(result.getLanguage(), state));
611
        result.setArea(detache(result.getArea(), state));
612
        return result;
613
    }
614

    
615
    protected <T extends TextData> T  handlePersistedTextData(TextData element, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
616
        T result = handlePersisted((DescriptionElementBase)element, state);
617
        //complete
618
        result.setFormat(detache(result.getFormat(), state));
619
        handleMap(result, TextData.class, "multilanguageText", Language.class, LanguageString.class, state);
620
        return result;
621
    }
622

    
623
    protected <T extends Distribution> T  handlePersistedDistribution(Distribution element, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
624
        T result = handlePersisted((DescriptionElementBase)element, state);
625
        //complete
626
        result.setArea(detache(result.getArea(), state));
627
        result.setStatus(detache(result.getStatus(), state));
628
        return result;
629
    }
630

    
631
    protected ExtensionType handlePersistedExtensionType(ExtensionType term, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
632
        ExtensionType result = handlePersisted((DefinedTermBase)term, state);
633
        //complete
634
        return result;
635
    }
636

    
637
    protected MarkerType handlePersistedMarkerType(MarkerType term, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
638
        MarkerType result = handlePersisted((DefinedTermBase)term, state);
639
        //complete
640
        return result;
641
    }
642

    
643
    protected NomenclaturalStatusType handlePersistedNomenclaturalStatusType(NomenclaturalStatusType term, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
644
        NomenclaturalStatusType result = handlePersisted((OrderedTermBase)term, state);
645
        //complete
646
        return result;
647
    }
648

    
649
    protected DefinedTerm handlePersistedDefinedTerm(DefinedTerm term, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
650
        DefinedTerm result = handlePersisted((DefinedTermBase)term, state);
651
        //complete
652
        return result;
653
    }
654

    
655
    //placeholder for not implemented methods for subclasses
656
    protected DefinedTermBase<?> handlePersistedTerm(DefinedTermBase term, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
657
        DefinedTermBase<?> result = handlePersisted(term, state);
658
        logger.warn("Class not yet handled: " + term.getClass().getSimpleName());
659
        return result;
660
    }
661

    
662
    protected TermVocabulary<?> handlePersistedVocabulary(TermVocabulary voc, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
663
        TermVocabulary<?> result = (TermVocabulary<?>)handlePersisted((TermCollection)voc, state);
664
        handleCollection(result, TermVocabulary.class, "terms", DefinedTermBase.class, state);
665
        return result;
666
    }
667

    
668
    protected TermTree<?> handlePersistedTermTree(TermTree tree, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
669
        //TODO TermGraphBase is still missing
670
        TermTree<?> result = (TermTree<?>)handlePersisted((TermCollection)tree, state);
671
        //complete
672
        result.getRoot().setUuid(tree.getRoot().getUuid());
673
        return result;
674
    }
675

    
676
    protected TermNode<?> handlePersistedTermNode(TermNode node, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
677
        TermNode<?> result = (TermNode<?>)handlePersisted((TermRelationBase)node, state);
678
        //complete
679
        setInvisible(result, "parent", detache(result.getParent(), state));
680
        handleCollection(result, TermNode.class, "inapplicableIf", FeatureState.class, state);
681
        handleCollection(result, TermNode.class, "onlyApplicableIf", FeatureState.class, state);
682
        handleCollection(result, TermNode.class, "children", TermNode.class, state);
683

    
684
        return result;
685
    }
686

    
687
    protected Representation handlePersistedRepresentation(Representation representation, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
688
        Representation result = (Representation)handlePersisted((LanguageStringBase)representation, state);
689
        return result;
690
    }
691

    
692
    protected <T extends TermBase> T  handlePersisted(TermBase termBase, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
693
        T result = handlePersisted((IdentifiableEntity)termBase, state);
694
        //complete
695
        handleCollection(result, TermBase.class, "representations", Representation.class, state);
696
        return result;
697
    }
698

    
699
    protected <T extends TermCollection> T  handlePersisted(TermCollection termCollection, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
700
        T result = handlePersisted((TermBase)termCollection, state);
701
        //complete
702
        handleCollection(result, TermCollection.class, "termRelations", TermRelationBase.class, state);
703
        return result;
704
    }
705

    
706
    protected <T extends TermRelationBase> T  handlePersisted(TermRelationBase termRelationBase, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
707
        T result = handlePersisted((VersionableEntity)termRelationBase, state);
708
        result.setTerm(detache(result.getTerm(), state));
709
        setInvisible(result, TermRelationBase.class, "graph", detache(result.getGraph(), state));
710
        return result;
711
    }
712

    
713
    protected User handlePersistedUser(User user, Cdm2CdmImportState state) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
714
        User result = (User)handlePersistedCdmBase(user, state);
715
        if (result.getUsername().equals("admin")){
716
            result = getUserService().listByUsername("admin", MatchMode.EXACT, null, null, null, null, null).iterator().next();
717
            state.putPermanent(user.getUuid(), result);
718
            cache(result, state); //necessary?
719
            state.addToSave(result);
720
            state.removeToSave(user);
721
        }
722
        if (!result.isPersited()){
723
            result.setAuthorities(new HashSet<>());
724
            result.setGrantedAuthorities(new HashSet<>());
725
            setInvisible(result, "groups", new HashSet<>());
726
        }
727
        result.setPerson(detache(user.getPerson(), state));
728
        return result;
729
    }
730

    
731

    
732
    protected LanguageString handlePersistedLanguageString(LanguageString languageString, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
733
        LanguageString result = handlePersisted((LanguageStringBase)languageString, state);
734
        //complete
735
        handleCollection(result, LanguageString.class, "intextReferences", IntextReference.class, state);
736
        return result;
737
    }
738

    
739
    protected Rights handlePersistedRights(Rights rights, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
740
        Rights result = handlePersisted((LanguageStringBase)rights, state);
741
        result.setAgent(detache(rights.getAgent(), state));
742
        result.setType(detache(rights.getType(), state));
743
        //complete
744
        return result;
745
    }
746

    
747
    protected IntextReference handlePersistedIntextReference(IntextReference intextReference, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
748
        IntextReference result = handlePersisted((VersionableEntity)intextReference, state);
749
        result.setReferencedEntity(detache(result.getReferencedEntity(), false, state));
750
        Method targetMethod = IntextReference.class.getDeclaredMethod("setTarget", IIntextReferenceTarget.class);
751
        targetMethod.setAccessible(true);
752
        targetMethod.invoke(result, detache(result.getTarget(), false, state));
753
        return result;
754
    }
755

    
756
    protected <T extends TaxonDescription> T  handlePersistedTaxonDescription(TaxonDescription taxDescription, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
757
        T result = handlePersisted((DescriptionBase)taxDescription, state);
758
        //complete
759
        setInvisible(taxDescription, "taxon", detache(taxDescription.getTaxon(), state));
760
        handleCollection(taxDescription, TaxonDescription.class, "geoScopes", NamedArea.class, state);
761
        handleCollection(taxDescription, TaxonDescription.class, "scopes", DefinedTerm.class, state);
762
        return result;
763
    }
764

    
765
    protected <T extends TaxonDescription> T  handlePersistedTaxonNameDescription(TaxonNameDescription nameDescription, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
766
        T result = handlePersisted((DescriptionBase)nameDescription, state);
767
        //complete
768
        setInvisible(nameDescription, "taxonName", detache(nameDescription.getTaxonName(), state));
769
        return result;
770
    }
771

    
772

    
773
// ***************************** BASE CLASSES ********************************************/
774

    
775
    protected <T extends CdmBase> T handlePersistedCdmBase(CdmBase cdmBase, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
776
        T result = (T)getTarget(cdmBase, state);
777
        //complete
778
        cdmBase.setCreatedBy(detache(cdmBase.getCreatedBy(), state));
779
        return result;
780
    }
781

    
782
    protected <T extends VersionableEntity> T handlePersisted(VersionableEntity entity, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
783
        T result = (T)handlePersistedCdmBase((CdmBase)entity, state);
784
        //complete
785
        entity.setUpdatedBy(detache(entity.getUpdatedBy(), state));
786
        return result;
787
    }
788

    
789
    protected <T extends AnnotatableEntity> T handlePersisted(AnnotatableEntity entity, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
790
        T result = handlePersisted((VersionableEntity)entity, state);
791
        //complete
792
        handleCollection(result, AnnotatableEntity.class, "annotations", Annotation.class, state);
793
        handleCollection(result, AnnotatableEntity.class, "markers", Marker.class, state);
794
        return result;
795
    }
796

    
797
    protected <T extends SourcedEntityBase<?>> T  handlePersisted(SourcedEntityBase sourcedEntity,
798
            Cdm2CdmImportState state)
799
            throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
800
        int originalId = sourcedEntity.getId();
801
        T result = handlePersisted((AnnotatableEntity)sourcedEntity, state);
802
        //complete
803
        handleCollection(result, SourcedEntityBase.class, "sources", OriginalSourceBase.class, state);
804
        if (!result.isPersited()){
805
            if(state.getConfig().isRemoveImportSources()){
806
                filterImportSources(result.getSources());
807
            }
808
            if (state.getConfig().isAddSources()){
809
                Reference sourceRef = getSourceReference(state);
810
                OriginalSourceBase newSource = result.addImportSource(String.valueOf(originalId), sourcedEntity.getClass().getSimpleName(),
811
                        sourceRef, null);
812
                getCommonService().save(newSource);
813
                addExistingObject(newSource, state);
814
            }
815
        }
816
        return result;
817
    }
818

    
819
    /**
820
     * @param sources
821
     */
822
    private void filterImportSources(Set<? extends OriginalSourceBase> sources) {
823
        Set<OriginalSourceBase> toDelete = new HashSet<>();
824
        for (OriginalSourceBase osb: sources){
825
            if (osb.getType() == OriginalSourceType.Import){
826
                toDelete.add(osb);
827
            }
828
        }
829
        for (OriginalSourceBase osb: toDelete){
830
            sources.remove(osb);
831
        }
832
    }
833

    
834
    protected <T extends IdentifiableEntity> T  handlePersisted(IdentifiableEntity identifiableEntity, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
835
        T result = handlePersisted((SourcedEntityBase)identifiableEntity, state);
836
        //complete
837
        handleCollection(result, IdentifiableEntity.class, "credits", Credit.class, state);
838
        handleCollection(result, IdentifiableEntity.class, "extensions", Extension.class, state);
839
        handleCollection(result, IdentifiableEntity.class, "identifiers", Identifier.class, state);
840
        handleCollection(result, IdentifiableEntity.class, "rights", Rights.class, state);
841
        handleCollection(result, IdentifiableEntity.class, "links", ExternalLink.class, state);
842

    
843
        return result;
844
    }
845

    
846
    protected <T extends DefinedTermBase> T  handlePersisted(DefinedTermBase definedTermBase, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
847
        T result = handlePersisted((TermBase)definedTermBase, state);
848
        //complete
849
        handleCollection(result, DefinedTermBase.class, "media", Media.class, state);
850
        handleCollection(result, DefinedTermBase.class, "generalizationOf", DefinedTermBase.class, state);
851
        handleCollection(result, DefinedTermBase.class, "includes", DefinedTermBase.class, state);
852
        result.setKindOf(detache(result.getKindOf(), state));
853
        result.setPartOf(detache(result.getPartOf(), state));
854
        setInvisible(result, DefinedTermBase.class, "vocabulary", detache(result.getVocabulary(), state));
855

    
856
        return result;
857
    }
858

    
859
    protected <T extends OriginalSourceBase> T  handlePersisted(OriginalSourceBase source, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
860
        T result = handlePersisted((AnnotatableEntity)source, state);
861
        //complete
862
        result.setCitation(detache(result.getCitation(), state));
863
        handleCollection(result, OriginalSourceBase.class, "links", ExternalLink.class, state);
864
        return result;
865
    }
866

    
867
    protected <T extends LanguageStringBase> T  handlePersisted(LanguageStringBase lsBase, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
868
        T result = handlePersisted((AnnotatableEntity)lsBase, state);
869
        //complete
870
        result.setLanguage(detache(lsBase.getLanguage(), state));
871
        return result;
872
    }
873

    
874
    protected <T extends TeamOrPersonBase> T  handlePersisted(TeamOrPersonBase teamOrPerson, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
875
        T result = handlePersisted((AgentBase)teamOrPerson, state);
876
        //complete
877
        return result;
878
    }
879

    
880
    protected <T extends AgentBase> T  handlePersisted(AgentBase agent, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
881
        T result = handlePersisted((IdentifiableMediaEntity)agent, state);
882
        result.setContact(detache(result.getContact(), state));
883
        //complete
884
        return result;
885
    }
886

    
887
    protected <T extends TaxonBase> T  handlePersisted(TaxonBase taxonBase, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
888
        T result = handlePersisted((IdentifiableEntity)taxonBase, state);
889
        //complete
890
        result.setName(detache(taxonBase.getName(), state));
891
        result.setSec(detache(taxonBase.getSec(), state));
892
        return result;
893
    }
894

    
895
    protected <T extends IdentifiableMediaEntity> T  handlePersisted(IdentifiableMediaEntity mediaEntity, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
896
        T result = handlePersisted((IdentifiableEntity)mediaEntity, state);
897
        //complete
898
        handleCollection(result, IdentifiableMediaEntity.class, "media", Media.class, state);
899
        return result;
900
    }
901

    
902
    protected <T extends SingleSourcedEntityBase> T  handlePersisted(SingleSourcedEntityBase referencedEntity, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
903
        T result = handlePersisted((AnnotatableEntity)referencedEntity, state);
904
        //complete
905
        result.setCitation(detache(result.getCitation(), state));
906
        return result;
907
    }
908

    
909
    protected <T extends DescriptionBase> T  handlePersisted(DescriptionBase descriptionBase, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
910
        T result = handlePersisted((IdentifiableEntity)descriptionBase, state);
911
        //complete
912
        handleCollection(result, DescriptionBase.class, "descriptionElements", DescriptionElementBase.class, state);
913
        handleCollection(result, DescriptionBase.class, "descriptiveDataSets", DescriptiveDataSet.class, state);
914
        handleCollection(result, DescriptionBase.class, "descriptionSources", Reference.class, state);
915
        result.setDescribedSpecimenOrObservation(detache(descriptionBase.getDescribedSpecimenOrObservation(), state));
916
        return result;
917
    }
918

    
919
    protected <T extends DescriptionElementBase> T  handlePersisted(DescriptionElementBase element, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
920
        T result = handlePersisted((AnnotatableEntity)element, state);
921
        //complete
922
        result.setFeature(detache(result.getFeature(), state));
923
        setInvisible(result, DescriptionElementBase.class, "inDescription", detache(result.getInDescription(), state));
924
        handleCollection(result, DescriptionElementBase.class, "sources", DescriptionElementSource.class, state);
925
        handleCollection(result, DescriptionElementBase.class, "media", Media.class, state);
926
        handleCollection(result, DescriptionElementBase.class, "modifiers", DefinedTerm.class, state);
927
        handleMap(result, DescriptionElementBase.class, "modifyingText", Language.class, LanguageString.class, state);
928

    
929
        return result;
930
    }
931

    
932
    protected <T extends RelationshipBase> T  handlePersisted(RelationshipBase relBase, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
933
        T result = handlePersisted((SingleSourcedEntityBase)relBase, state);
934
        return result;
935
    }
936

    
937

    
938
//************************** COLLECTIONS / MAPS ****************************************/
939

    
940
    protected <HOLDER extends CdmBase, ITEM extends CdmBase> void handleCollection(
941
            HOLDER holder, Class<? super HOLDER> declaringClass, String parameter, Class<ITEM> itemClass,
942
            Cdm2CdmImportState state)
943
            throws NoSuchFieldException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
944

    
945
        Collection<ITEM> oldCollection = setNewCollection(holder, declaringClass, parameter, itemClass);
946
        Collection<ITEM> newCollection = getTargetCollection(itemClass, oldCollection, state);
947
        Field field = declaringClass.getDeclaredField(parameter);
948
        field.setAccessible(true);
949
        field.set(holder, newCollection);
950
    }
951

    
952
    protected <HOLDER extends CdmBase, KEY extends CdmBase, ITEM extends CdmBase>
953
            void handleMap(
954
            HOLDER holder, Class<? super HOLDER> declaringClass, String parameter,
955
            Class<KEY> keyClass, Class<ITEM> itemClass, Cdm2CdmImportState state)
956
            throws NoSuchFieldException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
957

    
958
        //TODO we do not need to set the new map 2x
959
        Map<KEY,ITEM> oldMap = setNewMap(holder, declaringClass, parameter, keyClass, itemClass);
960
        Map<KEY,ITEM> newMap = getTargetMap(oldMap, state);
961
        Field field = declaringClass.getDeclaredField(parameter);
962
        field.setAccessible(true);
963
        field.set(holder, newMap);
964
    }
965

    
966
    protected <T extends CdmBase> Collection<T> setNewCollection(CdmBase obj, Class<?> holderClass,
967
            String parameter, Class<T> entityClass) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
968
        Field field = holderClass.getDeclaredField(parameter);
969
        field.setAccessible(true);
970
        Collection<T> oldValue = (Collection<T>)field.get(obj);
971
        Collection<T> newValue = null;
972
        if (Set.class.isAssignableFrom(field.getType())){
973
            newValue = new HashSet<>();
974
        }else if (List.class.isAssignableFrom(field.getType())){
975
            newValue = new ArrayList<>();
976
        }else{
977
            throw new RuntimeException("Unsupported collection type: " + field.getType().getCanonicalName());
978
        }
979
        field.set(obj, newValue);
980
        return oldValue;
981
    }
982

    
983
    protected <KEY extends CdmBase, ITEM extends CdmBase> Map<KEY,ITEM> setNewMap(CdmBase obj, Class<?> holderClass,
984
            String parameter, Class<KEY> keyClass, Class<ITEM> itemClass) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
985
        Field field = holderClass.getDeclaredField(parameter);
986
        field.setAccessible(true);
987
        Map<KEY,ITEM> oldValue = (Map<KEY,ITEM>)field.get(obj);
988
        Map<KEY,ITEM> newValue = null;
989
        if (Map.class.isAssignableFrom(field.getType())){
990
            newValue = new HashMap<>();
991
        }else{
992
            throw new RuntimeException("Unsupported map type: " + field.getType().getCanonicalName());
993
        }
994
        field.set(obj, newValue);
995
        return oldValue;
996
    }
997

    
998

    
999
    private <T extends Collection<S>, S extends CdmBase> Collection<S> getTargetCollection(
1000
            Class<S> clazz, T sourceCollection, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
1001
        Collection<S> result =  new ArrayList<>();
1002
        if (Set.class.isAssignableFrom(sourceCollection.getClass())){
1003
            result = new HashSet<>();
1004
        }
1005
        for (S entity : sourceCollection){
1006
            S target = detache(entity, state);
1007
            result.add(target);
1008
        }
1009
        return result;
1010
    }
1011

    
1012
    private <K extends CdmBase, V extends CdmBase> Map<K,V> getTargetMap(Map<K,V> sourceMap, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
1013
        Map<K,V> result = new HashMap<>();
1014
        for (K key : sourceMap.keySet()){
1015
            K targetKey = detache(key, state);
1016
            V targetValue = detache(sourceMap.get(key), state);
1017
            result.put(targetKey, targetValue);
1018
        }
1019
        return result;
1020
    }
1021

    
1022
// ****************************** INVISIBLE **************************************/
1023

    
1024
    protected void setInvisible(Object holder, String fieldName, Object value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
1025
        setInvisible(holder, holder.getClass(), fieldName, value);
1026
    }
1027
    protected void setInvisible(Object holder, Class<?> holderClazz, String fieldName, Object value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
1028
        Field field = holderClazz.getDeclaredField(fieldName);
1029
        field.setAccessible(true);
1030
        field.set(holder, value);
1031
    }
1032

    
1033
// ************************* GET TARGET ******************************************/
1034

    
1035

    
1036
    //TODO this should be cached for partition
1037
    private <T extends CdmBase> T getTarget(T source, Cdm2CdmImportState state) {
1038
        if (source == null){
1039
            return null;
1040
        }
1041
        T result = getCached(source, state);
1042
//        if (result == null){
1043
//            Class<T> clazz = (Class<T>)source.getClass();
1044
//            result = getCommonService().find(clazz, source.getUuid());
1045
//        }
1046
        if (result == null){
1047
            //Alternative: clone?
1048
            result = CdmBase.deproxy(source);
1049
            result.setId(0);
1050
            cache(result, state);
1051
            state.addToSave(result);
1052
        }
1053
        return result;
1054
    }
1055

    
1056
// ******************* CACHE *******************************************************/
1057

    
1058

    
1059
    protected void cache(CdmBase cdmBase, Cdm2CdmImportState state) {
1060
       if (cdmBase instanceof User || cdmBase instanceof DefinedTermBase){
1061
           state.putPermanent(cdmBase.getUuid(), cdmBase);
1062
       }else{
1063
           state.putToSessionCache(cdmBase);
1064
       }
1065
       addExistingObject(cdmBase, state);
1066

    
1067
    }
1068

    
1069
    private void addExistingObject(CdmBase cdmBase, Cdm2CdmImportState state) {
1070
        cdmBase = CdmBase.deproxy(cdmBase);
1071
        Set<UUID> set = state.getExistingObjects(cdmBase.getClass());
1072
        if (set == null){
1073
            set = loadExistingUuids(cdmBase.getClass(), state);
1074
//            set = new HashSet<>();
1075
//            existingObjects.put(cdmBase.getClass(), set);
1076
        }
1077
        set.add(cdmBase.getUuid());
1078
    }
1079

    
1080
    protected boolean isInCache(CdmBase cdmBase, Cdm2CdmImportState state) {
1081
        return getCached(cdmBase, state) != null;
1082
    }
1083

    
1084
    protected <T extends CdmBase> T getCached(T cdmBase, Cdm2CdmImportState state) {
1085
        T result = (T)state.getFromSessionCache(cdmBase.getUuid());
1086
        if (result == null){
1087
            result = (T)state.getPermanent(cdmBase.getUuid());
1088
        }
1089
        return result;
1090
    }
1091

    
1092
    protected void clearCache(Cdm2CdmImportState state) {
1093
        state.clearSessionCache();
1094
    }
1095

    
1096
    private Reference getSourceReference(Cdm2CdmImportState state) {
1097
        UUID uuid = state.getConfig().getSourceRefUuid();
1098
        if (uuid == null && state.getConfig().getSourceReference() != null){
1099
            uuid = state.getConfig().getSourceReference().getUuid();
1100
            state.getConfig().setSourceRefUuid(uuid);
1101
        }
1102
        Reference result = (Reference)state.getFromSessionCache(uuid);
1103
        if (result == null){
1104
            result = (Reference)state.getPermanent(uuid);
1105
        }
1106
        if (result == null){
1107
            result = getReferenceService().find(uuid);
1108
        }
1109

    
1110
        if (result == null){
1111
            result = state.getConfig().getSourceReference();
1112
            if (result == null){
1113
                result = ReferenceFactory.newDatabase();
1114
                //TODO
1115
                result.setTitle("Cdm2Cdm Import");
1116
            }
1117
            getReferenceService().save(result);
1118
            state.putToSessionCache(result);
1119
        }
1120
        return result;
1121
    }
1122

    
1123

    
1124
    protected ITaxonNodeOutStreamPartitioner getTaxonNodePartitioner(Cdm2CdmImportState state, IProgressMonitor monitor,
1125
            Cdm2CdmImportConfigurator config) {
1126
        ITaxonNodeOutStreamPartitioner partitioner = config.getPartitioner();
1127
        if (partitioner == null){
1128
            if(!config.isConcurrent()){
1129
                partitioner = TaxonNodeOutStreamPartitioner.NewInstance(sourceRepo(state), state,
1130
                        state.getConfig().getTaxonNodeFilter(), 100,
1131
                        monitor, 1, TaxonNodeOutStreamPartitioner.fullPropertyPaths);
1132
                ((TaxonNodeOutStreamPartitioner)partitioner).setLastCommitManually(true);
1133
            }else{
1134
                partitioner = TaxonNodeOutStreamPartitionerConcurrent
1135
                        .NewInstance(state.getConfig().getSource(), state.getConfig().getTaxonNodeFilter(),
1136
                                1000, monitor, 1, TaxonNodeOutStreamPartitioner.fullPropertyPaths);
1137
            }
1138
        }
1139
        return partitioner;
1140
    }
1141

    
1142
}
(2-2/6)