Project

General

Profile

Download (55.7 KB) Statistics
| Branch: | 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.pesi.fauEu2Cdm;
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.log4j.Logger;
24

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

    
107
/**
108
 * @author a.mueller
109
 * @since 17.08.2019
110
 */
111
public abstract class FauEu2CdmImportBase
112
        extends CdmImportBase<FauEu2CdmImportConfigurator, FauEu2CdmImportState> {
113

    
114
    private static final long serialVersionUID = 8917991155285743172L;
115
    private static final Logger logger = Logger.getLogger(FauEu2CdmImportBase.class);
116

    
117
    //quick and dirty
118
    private FauEu2CdmImportState state;
119

    
120
    //TODO move to state
121
    private Map<UUID, CdmBase> sessionCache = new HashMap<>();
122

    
123

    
124
    protected Set<CdmBase> toSave = new HashSet<>();
125

    
126
    protected ICdmRepository sourceRepo(FauEu2CdmImportState state){
127
        ICdmRepository repo = state.getSourceRepository();
128
        if (repo == null){
129
            System.out.println("start source repo");
130
            boolean omitTermLoading = true;
131
            repo = CdmApplicationController.NewInstance(state.getConfig().getSource(),
132
                    DbSchemaValidation.VALIDATE, omitTermLoading);
133
            state.setSourceRepository(repo);
134
            System.out.println("end source repo");
135
        }
136
        return repo;
137
    }
138

    
139
    protected  Contact detache(Contact contact) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
140
        contact = CdmBase.deproxy(contact);
141
        if (contact == null){
142
            return contact;
143
        }else{
144
            return handlePersistedContact(contact);
145
        }
146
    }
147

    
148
    protected  IIntextReferencable detache(IIntextReferencable cdmBase, boolean onlyForDefinedSignature) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
149
        return (IIntextReferencable)detache((CdmBase)cdmBase);
150
    }
151
    protected  IIntextReferenceTarget detache(IIntextReferenceTarget cdmBase, boolean onlyForDefinedSignature) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
152
        return (IIntextReferenceTarget)detache((CdmBase)cdmBase);
153
    }
154

    
155
    protected <T extends CdmBase> T detache(T cdmBase) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
156
        return detache(cdmBase, false);
157
    }
158

    
159
    private Map<Class,Set<UUID>> existingObjects = new HashMap<>();
160
    protected <T extends CdmBase> T detache(T cdmBase, boolean notFromSource) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
161
        cdmBase = CdmBase.deproxy(cdmBase);
162
        if (cdmBase == null ){
163
            return cdmBase;
164
        }else if(isInCache(cdmBase)){
165
            return getCached(cdmBase);
166
        }else {
167
            if (existingObjects.get(cdmBase.getClass()) == null){
168
                loadExistingUuids(cdmBase.getClass());
169
            }
170
            boolean exists = existingObjects.get(cdmBase.getClass()).contains(cdmBase.getUuid());
171
            if (exists){
172
                Class<T> clazz = (Class<T>)cdmBase.getClass();
173
                T existingObj = getCommonService().find(clazz, cdmBase.getUuid());
174
                if (existingObj != null){
175
                    cache(existingObj);
176
                    return existingObj;
177
                }else{
178
                    logger.warn("Object should exist already but does not exist in target. This should not happen: " + cdmBase.getClass().getSimpleName() + "/" + cdmBase.getUuid());
179
                }
180
            }
181
        }
182
        if ( !cdmBase.isPersited()){
183
            logger.warn("Non persisted object not in cache and not in target DB. This should not happen: " + cdmBase.getUuid());
184
            return cdmBase; //should not happen anymore; either in cache or in target or persisted in source
185
        }else{
186
            return notFromSource? null : (T)handlePersisted(cdmBase);
187
        }
188
    }
189

    
190
    /**
191
     * @param class1
192
     * @return
193
     */
194
    private Set<UUID> loadExistingUuids(Class<? extends CdmBase> clazz) {
195
        List<UUID> list = getCommonService().listUuid(clazz);
196
        Set<UUID> result = new HashSet<>(list);
197
        existingObjects.put(clazz, result);
198
        return result;
199
    }
200

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

    
287

    
288
    protected TaxonNode handlePersistedTaxonNode(TaxonNode node) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
289

    
290
        TaxonNode result = handlePersisted((AnnotatableEntity)node);
291
        if (result ==null){
292
            return result;
293
        }
294
        //complete
295
        handleCollection(result, TaxonNode.class, "agentRelations", TaxonNodeAgentRelation.class);
296
        result.setTaxon(detache(result.getTaxon()));
297
        result.setReference(detache(node.getReference()));
298
        result.setSynonymToBeUsed(detache(result.getSynonymToBeUsed()));
299
        handleMap(result, TaxonNode.class, "excludedNote", Language.class, LanguageString.class);
300
        //classification, parent, children
