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;
24
import org.apache.logging.log4j.Logger;
25

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

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

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

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

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

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

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

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

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

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

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

    
301

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
437

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

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

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

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

    
465
        return result;
466
    }
467

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
685
        return result;
686
    }
687

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

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

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

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

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

    
732

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

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

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

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

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

    
773

    
774
// ***************************** BASE CLASSES ********************************************/
775

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

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

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

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

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

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

    
844
        return result;
845
    }
846

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

    
857
        return result;
858
    }
859

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

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

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

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

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

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

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

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

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

    
930
        return result;
931
    }
932

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

    
938

    
939
//************************** COLLECTIONS / MAPS ****************************************/
940

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

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

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

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

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

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

    
999

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

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

    
1023
// ****************************** INVISIBLE **************************************/
1024

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

    
1034
// ************************* GET TARGET ******************************************/
1035

    
1036

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

    
1057
// ******************* CACHE *******************************************************/
1058

    
1059

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

    
1068
    }
1069

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

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

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

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

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

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

    
1124

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

    
1143
}
(2-2/6)