Project

General

Profile

Download (66.4 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 detach(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 detach(IIntextReferencable cdmBase, boolean onlyForDefinedSignature, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
164
        return (IIntextReferencable)detach((CdmBase)cdmBase, state);
165
    }
166
    protected  IIntextReferenceTarget detach(IIntextReferenceTarget cdmBase, boolean onlyForDefinedSignature, Cdm2CdmImportState state) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
167
        return (IIntextReferenceTarget)detach((CdmBase)cdmBase, state);
168
    }
169

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

    
174
    protected <T extends CdmBase> T detach(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(detach(result.getTaxon(), state));
311
        result.setCitation(detach(node.getReference(), state));
312
        result.setSynonymToBeUsed(detach(result.getSynonymToBeUsed(), state));
313
        handleMap(result, TaxonNode.class, "excludedNote", Language.class, LanguageString.class, state);
314
        //classification, parent, children
315
        this.setInvisible(node, "classification", detach(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 = detach(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", detach(result.getAcceptedTaxon(), state));
359
        result.setType(detach(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(detach(result.getFromTaxon(), state));
367
        result.setToTaxon(detach(result.getToTaxon(), state));
368
        result.setType(detach(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", detach(result.getFromName(), state));
376
        setInvisible(result, "relatedTo", detach(result.getToName(), state));
377
//        result.setFromName(detache(result.getFromName(), state));
378
//        result.setToName(detache(result.getToName(), state));
379
        result.setType(detach(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", detach(result.getParentName(), state));
387
        setInvisible(result, "relatedTo", detach(result.getHybridName(), state));
388
//        result.setFromName(detache(result.getFromName()));
389
//        result.setToName(detache(result.getToName()));
390
        result.setType(detach(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(detach(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(detach(result.getCitation(), state));
405
        handleCollection(result, TypeDesignationBase.class, "registrations", Registration.class, state);
406
        handleCollection(result, TypeDesignationBase.class, "typifiedNames", TaxonName.class, state);
407
        result.setTypeStatus(detach(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", detach(result.getPerson(), state));
416
        result.setInstitute(detach(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(detach(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(detach(result.getAgent(), state));
432
        result.setType(detach(result.getType(), state));
433
        setInvisible(result, "taxonNode", detach(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(detach(result.getRank(), state));
443
        result.setCombinationAuthorship(detach(result.getCombinationAuthorship(), state));
444
        result.setExCombinationAuthorship(detach(result.getExCombinationAuthorship(), state));
445
        result.setBasionymAuthorship(detach(result.getBasionymAuthorship(), state));
446
        result.setExBasionymAuthorship(detach(result.getExBasionymAuthorship(), state));
447
        result.setInBasionymAuthorship(detach(result.getInBasionymAuthorship(), state));
448
        result.setInCombinationAuthorship(detach(result.getInCombinationAuthorship(), state));
449

    
450
        result.setNomenclaturalReference(detach(result.getNomenclaturalReference(), state));
451
        result.setNomenclaturalSource(detach(result.getNomenclaturalSource(), state));
452
        result.setHomotypicalGroup(detach(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(detach(annotation.getAnnotationType(), state));
479
        result.setCommentator(detach(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(detach(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(detach(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(detach(result.getLevel(), state));
536
        result.setType(detach(result.getType(), state));
537
        result.setShape(detach(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(detach(classification.getName(), state));
545
        result.setReference(detach(classification.getReference(), state));
546
        result.setRootNode(detach(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(detach(result.getAuthorship(), state));
555
        result.setInstitution(detach(result.getInstitution(), state));
556
        result.setSchool(detach(result.getSchool(), state));
557
        result.setInReference(detach(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(detach(result.getSex(), state));
566
        result.setLifeStage(detach(result.getLifeStage(), state));
567
        result.setKindOfUnit(detach(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(detach(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(detach(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
        detach(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(detach(result.getLanguage(), state));
612
        result.setArea(detach(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(detach(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(detach(result.getArea(), state));
628
        result.setStatus(detach(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", detach(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(detach(result.getTerm(), state));
710
        setInvisible(result, TermRelationBase.class, "graph", detach(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
            //TODO why only admin, is this not a problem for all duplicated usernames? Was this a preliminary decision?
718
            result = getUserService().listByUsername("admin", MatchMode.EXACT, null, null, null, null, null).iterator().next();
719
            state.putPermanent(user.getUuid(), result);
720
            cache(result, state); //necessary?
721
            state.addToSave(result);
722
            state.removeToSave(user);
723
        }
724
        if (!result.isPersited()){
725
            result.setAuthorities(new HashSet<>());
726
            result.setGrantedAuthorities(new HashSet<>());
727
            setInvisible(result, "groups", new HashSet<>());
728
        }
729
        result.setPerson(detach(user.getPerson(), state));
730
        return result;
731
    }
732

    
733

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

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

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

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

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

    
774

    
775
// ***************************** BASE CLASSES ********************************************/
776

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

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

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

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

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

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

    
845
        return result;
846
    }
847

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

    
858
        return result;
859
    }
860

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

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

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

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

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

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

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

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

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

    
931
        return result;
932
    }
933

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

    
939

    
940
//************************** COLLECTIONS / MAPS ****************************************/
941

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

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

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

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

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

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

    
1000

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

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

    
1024
// ****************************** USER HANDLING
1025

    
1026
    private User makeCreatedUpdatedBy(User createdByOriginal, Cdm2CdmImportState state, boolean isUpdatedBy) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
1027
        UserImportMode mode = isUpdatedBy? state.getConfig().getUpdatedByMode() : state.getConfig().getCreatedByMode();
1028

    
1029
        switch (mode) {
1030
        case NONE:
1031
            return null;
1032
        case ORIGINAL:
1033
            return detach(createdByOriginal, state);
1034
        default:
1035
            logger.warn("Mode not yet supported: " + mode);
1036
            return null;
1037
        }
1038
    }
1039

    
1040

    
1041
// ****************************** INVISIBLE **************************************/
1042

    
1043
    protected void setInvisible(Object holder, String fieldName, Object value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
1044
        setInvisible(holder, holder.getClass(), fieldName, value);
1045
    }
1046
    protected void setInvisible(Object holder, Class<?> holderClazz, String fieldName, Object value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
1047
        Field field = holderClazz.getDeclaredField(fieldName);
1048
        field.setAccessible(true);
1049
        field.set(holder, value);
1050
    }
1051

    
1052
// ************************* GET TARGET ******************************************/
1053

    
1054

    
1055
    //TODO this should be cached for partition
1056
    private <T extends CdmBase> T getTarget(T source, Cdm2CdmImportState state) {
1057
        if (source == null){
1058
            return null;
1059
        }
1060
        T result = getCached(source, state);
1061
//        if (result == null){
1062
//            Class<T> clazz = (Class<T>)source.getClass();
1063
//            result = getCommonService().find(clazz, source.getUuid());
1064
//        }
1065
        if (result == null){
1066
            //Alternative: clone?
1067
            result = CdmBase.deproxy(source);
1068
            result.setId(0);
1069
            cache(result, state);
1070
            state.addToSave(result);
1071
        }
1072
        return result;
1073
    }
1074

    
1075
// ******************* CACHE *******************************************************/
1076

    
1077
    protected void cache(CdmBase cdmBase, Cdm2CdmImportState state) {
1078
       if (cdmBase instanceof User || cdmBase instanceof DefinedTermBase){
1079
           state.putPermanent(cdmBase.getUuid(), cdmBase);
1080
       }else{
1081
           state.putToSessionCache(cdmBase);
1082
       }
1083
       addExistingObject(cdmBase, state);
1084
    }
1085

    
1086
    private void addExistingObject(CdmBase cdmBase, Cdm2CdmImportState state) {
1087
        cdmBase = CdmBase.deproxy(cdmBase);
1088
        Set<UUID> set = state.getExistingObjects(cdmBase.getClass());
1089
        if (set == null){
1090
            set = loadExistingUuids(cdmBase.getClass(), state);
1091
//            set = new HashSet<>();
1092
//            existingObjects.put(cdmBase.getClass(), set);
1093
        }
1094
        set.add(cdmBase.getUuid());
1095
    }
1096

    
1097
    protected boolean isInCache(CdmBase cdmBase, Cdm2CdmImportState state) {
1098
        return getCached(cdmBase, state) != null;
1099
    }
1100

    
1101
    protected <T extends CdmBase> T getCached(T cdmBase, Cdm2CdmImportState state) {
1102
        T result = (T)state.getFromSessionCache(cdmBase.getUuid());
1103
        if (result == null){
1104
            result = (T)state.getPermanent(cdmBase.getUuid());
1105
        }
1106
        return result;
1107
    }
1108

    
1109
    protected void clearCache(Cdm2CdmImportState state) {
1110
        state.clearSessionCache();
1111
    }
1112

    
1113
    private Reference getSourceReference(Cdm2CdmImportState state) {
1114
        UUID uuid = state.getConfig().getSourceRefUuid();
1115
        if (uuid == null && state.getConfig().getSourceReference() != null){
1116
            uuid = state.getConfig().getSourceReference().getUuid();
1117
            state.getConfig().setSourceRefUuid(uuid);
1118
        }
1119
        Reference result = (Reference)state.getFromSessionCache(uuid);
1120
        if (result == null){
1121
            result = (Reference)state.getPermanent(uuid);
1122
        }
1123
        if (result == null){
1124
            result = getReferenceService().find(uuid);
1125
        }
1126

    
1127
        if (result == null){
1128
            result = state.getConfig().getSourceReference();
1129
            if (result == null){
1130
                result = ReferenceFactory.newDatabase();
1131
                //TODO
1132
                result.setTitle("Cdm2Cdm Import");
1133
            }
1134
            getReferenceService().save(result);
1135
            state.putToSessionCache(result);
1136
        }
1137
        return result;
1138
    }
1139

    
1140

    
1141
    protected ITaxonNodeOutStreamPartitioner getTaxonNodePartitioner(Cdm2CdmImportState state, IProgressMonitor monitor,
1142
            Cdm2CdmImportConfigurator config) {
1143
        ITaxonNodeOutStreamPartitioner partitioner = config.getPartitioner();
1144
        if (partitioner == null){
1145
            if(!config.isConcurrent()){
1146
                partitioner = TaxonNodeOutStreamPartitioner.NewInstance(sourceRepo(state), state,
1147
                        state.getConfig().getTaxonNodeFilter(), 100,
1148
                        monitor, 1, TaxonNodeOutStreamPartitioner.fullPropertyPaths);
1149
                ((TaxonNodeOutStreamPartitioner)partitioner).setLastCommitManually(true);
1150
            }else{
1151
                partitioner = TaxonNodeOutStreamPartitionerConcurrent
1152
                        .NewInstance(state.getConfig().getSource(), state.getConfig().getTaxonNodeFilter(),
1153
                                1000, monitor, 1, TaxonNodeOutStreamPartitioner.fullPropertyPaths);
1154
            }
1155
        }
1156
        return partitioner;
1157
    }
1158

    
1159
}
(2-2/7)