301
        this.setInvisible(node, "classification", detache(node.getClassification()));
302
        handleParentTaxonNode(result);
303
        setNewCollection(node, TaxonNode.class, "childNodes", TaxonNode.class);
304
        return result;
305
    }
306

    
307
    private void handleParentTaxonNode(TaxonNode childNode) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
308
        TaxonNode parent = detache(childNode.getParent(), true);
309
        //TODO
310
        String microReference = null;
311
        Reference reference = null;
312
        if (parent == null && childNode.getClassification().getRootNode().equals(childNode)){
313
            //do nothing
314
        }else if (parent == null ){
315
            childNode.getClassification().addChildNode(childNode, reference, microReference) ;
316
        }else{
317
            parent.addChildNode(childNode, reference, microReference);
318
        }
319
    }
320

    
321
    protected Taxon handlePersistedTaxon(Taxon taxon) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
322
        Taxon result = handlePersisted((TaxonBase)taxon);
323
        //complete
324
        handleCollection(result, Taxon.class, "synonyms", Synonym.class);
325
//        handleCollection(result, Taxon.class, "taxonNodes", TaxonNode.class);
326
        setNewCollection(result, Taxon.class, "taxonNodes", TaxonNode.class);
327
        handleCollection(result, Taxon.class, "relationsFromThisTaxon", TaxonRelationship.class);
328
        handleCollection(result, Taxon.class, "relationsToThisTaxon", TaxonRelationship.class);
329
        if (this.doDescriptions(state)){
330
            handleCollection(result, Taxon.class, "descriptions", TaxonDescription.class);
331
        }else{
332
            setNewCollection(result, Taxon.class, "descriptions", TaxonDescription.class);
333
        }
334
        return result;
335
    }
336

    
337
    protected boolean doDescriptions(FauEu2CdmImportState state) {
338
        return false;
339
    }
340

    
341
    protected Synonym handlePersistedSynonym(Synonym synonym) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
342
        Synonym result = handlePersisted((TaxonBase)synonym);
343
        //complete
344
        setInvisible(result, "acceptedTaxon", detache(result.getAcceptedTaxon()));
345
        result.setType(detache(result.getType()));
346
        return result;
347
    }
348

    
349
    protected TaxonRelationship handlePersistedTaxonRelationship(TaxonRelationship taxRel) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
350
        TaxonRelationship result = handlePersisted((RelationshipBase)taxRel);
351
        //complete
352
        result.setFromTaxon(detache(result.getFromTaxon()));
353
        result.setToTaxon(detache(result.getToTaxon()));
354
        result.setType(detache(result.getType()));
355
        return result;
356
    }
357

    
358
    protected NameRelationship handlePersistedNameRelationship(NameRelationship rel) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
359
        NameRelationship result = handlePersisted((RelationshipBase)rel);
360
        //complete
361
        setInvisible(result, "relatedFrom", detache(result.getFromName()));
362
        setInvisible(result, "relatedTo", detache(result.getToName()));
363
//        result.setFromName(detache(result.getFromName()));
364
//        result.setToName(detache(result.getToName()));
365
        result.setType(detache(result.getType()));
366
        return result;
367
    }
368

    
369
    protected HybridRelationship handlePersistedHybridRelationship(HybridRelationship rel) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
370
        HybridRelationship result = handlePersisted((RelationshipBase)rel);
371
        //complete
372
        setInvisible(result, "relatedFrom", detache(result.getParentName()));
373
        setInvisible(result, "relatedTo", detache(result.getHybridName()));
374
//        result.setFromName(detache(result.getFromName()));
375
//        result.setToName(detache(result.getToName()));
376
        result.setType(detache(result.getType()));
377
        return result;
378
    }
379

    
380
    protected NomenclaturalStatus handlePersistedNomenclaturalStatus(NomenclaturalStatus status) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
381
        NomenclaturalStatus result = handlePersisted((ReferencedEntityBase)status);
382
        //complete
383
        result.setType(detache(result.getType()));
384
        return result;
385
    }
386

    
387
    protected TypeDesignationBase handlePersistedTypeDesignationBase(TypeDesignationBase<?> designation) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
388
        TypeDesignationBase result = handlePersisted((SourcedEntityBase)designation);
389
        //complete
390
        result.setCitation(detache(result.getCitation()));
391
        handleCollection(result, TypeDesignationBase.class, "registrations", Registration.class);
392
        handleCollection(result, TypeDesignationBase.class, "typifiedNames", TaxonName.class);
393
        result.setTypeStatus(detache(result.getTypeStatus()));
394
        return result;
395
    }
396

    
397
    protected InstitutionalMembership handlePersistedInstitutionalMembership(InstitutionalMembership institutionalMembership) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
398
        InstitutionalMembership result = handlePersisted((VersionableEntity)institutionalMembership);
399
        //complete
400
//        result.setPerson(detache(result.getPerson()));
401
        setInvisible(result, "person", detache(result.getPerson()));
402
        result.setInstitute(detache(result.getInstitute()));
403
        return result;
404
    }
405

    
406
    protected Institution handlePersistedInstitution(Institution institution) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
407
        Institution result = handlePersisted((AgentBase)institution);
408
        //complete
409
        result.setIsPartOf(detache(result.getIsPartOf()));
410
        handleCollection(result, Institution.class, "types", DefinedTerm.class);
411
        return result;
412
    }
413

    
414
    protected TaxonNodeAgentRelation handlePersistedTaxonNodeAgentRelation(TaxonNodeAgentRelation nodeAgentRel) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
415
        TaxonNodeAgentRelation result = handlePersisted((AnnotatableEntity)nodeAgentRel);
416
        //complete
417
        result.setAgent(detache(result.getAgent()));
418
        result.setType(detache(result.getType()));
419
        setInvisible(result, "taxonNode", detache(result.getTaxonNode()));
420
        return result;
421
    }
422

    
423

    
424
    protected TaxonName handlePersistedTaxonName(TaxonName taxonName) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
425
        @SuppressWarnings("rawtypes")
426
        TaxonName result = handlePersisted((IdentifiableEntity)taxonName);
427
        //complete
428
        result.setRank(detache(result.getRank()));
429
        result.setCombinationAuthorship(detache(result.getCombinationAuthorship()));
430
        result.setExCombinationAuthorship(detache(result.getExCombinationAuthorship()));
431
        result.setBasionymAuthorship(detache(result.getBasionymAuthorship()));
432
        result.setExBasionymAuthorship(detache(result.getExBasionymAuthorship()));
433
        result.setInBasionymAuthorship(detache(result.getInBasionymAuthorship()));
434
        result.setInCombinationAuthorship(detache(result.getInCombinationAuthorship()));
435

    
436
        result.setNomenclaturalReference(detache(result.getNomenclaturalReference()));
437
        result.setNomenclaturalSource(detache(result.getNomenclaturalSource()));
438
        result.setHomotypicalGroup(detache(result.getHomotypicalGroup()));
439
        handleCollection(result, TaxonName.class, "descriptions", TaxonNameDescription.class);
440
        handleCollection(result, TaxonName.class, "hybridChildRelations", HybridRelationship.class);
441
        handleCollection(result, TaxonName.class, "hybridParentRelations", HybridRelationship.class);
442
        handleCollection(result, TaxonName.class, "relationsFromThisName", NameRelationship.class);
443
        handleCollection(result, TaxonName.class, "relationsToThisName", NameRelationship.class);
444
        handleCollection(result, TaxonName.class, "status", NomenclaturalStatus.class);
445

    
446
        handleCollection(result, TaxonName.class, "registrations", Registration.class);
447
        handleCollection(result, TaxonName.class, "typeDesignations", TypeDesignationBase.class);
448

    
449
        handleCollection(result, TaxonName.class, "taxonBases", TaxonBase.class);
450

    
451
        return result;
452
    }
453

    
454
    protected HomotypicalGroup handlePersistedHomotypicalGroup(HomotypicalGroup group) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
455
        HomotypicalGroup result = handlePersisted((AnnotatableEntity)group);
456
        //complete
457
        handleCollection(result, HomotypicalGroup.class, "typifiedNames", TaxonName.class);
458
        return result;
459
    }
460

    
461
    protected Annotation handlePersistedAnnotation(Annotation annotation) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
462
        Annotation result = handlePersisted((AnnotatableEntity)annotation);
463
        //complete
464
        result.setAnnotationType(detache(annotation.getAnnotationType()));
465
        result.setCommentator(detache(result.getCommentator()));
466
        handleCollection(result, Annotation.class, "intextReferences", IntextReference.class);
467
        return result;
468
    }
469

    
470
    protected Extension handlePersistedExtension(Extension extension) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
471
        Extension result = handlePersisted((VersionableEntity)extension);
472
        //complete
473
        result.setType(detache(extension.getType()));
474
        return result;
475
    }
476

    
477
    protected Marker handlePersistedMarker(Marker marker) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
478
        Marker result = handlePersisted((VersionableEntity)marker);
479
        //complete
480
        result.setMarkerType(detache(marker.getMarkerType()));
481
        return result;
482
    }
483

    
484
    protected Team handlePersistedTeam(Team team) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
485
        Team result = handlePersisted((TeamOrPersonBase)team);
486
        //complete
487
        handleCollection(result, Team.class, "teamMembers", Person.class);
488
        return result;
489
    }
490

    
491
    protected Contact handlePersistedContact(Contact contact) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
492
        Contact result = contact; // getTarget(contact);
493
        if (result ==null){
494
            return result;
495
        }
496
        if (!contact.getAddresses().isEmpty() || !contact.getEmailAddresses().isEmpty()
497
               || !contact.getFaxNumbers().isEmpty() ||!contact.getPhoneNumbers().isEmpty()
498
               ||!contact.getUrls().isEmpty()){
499
            logger.warn("Addresses not yet implemented");
500
        }
501
        setInvisible(result, "addresses", new HashSet<>());
502
//        handleCollection(result, Contact.class, "", Address.class);
503
        setInvisible(result, "faxNumbers", new ArrayList<>());
504
        setInvisible(result, "phoneNumbers", new ArrayList<>());
505
        setInvisible(result, "emailAddresses", new ArrayList<>());
506
        setInvisible(result, "urls", new ArrayList<>());
507
        return result;
508
    }
509

    
510
    protected Person handlePersistedPerson(Person person) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
511
        Person result = handlePersisted((TeamOrPersonBase)person);
512
        //complete
513
        handleCollection(result, Person.class, "institutionalMemberships", InstitutionalMembership.class);
514
        return result;
515
    }
516

    
517
    protected NamedArea handlePersistedNamedArea(NamedArea area) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
518
        NamedArea result = handlePersisted((OrderedTermBase)area);
519
        //complete
520
        handleCollection(result, NamedArea.class, "countries", Country.class);
521
        result.setLevel(detache(result.getLevel()));
522
        result.setType(detache(result.getType()));
523
        result.setShape(detache(result.getShape()));
524
        return result;
525
    }
526

    
527
    protected Classification handlePersistedClassification(Classification classification) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
528
        Classification result = handlePersisted((IdentifiableEntity)classification);
529
        //complete
530
        result.setName(detache(classification.getName()));
531
        result.setReference(detache(classification.getReference()));
532
        result.setRootNode(detache(classification.getRootNode()));
533
        handleCollection(result, Classification.class, "geoScopes", NamedArea.class);
534
        handleMap(result, Classification.class, "description", Language.class, LanguageString.class);
535
        return result;
536
    }
537

    
538
    protected Reference handlePersistedReference(Reference reference) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
539
        Reference result = handlePersisted((IdentifiableMediaEntity)reference);
540
        result.setAuthorship(detache(result.getAuthorship()));
541
        result.setInstitution(detache(result.getInstitution()));
542
        result.setSchool(detache(result.getSchool()));
543
        result.setInReference(detache(result.getInReference()));
544
        return result;
545
    }
546

    
547
    protected SpecimenOrObservationBase<?> handlePersistedSpecimenOrObservationBase(SpecimenOrObservationBase specimen) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
548
        //TODO implement for classes
549
        SpecimenOrObservationBase<?> result = handlePersisted((IdentifiableEntity)specimen);
550
        //complete
551
        result.setSex(detache(result.getSex()));
552
        result.setLifeStage(detache(result.getLifeStage()));
553
        result.setKindOfUnit(detache(result.getKindOfUnit()));
554
        handleCollection(result, SpecimenOrObservationBase.class, "determinations", DeterminationEvent.class);
555
        handleCollection(result, SpecimenOrObservationBase.class, "descriptions", SpecimenDescription.class);
556
        handleCollection(result, SpecimenOrObservationBase.class, "derivationEvents", DerivationEvent.class);
557
        handleMap(result, SpecimenOrObservationBase.class, "definition", Language.class, LanguageString.class);
558
        return result;
559
    }
560

    
561
    protected IdentifiableSource handlePersistedIdentifiableSource(IdentifiableSource source) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
562
        IdentifiableSource result = handlePersisted((OriginalSourceBase)source);
563
        //complete
564
        return result;
565
    }
566

    
567
    protected DescriptionElementSource handlePersistedDescriptionElementSource(DescriptionElementSource source) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
568
        DescriptionElementSource result = handlePersisted((OriginalSourceBase)source);
569
        //complete
570
        result.setNameUsedInSource(detache(result.getNameUsedInSource()));
571
        return result;
572
    }
573

    
574
    protected <T extends CommonTaxonName> T  handlePersistedCommonTaxonName(CommonTaxonName element) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
575
        T result = handlePersisted((DescriptionElementBase)element);
576
        //complete
577
        result.setLanguage(detache(result.getLanguage()));
578
        result.setArea(detache(result.getArea()));
579
        return result;
580
    }
581

    
582
    protected <T extends TextData> T  handlePersistedTextData(TextData element) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
583
        T result = handlePersisted((DescriptionElementBase)element);
584
        //complete
585
        result.setFormat(detache(result.getFormat()));
586
        handleMap(result, TextData.class, "multilanguageText", Language.class, LanguageString.class);
587
        return result;
588
    }
589

    
590
    protected <T extends Distribution> T  handlePersistedDistribution(Distribution element) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
591
        T result = handlePersisted((DescriptionElementBase)element);
592
        //complete
593
        result.setArea(detache(result.getArea()));
594
        result.setStatus(detache(result.getStatus()));
595
        return result;
596
    }
597

    
598
    protected ExtensionType handlePersistedExtensionType(ExtensionType term) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
599
        ExtensionType result = handlePersisted((DefinedTermBase)term);
600
        //complete
601
        return result;
602
    }
603

    
604
    protected MarkerType handlePersistedMarkerType(MarkerType term) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
605
        MarkerType result = handlePersisted((DefinedTermBase)term);
606
        //complete
607
        return result;
608
    }
609

    
610
    protected NomenclaturalStatusType handlePersistedNomenclaturalStatusType(NomenclaturalStatusType term) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
611
        NomenclaturalStatusType result = handlePersisted((OrderedTermBase)term);
612
        //complete
613
        return result;
614
    }
615

    
616
    protected DefinedTerm handlePersistedDefinedTerm(DefinedTerm term) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
617
        DefinedTerm result = handlePersisted((DefinedTermBase)term);
618
        //complete
619
        return result;
620
    }
621

    
622
    //placeholder for not implemented methods for subclasses
623
    protected DefinedTermBase<?> handlePersistedTerm(DefinedTermBase term) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
624
        DefinedTermBase<?> result = handlePersisted(term);
625
        logger.warn("Class not yet handled: " + term.getClass().getSimpleName());
626
        return result;
627
    }
628

    
629
    protected TermVocabulary<?> handlePersistedVocabulary(TermVocabulary voc) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
630
        TermVocabulary<?> result = (TermVocabulary<?>)handlePersisted((TermCollection)voc);
631
        handleCollection(result, TermVocabulary.class, "terms", DefinedTermBase.class);
632
        return result;
633
    }
634

    
635
    protected TermNode<?> handlePersistedTermNode(TermNode node) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
636
        TermNode<?> result = (TermNode<?>)handlePersisted((TermRelationBase)node);
637
        //complete
638
        setInvisible(result, "parent", detache(result.getParent()));
639
        handleCollection(result, TermNode.class, "inapplicableIf", FeatureState.class);
640
        handleCollection(result, TermNode.class, "onlyApplicableIf", FeatureState.class);
641
        handleCollection(result, TermNode.class, "inapplicableIf_old", State.class);
642
        handleCollection(result, TermNode.class, "onlyApplicableIf_old", State.class);
643
        handleCollection(result, TermNode.class, "children", TermNode.class);
644

    
645
        return result;
646
    }
647

    
648
    protected Representation handlePersistedRepresentation(Representation representation) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
649
        Representation result = (Representation)handlePersisted((LanguageStringBase)representation);
650
        return result;
651
    }
652

    
653
    protected <T extends TermBase> T  handlePersisted(TermBase termBase) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
654
        T result = handlePersisted((IdentifiableEntity)termBase);
655
        //complete
656
        handleCollection(result, TermBase.class, "representations", Representation.class);
657
        return result;
658
    }
659

    
660
    protected <T extends TermCollection> T  handlePersisted(TermCollection termCollection) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
661
        T result = handlePersisted((TermBase)termCollection);
662
        //complete
663
        handleCollection(result, TermCollection.class, "termRelations", TermRelationBase.class);
664
        return result;
665
    }
666

    
667
    protected <T extends TermRelationBase> T  handlePersisted(TermRelationBase termRelationBase) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
668
        T result = handlePersisted((VersionableEntity)termRelationBase);
669
        result.setTerm(detache(result.getTerm()));
670
        setInvisible(result, TermRelationBase.class, "graph", detache(result.getGraph()));
671
        return result;
672
    }
673

    
674
    protected User handlePersistedUser(User user) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
675
        User result = (User)handlePersistedCdmBase(user);
676
        if (result.getUsername().equals("admin")){
677
            result = getUserService().listByUsername("admin", MatchMode.EXACT, null, null, null, null, null).iterator().next();
678
            getState().putPermanent(user.getUuid(), result);
679
            cache(result); //necessary?
680
            toSave.add(result);
681
            toSave.remove(user);
682
        }
683
        if (!result.isPersited()){
684
            result.setAuthorities(new HashSet<>());
685
            result.setGrantedAuthorities(new HashSet<>());
686
            setInvisible(result, "groups", new HashSet<>());
687
        }
688
        return result;
689
    }
690

    
691

    
692
    protected LanguageString handlePersistedLanguageString(LanguageString languageString) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
693
        LanguageString result = handlePersisted((LanguageStringBase)languageString);
694
        //complete
695
        handleCollection(result, LanguageString.class, "intextReferences", IntextReference.class);
696
        return result;
697
    }
698

    
699
    protected IntextReference handlePersistedIntextReference(IntextReference intextReference) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
700
        IntextReference result = handlePersisted((VersionableEntity)intextReference);
701
        result.setReferencedEntity(detache(result.getReferencedEntity(), false));
702
        Method targetMethod = IntextReference.class.getDeclaredMethod("setTarget", IIntextReferenceTarget.class);
703
        targetMethod.setAccessible(true);
704
        targetMethod.invoke(result, detache(result.getTarget(), false));
705
        return result;
706
    }
707

    
708
    protected <T extends TaxonDescription> T  handlePersistedTaxonDescription(TaxonDescription taxDescription) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
709
        T result = handlePersisted((DescriptionBase)taxDescription);
710
        //complete
711
        setInvisible(taxDescription, "taxon", detache(taxDescription.getTaxon()));
712
        handleCollection(taxDescription, TaxonDescription.class, "geoScopes", NamedArea.class);
713
        handleCollection(taxDescription, TaxonDescription.class, "scopes", DefinedTerm.class);
714
        return result;
715
    }
716

    
717
    protected <T extends TaxonDescription> T  handlePersistedTaxonNameDescription(TaxonNameDescription nameDescription) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
718
        T result = handlePersisted((DescriptionBase)nameDescription);
719
        //complete
720
        setInvisible(nameDescription, "taxonName", detache(nameDescription.getTaxonName()));
721
        return result;
722
    }
723

    
724

    
725
// ***************************** BASE CLASSES ********************************************/
726

    
727
    protected <T extends CdmBase> T handlePersistedCdmBase(CdmBase cdmBase) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
728
        T result = (T)getTarget(cdmBase);
729
        //complete
730
        cdmBase.setCreatedBy(detache(cdmBase.getCreatedBy()));
731
        return result;
732
    }
733

    
734
    protected <T extends VersionableEntity> T handlePersisted(VersionableEntity entity) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
735
        T result = (T)handlePersistedCdmBase((CdmBase)entity);
736
        //complete
737
        entity.setUpdatedBy(detache(entity.getUpdatedBy()));
738
        return result;
739
    }
740

    
741
    protected <T extends AnnotatableEntity> T handlePersisted(AnnotatableEntity entity) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
742
        T result = handlePersisted((VersionableEntity)entity);
743
        //complete
744
        handleCollection(result, AnnotatableEntity.class, "annotations", Annotation.class);
745
        handleCollection(result, AnnotatableEntity.class, "markers", Marker.class);
746
        return result;
747
    }
748

    
749
    protected <T extends SourcedEntityBase> T  handlePersisted(SourcedEntityBase sourcedEntity) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
750
        T result = handlePersisted((AnnotatableEntity)sourcedEntity);
751
        //complete
752
        handleCollection(result, SourcedEntityBase.class, "sources", OriginalSourceBase.class);
753
        return result;
754
    }
755

    
756
    protected <T extends IdentifiableEntity> T  handlePersisted(IdentifiableEntity identifiableEntity) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
757
        T result = handlePersisted((SourcedEntityBase)identifiableEntity);
758
        //complete
759
        handleCollection(result, IdentifiableEntity.class, "credits", Credit.class);
760
        handleCollection(result, IdentifiableEntity.class, "extensions", Extension.class);
761
        handleCollection(result, IdentifiableEntity.class, "identifiers", Identifier.class);
762
        handleCollection(result, IdentifiableEntity.class, "rights", Rights.class);
763
        return result;
764
    }
765

    
766
    protected <T extends DefinedTermBase> T  handlePersisted(DefinedTermBase definedTermBase) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
767
        T result = handlePersisted((TermBase)definedTermBase);
768
        //complete
769
        handleCollection(result, DefinedTermBase.class, "media", Media.class);
770
        handleCollection(result, DefinedTermBase.class, "generalizationOf", DefinedTermBase.class);
771
        handleCollection(result, DefinedTermBase.class, "includes", DefinedTermBase.class);
772
        result.setKindOf(detache(result.getKindOf()));
773
        result.setPartOf(detache(result.getPartOf()));
774
        setInvisible(result, DefinedTermBase.class, "vocabulary", detache(result.getVocabulary()));
775

    
776
        return result;
777
    }
778

    
779
    protected <T extends OriginalSourceBase> T  handlePersisted(OriginalSourceBase source) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
780
        T result = handlePersisted((ReferencedEntityBase)source);
781
        //complete
782
        handleCollection(result, OriginalSourceBase.class, "links", ExternalLink.class);
783
        return result;
784
    }
785

    
786
    protected <T extends LanguageStringBase> T  handlePersisted(LanguageStringBase lsBase) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
787
        T result = handlePersisted((AnnotatableEntity)lsBase);
788
        //complete
789
        result.setLanguage(detache(lsBase.getLanguage()));
790
        return result;
791
    }
792

    
793
    protected <T extends TeamOrPersonBase> T  handlePersisted(TeamOrPersonBase teamOrPerson) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
794
        T result = handlePersisted((AgentBase)teamOrPerson);
795
        //complete
796
        return result;
797
    }
798

    
799
    protected <T extends AgentBase> T  handlePersisted(AgentBase agent) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
800
        T result = handlePersisted((IdentifiableMediaEntity)agent);
801
        result.setContact(detache(result.getContact()));
802
        //complete
803
        return result;
804
    }
805

    
806
    protected <T extends TaxonBase> T  handlePersisted(TaxonBase taxonBase) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
807
        T result = handlePersisted((IdentifiableEntity)taxonBase);
808
        //complete
809
        result.setName(detache(taxonBase.getName()));
810
        result.setSec(detache(taxonBase.getSec()));
811
        return result;
812
    }
813

    
814
    protected <T extends IdentifiableMediaEntity> T  handlePersisted(IdentifiableMediaEntity mediaEntity) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
815
        T result = handlePersisted((IdentifiableEntity)mediaEntity);
816
        //complete
817
        handleCollection(result, IdentifiableMediaEntity.class, "media", Media.class);
818
        return result;
819
    }
820

    
821
    protected <T extends ReferencedEntityBase> T  handlePersisted(ReferencedEntityBase referencedEntity) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
822
        T result = handlePersisted((AnnotatableEntity)referencedEntity);
823
        //complete
824
        result.setCitation(detache(result.getCitation()));
825
        return result;
826
    }
827

    
828
    protected <T extends DescriptionBase> T  handlePersisted(DescriptionBase descriptionBase) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
829
        T result = handlePersisted((IdentifiableEntity)descriptionBase);
830
        //complete
831
        handleCollection(result, DescriptionBase.class, "descriptionElements", DescriptionElementBase.class);
832
        handleCollection(result, DescriptionBase.class, "descriptiveDataSets", DescriptiveDataSet.class);
833
        handleCollection(result, DescriptionBase.class, "descriptionSources", Reference.class);
834
        result.setDescribedSpecimenOrObservation(detache(descriptionBase.getDescribedSpecimenOrObservation()));
835
        return result;
836
    }
837

    
838
    protected <T extends DescriptionElementBase> T  handlePersisted(DescriptionElementBase element) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
839
        T result = handlePersisted((AnnotatableEntity)element);
840
        //complete
841
        result.setFeature(detache(result.getFeature()));
842
        setInvisible(result, DescriptionElementBase.class, "inDescription", detache(result.getInDescription()));
843
        handleCollection(result, DescriptionElementBase.class, "sources", DescriptionElementSource.class);
844
        handleCollection(result, DescriptionElementBase.class, "media", Media.class);
845
        handleCollection(result, DescriptionElementBase.class, "modifiers", DefinedTerm.class);
846
        handleMap(result, DescriptionElementBase.class, "modifyingText", Language.class, LanguageString.class);
847

    
848
        return result;
849
    }
850

    
851
    protected <T extends RelationshipBase> T  handlePersisted(RelationshipBase relBase) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
852
        T result = handlePersisted((ReferencedEntityBase)relBase);
853
        return result;
854
    }
855

    
856

    
857
//************************** COLLECTIONS / MAPS ****************************************/
858

    
859
    protected <HOLDER extends CdmBase, ITEM extends CdmBase> void handleCollection(
860
            HOLDER holder, Class<? super HOLDER> declaringClass, String parameter, Class<ITEM> itemClass)
861
            throws NoSuchFieldException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
862

    
863
        Collection<ITEM> oldCollection = setNewCollection(holder, declaringClass, parameter, itemClass);
864
        Collection<ITEM> newCollection = getTargetCollection(itemClass, oldCollection);
865
        Field field = declaringClass.getDeclaredField(parameter);
866
        field.setAccessible(true);
867
        field.set(holder, newCollection);
868
    }
869

    
870
    protected <HOLDER extends CdmBase, KEY extends CdmBase, ITEM extends CdmBase>
871
            void handleMap(
872
            HOLDER holder, Class<? super HOLDER> declaringClass, String parameter,
873
            Class<KEY> keyClass, Class<ITEM> itemClass)
874
            throws NoSuchFieldException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
875

    
876
        //TODO we do not need to set the new map 2x
877
        Map<KEY,ITEM> oldMap = setNewMap(holder, declaringClass, parameter, keyClass, itemClass);
878
        Map<KEY,ITEM> newMap = getTargetMap(oldMap);
879
        Field field = declaringClass.getDeclaredField(parameter);
880
        field.setAccessible(true);
881
        field.set(holder, newMap);
882
    }
883

    
884
    protected <T extends CdmBase> Collection<T> setNewCollection(CdmBase obj, Class<?> holderClass,
885
            String parameter, Class<T> entityClass) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
886
        Field field = holderClass.getDeclaredField(parameter);
887
        field.setAccessible(true);
888
        Collection<T> oldValue = (Collection<T>)field.get(obj);
889
        Collection<T> newValue = null;
890
        if (Set.class.isAssignableFrom(field.getType())){
891
            newValue = new HashSet<>();
892
        }else if (List.class.isAssignableFrom(field.getType())){
893
            newValue = new ArrayList<>();
894
        }else{
895
            throw new RuntimeException("Unsupported collection type: " + field.getType().getCanonicalName());
896
        }
897
        field.set(obj, newValue);
898
        return oldValue;
899
    }
900

    
901
    protected <KEY extends CdmBase, ITEM extends CdmBase> Map<KEY,ITEM> setNewMap(CdmBase obj, Class<?> holderClass,
902
            String parameter, Class<KEY> keyClass, Class<ITEM> itemClass) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
903
        Field field = holderClass.getDeclaredField(parameter);
904
        field.setAccessible(true);
905
        Map<KEY,ITEM> oldValue = (Map<KEY,ITEM>)field.get(obj);
906
        Map<KEY,ITEM> newValue = null;
907
        if (Map.class.isAssignableFrom(field.getType())){
908
            newValue = new HashMap<>();
909
        }else{
910
            throw new RuntimeException("Unsupported map type: " + field.getType().getCanonicalName());
911
        }
912
        field.set(obj, newValue);
913
        return oldValue;
914
    }
915

    
916

    
917
    private <T extends Collection<S>, S extends CdmBase> Collection<S> getTargetCollection(Class<S> clazz, T sourceCollection) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
918
        Collection<S> result =  new ArrayList<>();
919
        if (Set.class.isAssignableFrom(sourceCollection.getClass())){
920
            result = new HashSet<>();
921
        }
922
        for (S entity : sourceCollection){
923
            S target = detache(entity);
924
            result.add(target);
925
        }
926
        return result;
927
    }
928

    
929
    private <K extends CdmBase, V extends CdmBase> Map<K,V> getTargetMap(Map<K,V> sourceMap) throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException, NoSuchMethodException {
930
        Map<K,V> result = new HashMap<>();
931
        for (K key : sourceMap.keySet()){
932
            K targetKey = detache(key);
933
            V targetValue = detache(sourceMap.get(key));
934
            result.put(targetKey, targetValue);
935
        }
936
        return result;
937
    }
938

    
939
// ****************************** INVISIBLE **************************************/
940

    
941
    protected void setInvisible(Object holder, String fieldName, Object value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
942
        setInvisible(holder, holder.getClass(), fieldName, value);
943
    }
944
    protected void setInvisible(Object holder, Class<?> holderClazz, String fieldName, Object value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
945
        Field field = holderClazz.getDeclaredField(fieldName);
946
        field.setAccessible(true);
947
        field.set(holder, value);
948
    }
949

    
950
// ************************* GET TARGET ******************************************/
951

    
952

    
953
    //TODO this should be cached for partition
954
    private <T extends CdmBase> T getTarget(T source) {
955
        if (source == null){
956
            return null;
957
        }
958
        T result = getCached(source);
959
//        if (result == null){
960
//            Class<T> clazz = (Class<T>)source.getClass();
961
//            result = getCommonService().find(clazz, source.getUuid());
962
//        }
963
        if (result == null){
964
            //Alternative: clone?
965
            result = CdmBase.deproxy(source);
966
            result.setId(0);
967
            cache(result);
968
            toSave.add(result);
969
        }
970
        return result;
971
    }
972

    
973
// ******************* CACHE *******************************************************/
974

    
975

    
976
    protected void cache(CdmBase cdmBase) {
977
       if (cdmBase instanceof User || cdmBase instanceof DefinedTermBase){
978
           getState().putPermanent(cdmBase.getUuid(), cdmBase);
979
       }else{
980
           sessionCache.put(cdmBase.getUuid(), cdmBase);
981
       }
982
       addExistingObject(cdmBase);
983

    
984
    }
985

    
986
    private void addExistingObject(CdmBase cdmBase) {
987
        cdmBase = CdmBase.deproxy(cdmBase);
988
        Set<UUID> set = existingObjects.get(cdmBase.getClass());
989
        if (set == null){
990
            set = loadExistingUuids(cdmBase.getClass());
991
//            set = new HashSet<>();
992
//            existingObjects.put(cdmBase.getClass(), set);
993
        }
994
        set.add(cdmBase.getUuid());
995
    }
996

    
997
    protected boolean isInCache(CdmBase cdmBase) {
998
        return getCached(cdmBase) != null;
999
    }
1000

    
1001
    protected <T extends CdmBase> T getCached(T cdmBase) {
1002
        T result = (T)sessionCache.get(cdmBase.getUuid());
1003
        if (result == null){
1004
            result = (T)getState().getPermanent(cdmBase.getUuid());
1005
        }
1006
        return result;
1007
    }
1008

    
1009
    protected void clearCache() {
1010
        sessionCache.clear();
1011
    }
1012

    
1013
    public FauEu2CdmImportState getState() {
1014
        return state;
1015
    }
1016

    
1017
    public void setState(FauEu2CdmImportState state) {
1018
        this.state = state;
1019
    }
1020

    
1021
}
(2-2/6)