Project

General

Profile

Download (242 KB) Statistics
| Branch: | Tag: | Revision:
1
// $Id$
2
/**
3
 * Copyright (C) 2013 EDIT
4
 * European Distributed Institute of Taxonomy
5
 * http://www.e-taxonomy.eu
6
 *
7
 * The contents of this file are subject to the Mozilla Public License Version 1.1
8
 * See LICENSE.TXT at the top of this package for the full license terms.
9
 */
10
package eu.etaxonomy.cdm.io.taxonx2013;
11

    
12
import java.io.BufferedWriter;
13
import java.io.File;
14
import java.io.FileWriter;
15
import java.io.IOException;
16
import java.net.URI;
17
import java.util.ArrayList;
18
import java.util.HashMap;
19
import java.util.List;
20
import java.util.Map;
21
import java.util.Set;
22
import java.util.UUID;
23
import java.util.regex.Pattern;
24

    
25
import javax.xml.transform.TransformerException;
26
import javax.xml.transform.TransformerFactoryConfigurationError;
27

    
28
import org.apache.commons.lang.StringUtils;
29
import org.apache.log4j.Logger;
30
import org.w3c.dom.Node;
31
import org.w3c.dom.NodeList;
32

    
33
import com.ibm.lsid.MalformedLSIDException;
34

    
35
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
36
import eu.etaxonomy.cdm.api.service.pager.Pager;
37
import eu.etaxonomy.cdm.model.agent.AgentBase;
38
import eu.etaxonomy.cdm.model.agent.Person;
39
import eu.etaxonomy.cdm.model.common.CdmBase;
40
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
41
import eu.etaxonomy.cdm.model.common.LSID;
42
import eu.etaxonomy.cdm.model.common.Language;
43
import eu.etaxonomy.cdm.model.common.OriginalSourceType;
44
import eu.etaxonomy.cdm.model.common.UuidAndTitleCache;
45
import eu.etaxonomy.cdm.model.description.Feature;
46
import eu.etaxonomy.cdm.model.description.FeatureNode;
47
import eu.etaxonomy.cdm.model.description.FeatureTree;
48
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
49
import eu.etaxonomy.cdm.model.description.TaxonDescription;
50
import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
51
import eu.etaxonomy.cdm.model.description.TextData;
52
import eu.etaxonomy.cdm.model.name.BacterialName;
53
import eu.etaxonomy.cdm.model.name.BotanicalName;
54
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
55
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
56
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
57
import eu.etaxonomy.cdm.model.name.NonViralName;
58
import eu.etaxonomy.cdm.model.name.Rank;
59
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
60
import eu.etaxonomy.cdm.model.name.ZoologicalName;
61
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
62
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
63
import eu.etaxonomy.cdm.model.reference.Reference;
64
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
65
import eu.etaxonomy.cdm.model.taxon.Classification;
66
import eu.etaxonomy.cdm.model.taxon.Synonym;
67
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
68
import eu.etaxonomy.cdm.model.taxon.Taxon;
69
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
70
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
71
import eu.etaxonomy.cdm.persistence.query.MatchMode;
72
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
73
import eu.etaxonomy.cdm.strategy.parser.INonViralNameParser;
74
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
75

    
76
/**
77
 * @author pkelbert
78
 * @date 2 avr. 2013
79
 *
80
 */
81
public class TaxonXTreatmentExtractor extends TaxonXExtractor{
82

    
83
    private static final Logger logger = Logger.getLogger(TaxonXTreatmentExtractor.class);
84

    
85
    private static final String notMarkedUp = "Not marked-up";
86
    private static final UUID proIbioTreeUUID = UUID.fromString("2c49f506-c7f7-44de-a8b9-2e695de3769c");
87
    private static final UUID OtherUUID = UUID.fromString("6465f8aa-2175-446f-807e-7163994b120f");
88
    private static final UUID NotMarkedUpUUID = UUID.fromString("796fe3a5-2c9c-4a89-b298-7598ca944063");
89
    private static final boolean skippQuestion = true;
90

    
91
    private final NomenclaturalCode nomenclaturalCode;
92
    private Classification classification;
93

    
94
    private  String treatmentMainName,originalTreatmentName;
95

    
96
    private final HashMap<String,Map<String,String>> namesMap = new HashMap<String, Map<String,String>>();
97

    
98

    
99
    private final Pattern keypattern = Pattern.compile("^(\\d+.*|-\\d+.*)");
100
    private final Pattern keypatternend = Pattern.compile("^.+?\\d$");
101

    
102
    private boolean maxRankRespected =false;
103
    private Map<String, Feature> featuresMap;
104

    
105
    private MyName currentMyName;
106

    
107
    private Reference<?> sourceUrlRef;
108

    
109
    private final TaxonXAddSources sourceHandler = new TaxonXAddSources();
110

    
111
    /**
112
     * @param nomenclaturalCode
113
     * @param classification
114
     * @param importer
115
     * @param configState
116
     */
117
    public TaxonXTreatmentExtractor(NomenclaturalCode nomenclaturalCode, Classification classification, TaxonXImport importer,
118
            TaxonXImportState configState,Map<String, Feature> featuresMap,  Reference<?> urlSource ) {
119
        this.nomenclaturalCode=nomenclaturalCode;
120
        this.classification = classification;
121
        this.importer=importer;
122
        this.configState=configState;
123
        this.featuresMap=featuresMap;
124
        this.sourceUrlRef =urlSource;
125
        prepareCollectors(configState, importer.getAgentService());
126
        this.sourceHandler.setSourceUrlRef(sourceUrlRef);
127
        this.sourceHandler.setImporter(importer);
128
        this.sourceHandler.setConfigState(configState);
129
    }
130

    
131
    /**
132
     * extracts all the treament information and save them
133
     * @param treatmentnode: the XML Node
134
     * @param tosave: the list of object to save into the CDM
135
     * @param refMods: the reference extracted from the MODS
136
     * @param sourceName: the URI of the document
137
     */
138
    @SuppressWarnings({ "rawtypes", "unused" })
139
    protected void extractTreatment(Node treatmentnode, List<Object> tosave, Reference<?> refMods, URI sourceName) {
140
        logger.info("extractTreatment");
141
        List<TaxonNameBase> nametosave = new ArrayList<TaxonNameBase>();
142
        NodeList children = treatmentnode.getChildNodes();
143
        Taxon acceptedTaxon =null;
144
        Taxon defaultTaxon =null;
145
        boolean refgroup=false;
146

    
147
        for (int i=0;i<children.getLength();i++){
148
            if(children.item(i).getNodeName().equalsIgnoreCase("tax:ref_group")) {
149
                refgroup=true;
150
            }
151
        }
152

    
153
        for (int i=0;i<children.getLength();i++){
154

    
155
            if (children.item(i).getNodeName().equalsIgnoreCase("tax:nomenclature")){
156
                NodeList nomenclature = children.item(i).getChildNodes();
157
                boolean containsName=false;
158
                for(int k=0;k<nomenclature.getLength();k++){
159
                    if(nomenclature.item(k).getNodeName().equalsIgnoreCase("tax:name")){
160
                        containsName=true;
161
                        break;
162
                    }
163
                }
164
                if (containsName){
165
                    reloadClassification();
166
                    //extract "main" the scientific name
167
                    try{
168
                        acceptedTaxon = extractNomenclature(children.item(i),nametosave,refMods);
169
                    }catch(ClassCastException e){e.printStackTrace();System.exit(0);}
170
                    //                    System.out.println("acceptedTaxon : "+acceptedTaxon);
171
                }
172
            }
173
            else if (children.item(i).getNodeName().equalsIgnoreCase("tax:ref_group") && maxRankRespected){
174
                reloadClassification();
175
                //extract the References within the document
176
                extractReferences(children.item(i),nametosave,acceptedTaxon,refMods);
177
            }
178
            else if (children.item(i).getNodeName().equalsIgnoreCase("tax:div") &&
179
                    children.item(i).getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("multiple") && maxRankRespected){
180
                File file = new File("/home/pkelbert/Bureau/multipleTaxonX.txt");
181
                FileWriter writer;
182
                try {
183
                    writer = new FileWriter(file ,true);
184
                    writer.write(sourceName+"\n");
185
                    writer.flush();
186
                    writer.close();
187
                } catch (IOException e1) {
188
                    // TODO Auto-generated catch block
189
                    e1.printStackTrace();
190
                }
191
                //                String multiple = askMultiple(children.item(i));
192
                String multiple = "Other";
193
                if (multiple.equalsIgnoreCase("other")) {
194
                    extractSpecificFeatureNotStructured(children.item(i),acceptedTaxon, defaultTaxon,nametosave, refMods,multiple);
195
                }
196
                else
197
                    if (multiple.equalsIgnoreCase("synonyms")) {
198
                        try{
199
                            extractSynonyms(children.item(i),acceptedTaxon, refMods);
200
                        }catch(NullPointerException e){
201
                            logger.warn("the accepted taxon is maybe null");
202
                        }
203
                    }
204
                    else
205
                        if(multiple.equalsIgnoreCase("material examined")){
206
                            extractMaterials(children.item(i),acceptedTaxon, refMods, nametosave);
207
                        }
208
                        else
209
                            if (multiple.equalsIgnoreCase("distribution")){
210
                                extractDistribution(children.item(i),acceptedTaxon,defaultTaxon,nametosave, refMods);
211
                            }
212
                            else
213
                                if (multiple.equalsIgnoreCase("type status")){
214
                                    extractDescriptionWithReference(children.item(i),acceptedTaxon,defaultTaxon,refMods, "TypeStatus");
215
                                }
216
                                else
217
                                    if (multiple.equalsIgnoreCase("vernacular name")){
218
                                        extractDescriptionWithReference(children.item(i),acceptedTaxon,defaultTaxon,refMods, Feature.COMMON_NAME().getTitleCache());
219

    
220
                                    }
221
                                    else{
222
                                        extractSpecificFeature(children.item(i),acceptedTaxon,defaultTaxon,nametosave, refMods,multiple);
223
                                    }
224

    
225
            }
226
            else if(children.item(i).getNodeName().equalsIgnoreCase("tax:div") &&
227
                    children.item(i).getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("biology_ecology") && maxRankRespected){
228
                extractFeature(children.item(i),acceptedTaxon,defaultTaxon, nametosave, refMods, Feature.BIOLOGY_ECOLOGY());
229
            }
230
            else if(children.item(i).getNodeName().equalsIgnoreCase("tax:div") &&
231
                    children.item(i).getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("vernacularName") && maxRankRespected){
232
                extractDescriptionWithReference(children.item(i),acceptedTaxon,defaultTaxon,refMods, Feature.COMMON_NAME().getTitleCache());
233
            }
234
            else if(children.item(i).getNodeName().equalsIgnoreCase("tax:div") &&
235
                    children.item(i).getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("description") && maxRankRespected){
236
                extractFeature(children.item(i),acceptedTaxon,defaultTaxon,nametosave, refMods, Feature.DESCRIPTION());
237
            }
238
            else if(children.item(i).getNodeName().equalsIgnoreCase("tax:div") &&
239
                    children.item(i).getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("diagnosis") && maxRankRespected){
240
                extractFeature(children.item(i),acceptedTaxon,defaultTaxon,nametosave, refMods,Feature.DIAGNOSIS());
241
            }
242
            else if(children.item(i).getNodeName().equalsIgnoreCase("tax:div") &&
243
                    children.item(i).getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("discussion") && maxRankRespected){
244
                extractFeature(children.item(i),acceptedTaxon,defaultTaxon,nametosave, refMods, Feature.DISCUSSION());
245
            }
246
            else if(children.item(i).getNodeName().equalsIgnoreCase("tax:div") &&
247
                    children.item(i).getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("note") && maxRankRespected){
248
                extractFeature(children.item(i),acceptedTaxon,defaultTaxon,nametosave, refMods, Feature.DESCRIPTION());
249
            }
250

    
251
            else if(children.item(i).getNodeName().equalsIgnoreCase("tax:div") &&
252
                    children.item(i).getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("distribution") && maxRankRespected){
253
                extractDistribution(children.item(i),acceptedTaxon,defaultTaxon,nametosave, refMods);
254
            }
255
            else if(children.item(i).getNodeName().equalsIgnoreCase("tax:div") &&
256
                    children.item(i).getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("etymology") && maxRankRespected){
257
                extractFeature(children.item(i),acceptedTaxon,defaultTaxon,nametosave,refMods,Feature.ETYMOLOGY());
258
            }
259

    
260
            else if(children.item(i).getNodeName().equalsIgnoreCase("tax:div") &&
261
                    children.item(i).getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("materials_examined") && maxRankRespected){
262
                extractMaterials(children.item(i),acceptedTaxon, refMods, nametosave);
263
            }
264
            else if(children.item(i).getNodeName().equalsIgnoreCase("tax:figure") && maxRankRespected){
265
                extractSpecificFeature(children.item(i),acceptedTaxon,defaultTaxon, nametosave, refMods, "Figure");
266
            }
267
            else if(children.item(i).getNodeName().equalsIgnoreCase("tax:div") &&
268
                    children.item(i).getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("Other") && maxRankRespected){
269
                extractSpecificFeature(children.item(i),acceptedTaxon,defaultTaxon, nametosave, refMods, "table");
270
            }
271

    
272
            else if(children.item(i).getNodeName().equalsIgnoreCase("tax:div") &&
273
                    children.item(i).getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("key") && maxRankRespected){
274
                //TODO IGNORE keys for the moment
275
                //extractKey(children.item(i),acceptedTaxon, nametosave,source, refMods);
276
                extractSpecificFeatureNotStructured(children.item(i),acceptedTaxon,defaultTaxon,nametosave, refMods,"Keys - unparsed");
277
            }
278
            else{
279
                if (!children.item(i).getNodeName().equalsIgnoreCase("tax:pb")){
280
                    //logger.info("ANOTHER KIND OF NODES: "+children.item(i).getNodeName()+", "+children.item(i).getAttributes());
281
                    if (children.item(i).getAttributes() !=null) {
282
                        //logger.info(children.item(i).getAttributes().item(0));
283
                    }
284
                    extractSpecificFeatureNotStructured(children.item(i),acceptedTaxon,defaultTaxon,nametosave, refMods,notMarkedUp);
285
                }
286
            }
287
        }
288
        //        logger.info("saveUpdateNames");
289
        if (maxRankRespected){
290
            importer.getNameService().saveOrUpdate(nametosave);
291
            importer.getClassificationService().saveOrUpdate(classification);
292
            //logger.info("saveUpdateNames-ok");
293
        }
294

    
295
        buildFeatureTree();
296
    }
297

    
298

    
299
    protected Map<String,Feature> getFeaturesUsed(){
300
        return featuresMap;
301
    }
302
    /**
303
     *
304
     */
305
    private void buildFeatureTree() {
306
        logger.info("buildFeatureTree");
307
        FeatureTree proibiospheretree = importer.getFeatureTreeService().find(proIbioTreeUUID);
308
        if (proibiospheretree == null){
309
            List<FeatureTree> trees = importer.getFeatureTreeService().list(FeatureTree.class, null, null, null, null);
310
            if (trees.size()==1) {
311
                FeatureTree ft = trees.get(0);
312
                if (featuresMap==null) {
313
                    featuresMap=new HashMap<String, Feature>();
314
                }
315
                for (Feature feature: ft.getDistinctFeatures()){
316
                    if(feature!=null) {
317
                        featuresMap.put(feature.getTitleCache(), feature);
318
                    }
319
                }
320
            }
321
            proibiospheretree = FeatureTree.NewInstance();
322
            proibiospheretree.setUuid(proIbioTreeUUID);
323
        }
324
        //        FeatureNode root = proibiospheretree.getRoot();
325
        FeatureNode root2 = proibiospheretree.getRoot();
326
        if (root2 != null){
327
            int nbChildren = root2.getChildCount()-1;
328
            while (nbChildren>-1){
329
                try{
330
                    root2.removeChild(nbChildren);
331
                }catch(Exception e){logger.warn("Can't remove child from FeatureTree "+e);}
332
                nbChildren --;
333
            }
334

    
335
        }
336

    
337
        for (Feature feature:featuresMap.values()) {
338
            root2.addChild(FeatureNode.NewInstance(feature));
339
        }
340
        importer.getFeatureTreeService().saveOrUpdate(proibiospheretree);
341

    
342
    }
343

    
344

    
345
    /**
346
     * @param keys
347
     * @param acceptedTaxon: the current acceptedTaxon
348
     * @param nametosave: the list of objects to save into the CDM
349
     * @param refMods: the current reference extracted from the MODS
350
     */
351
    /*   @SuppressWarnings("rawtypes")
352
    private void extractKey(Node keys, Taxon acceptedTaxon,List<TaxonNameBase> nametosave, Reference<?> refMods) {
353
        acceptedTaxon = CdmBase.deproxy(acceptedTaxon, Taxon.class);
354

    
355
        NodeList children = keys.getChildNodes();
356
        String key="";
357
        PolytomousKey poly =  PolytomousKey.NewInstance();
358
        poly.addSource(OriginalSourceType.Import, null,null,refMods,null);
359
        poly.addSource(OriginalSourceType.Import, null,null,sourceUrlRef,null);
360
        poly.addTaxonomicScope(acceptedTaxon);
361
        poly.setTitleCache("bloup", true);
362
        //        poly.addCoveredTaxon(acceptedTaxon);
363
        PolytomousKeyNode root = poly.getRoot();
364
        PolytomousKeyNode previous = null,tmpKey=null;
365
        Taxon taxonKey=null;
366
        List<PolytomousKeyNode> polyNodes = new ArrayList<PolytomousKeyNode>();
367

    
368
        //        String fullContent = keys.getTextContent();
369
        for (int i=0;i<children.getLength();i++){
370
            if (children.item(i).getNodeName().equalsIgnoreCase("tax:p")){
371
                NodeList paragraph = children.item(i).getChildNodes();
372
                key="";
373
                taxonKey=null;
374
                for (int j=0;j<paragraph.getLength();j++){
375
                    if (paragraph.item(j).getNodeName().equalsIgnoreCase("#text")){
376
                        if (! paragraph.item(j).getTextContent().trim().isEmpty()){
377
                            key+=paragraph.item(j).getTextContent().trim();
378
                            //                            logger.info("KEY: "+j+"--"+key);
379
                        }
380
                    }
381
                    if(paragraph.item(j).getNodeName().equalsIgnoreCase("tax:name")){
382
                        taxonKey=getTaxonFromXML(paragraph.item(j),nametosave,refMods);
383
                    }
384
                }
385
                //                logger.info("keypattern.matcher(key).matches(): "+keypattern.matcher(key).matches());
386
                if (keypattern.matcher(key).matches()){
387
                    tmpKey = PolytomousKeyNode.NewInstance(key);
388
                    if (taxonKey!=null) {
389
                        tmpKey.setTaxon(taxonKey);
390
                    }
391
                    polyNodes.add(tmpKey);
392
                    if (previous == null) {
393
                        root.addChild(tmpKey);
394
                    } else {
395
                        previous.addChild(tmpKey);
396
                    }
397
                }else{
398
                    if (!key.isEmpty()){
399
                        tmpKey=PolytomousKeyNode.NewInstance(key);
400
                        if (taxonKey!=null) {
401
                            tmpKey.setTaxon(taxonKey);
402
                        }
403
                        polyNodes.add(tmpKey);
404
                        if (keypatternend.matcher(key).matches()) {
405
                            root.addChild(tmpKey);
406
                            previous=tmpKey;
407
                        } else{
408
                            previous.addChild(tmpKey);
409
                        }
410

    
411
                    }
412
                }
413
            }
414
        }
415
        importer.getPolytomousKeyNodeService().saveOrUpdate(polyNodes);
416
        importer.getPolytomousKeyService().saveOrUpdate(poly);
417
    }
418
     */
419
    //    /**
420
    //     * @param taxons: the XML Nodegroup
421
    //     * @param nametosave: the list of objects to save into the CDM
422
    //     * @param acceptedTaxon: the current accepted Taxon
423
    //     * @param refMods: the current reference extracted from the MODS
424
    //     *
425
    //     * @return Taxon object built
426
    //     */
427
    //    @SuppressWarnings({ "rawtypes", "unchecked" })
428
    //    private Taxon getTaxonFromXML(Node taxons, List<TaxonNameBase> nametosave, Reference<?> refMods) {
429
    //        //        logger.info("getTaxonFromXML");
430
    //        //        logger.info("acceptedTaxon: "+acceptedTaxon);
431
    //
432
    //        // TaxonNameBase nameToBeFilled = null;
433
    //
434
    //        currentMyName = new MyName();
435
    //        NomenclaturalStatusType statusType = null;
436
    //
437
    //        try {
438
    //            currentMyName = extractScientificName(taxons);
439
    //            if (!currentMyName.getStatus().isEmpty()){
440
    //                try {
441
    //                    statusType = nomStatusString2NomStatus(currentMyName.getStatus());
442
    //                } catch (UnknownCdmTypeException e) {
443
    //                    addProblematicStatusToFile(currentMyName.getStatus());
444
    //                    logger.warn("Problem with status");
445
    //                }
446
    //            }
447
    //
448
    //        } catch (TransformerFactoryConfigurationError e1) {
449
    //            logger.warn(e1);
450
    //        } catch (TransformerException e1) {
451
    //            logger.warn(e1);
452
    //        }
453
    //        /*  INonViralNameParser parser = NonViralNameParserImpl.NewInstance();
454
    //
455
    //        nameToBeFilled = parser.parseFullName(currentMyName.getName(), nomenclaturalCode, currentMyName.getRank());
456
    //        if (nameToBeFilled.hasProblem() &&
457
    //                !((nameToBeFilled.getParsingProblems().size()==1) && nameToBeFilled.getParsingProblems().contains(ParserProblem.CheckRank)) ) {
458
    //            //            if (nameToBeFilled.hasProblem() && nameToBeFilled.getParsingProblems().contains(ParserProblem.UnparsableNamePart)){
459
    //            addProblemNameToFile(currentMyName.getName(),"",nomenclaturalCode,currentMyName.getRank());
460
    //            nameToBeFilled=solveNameProblem(currentMyName.getOriginalName(), currentMyName.getName(),parser, currentMyName.getAuthor(), currentMyName.getRank());
461
    //        }
462
    //
463
    //        nameToBeFilled = getTaxonNameBase(nameToBeFilled,nametosave,statusType);
464
    //         */
465
    //        TaxonNameBase nameToBeFilled = currentMyName.getTaxonNameBase();
466
    //        Taxon t = currentMyName.getTaxon();
467
    //        //        importer.getNameService().saveOrUpdate(nametosave);
468
    //        /*    Taxon t = importer.getTaxonService().findBestMatchingTaxon(nameToBeFilled.getTitleCache());
469
    //         */
470
    //        boolean statusMatch=false;
471
    //        if(t !=null ){
472
    //            statusMatch=compareStatus(t, statusType);
473
    //        }
474
    //        if (t ==null || (t != null && !statusMatch)){
475
    //            if(statusType != null) {
476
    //                nameToBeFilled.addStatus(NomenclaturalStatus.NewInstance(statusType));
477
    //            }
478
    //            t= new Taxon(nameToBeFilled,(Reference<?>) nameToBeFilled.getNomenclaturalReference() );//TODO TOFIX reference
479
    //            if (t.getSec() == null) {
480
    //                t.setSec(refMods);
481
    //            }
482
    //            if(!configState.getConfig().doKeepOriginalSecundum()) {
483
    //                t.setSec(configState.getConfig().getSecundum());
484
    //                logger.info("SET SECUNDUM "+configState.getConfig().getSecundum());
485
    //            }
486
    //            t.addSource(OriginalSourceType.Import,null,null,refMods,null);
487
    //            t.addSource(OriginalSourceType.Import, null,null,sourceUrlRef,null);
488
    //
489
    //
490
    //            if (!currentMyName.getIdentifier().isEmpty() && (currentMyName.getIdentifier().length()>2)){
491
    //                setLSID(currentMyName.getIdentifier(), t);
492
    //            }
493
    //
494
    //            //            Taxon parentTaxon = currentMyName.getHigherTaxa();
495
    //            //            if (parentTaxon == null && !skippQuestion) {
496
    //            //                parentTaxon =  askParent(t, classification);
497
    //            //            }
498
    //            //            if (parentTaxon ==null){
499
    //            //                while (parentTaxon == null) {
500
    //            //                    System.out.println("parent is null");
501
    //            //                    parentTaxon = createParent(t, refMods);
502
    //            //                    classification.addParentChild(parentTaxon, t, refMods, null);
503
    //            //                }
504
    //            //            }else{
505
    //            //                classification.addParentChild(parentTaxon, t, refMods, null);
506
    //            //            }
507
    //        }
508
    //        else{
509
    //            t = CdmBase.deproxy(t, Taxon.class);
510
    //        }
511
    //        if (!configState.getConfig().doKeepOriginalSecundum()) {
512
    //            t.setSec(configState.getConfig().getSecundum());
513
    //            logger.info("SET SECUNDUM "+configState.getConfig().getSecundum());
514
    //        }
515
    //        return t;
516
    //    }
517

    
518

    
519

    
520

    
521
    //    private Taxon getTaxonFromTaxonNameBase(TaxonNameBase tnb,Reference<?> ref){
522
    //        Taxon taxon = null;
523
    ////        System.out.println(tnb.getTitleCache());
524
    //        Taxon cc= importer.getTaxonService().findBestMatchingTaxon(tnb.getTitleCache());
525
    //        if (cc != null){
526
    //            if ((cc.getSec() == null || cc.getSec().toString().isEmpty()) || (cc.getSec() != null &&
527
    //                    cc.getSec().getTitleCache().equalsIgnoreCase(ref.getTitleCache()))) {
528
    //                if(cc.getSec() == null || cc.getSec().toString().isEmpty()){
529
    //                    cc.setSec(ref);
530
    //                    importer.getTaxonService().saveOrUpdate(cc);
531
    //                }
532
    //                taxon=cc;
533
    //            }
534
    //        }
535
    //        else{
536
    //            //            List<TaxonBase> c = importer.getTaxonService().searchTaxaByName(tnb.getTitleCache(), ref);
537
    //            List<TaxonBase> c = importer.getTaxonService().list(TaxonBase.class, 0, 0, null, null);
538
    //            for (TaxonBase b : c) {
539
    //                try{
540
    //                    taxon = (Taxon) b;
541
    //                }catch(ClassCastException e){logger.warn("error while casting existing taxonnamebase");}
542
    //            }
543
    //        }
544
    //        if (taxon == null){
545
    ////            System.out.println("NEW TAXON HERE "+tnb.toString()+", "+ref.toString());
546
    //            taxon = Taxon.NewInstance(tnb, ref); //sec set null
547
    //            importer.getTaxonService().save(taxon);
548
    //
549
    //        }
550
    //        taxon = (Taxon) importer.getTaxonService().find(taxon.getUuid());
551
    //
552
    //        boolean exist = false;
553
    //        for (TaxonNode p : classification.getAllNodes()){
554
    //            if(p.getTaxon().equals(taxon)) {
555
    //                exist =true;
556
    //            }
557
    //        }
558
    //        if (!exist){
559
    //            taxon = (Taxon) importer.getTaxonService().find(taxon.getUuid());
560
    //            Taxon parentTaxon = currentMyName.getHigherTaxa();
561
    //            if (parentTaxon != null) {
562
    //                classification.addParentChild(parentTaxon, taxon, ref, null);
563
    //            } else {
564
    //                System.out.println("HERE???");
565
    //                classification.addChildTaxon(taxon, ref, null);
566
    //            }
567
    //            importer.getClassificationService().saveOrUpdate(classification);
568
    //            //                        refreshTransaction();
569
    //        }
570
    //        taxon = CdmBase.deproxy(taxon, Taxon.class);
571
    //        //        System.out.println("TAXON RETOURNE : "+taxon.getTitleCache());
572
    //        return taxon;
573
    //    }
574
    /**
575
     * @param taxons: the XML Nodegroup
576
     * @param nametosave: the list of objects to save into the CDM
577
     * @param acceptedTaxon: the current accepted Taxon
578
     * @param refMods: the current reference extracted from the MODS
579
     *
580
     * @return Taxon object built
581
     */
582
    @SuppressWarnings({ "rawtypes", "unused" })
583
    private TaxonNameBase getTaxonNameBaseFromXML(Node taxons, List<TaxonNameBase> nametosave, Reference<?> refMods, boolean isSynonym) {
584
        //        logger.info("getTaxonFromXML");
585
        //        logger.info("acceptedTaxon: "+acceptedTaxon);
586
        logger.info("getTaxonNameBaseFromXML");
587
        TaxonNameBase nameToBeFilled = null;
588

    
589
        currentMyName=new MyName(isSynonym);
590

    
591
        NomenclaturalStatusType statusType = null;
592
        try {
593
            currentMyName = extractScientificName(taxons,refMods);
594
        } catch (TransformerFactoryConfigurationError e1) {
595
            logger.warn(e1);
596
        } catch (TransformerException e1) {
597
            logger.warn(e1);
598
        }
599
        /* INonViralNameParser parser = NonViralNameParserImpl.NewInstance();
600

    
601
        nameToBeFilled = parser.parseFullName(currentMyName.getName(), nomenclaturalCode, currentMyName.getRank());
602
        if (nameToBeFilled.hasProblem() &&
603
                !((nameToBeFilled.getParsingProblems().size()==1) && nameToBeFilled.getParsingProblems().contains(ParserProblem.CheckRank)) ) {
604
            //            if (nameToBeFilled.hasProblem() && nameToBeFilled.getParsingProblems().contains(ParserProblem.UnparsableNamePart)){
605
            addProblemNameToFile(currentMyName.getName(),"",nomenclaturalCode,currentMyName.getRank());
606
            nameToBeFilled=solveNameProblem(currentMyName.getOriginalName(), currentMyName.getName(),parser,currentMyName.getAuthor(), currentMyName.getRank());
607
        }
608

    
609
        nameToBeFilled = getTaxonNameBase(nameToBeFilled,nametosave,statusType);
610
         */
611
        nameToBeFilled = currentMyName.getTaxonNameBase();
612
        return nameToBeFilled;
613

    
614
    }
615

    
616
    //    @SuppressWarnings("rawtypes")
617
    //    private TaxonNameBase getTaxonNameBase (TaxonNameBase name, List<TaxonNameBase> nametosave, NomenclaturalStatusType statusType){
618
    //        List<TaxonNameBase> names = importer.getNameService().list(TaxonNameBase.class, null, null, null, null);
619
    //        for (TaxonNameBase tb : names){
620
    //            if (tb.getTitleCache().equalsIgnoreCase(name.getTitleCache())) {
621
    //                boolean statusMatch=false;
622
    //                if(tb !=null ){
623
    //                    statusMatch=compareStatus(tb, statusType);
624
    //                }
625
    //                if (!statusMatch){
626
    //                    if(statusType != null) {
627
    //                        name.addStatus(NomenclaturalStatus.NewInstance(statusType));
628
    //                    }
629
    //                }else
630
    //                {
631
    //                    logger.info("TaxonNameBase FOUND"+name.getTitleCache());
632
    //                    return  CdmBase.deproxy(tb, TaxonNameBase.class);
633
    //                }
634
    //            }
635
    //        }
636
    //        //        logger.info("TaxonNameBase NOT FOUND "+name.getTitleCache());
637
    //        //        System.out.println("add name "+name);
638
    //        nametosave.add(name);
639
    //        name = CdmBase.deproxy(name, TaxonNameBase.class);
640
    //        return name;
641
    //
642
    //    }
643

    
644

    
645

    
646
    //    /**
647
    //     * @param tb
648
    //     * @param statusType
649
    //     * @return
650
    //     */
651
    //    private boolean compareStatus(TaxonNameBase tb, NomenclaturalStatusType statusType) {
652
    //        boolean statusMatch=false;
653
    //        //found one taxon
654
    //        Set<NomenclaturalStatus> status = tb.getStatus();
655
    //        if (statusType!=null && status.size()>0){ //the statusType is known for both taxon
656
    //            for (NomenclaturalStatus st:status){
657
    //                NomenclaturalStatusType stype = st.getType();
658
    //                if (stype.toString().equalsIgnoreCase(statusType.toString())) {
659
    //                    statusMatch=true;
660
    //                }
661
    //            }
662
    //        }
663
    //        else{
664
    //            if(statusType == null && status.size()==0) {//there is no statusType, we can assume it's the same
665
    //                statusMatch=true;
666
    //            }
667
    //        }
668
    //        return statusMatch;
669
    //    }
670

    
671
    /**
672
     *
673
     */
674
    private void reloadClassification() {
675
        logger.info("reloadClassification");
676
        Classification cl = importer.getClassificationService().find(classification.getUuid());
677
        if (cl != null){
678
            classification=cl;
679
        }else{
680
            importer.getClassificationService().saveOrUpdate(classification);
681
            classification = importer.getClassificationService().find(classification.getUuid());
682
        }
683
    }
684

    
685
    //    /**
686
    //     * Create a Taxon for the current NameBase, based on the current reference
687
    //     * @param taxonNameBase
688
    //     * @param refMods: the current reference extracted from the MODS
689
    //     * @return Taxon
690
    //     */
691
    //    @SuppressWarnings({ "unused", "rawtypes" })
692
    //    private Taxon getTaxon(TaxonNameBase taxonNameBase, Reference<?> refMods) {
693
    //        Taxon t = new Taxon(taxonNameBase,null );
694
    //        if (!configState.getConfig().doKeepOriginalSecundum() || (t.getSec() == null)) {
695
    //            t.setSec(configState.getConfig().getSecundum());
696
    //            logger.info("SET SECUNDUM "+configState.getConfig().getSecundum());
697
    //        }
698
    //        /*<<<<<<< .courant
699
    //        boolean sourceExists=false;
700
    //        Set<IdentifiableSource> sources = t.getSources();
701
    //        for (IdentifiableSource src : sources){
702
    //            String micro = src.getCitationMicroReference();
703
    //            Reference r = src.getCitation();
704
    //            if (r.equals(refMods) && micro == null) {
705
    //                sourceExists=true;
706
    //            }
707
    //        }
708
    //        if(!sourceExists) {
709
    //            t.addSource(null,null,refMods,null);
710
    //        }
711
    //=======*/
712
    //        t.addSource(OriginalSourceType.Import,null,null,refMods,null);
713
    //        t.addSource(OriginalSourceType.Import, null,null,sourceUrlRef,null);
714
    //        return t;
715
    //    }
716

    
717
    private void  extractDescriptionWithReference(Node typestatus, Taxon acceptedTaxon, Taxon defaultTaxon, Reference<?> refMods,
718
            String featureName) {
719
        //        System.out.println("extractDescriptionWithReference !");
720
        logger.info("extractDescriptionWithReference");
721
        NodeList children = typestatus.getChildNodes();
722

    
723
        Feature currentFeature=getFeatureObjectFromString(featureName);
724

    
725
        String r="";String s="";
726
        for (int i=0;i<children.getLength();i++){
727
            if (children.item(i).getNodeName().equalsIgnoreCase("tax:p")){
728
                s+=children.item(i).getTextContent().trim();
729
            }
730
            if (children.item(i).getNodeName().equalsIgnoreCase("tax:bibref")){
731
                r+= children.item(i).getTextContent().trim();
732
            }
733
            if (s.indexOf(r)>-1) {
734
                s=s.split(r)[0];
735
            }
736
        }
737

    
738
        Reference<?> currentref =  ReferenceFactory.newGeneric();
739
        if(!r.isEmpty()) {
740
            currentref.setTitleCache(r, true);
741
        } else {
742
            currentref=refMods;
743
        }
744
        setParticularDescription(s,acceptedTaxon,defaultTaxon, currentref, refMods,currentFeature);
745
    }
746

    
747
    /**
748
     * @param nametosave
749
     * @param distribution: the XML node group
750
     * @param acceptedTaxon: the current accepted Taxon
751
     * @param defaultTaxon: the current defaultTaxon, only used if there is no accepted name
752
     * @param refMods: the current reference extracted from the MODS
753
     */
754
    @SuppressWarnings("rawtypes")
755
    private void extractDistribution(Node distribution, Taxon acceptedTaxon, Taxon defaultTaxon, List<TaxonNameBase> nametosave, Reference<?> refMods) {
756
        logger.info("extractDistribution");
757
        //        logger.info("acceptedTaxon: "+acceptedTaxon);
758
        NodeList children = distribution.getChildNodes();
759
        Map<Integer,List<MySpecimenOrObservation>> specimenOrObservations = new HashMap<Integer, List<MySpecimenOrObservation>>();
760
        Map<Integer,String> descriptionsFulltext = new HashMap<Integer,String>();
761

    
762
        for (int i=0;i<children.getLength();i++){
763
            if (children.item(i).getNodeName().equalsIgnoreCase("tax:p")){
764
                NodeList paragraph = children.item(i).getChildNodes();
765
                for (int j=0;j<paragraph.getLength();j++){
766
                    if (paragraph.item(j).getNodeName().equalsIgnoreCase("#text")){
767
                        extractText(descriptionsFulltext, i, paragraph.item(j));
768
                    }
769
                    else if (paragraph.item(j).getNodeName().equalsIgnoreCase("tax:name")){
770
                        extractInLine(nametosave, refMods, descriptionsFulltext, i,paragraph.item(j));
771
                    }
772
                    else if (paragraph.item(j).getNodeName().equalsIgnoreCase("tax:collection_event")){
773
                        MySpecimenOrObservation specimenOrObservation = new MySpecimenOrObservation();
774
                        DerivedUnit derivedUnitBase = null;
775
                        specimenOrObservation = extractSpecimenOrObservation(paragraph.item(j), derivedUnitBase, SpecimenOrObservationType.DerivedUnit);
776
                        extractTextFromSpecimenOrObservation(specimenOrObservations, descriptionsFulltext, i, specimenOrObservation);
777
                    }
778
                }
779
            }
780
        }
781

    
782
        int m=0;
783
        for (int k:descriptionsFulltext.keySet()) {
784
            if (k>m) {
785
                m=k;
786
            }
787
        }
788
        for (int k:specimenOrObservations.keySet()) {
789
            if (k>m) {
790
                m=k;
791
            }
792
        }
793

    
794

    
795
        if(acceptedTaxon!=null){
796
            TaxonDescription td =importer.getTaxonDescription(acceptedTaxon, false, true);
797
            Feature currentFeature = Feature.DISTRIBUTION();
798
            //        DerivedUnit derivedUnitBase=null;
799
            //        String descr="";
800
            for (int k=0;k<=m;k++){
801
                if(specimenOrObservations.keySet().contains(k)){
802
                    for (MySpecimenOrObservation soo:specimenOrObservations.get(k) ) {
803
                        handleAssociation(acceptedTaxon, refMods, td, soo);
804
                    }
805
                }
806

    
807
                if (descriptionsFulltext.keySet().contains(k)){
808
                    if (!stringIsEmpty(descriptionsFulltext.get(k).trim()) && (descriptionsFulltext.get(k).startsWith("Hab.") || descriptionsFulltext.get(k).startsWith("Habitat"))){
809
                        setParticularDescription(descriptionsFulltext.get(k),acceptedTaxon,defaultTaxon, refMods, Feature.HABITAT());
810
                        break;
811
                    }
812
                    else{
813
                        handleTextData(refMods, descriptionsFulltext, td, currentFeature, k);
814
                    }
815
                }
816

    
817
                if (descriptionsFulltext.keySet().contains(k) || specimenOrObservations.keySet().contains(k)){
818
                    acceptedTaxon.addDescription(td);
819
                    sourceHandler.addAndSaveSource(refMods, td, null);
820
                    importer.getTaxonService().saveOrUpdate(acceptedTaxon);
821
                }
822
            }
823
        }
824
    }
825

    
826
    /**
827
     * @param refMods
828
     * @param descriptionsFulltext
829
     * @param td
830
     * @param currentFeature
831
     * @param k
832
     */
833
    private void handleTextData(Reference<?> refMods, Map<Integer, String> descriptionsFulltext, TaxonDescription td,
834
            Feature currentFeature, int k) {
835
        //logger.info("handleTextData");
836
        TextData textData = TextData.NewInstance();
837
        textData.setFeature(currentFeature);
838
        textData.putText(Language.UNKNOWN_LANGUAGE(), descriptionsFulltext.get(k));
839
        sourceHandler.addSource(refMods, textData);
840
        td.addElement(textData);
841
    }
842

    
843
    /**
844
     * @param acceptedTaxon
845
     * @param refMods
846
     * @param td
847
     * @param soo
848
     */
849
    private void handleAssociation(Taxon acceptedTaxon, Reference<?> refMods, TaxonDescription td, MySpecimenOrObservation soo) {
850
        logger.info("handleAssociation");
851
        String descr=soo.getDescr();
852
        DerivedUnit derivedUnitBase = soo.getDerivedUnitBase();
853

    
854
        sourceHandler.addAndSaveSource(refMods, derivedUnitBase);
855

    
856
        TaxonDescription taxonDescription = importer.getTaxonDescription(acceptedTaxon, false, true);
857
        
858
        Feature feature=null;
859
        feature = makeFeature(derivedUnitBase);
860
        if(!StringUtils.isEmpty(descr)) {
861
            derivedUnitBase.setTitleCache(descr, true);
862
        }
863

    
864
        IndividualsAssociation indAssociation = createIndividualAssociation(refMods, derivedUnitBase, feature);
865

    
866
        taxonDescription.addElement(indAssociation);
867
        sourceHandler.addAndSaveSource(refMods, taxonDescription,null);
868
        importer.getTaxonService().saveOrUpdate(acceptedTaxon);
869
        td.setDescribedSpecimenOrObservation(soo.getDerivedUnitBase());
870
    }
871

    
872
    /**
873
     * create an individualAssociation
874
     * @param refMods
875
     * @param derivedUnitBase
876
     * @param feature
877
     * @return
878
     */
879
    private IndividualsAssociation createIndividualAssociation(Reference<?> refMods, DerivedUnit derivedUnitBase,
880
            Feature feature) {
881
        logger.info("createIndividualAssociation");
882
        IndividualsAssociation indAssociation = IndividualsAssociation.NewInstance();
883
        indAssociation.setAssociatedSpecimenOrObservation(derivedUnitBase);
884
        indAssociation.setFeature(feature);
885
        indAssociation = sourceHandler.addSource(refMods, indAssociation);
886
        return indAssociation;
887
    }
888

    
889
    /**
890
     * @param specimenOrObservations
891
     * @param descriptionsFulltext
892
     * @param i
893
     * @param specimenOrObservation
894
     */
895
    private void extractTextFromSpecimenOrObservation(Map<Integer, List<MySpecimenOrObservation>> specimenOrObservations,
896
            Map<Integer, String> descriptionsFulltext, int i, MySpecimenOrObservation specimenOrObservation) {
897
        logger.info("extractTextFromSpecimenOrObservation");
898
        List<MySpecimenOrObservation> speObsList = specimenOrObservations.get(i);
899
        if (speObsList == null) {
900
            speObsList=new ArrayList<MySpecimenOrObservation>();
901
        }
902
        speObsList.add(specimenOrObservation);
903
        specimenOrObservations.put(i,speObsList);
904

    
905
        String s = specimenOrObservation.getDerivedUnitBase().toString();
906
        if (descriptionsFulltext.get(i) !=null){
907
            s = descriptionsFulltext.get(i)+" "+s;
908
        }
909
        descriptionsFulltext.put(i, s);
910
    }
911

    
912
    /**
913
     * Extract the text with the inline link to a taxon
914
     * @param nametosave
915
     * @param refMods
916
     * @param descriptionsFulltext
917
     * @param i
918
     * @param paragraph
919
     */
920
    @SuppressWarnings("rawtypes")
921
    private void extractInLine(List<TaxonNameBase> nametosave, Reference<?> refMods, Map<Integer, String> descriptionsFulltext,
922
            int i, Node paragraph) {
923
        //logger.info("extractInLine");
924
        String inLine=getInlineText(nametosave, refMods, paragraph);
925
        if (descriptionsFulltext.get(i) !=null){
926
            inLine = descriptionsFulltext.get(i)+inLine;
927
        }
928
        descriptionsFulltext.put(i, inLine);
929
    }
930

    
931
    /**
932
     * Extract the raw text from a Node
933
     * @param descriptionsFulltext
934
     * @param node
935
     * @param j
936
     */
937
    private void extractText(Map<Integer, String> descriptionsFulltext, int i, Node node) {
938
        //logger.info("extractText");
939
        if(!node.getTextContent().trim().isEmpty()) {
940
            String s =node.getTextContent().trim();
941
            if (descriptionsFulltext.get(i) !=null){
942
                s = descriptionsFulltext.get(i)+" "+s;
943
            }
944
            descriptionsFulltext.put(i, s);
945
        }
946
    }
947

    
948

    
949
    /**
950
     * @param materials: the XML node group
951
     * @param acceptedTaxon: the current accepted Taxon
952
     * @param refMods: the current reference extracted from the MODS
953
     */
954
    @SuppressWarnings("rawtypes")
955
    private void extractMaterials(Node materials, Taxon acceptedTaxon, Reference<?> refMods,List<TaxonNameBase> nametosave) {
956
        logger.info("EXTRACTMATERIALS");
957
        //        logger.info("acceptedTaxon: "+acceptedTaxon);
958
        NodeList children = materials.getChildNodes();
959
        NodeList events = null;
960
        //        String descr="";
961

    
962

    
963
        for (int i=0;i<children.getLength();i++){
964
            String rawAssociation="";
965
            boolean added=false;
966
            if (children.item(i).getNodeName().equalsIgnoreCase("tax:p")){
967
                events = children.item(i).getChildNodes();
968
                for(int k=0;k<events.getLength();k++){
969
                    if (events.item(k).getNodeName().equalsIgnoreCase("tax:name")){
970
                        String inLine= getInlineText(nametosave, refMods, events.item(k));
971
                        if(!inLine.isEmpty()) {
972
                            rawAssociation+=inLine;
973
                        }
974
                    }
975
                    if (! events.item(k).getNodeName().equalsIgnoreCase("tax:name")
976
                            && !events.item(k).getNodeName().equalsIgnoreCase("tax:collection_event")){
977
                        rawAssociation+= events.item(k).getTextContent().trim();
978
                    }
979
                    if(events.item(k).getNodeName().equalsIgnoreCase("tax:collection_event")){
980
                        if (!containsDistinctLetters(rawAssociation.replaceAll(";",""))) {
981
                            rawAssociation="no description text";
982
                        }
983
                        added=true;
984
                        handleDerivedUnitFacadeAndBase(acceptedTaxon, refMods, events.item(k), rawAssociation);
985
                    }
986
                    if (!rawAssociation.isEmpty() && !added){
987

    
988
                        Feature feature = Feature.MATERIALS_EXAMINED();
989
                        featuresMap.put(feature.getTitleCache(),feature);
990

    
991
                        TextData textData = createTextData(rawAssociation, refMods, feature);
992

    
993
                        if(! rawAssociation.isEmpty() && (acceptedTaxon!=null)){
994
                            TaxonDescription td =importer.getTaxonDescription(acceptedTaxon, false, true);
995
                            td.addElement(textData);
996
                            acceptedTaxon.addDescription(td);
997
                            sourceHandler.addAndSaveSource(refMods, td, null);
998
                        }
999
                        //                        DerivedUnitFacade derivedUnitFacade = getFacade(rawAssociation.replaceAll(";",""),SpecimenOrObservationType.DerivedUnit);
1000
                        //                        derivedUnitBase = derivedUnitFacade.innerDerivedUnit();
1001
                        //
1002
                        //                        TaxonDescription taxonDescription = importer.getTaxonDescription(acceptedTaxon, false, true);
1003
                        //                        acceptedTaxon.addDescription(taxonDescription);
1004
                        //
1005
                        //                        IndividualsAssociation indAssociation = IndividualsAssociation.NewInstance();
1006
                        //
1007
                        //                        Feature feature = Feature.MATERIALS_EXAMINED();
1008
                        //                        featuresMap.put(feature.getTitleCache(),feature);
1009
                        //                        if(!StringUtils.isEmpty(rawAssociation)) {
1010
                        //                            derivedUnitBase.setTitleCache(rawAssociation, true);
1011
                        //                        }
1012
                        //                        indAssociation.setAssociatedSpecimenOrObservation(derivedUnitBase);
1013
                        //                        indAssociation.setFeature(feature);
1014
                        //                        indAssociation.addSource(OriginalSourceType.Import, null, null, refMods, null);
1015
                        //
1016
                        //                        /*boolean sourceExists=false;
1017
                        //                        Set<DescriptionElementSource> dsources = indAssociation.getSources();
1018
                        //                        for (DescriptionElementSource src : dsources){
1019
                        //                            String micro = src.getCitationMicroReference();
1020
                        //                            Reference r = src.getCitation();
1021
                        //                            if (r.equals(refMods) && micro == null) {
1022
                        //                                sourceExists=true;
1023
                        //                            }
1024
                        //                        }
1025
                        //                        if(!sourceExists) {
1026
                        //                            indAssociation.addSource(null, null, refMods, null);
1027
                        //                        }*/
1028
                        //                        taxonDescription.addElement(indAssociation);
1029
                        //                        taxonDescription.setTaxon(acceptedTaxon);
1030
                        //                        taxonDescription.addSource(OriginalSourceType.Import, null,null,refMods,null);
1031
                        //
1032
                        //                        /*sourceExists=false;
1033
                        //                        Set<IdentifiableSource> sources = taxonDescription.getSources();
1034
                        //                        for (IdentifiableSource src : sources){
1035
                        //                            String micro = src.getCitationMicroReference();
1036
                        //                            Reference r = src.getCitation();
1037
                        //                            if (r.equals(refMods) && micro == null) {
1038
                        //                                sourceExists=true;
1039
                        //                            }
1040
                        //                        }
1041
                        //                        if(!sourceExists) {
1042
                        //                            taxonDescription.addSource(OriginalSourceType.Import,null,null,refMods,null);
1043
                        //                        }*/
1044
                        //
1045
                        //                        importer.getDescriptionService().saveOrUpdate(taxonDescription);
1046
                        importer.getTaxonService().saveOrUpdate(acceptedTaxon);
1047

    
1048
                        rawAssociation="";
1049
                    }
1050
                }
1051
            }
1052
        }
1053
    }
1054

    
1055
    /**
1056
     * @param acceptedTaxon
1057
     * @param refMods
1058
     * @param events
1059
     * @param rawAssociation
1060
     * @param k
1061
     */
1062
    private void handleDerivedUnitFacadeAndBase(Taxon acceptedTaxon, Reference<?> refMods, Node event,
1063
            String rawAssociation) {
1064
        logger.info("handleDerivedUnitFacadeAndBase");
1065
        String descr;
1066
        DerivedUnit derivedUnitBase;
1067
        MySpecimenOrObservation myspecimenOrObservation;
1068
        DerivedUnitFacade derivedUnitFacade = getFacade(rawAssociation.replaceAll(";",""),SpecimenOrObservationType.DerivedUnit);
1069
        derivedUnitBase = derivedUnitFacade.innerDerivedUnit();
1070

    
1071
        sourceHandler.addAndSaveSource(refMods, derivedUnitBase);
1072

    
1073
        myspecimenOrObservation = extractSpecimenOrObservation(event,derivedUnitBase,SpecimenOrObservationType.DerivedUnit);
1074
        derivedUnitBase = myspecimenOrObservation.getDerivedUnitBase();
1075
        descr=myspecimenOrObservation.getDescr();
1076

    
1077
        sourceHandler.addAndSaveSource(refMods, derivedUnitBase);
1078

    
1079
        TaxonDescription taxonDescription = importer.getTaxonDescription(acceptedTaxon, false, true);
1080
        
1081
        Feature feature = makeFeature(derivedUnitBase);
1082
        featuresMap.put(feature.getTitleCache(),feature);
1083
        if(!StringUtils.isEmpty(descr)) {
1084
            derivedUnitBase.setTitleCache(descr, true);
1085
        }
1086

    
1087
        IndividualsAssociation indAssociation = createIndividualAssociation(refMods, derivedUnitBase, feature);
1088

    
1089
        taxonDescription.addElement(indAssociation);
1090
        sourceHandler.addAndSaveSource(refMods, taxonDescription,null);
1091
        importer.getTaxonService().saveOrUpdate(acceptedTaxon);
1092
    }
1093

    
1094

    
1095

    
1096
    /**
1097
     * @param materials: the XML node group
1098
     * @param acceptedTaxon: the current accepted Taxon
1099
     * @param refMods: the current reference extracted from the MODS
1100
     */
1101
    private String extractMaterialsDirect(Node materials, Taxon acceptedTaxon, Reference<?> refMods, String event) {
1102
        logger.info("extractMaterialsDirect");
1103
        //        logger.info("acceptedTaxon: "+acceptedTaxon);
1104
        String descr="";
1105

    
1106
        DerivedUnit derivedUnitBase=null;
1107
        MySpecimenOrObservation myspecimenOrObservation = extractSpecimenOrObservation(materials,derivedUnitBase, SpecimenOrObservationType.DerivedUnit);
1108
        derivedUnitBase = myspecimenOrObservation.getDerivedUnitBase();
1109

    
1110
        sourceHandler.addAndSaveSource(refMods, derivedUnitBase);
1111

    
1112
        TaxonDescription taxonDescription = importer.getTaxonDescription(acceptedTaxon, false, true);
1113

    
1114
        Feature feature=null;
1115
        if (event.equalsIgnoreCase("collection")){
1116
            feature = makeFeature(derivedUnitBase);
1117
        }
1118
        else{
1119
            feature = Feature.MATERIALS_EXAMINED();
1120
        }
1121
        featuresMap.put(feature.getTitleCache(),  feature);
1122

    
1123
        descr=myspecimenOrObservation.getDescr();
1124
        if(!StringUtils.isEmpty(descr)) {
1125
            derivedUnitBase.setTitleCache(descr, true);
1126
        }
1127

    
1128
        IndividualsAssociation indAssociation = createIndividualAssociation(refMods, derivedUnitBase, feature);
1129

    
1130
        taxonDescription.addElement(indAssociation);
1131
        sourceHandler.addAndSaveSource(refMods, taxonDescription,null);
1132
        importer.getTaxonService().saveOrUpdate(acceptedTaxon);
1133

    
1134
        return derivedUnitBase.getTitleCache();
1135

    
1136
    }
1137

    
1138

    
1139
    /**
1140
     * @param description: the XML node group
1141
     * @param acceptedTaxon: the current acceptedTaxon
1142
     * @param defaultTaxon: the current defaultTaxon, only used if there is no accepted name
1143
     * @param nametosave: the list of objects to save into the CDM
1144
     * @param refMods: the current reference extracted from the MODS
1145
     * @param featureName: the feature name
1146
     */
1147
    @SuppressWarnings({ "rawtypes"})
1148
    private String extractSpecificFeature(Node description, Taxon acceptedTaxon, Taxon defaultTaxon,
1149
            List<TaxonNameBase> nametosave, Reference<?> refMods, String featureName ) {
1150
        logger.info("extractSpecificFeature "+featureName);
1151
        //        System.out.println("GRUUUUuu");
1152
        NodeList children = description.getChildNodes();
1153
        NodeList insideNodes ;
1154
        NodeList trNodes;
1155
        //        String descr ="";
1156
        String localdescr="";
1157
        List<String> blabla=null;
1158
        List<String> text = new ArrayList<String>();
1159

    
1160
        String table="<table>";
1161
        String head="";
1162
        String line="";
1163

    
1164
        Feature currentFeature=getFeatureObjectFromString(featureName);
1165

    
1166
        //        String fullContent = description.getTextContent();
1167
        for (int i=0;i<children.getLength();i++){
1168
            //            localdescr="";
1169
            if (children.item(i).getNodeName().equalsIgnoreCase("#text") && !children.item(i).getTextContent().trim().isEmpty()){
1170
                text.add(children.item(i).getTextContent().trim());
1171
            }
1172
            if (featureName.equalsIgnoreCase("table")){
1173
                if (children.item(i).getNodeName().equalsIgnoreCase("tax:div") &&
1174
                        children.item(i).getAttributes().getNamedItem("otherType").getNodeValue().equalsIgnoreCase("thead")){
1175
                    head = extractTableHead(children.item(i));
1176
                    table+=head;
1177
                    line = extractTableLine(children.item(i));
1178
                    if (!line.equalsIgnoreCase("<tr></tr>")) {
1179
                        table+=line;
1180
                    }
1181
                }
1182
                if (children.item(i).getNodeName().equalsIgnoreCase("tax:div") &&
1183
                        children.item(i).getAttributes().getNamedItem("otherType").getNodeValue().equalsIgnoreCase("tr")){
1184
                    line = extractTableLineWithColumn(children.item(i).getChildNodes());
1185
                    if(!line.equalsIgnoreCase("<tr></tr>")) {
1186
                        table+=line;
1187
                    }
1188
                }
1189
            }
1190
            if (children.item(i).getNodeName().equalsIgnoreCase("tax:p")){
1191
                insideNodes=children.item(i).getChildNodes();
1192
                blabla= new ArrayList<String>();
1193
                for (int j=0;j<insideNodes.getLength();j++){
1194
                    if (insideNodes.item(j).getNodeName().equalsIgnoreCase("tax:name")){
1195
                        String inlinetext = getInlineText(nametosave, refMods, insideNodes.item(j));
1196
                        if (!inlinetext.isEmpty()) {
1197
                            blabla.add(inlinetext);
1198
                        }
1199
                    }
1200
                    if (insideNodes.item(j).getNodeName().equalsIgnoreCase("#text")) {
1201
                        if(!insideNodes.item(j).getTextContent().trim().isEmpty()){
1202
                            blabla.add(insideNodes.item(j).getTextContent().trim());
1203
                            //                            localdescr += insideNodes.item(j).getTextContent().trim();
1204
                        }
1205
                    }
1206
                }
1207
                if (!blabla.isEmpty()) {
1208
                    String blaStr = StringUtils.join(blabla," ").trim();
1209
                    if(!stringIsEmpty(blaStr)) {
1210
                        setParticularDescription(blaStr,acceptedTaxon,defaultTaxon, refMods,currentFeature);
1211
                        text.add(blaStr);
1212
                    }
1213
                }
1214

    
1215
            }
1216
            if (children.item(i).getNodeName().equalsIgnoreCase("#text")){
1217
                if(!children.item(i).getTextContent().trim().isEmpty()){
1218
                    localdescr = children.item(i).getTextContent().trim();
1219
                    if(!stringIsEmpty(localdescr)) {
1220
                        setParticularDescription(localdescr,acceptedTaxon,defaultTaxon, refMods,currentFeature);
1221
                    }
1222
                }
1223
            }
1224
        }
1225

    
1226
        table+="</table>";
1227
        if (!table.equalsIgnoreCase("<table></table>")){
1228
            //            System.out.println("TABLE : "+table);
1229
            text.add(table);
1230
        }
1231

    
1232
        if (text !=null && !text.isEmpty()) {
1233
            return StringUtils.join(text," ");
1234
        } else {
1235
            return "";
1236
        }
1237

    
1238
    }
1239

    
1240
    /**
1241
     * @param children
1242
     * @param i
1243
     * @return
1244
     */
1245
    private String extractTableLine(Node child) {
1246
        //logger.info("extractTableLine");
1247
        String line;
1248
        line="<tr>";
1249
        if (child.getAttributes().getNamedItem("otherType").getNodeValue().equalsIgnoreCase("tr")){
1250
            line = extractTableLineWithColumn(child.getChildNodes());
1251
        }
1252
        line+="</tr>";
1253
        return line;
1254
    }
1255

    
1256
    /**
1257
     * @param children
1258
     * @param i
1259
     * @return
1260
     */
1261
    private String extractTableHead(Node child) {
1262
        //logger.info("extractTableHead");
1263
        String head;
1264
        String line;
1265
        head="<th>";
1266
        NodeList trNodes = child.getChildNodes();
1267
        for (int k=0;k<trNodes.getLength();k++){
1268
            if (trNodes.item(k).getNodeName().equalsIgnoreCase("tax:div")
1269
                    && trNodes.item(k).getAttributes().getNamedItem("otherType").getNodeValue().equalsIgnoreCase("tr")){
1270
                line = extractTableLineWithColumn(trNodes.item(k).getChildNodes());
1271
                head+=line;
1272
            }
1273
        }
1274
        head+="</th>";
1275
        return head;
1276
    }
1277

    
1278
    /**
1279
     * build a html table line, with td columns
1280
     * @param tdNodes
1281
     * @return an html coded line
1282
     */
1283
    private String extractTableLineWithColumn(NodeList tdNodes) {
1284
        //logger.info("extractTableLineWithColumn");
1285
        String line;
1286
        line="<tr>";
1287
        for (int l=0;l<tdNodes.getLength();l++){
1288
            if (tdNodes.item(l).getNodeName().equalsIgnoreCase("tax:p")){
1289
                line+="<td>"+tdNodes.item(l).getTextContent()+"</td>";
1290
            }
1291
        }
1292
        line+="</tr>";
1293
        return line;
1294
    }
1295

    
1296
    /**
1297
     * @param description: the XML node group
1298
     * @param acceptedTaxon: the current acceptedTaxon
1299
     * @param defaultTaxon: the current defaultTaxon, only used if there is no accepted name
1300
     * @param nametosave: the list of objects to save into the CDM
1301
     * @param refMods: the current reference extracted from the MODS
1302
     * @param featureName: the feature name
1303
     */
1304
    @SuppressWarnings({ "unused", "rawtypes" })
1305
    private String extractSpecificFeatureNotStructured(Node description, Taxon acceptedTaxon, Taxon defaultTaxon,
1306
            List<TaxonNameBase> nametosave, Reference<?> refMods, String featureName ) {
1307
        logger.info("extractSpecificFeatureNotStructured "+featureName);
1308
        NodeList children = description.getChildNodes();
1309
        NodeList insideNodes ;
1310
        List<String> blabla= new ArrayList<String>();
1311

    
1312

    
1313
        Feature currentFeature = getFeatureObjectFromString(featureName);
1314

    
1315
        String fullContent = description.getTextContent();
1316
        for (int i=0;i<children.getLength();i++){
1317
            if (children.item(i).getNodeName().equalsIgnoreCase("tax:p")){
1318
                insideNodes=children.item(i).getChildNodes();
1319
                for (int j=0;j<insideNodes.getLength();j++){
1320
                    if (insideNodes.item(j).getNodeName().equalsIgnoreCase("tax:name")){
1321
                        String inlineText =getInlineText(nametosave, refMods, insideNodes.item(j));
1322
                        if(!inlineText.isEmpty()) {
1323
                            blabla.add(inlineText);
1324
                        }
1325
                    }
1326
                    if (insideNodes.item(j).getNodeName().equalsIgnoreCase("#text")) {
1327
                        if(!insideNodes.item(j).getTextContent().trim().isEmpty()){
1328
                            blabla.add(insideNodes.item(j).getTextContent().trim());
1329
                        }
1330
                    }
1331
                }
1332
            }
1333
            if (children.item(i).getNodeName().equalsIgnoreCase("#text")){
1334
                if(!children.item(i).getTextContent().trim().isEmpty()){
1335
                    String localdescr = children.item(i).getTextContent().trim();
1336
                    if(!localdescr.isEmpty())
1337
                    {
1338
                        blabla.add(localdescr);
1339
                    }
1340
                }
1341
            }
1342
        }
1343

    
1344
        if (blabla !=null && !blabla.isEmpty()) {
1345
            String blaStr = StringUtils.join(blabla," ").trim();
1346
            if (! stringIsEmpty(blaStr)) {
1347
                setParticularDescription(blaStr,acceptedTaxon,defaultTaxon, refMods,currentFeature);
1348
                return blaStr;
1349
            } else {
1350
                return "";
1351
            }
1352
        } else {
1353
            return "";
1354
        }
1355

    
1356
    }
1357

    
1358
    /**
1359
     * @param blaStr
1360
     * @return
1361
     */
1362
    private boolean stringIsEmpty(String blaStr) {
1363
        if (!StringUtils.isEmpty(blaStr)) {
1364
            if (!blaStr.equalsIgnoreCase(".")) {
1365
                if (!blaStr.equalsIgnoreCase(",")) {
1366
                    if (!blaStr.equalsIgnoreCase(";")) {
1367
                        return false;
1368
                    }
1369
                }
1370
            }
1371
        }
1372
        return true;
1373
    }
1374

    
1375
    /**
1376
     * @param nametosave
1377
     * @param refMods
1378
     * @param insideNodes
1379
     * @param blabla
1380
     * @param j
1381
     */
1382
    @SuppressWarnings({ "rawtypes" })
1383
    private String getInlineText(List<TaxonNameBase> nametosave, Reference<?> refMods, Node insideNode) {
1384
        //logger.info("getInlineText");
1385
        TaxonNameBase tnb = getTaxonNameBaseFromXML(insideNode, nametosave,refMods,false);
1386
        //                        Taxon tax = getTaxonFromTxonNameBase(tnb, refMods);
1387
        Taxon tax = currentMyName.getTaxon();
1388
        if(tnb !=null){
1389
            String linkedTaxon = tnb.toString().split("sec")[0];//TODO NOT IMPLEMENTED IN THE CDM YET
1390
            return "<cdm:taxon uuid='"+tax.getUuid()+"'>"+linkedTaxon+"</cdm:taxon>";
1391
        }
1392
        return "";
1393
    }
1394

    
1395
    /**
1396
     * @param featureName
1397
     * @return
1398
     */
1399
    @SuppressWarnings("rawtypes")
1400
    private Feature getFeatureObjectFromString(String featureName) {
1401
        logger.info("getFeatureObjectFromString");
1402
        List<Feature> features = importer.getTermService().list(Feature.class, null,null,null,null);
1403
        Feature currentFeature=null;
1404
        for (Feature feature: features){
1405
            String tmpF = feature.getTitleCache();
1406
            if (tmpF.equalsIgnoreCase(featureName)) {
1407
                currentFeature=feature;
1408
                //                System.out.println("currentFeatureFromList "+currentFeature.getUuid());
1409
            }
1410
        }
1411
        if (currentFeature == null) {
1412
            currentFeature=Feature.NewInstance(featureName, featureName, featureName);
1413
            if(featureName.equalsIgnoreCase("Other")){
1414
                currentFeature.setUuid(OtherUUID);
1415
            }
1416
            if(featureName.equalsIgnoreCase(notMarkedUp)){
1417
                currentFeature.setUuid(NotMarkedUpUUID);
1418
            }
1419
            importer.getTermService().saveOrUpdate(currentFeature);
1420
        }
1421
        return currentFeature;
1422
    }
1423

    
1424

    
1425

    
1426

    
1427
    /**
1428
     * @param children: the XML node group
1429
     * @param nametosave: the list of objects to save into the CDM
1430
     * @param acceptedTaxon: the current acceptedTaxon
1431
     * @param refMods: the current reference extracted from the MODS
1432
     * @param fullContent :the parsed XML content
1433
     * @return a list of description (text)
1434
     */
1435
    @SuppressWarnings({ "unused", "rawtypes" })
1436
    private List<String> parseParagraph(List<TaxonNameBase> nametosave, Taxon acceptedTaxon, Reference<?> refMods, Node paragraph, Feature feature){
1437
        logger.info("parseParagraph "+feature.toString());
1438
        List<String> fullDescription=  new ArrayList<String>();
1439
        //        String localdescr;
1440
        String descr="";
1441
        NodeList insideNodes ;
1442
        boolean collectionEvent = false;
1443
        List<Node>collectionEvents = new ArrayList<Node>();
1444

    
1445
        NodeList children = paragraph.getChildNodes();
1446

    
1447
        for (int i=0;i<children.getLength();i++){
1448
            //            localdescr="";
1449
            if (children.item(i).getNodeName().equalsIgnoreCase("#text") && !children.item(i).getTextContent().trim().isEmpty()){
1450
                descr += children.item(i).getTextContent().trim();
1451
            }
1452
            if (children.item(i).getNodeName().equalsIgnoreCase("tax:p")){
1453
                insideNodes=children.item(i).getChildNodes();
1454
                List<String> blabla= new ArrayList<String>();
1455
                for (int j=0;j<insideNodes.getLength();j++){
1456
                    boolean nodeKnown = false;
1457
                    //                    System.out.println("insideNodes.item(j).getNodeName() : "+insideNodes.item(j).getNodeName());
1458
                    if (insideNodes.item(j).getNodeName().equalsIgnoreCase("tax:name")){
1459
                        String inlineText = getInlineText(nametosave, refMods, insideNodes.item(j));
1460
                        if (!inlineText.isEmpty()) {
1461
                            blabla.add(inlineText);
1462
                        }
1463
                        nodeKnown=true;
1464
                    }
1465
                    if (insideNodes.item(j).getNodeName().equalsIgnoreCase("#text")) {
1466
                        if(!insideNodes.item(j).getTextContent().trim().isEmpty()){
1467
                            blabla.add(insideNodes.item(j).getTextContent().trim());
1468
                            //                            localdescr += insideNodes.item(j).getTextContent().trim();
1469
                        }
1470
                        nodeKnown=true;
1471
                    }
1472
                    if (insideNodes.item(j).getNodeName().equalsIgnoreCase("tax:bibref")) {
1473
                        String ref = insideNodes.item(j).getTextContent().trim();
1474
                        if (ref.endsWith(";")  && ((ref.length())>1)) {
1475
                            ref=ref.substring(0, ref.length()-1)+".";
1476
                        }
1477
                        Reference<?> reference = ReferenceFactory.newGeneric();
1478
                        reference.setTitleCache(ref, true);
1479
                        blabla.add(reference.getTitleCache());
1480
                        nodeKnown=true;
1481
                    }
1482
                    if  (insideNodes.item(j).getNodeName().equalsIgnoreCase("tax:figure")){
1483
                        String figure = extractSpecificFeature(insideNodes.item(j),acceptedTaxon,acceptedTaxon, nametosave, refMods, "figure");
1484
                        blabla.add(figure);
1485
                    }
1486
                    if(insideNodes.item(j).getNodeName().equalsIgnoreCase("tax:div") &&
1487
                            insideNodes.item(j).getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("Other") &&
1488
                            insideNodes.item(j).getAttributes().getNamedItem("otherType").getNodeValue().equalsIgnoreCase("table")){
1489
                        String table = extractSpecificFeature(insideNodes.item(j),acceptedTaxon,acceptedTaxon, nametosave, refMods, "table");
1490
                        blabla.add(table);
1491
                    }
1492
                    if  (insideNodes.item(j).getNodeName().equalsIgnoreCase("tax:collection_event")) {
1493
                        //                        logger.warn("SEEMS TO BE COLLECTION EVENT INSIDE A "+feature.toString());
1494
                        String titlecache  = extractMaterialsDirect(insideNodes.item(j), acceptedTaxon, refMods, "collection");
1495
                        blabla.add(titlecache);
1496
                        collectionEvent=true;
1497
                        collectionEvents.add(insideNodes.item(j));
1498
                        nodeKnown=true;
1499
                    }
1500
                    //                    if (!nodeKnown && !insideNodes.item(j).getNodeName().equalsIgnoreCase("tax:pb")) {
1501
                    //                        logger.info("Node not handled yet : "+insideNodes.item(j).getNodeName());
1502
                    //                    }
1503

    
1504
                }
1505
                if (!StringUtils.isEmpty(StringUtils.join(blabla," "))) {
1506
                    fullDescription.add(StringUtils.join(blabla," "));
1507
                }
1508
            }
1509
            if  (children.item(i).getNodeName().equalsIgnoreCase("tax:figure")){
1510
                String figure = extractSpecificFeature(children.item(i),acceptedTaxon,acceptedTaxon, nametosave, refMods, "Figure");
1511
                fullDescription.add(figure);
1512
            }
1513
            if(children.item(i).getNodeName().equalsIgnoreCase("tax:div") &&
1514
                    children.item(i).getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("Other") &&
1515
                    children.item(i).getAttributes().getNamedItem("otherType").getNodeValue().equalsIgnoreCase("table")){
1516
                String table = extractSpecificFeature(children.item(i),acceptedTaxon,acceptedTaxon, nametosave, refMods, "table");
1517
                fullDescription.add(table);
1518
            }
1519
        }
1520

    
1521
        if( !stringIsEmpty(descr.trim())){
1522
            Feature currentFeature= getNotMarkedUpFeatureObject();
1523
            setParticularDescription(descr.trim(),acceptedTaxon,acceptedTaxon, refMods,currentFeature);
1524
        }
1525
        //        if (collectionEvent) {
1526
        //            logger.warn("SEEMS TO BE COLLECTION EVENT INSIDE A "+feature.toString());
1527
        //            for (Node coll:collectionEvents){
1528
        //                = extractMaterialsDirect(coll, acceptedTaxon, refMods, "collection");
1529
        //            }
1530
        //        }
1531
        return fullDescription;
1532
    }
1533

    
1534

    
1535
    /**
1536
     * @param description: the XML node group
1537
     * @param acceptedTaxon: the current acceptedTaxon
1538
     * @param defaultTaxon: the current defaultTaxon, only used if there is no accepted name
1539
     * @param nametosave: the list of objects to save into the CDM
1540
     * @param refMods: the current reference extracted from the MODS
1541
     * @param feature: the feature to link the data with
1542
     */
1543
    @SuppressWarnings("rawtypes")
1544
    private void extractFeature(Node description, Taxon acceptedTaxon, Taxon defaultTaxon, List<TaxonNameBase> nametosave, Reference<?> refMods, Feature feature){
1545
        logger.info("EXTRACT FEATURE "+feature.toString());
1546
        acceptedTaxon = CdmBase.deproxy(acceptedTaxon, Taxon.class);
1547
        List<String> fullDescription= parseParagraph( nametosave, acceptedTaxon, refMods, description,feature);
1548

    
1549
        //        System.out.println("Feature : "+feature.toString()+", "+fullDescription.toString());
1550
        if (!fullDescription.isEmpty() &&!stringIsEmpty(StringUtils.join(fullDescription," ").trim())) {
1551
            setParticularDescription(StringUtils.join(fullDescription," ").trim(),acceptedTaxon,defaultTaxon, refMods,feature);
1552
        }
1553

    
1554
    }
1555

    
1556

    
1557
    /**
1558
     * @param descr: the XML Nodegroup to parse
1559
     * @param acceptedTaxon: the current acceptedTaxon
1560
     * @param defaultTaxon: the current defaultTaxon, only used if there is no accepted name
1561
     * @param refMods: the current reference extracted from the MODS
1562
     * @param currentFeature: the feature name
1563
     * @return
1564
     */
1565
    private void setParticularDescription(String descr, Taxon acceptedTaxon, Taxon defaultTaxon, Reference<?> refMods, Feature currentFeature) {
1566
        logger.info("setParticularDescription "+currentFeature.getTitleCache()+", \n blabla : "+descr);
1567
        //        System.out.println("setParticularDescription "+currentFeature.getTitleCache()+", \n blabla : "+descr);
1568
        //        logger.info("acceptedTaxon: "+acceptedTaxon);
1569
        acceptedTaxon = CdmBase.deproxy(acceptedTaxon, Taxon.class);
1570

    
1571
        featuresMap.put(currentFeature.getTitleCache(),currentFeature);
1572

    
1573
        TextData textData = createTextData(descr, refMods, currentFeature);
1574

    
1575
        if(acceptedTaxon!=null){
1576
            TaxonDescription td =importer.getTaxonDescription(acceptedTaxon, false, true);
1577
            td.addElement(textData);
1578
            acceptedTaxon.addDescription(td);
1579

    
1580
            sourceHandler.addAndSaveSource(refMods, td, null);
1581
            importer.getTaxonService().saveOrUpdate(acceptedTaxon);
1582
        }
1583

    
1584
        if(! descr.isEmpty() && (acceptedTaxon == null) && (defaultTaxon != null)){
1585
            try{
1586
                Taxon tmp =(Taxon) importer.getTaxonService().find(defaultTaxon.getUuid());
1587
                if (tmp!=null) {
1588
                    defaultTaxon=CdmBase.deproxy(tmp,Taxon.class);
1589
                }else{
1590
                    importer.getTaxonService().saveOrUpdate(defaultTaxon);
1591
                }
1592
            }catch(Exception e){
1593
                logger.debug("TAXON EXISTS"+defaultTaxon);
1594
            }
1595

    
1596
            TaxonDescription td =importer.getTaxonDescription(defaultTaxon, false, true);
1597
            defaultTaxon.addDescription(td);
1598
            td.addElement(textData);
1599
            sourceHandler.addAndSaveSource(refMods, td, null);
1600
            importer.getTaxonService().saveOrUpdate(defaultTaxon);
1601
        }
1602
    }
1603

    
1604
    /**
1605
     * @param descr
1606
     * @param refMods
1607
     * @param currentFeature
1608
     * @return
1609
     */
1610
    private TextData createTextData(String descr, Reference<?> refMods, Feature currentFeature) {
1611
        //logger.info("createTextData");
1612
        TextData textData = TextData.NewInstance();
1613
        textData.setFeature(currentFeature);
1614
        sourceHandler.addSource(refMods, textData);
1615

    
1616
        textData.putText(Language.UNKNOWN_LANGUAGE(), descr);
1617
        return textData;
1618
    }
1619

    
1620

    
1621

    
1622
    /**
1623
     * @param descr: the XML Nodegroup to parse
1624
     * @param acceptedTaxon: the current acceptedTaxon
1625
     * @param defaultTaxon: the current defaultTaxon, only used if there is no accepted name
1626
     * @param refMods: the current reference extracted from the MODS
1627
     * @param currentFeature: the feature name
1628
     * @return
1629
     */
1630
    private void setParticularDescription(String descr, Taxon acceptedTaxon, Taxon defaultTaxon,Reference<?> currentRef, Reference<?> refMods, Feature currentFeature) {
1631
        //        System.out.println("setParticularDescriptionSPecial "+currentFeature);
1632
        //        logger.info("acceptedTaxon: "+acceptedTaxon);
1633
        logger.info("setParticularDescription");
1634
        acceptedTaxon = CdmBase.deproxy(acceptedTaxon, Taxon.class);
1635

    
1636
        featuresMap.put(currentFeature.getTitleCache(),currentFeature);
1637
        TextData textData = createTextData(descr, refMods, currentFeature);
1638

    
1639
        if(! descr.isEmpty() && (acceptedTaxon!=null)){
1640
            TaxonDescription td =importer.getTaxonDescription(acceptedTaxon, false, true);
1641
            td.addElement(textData);
1642
            acceptedTaxon.addDescription(td);
1643

    
1644
            sourceHandler.addAndSaveSource(refMods, td, currentRef);
1645
            importer.getTaxonService().saveOrUpdate(acceptedTaxon);
1646
        }
1647

    
1648
        if(! descr.isEmpty() && (acceptedTaxon == null) && (defaultTaxon != null)){
1649
            try{
1650
                Taxon tmp =(Taxon) importer.getTaxonService().find(defaultTaxon.getUuid());
1651
                if (tmp!=null) {
1652
                    defaultTaxon=CdmBase.deproxy(tmp,Taxon.class);
1653
                }else{
1654
                    importer.getTaxonService().saveOrUpdate(defaultTaxon);
1655
                }
1656
            }catch(Exception e){
1657
                logger.debug("TAXON EXISTS"+defaultTaxon);
1658
            }
1659

    
1660
            TaxonDescription td =importer.getTaxonDescription(defaultTaxon, false, true);
1661
            defaultTaxon.addDescription(td);
1662
            td.addElement(textData);
1663
            sourceHandler.addAndSaveSource(currentRef, td,currentRef);
1664
            importer.getTaxonService().saveOrUpdate(defaultTaxon);
1665
        }
1666
    }
1667

    
1668

    
1669

    
1670
    /**
1671
     * @param synonyms: the XML Nodegroup to parse
1672
     * @param nametosave: the list of objects to save into the CDM
1673
     * @param acceptedTaxon: the current acceptedTaxon
1674
     * @param refMods: the current reference extracted from the MODS
1675
     */
1676
    @SuppressWarnings({ "rawtypes" })
1677
    private void extractSynonyms(Node synonyms, Taxon acceptedTaxon,Reference<?> refMods) {
1678
        logger.info("extractSynonyms");
1679
        //System.out.println("extractSynonyms for: "+acceptedTaxon);
1680
        Taxon ttmp = (Taxon) importer.getTaxonService().find(acceptedTaxon.getUuid());
1681
        if (ttmp != null) {
1682
            acceptedTaxon = CdmBase.deproxy(ttmp,Taxon.class);
1683
        }
1684
        else{
1685
            acceptedTaxon = CdmBase.deproxy(acceptedTaxon, Taxon.class);
1686
        }
1687
        NodeList children = synonyms.getChildNodes();
1688
        TaxonNameBase nameToBeFilled = null;
1689
        List<MyName> names = new ArrayList<MyName>();
1690

    
1691
        if(synonyms.getNodeName().equalsIgnoreCase("tax:name")){
1692
            MyName myName;
1693
            try {
1694
                myName = extractScientificNameSynonym(synonyms,refMods);
1695
                names.add(myName);
1696
            } catch (TransformerFactoryConfigurationError e) {
1697
                logger.warn(e);
1698
            } catch (TransformerException e) {
1699
                logger.warn(e);
1700
            }
1701
        }
1702

    
1703

    
1704
        for (int i=0;i<children.getLength();i++){
1705
            if (children.item(i).getNodeName().equalsIgnoreCase("tax:p")){
1706
                NodeList tmp = children.item(i).getChildNodes();
1707
                //                String fullContent = children.item(i).getTextContent();
1708
                for (int j=0; j< tmp.getLength();j++){
1709
                    if(tmp.item(j).getNodeName().equalsIgnoreCase("tax:name")){
1710
                        MyName myName;
1711
                        try {
1712
                            myName = extractScientificNameSynonym(tmp.item(j),refMods);
1713
                            names.add(myName);
1714
                        } catch (TransformerFactoryConfigurationError e) {
1715
                            logger.warn(e);
1716
                        } catch (TransformerException e) {
1717
                            logger.warn(e);
1718
                        }
1719

    
1720
                    }
1721
                }
1722
            }
1723
            if(children.item(i).getNodeName().equalsIgnoreCase("tax:name")){
1724
                MyName myName;
1725
                try {
1726
                    myName = extractScientificNameSynonym(children.item(i),refMods);
1727
                    names.add(myName);
1728
                } catch (TransformerFactoryConfigurationError e) {
1729
                    logger.warn(e);
1730
                } catch (TransformerException e) {
1731
                    logger.warn(e);
1732
                }
1733

    
1734
            }
1735
        }
1736
        NomenclaturalStatusType statusType = null;
1737
        //System.out.println("names: "+names);
1738
        for(MyName name:names){
1739
            //System.out.println("HANDLE NAME "+name);
1740

    
1741
            statusType = null;
1742

    
1743
            nameToBeFilled = name.getTaxonNameBase();
1744

    
1745
            Synonym synonym = name.getSyno();
1746
            /* INonViralNameParser parser = NonViralNameParserImpl.NewInstance();
1747
            nameToBeFilled = parser.parseFullName(name.getName(), nomenclaturalCode, name.getRank());
1748
            if (nameToBeFilled.hasProblem() &&
1749
                    !((nameToBeFilled.getParsingProblems().size()==1) && nameToBeFilled.getParsingProblems().contains(ParserProblem.CheckRank)) ) {
1750
                //            if (nameToBeFilled.hasProblem() && nameToBeFilled.getParsingProblems().contains(ParserProblem.UnparsableNamePart)){
1751
                addProblemNameToFile(name.getName(),"",nomenclaturalCode,name.getRank());
1752
                nameToBeFilled = solveNameProblem(name.getOriginalName(), name.getName(), parser,name.getAuthor(), name.getRank());
1753
            }
1754
            nameToBeFilled = getTaxonNameBase(nameToBeFilled,nametosave,statusType);
1755
             */
1756
            if (!name.getIdentifier().isEmpty() && (name.getIdentifier().length()>2)){
1757
                setLSID(name.getIdentifier(), synonym);
1758
            }
1759

    
1760
            Set<Synonym> synonymsSet= acceptedTaxon.getSynonyms();
1761
            //            System.out.println(synonym.getName()+" -- "+synonym.getSec());
1762
            boolean synoExist = false;
1763
            for (Synonym syn: synonymsSet){
1764
                //System.out.println(syn.getName()+" -- "+syn.getSec());
1765
                boolean a =syn.getName().equals(synonym.getName());
1766
                boolean b = syn.getSec().equals(synonym.getSec());
1767
                if (a && b) {
1768
                    synoExist=true;
1769
                }
1770
            }
1771
            if (!synonymsSet.contains(synonym) && ! (synoExist)) {
1772
                //System.out.println("SYNONYM");
1773
                sourceHandler.addSource(refMods, synonym);
1774

    
1775
                acceptedTaxon.addSynonym(synonym, SynonymRelationshipType.SYNONYM_OF(),refMods, null);
1776

    
1777
            }
1778
        }
1779
        importer.getTaxonService().saveOrUpdate(acceptedTaxon);
1780
    }
1781

    
1782

    
1783
    /**
1784
     * @param refgroup: the XML nodes
1785
     * @param nametosave: the list of objects to save into the CDM
1786
     * @param acceptedTaxon: the current acceptedTaxon
1787
     * @param nametosave: the list of objects to save into the CDM
1788
     * @param refMods: the current reference extracted from the MODS
1789
     * @return the acceptedTaxon (why?)
1790
     * handle cases where the bibref are inside <p> and outside
1791
     */
1792
    @SuppressWarnings({ "rawtypes" })
1793
    private Taxon extractReferences(Node refgroup, List<TaxonNameBase> nametosave, Taxon acceptedTaxon, Reference<?> refMods) {
1794
        logger.info("extractReferences");
1795
        acceptedTaxon = CdmBase.deproxy(acceptedTaxon, Taxon.class);
1796

    
1797
        NodeList children = refgroup.getChildNodes();
1798
        NonViralName<?> nameToBeFilled = getNonViralNameAccNomenclature();
1799

    
1800
        ReferenceBuilder refBuild = new ReferenceBuilder(sourceHandler);
1801
        for (int i=0;i<children.getLength();i++){
1802
            if(children.item(i).getNodeName().equalsIgnoreCase("tax:bibref")){
1803
                String ref = children.item(i).getTextContent().trim();
1804
                refBuild.builReference(ref, treatmentMainName, nomenclaturalCode,  acceptedTaxon, refMods);
1805
                if (!refBuild.isFoundBibref()){
1806
                    extractReferenceRawText(children.item(i).getChildNodes(), nameToBeFilled, refMods, acceptedTaxon);
1807
                }
1808
            }
1809

    
1810
            if(children.item(i).getNodeName().equalsIgnoreCase("tax:p")){
1811
                NodeList references = children.item(i).getChildNodes();
1812
                String descr="";
1813
                for (int j=0;j<references.getLength();j++){
1814
                    if(references.item(j).getNodeName().equalsIgnoreCase("tax:bibref")){
1815
                        String ref = references.item(j).getTextContent().trim();
1816
                        refBuild.builReference(ref, treatmentMainName,  nomenclaturalCode,  acceptedTaxon, refMods);
1817
                    }
1818
                    else
1819
                        if (references.item(j).getNodeName().equalsIgnoreCase("#text")
1820
                                && !references.item(j).getTextContent().trim().isEmpty()){
1821
                            descr += references.item(j).getTextContent().trim();
1822
                        }
1823

    
1824
                }
1825
                if (!refBuild.isFoundBibref()){
1826
                    //if it's not tagged, put it as row information.
1827
                    //                    extractReferenceRawText(references, nameToBeFilled, nametosave, refMods, acceptedTaxon);
1828
                    //then put it as a not markup feature if not empty
1829
                    if (!stringIsEmpty(descr.trim())){
1830
                        Feature currentFeature= getNotMarkedUpFeatureObject();
1831
                        setParticularDescription(descr.trim(),acceptedTaxon,acceptedTaxon, refMods,currentFeature);
1832
                    }
1833
                }
1834
            }
1835
        }
1836
        //        importer.getClassificationService().saveOrUpdate(classification);
1837
        return acceptedTaxon;
1838

    
1839
    }
1840

    
1841
    /**
1842
     * get the non viral name according to the current nomenclature
1843
     * @return
1844
     */
1845
    private NonViralName<?> getNonViralNameAccNomenclature() {
1846
        //logger.info("getNonViralNameAccNomenclature");
1847
        NonViralName<?> nameToBeFilled = null;
1848
        if (nomenclaturalCode.equals(NomenclaturalCode.ICNAFP)){
1849
            nameToBeFilled = BotanicalName.NewInstance(null);
1850
        }
1851
        if (nomenclaturalCode.equals(NomenclaturalCode.ICZN)){
1852
            nameToBeFilled = ZoologicalName.NewInstance(null);
1853
        }
1854
        if (nomenclaturalCode.equals(NomenclaturalCode.ICNB)){
1855
            nameToBeFilled = BacterialName.NewInstance(null);
1856
        }
1857
        return nameToBeFilled;
1858
    }
1859

    
1860
    /**
1861
     * @return the feature object for the category "not marked up"
1862
     */
1863
    @SuppressWarnings("rawtypes")
1864
    private Feature getNotMarkedUpFeatureObject() {
1865
        logger.info("getNotMarkedUpFeatureObject");
1866
        List<Feature> features = importer.getTermService().list(Feature.class, null,null,null,null);
1867
        Feature currentFeature =null;
1868
        for (Feature feat: features){
1869
            String tmpF = feat.getTitleCache();
1870
            if (tmpF.equalsIgnoreCase(notMarkedUp)) {
1871
                currentFeature=feat;
1872
            }
1873
        }
1874
        if (currentFeature == null) {
1875
            currentFeature=Feature.NewInstance(notMarkedUp, notMarkedUp, notMarkedUp);
1876
            currentFeature.setUuid(NotMarkedUpUUID);
1877
            importer.getTermService().saveOrUpdate(currentFeature);
1878
        }
1879
        return currentFeature;
1880
    }
1881

    
1882
    /**
1883
     * @param references
1884
     * handle cases where the bibref are inside <p> and outside
1885
     */
1886
    @SuppressWarnings("rawtypes")
1887
    private void extractReferenceRawText(NodeList references, NonViralName<?> nameToBeFilled, Reference<?> refMods,
1888
            Taxon acceptedTaxon) {
1889
        logger.info("extractReferenceRawText");
1890
        String refString="";
1891
        NomenclaturalStatusType statusType = null;
1892
        currentMyName= new MyName(true);
1893
        for (int j=0;j<references.getLength();j++){
1894
            acceptedTaxon=CdmBase.deproxy(acceptedTaxon, Taxon.class);
1895
            //no bibref tag inside
1896
            //            System.out.println("references.item(j).getNodeName()"+references.item(j).getNodeName());
1897
            if (references.item(j).getNodeName().equalsIgnoreCase("tax:name")){
1898

    
1899
                try {
1900
                    currentMyName = extractScientificName(references.item(j),refMods);
1901
                    //                    if (myName.getNewName().isEmpty()) {
1902
                    //                        name=myName.getOriginalName()+"---"+myName.getRank()+"---"+myName.getIdentifier()+"---"+myName.getStatus();
1903
                    //                    } else {
1904
                    //                        name=myName.getNewName()+"---"+myName.getRank()+"---"+myName.getIdentifier()+"---"+myName.getStatus();
1905
                    //                    }
1906
                } catch (TransformerFactoryConfigurationError e) {
1907
                    logger.warn(e);
1908
                } catch (TransformerException e) {
1909
                    logger.warn(e);
1910
                }
1911

    
1912
                //                name=name.trim();
1913
            }
1914
            if (references.item(j).getNodeName().equalsIgnoreCase("#text")){
1915
                refString = references.item(j).getTextContent().trim();
1916
            }
1917
            if(references.item(j).getNodeName().equalsIgnoreCase("#text") && !references.item(j).getTextContent().trim().isEmpty()){
1918
                //
1919
                statusType = null;
1920
                if (!currentMyName.getStatus().isEmpty()){
1921
                    try {
1922
                        statusType = nomStatusString2NomStatus(currentMyName.getStatus());
1923
                    } catch (UnknownCdmTypeException e) {
1924
                        addProblematicStatusToFile(currentMyName.getStatus());
1925
                        logger.warn("Problem with status");
1926
                    }
1927
                }
1928

    
1929

    
1930
                /*INonViralNameParser parser = NonViralNameParserImpl.NewInstance();*/
1931
                String fullLineRefName = references.item(j).getTextContent().trim();
1932
                int nameOrRefOrOther=2;
1933
                nameOrRefOrOther=askIfNameContained(fullLineRefName);
1934
                //                System.out.println("NAMEORREFOR?? "+nameOrRefOrOther);
1935
                if (nameOrRefOrOther==0){
1936
                    /*TaxonNameBase nameTBF = parser.parseFullName(fullLineRefName, nomenclaturalCode, Rank.UNKNOWN_RANK());
1937
                    if (nameTBF.hasProblem() &&
1938
                            !((nameTBF.getParsingProblems().size()==1) && nameTBF.getParsingProblems().contains(ParserProblem.CheckRank)) ) {
1939
                        addProblemNameToFile(fullLineRefName,"",nomenclaturalCode,Rank.UNKNOWN_RANK());
1940
                        nameTBF=solveNameProblem(fullLineRefName, fullLineRefName,parser,currentMyName.getAuthor(), currentMyName.getRank());
1941
                    }
1942
                    nameTBF = getTaxonNameBase(nameTBF,nametosave,statusType);
1943
                     */
1944
                    TaxonNameBase nameTBF = currentMyName.getTaxonNameBase();
1945
                    Synonym synonym = null;
1946
                    if (!currentMyName.getStatus().isEmpty()){
1947
                        try {
1948
                            statusType = nomStatusString2NomStatus(currentMyName.getStatus());
1949
                            nameToBeFilled.addStatus(NomenclaturalStatus.NewInstance(statusType));
1950
                            synonym = Synonym.NewInstance(nameTBF, refMods);
1951
                        } catch (UnknownCdmTypeException e) {
1952
                            addProblematicStatusToFile(currentMyName.getStatus());
1953
                            logger.warn("Problem with status");
1954
                            synonym = Synonym.NewInstance(nameTBF, refMods);
1955
                            synonym.setAppendedPhrase(currentMyName.getStatus());
1956
                        }
1957
                    }
1958
                    else{
1959
                        synonym =  Synonym.NewInstance(nameTBF, refMods);
1960
                    }
1961

    
1962
                    Set<Synonym> synonymsSet= acceptedTaxon.getSynonyms();
1963
                    //                    System.out.println(synonym.getName()+" -- "+synonym.getSec());
1964
                    boolean synoExist = false;
1965
                    for (Synonym syn: synonymsSet){
1966
                        //                        System.out.println(syn.getName()+" -- "+syn.getSec());
1967
                        boolean a =syn.getName().equals(synonym.getName());
1968
                        boolean b = syn.getSec().equals(synonym.getSec());
1969
                        if (a && b) {
1970
                            synoExist=true;
1971
                        }
1972
                    }
1973
                    if (!synonymsSet.contains(synonym) && ! (synoExist)) {
1974
                        sourceHandler.addSource(refMods, synonym);
1975

    
1976
                        acceptedTaxon.addSynonym(synonym, SynonymRelationshipType.SYNONYM_OF(),refMods, null);
1977
                    }
1978
                }
1979

    
1980
                if (nameOrRefOrOther==1){
1981
                    Reference<?> re = ReferenceFactory.newGeneric();
1982
                    re.setTitleCache(fullLineRefName, true);
1983

    
1984
                    /* TaxonNameBase nameTBF = parser.parseFullName(currentMyName.getName(), nomenclaturalCode, currentMyName.getRank());
1985
                    if (nameTBF.hasProblem() &&
1986
                            !((nameTBF.getParsingProblems().size()==1) && nameTBF.getParsingProblems().contains(ParserProblem.CheckRank)) ) {
1987
                        addProblemNameToFile(currentMyName.getName(),"",nomenclaturalCode,currentMyName.getRank());
1988
                        nameTBF=solveNameProblem(currentMyName.getName(), currentMyName.getName(),parser,currentMyName.getAuthor(), currentMyName.getRank());
1989
                    }
1990
                    nameTBF = getTaxonNameBase(nameTBF,nametosave,statusType);
1991
                     */
1992
                    TaxonNameBase nameTBF = currentMyName.getTaxonNameBase();
1993
                    Synonym synonym = null;
1994
                    if (!currentMyName.getStatus().isEmpty()){
1995
                        try {
1996
                            statusType = nomStatusString2NomStatus(currentMyName.getStatus());
1997
                            nameToBeFilled.addStatus(NomenclaturalStatus.NewInstance(statusType));
1998
                            synonym = Synonym.NewInstance(nameTBF, refMods);
1999
                        } catch (UnknownCdmTypeException e) {
2000
                            addProblematicStatusToFile(currentMyName.getStatus());
2001
                            logger.warn("Problem with status");
2002
                            synonym = Synonym.NewInstance(nameTBF, refMods);
2003
                            synonym.setAppendedPhrase(currentMyName.getStatus());
2004
                        }
2005
                    }
2006
                    else{
2007
                        synonym =  Synonym.NewInstance(nameTBF, refMods);
2008
                    }
2009

    
2010
                    Set<Synonym> synonymsSet= acceptedTaxon.getSynonyms();
2011
                    //                    System.out.println(synonym.getName()+" -- "+synonym.getSec());
2012
                    boolean synoExist = false;
2013
                    for (Synonym syn: synonymsSet){
2014
                        //                        System.out.println(syn.getName()+" -- "+syn.getSec());
2015
                        boolean a =syn.getName().equals(synonym.getName());
2016
                        boolean b = syn.getSec().equals(synonym.getSec());
2017
                        if (a && b) {
2018
                            synoExist=true;
2019
                        }
2020
                    }
2021
                    if (!synonymsSet.contains(synonym) && ! (synoExist)) {
2022
                        sourceHandler.addSource(refMods, synonym);
2023

    
2024
                        acceptedTaxon.addSynonym(synonym, SynonymRelationshipType.SYNONYM_OF(),re, null);
2025
                    }
2026

    
2027
                }
2028

    
2029

    
2030
                if (!currentMyName.getIdentifier().isEmpty() && (currentMyName.getIdentifier().length()>2)){
2031
                    setLSID(currentMyName.getIdentifier(), acceptedTaxon);
2032
                }
2033
            }
2034

    
2035
            if(!currentMyName.getName().isEmpty()){
2036
                //logger.info("acceptedTaxon and name: *"+acceptedTaxon.getTitleCache()+"*, *"+currentMyName.getName()+"*");
2037
                if (acceptedTaxon.getTitleCache().split("sec")[0].trim().equalsIgnoreCase(currentMyName.getName().trim())){
2038
                    Reference<?> refS = ReferenceFactory.newGeneric();
2039
                    refS.setTitleCache(refString, true);
2040
                    //                            TaxonDescription td =importer.getTaxonDescription(acceptedTaxon, false, true);
2041
                    //                            acceptedTaxon.addDescription(td);
2042
                    //                            acceptedTaxon.addSource(refSource);
2043
                    //
2044
                    //                            TextData textData = TextData.NewInstance(Feature.CITATION());
2045
                    //
2046
                    //                            textData.addSource(null, null, refS, null);
2047
                    //                            td.addElement(textData);
2048
                    //                            td.addSource(refSource);
2049
                    //                            importer.getDescriptionService().saveOrUpdate(td);
2050

    
2051

    
2052
                    if (!currentMyName.getIdentifier().isEmpty() && (currentMyName.getIdentifier().length()>2)){
2053
                        setLSID(currentMyName.getIdentifier(), acceptedTaxon);
2054

    
2055
                    }
2056

    
2057
                    acceptedTaxon.getName().setNomenclaturalReference(refS);
2058
                }
2059
                else{
2060
                    /* INonViralNameParser parser = NonViralNameParserImpl.NewInstance();
2061
                    TaxonNameBase nameTBF = parser.parseFullName(currentMyName.getName(), nomenclaturalCode, currentMyName.getRank());
2062
                    if (nameTBF.hasProblem() &&
2063
                            !((nameTBF.getParsingProblems().size()==1) && nameTBF.getParsingProblems().contains(ParserProblem.CheckRank)) ) {
2064
                        //            if (nameToBeFilled.hasProblem() && nameToBeFilled.getParsingProblems().contains(ParserProblem.UnparsableNamePart)){
2065
                        addProblemNameToFile(currentMyName.getName(),"",nomenclaturalCode,currentMyName.getRank());
2066
                        nameTBF=solveNameProblem(currentMyName.getOriginalName(), currentMyName.getName(),parser,currentMyName.getAuthor(), currentMyName.getRank());
2067
                    }
2068
                    nameTBF = getTaxonNameBase(nameTBF,nametosave,statusType);
2069
                     */
2070
                    TaxonNameBase nameTBF = currentMyName.getTaxonNameBase();
2071
                    Synonym synonym = null;
2072
                    if (!currentMyName.getStatus().isEmpty()){
2073
                        try {
2074
                            statusType = nomStatusString2NomStatus(currentMyName.getStatus());
2075
                            nameToBeFilled.addStatus(NomenclaturalStatus.NewInstance(statusType));
2076
                            synonym = Synonym.NewInstance(nameTBF, refMods);
2077
                        } catch (UnknownCdmTypeException e) {
2078
                            addProblematicStatusToFile(currentMyName.getStatus());
2079
                            logger.warn("Problem with status");
2080
                            synonym = Synonym.NewInstance(nameTBF, refMods);
2081
                            synonym.setAppendedPhrase(currentMyName.getStatus());
2082
                        }
2083
                    }
2084
                    else{
2085
                        synonym =  Synonym.NewInstance(nameTBF, refMods);
2086
                    }
2087

    
2088

    
2089
                    if (!currentMyName.getIdentifier().isEmpty() && (currentMyName.getIdentifier().length()>2)){
2090
                        setLSID(currentMyName.getIdentifier(), synonym);
2091
                    }
2092

    
2093
                    Set<Synonym> synonymsSet= acceptedTaxon.getSynonyms();
2094
                    //                    System.out.println(synonym.getName()+" -- "+synonym.getSec());
2095
                    boolean synoExist = false;
2096
                    for (Synonym syn: synonymsSet){
2097
                        //                        System.out.println(syn.getName()+" -- "+syn.getSec());
2098
                        boolean a =syn.getName().equals(synonym.getName());
2099
                        boolean b = syn.getSec().equals(synonym.getSec());
2100
                        if (a && b) {
2101
                            synoExist=true;
2102
                        }
2103
                    }
2104
                    if (!synonymsSet.contains(synonym) && ! (synoExist)) {
2105
                        sourceHandler.addSource(refMods, synonym);
2106

    
2107
                        acceptedTaxon.addSynonym(synonym, SynonymRelationshipType.SYNONYM_OF(),refMods, null);
2108
                    }
2109
                }
2110
            }
2111
            importer.getTaxonService().saveOrUpdate(acceptedTaxon);
2112
        }
2113
    }
2114

    
2115

    
2116

    
2117
    /**
2118
     * @param identifier
2119
     * @param acceptedTaxon
2120
     */
2121
    @SuppressWarnings("rawtypes")
2122
    private void setLSID(String identifier, TaxonBase<?> taxon) {
2123
        //logger.info("setLSID");
2124
        //        boolean lsidok=false;
2125
        String id = identifier.split("__")[0];
2126
        String source = identifier.split("__")[1];
2127
        if (id.indexOf("lsid")>-1){
2128
            try {
2129
                LSID lsid = new LSID(id);
2130
                taxon.setLsid(lsid);
2131
                //                lsidok=true;
2132
            } catch (MalformedLSIDException e) {
2133
                logger.warn("Malformed LSID");
2134
            }
2135

    
2136
        }
2137

    
2138
        //logger.info("search reference for LSID");
2139
        //  if ((id.indexOf("lsid")<0) || !lsidok){
2140
        //ADD ORIGINAL SOURCE ID EVEN IF LSID
2141
        Reference<?> re = null;
2142
        Pager<Reference> references = importer.getReferenceService().findByTitle(Reference.class, source, MatchMode.EXACT, null, 1, null, null, null);
2143
        if( references !=null && references.getCount()>0){
2144
            re=references.getRecords().get(0);
2145
        }
2146
        //logger.info("search reference for LSID-end");
2147
        if(re == null){
2148
            re = ReferenceFactory.newGeneric();
2149
            re.setTitleCache(source, true);
2150
            importer.getReferenceService().saveOrUpdate(re);
2151
        }
2152
        re=CdmBase.deproxy(re, Reference.class);
2153

    
2154
        //logger.info("search source for LSID");
2155
        Set<IdentifiableSource> sources = taxon.getSources();
2156
        boolean lsidinsource=false;
2157
        boolean urlinsource=false;
2158
        for (IdentifiableSource src:sources){
2159
            if (id.equalsIgnoreCase(src.getIdInSource()) && re.getTitleCache().equals(src.getCitation().getTitleCache())) {
2160
                lsidinsource=true;
2161
            }
2162
            if (src.getIdInSource() == null && re.getTitleCache().equals(sourceUrlRef.getTitleCache())) {
2163
                urlinsource=true;
2164
            }
2165
        }
2166
        if(!lsidinsource) {
2167
            taxon.addSource(OriginalSourceType.Import, id,null,re,null);
2168
        }
2169
        if(!urlinsource)
2170
        {
2171
            sourceUrlRef=CdmBase.deproxy(sourceUrlRef, Reference.class);
2172
            taxon.addSource(OriginalSourceType.Import, null,null,sourceUrlRef,null);
2173
            // }
2174
        }
2175

    
2176
    }
2177

    
2178
    /**
2179
     * try to solve a parsing problem for a scientific name
2180
     * @param original : the name from the OCR document
2181
     * @param name : the tagged version
2182
     * @param parser
2183
     * @return the corrected TaxonNameBase
2184
     */
2185
    /*   @SuppressWarnings({ "unchecked", "rawtypes" })
2186
    private TaxonNameBase<?,?> solveNameProblem(String original, String name, INonViralNameParser parser, String author, Rank rank) {
2187
        Map<String,String> ato = namesMap.get(original);
2188
        if (ato == null) {
2189
            ato = namesMap.get(original+" "+author);
2190
        }
2191

    
2192

    
2193
        if (ato == null && rank.equals(Rank.UNKNOWN_RANK())){
2194
            rank=askForRank(original, Rank.UNKNOWN_RANK(), nomenclaturalCode);
2195
        }
2196
        if (ato != null && rank.equals(Rank.UNKNOWN_RANK())){
2197
            rank = getRank(ato);
2198
        }
2199
        //        TaxonNameBase<?,?> nameTBF = parser.parseFullName(name, nomenclaturalCode, rank);
2200
        TaxonNameBase<?,?> nameTBF = parser.parseSimpleName(name, nomenclaturalCode, rank);
2201
        //                logger.info("RANK: "+rank);
2202
        int retry=0;
2203
        List<ParserProblem> problems = nameTBF.getParsingProblems();
2204
        for (ParserProblem pb:problems) {
2205
            System.out.println(pb.toString());
2206
        }
2207
        while (nameTBF.hasProblem() && (retry <1) && !((nameTBF.getParsingProblems().size()==1) && nameTBF.getParsingProblems().contains(ParserProblem.CheckRank))){
2208
            addProblemNameToFile(name,author,nomenclaturalCode,rank);
2209
            String fullname=name;
2210
            if(! skippQuestion) {
2211
                fullname =  getFullReference(name,nameTBF.getParsingProblems());
2212
            }
2213
            if (nomenclaturalCode.equals(NomenclaturalCode.ICNAFP)){
2214
                nameTBF = BotanicalName.NewInstance(null);
2215
            }
2216
            if (nomenclaturalCode.equals(NomenclaturalCode.ICZN)){
2217
                nameTBF = ZoologicalName.NewInstance(null);
2218
            }
2219
            if (nomenclaturalCode.equals(NomenclaturalCode.ICNB)){
2220
                nameTBF= BacterialName.NewInstance(null);
2221
            }
2222
            parser.parseReferencedName(nameTBF, fullname, rank, false);
2223
            retry++;
2224
        }
2225
        if (retry == 1){
2226
            if(author != null){
2227
                if (name.indexOf(author)>-1) {
2228
                    nameTBF = parser.parseSimpleName(name.substring(0, name.indexOf(author)), nomenclaturalCode, rank);
2229
                } else {
2230
                    nameTBF = parser.parseSimpleName(name, nomenclaturalCode, rank);
2231
                }
2232
                if (nameTBF.hasProblem()){
2233
                    if (name.indexOf(author)>-1) {
2234
                        addProblemNameToFile(name.substring(0, name.indexOf(author)),author,nomenclaturalCode,rank);
2235
                    } else {
2236
                        addProblemNameToFile(name,author,nomenclaturalCode,rank);
2237
                    }
2238
                    //                    System.out.println("TBF still has problems "+nameTBF.hasProblem());
2239
                    problems = nameTBF.getParsingProblems();
2240
                    for (ParserProblem pb:problems) {
2241
                        System.out.println(pb.toString());
2242
                    }
2243
                    nameTBF.setFullTitleCache(name, true);
2244
                }else{
2245
                    if (nomenclaturalCode.equals(NomenclaturalCode.ICNAFP)) {
2246
                        ((BotanicalName) nameTBF).setAuthorshipCache(currentMyName.getAuthor());
2247
                    }
2248
                    if (nomenclaturalCode.equals(NomenclaturalCode.ICZN)) {
2249
                        ((ZoologicalName) nameTBF).setAuthorshipCache(currentMyName.getAuthor());
2250
                    }
2251
                    if (nomenclaturalCode.equals(NomenclaturalCode.ICNB)) {
2252
                        ((BacterialName) nameTBF).setAuthorshipCache(currentMyName.getAuthor());
2253
                    }
2254
                }
2255
                //                    logger.info("FULL TITLE CACHE "+name);
2256
            }else{
2257
                nameTBF.setFullTitleCache(name, true);
2258
            }
2259
        }
2260
        return nameTBF;
2261
    }
2262

    
2263
     */
2264

    
2265
    /**
2266
     * @param nomenclatureNode: the XML nodes
2267
     * @param nametosave: the list of objects to save into the CDM
2268
     * @param refMods: the current reference extracted from the MODS
2269
     * @return
2270
     */
2271
    @SuppressWarnings({ "rawtypes" })
2272
    private Taxon extractNomenclature(Node nomenclatureNode,  List<TaxonNameBase> nametosave, Reference<?> refMods) throws ClassCastException{
2273
        refMods=CdmBase.deproxy(refMods, Reference.class);
2274

    
2275
        logger.info("extractNomenclature");
2276
        NodeList children = nomenclatureNode.getChildNodes();
2277
        String freetext="";
2278
        NonViralName<?> nameToBeFilled = null;
2279
        Taxon acceptedTaxon = null;
2280
        //   INonViralNameParser parser = NonViralNameParserImpl.NewInstance();
2281

    
2282
        //        String fullContent = nomenclatureNode.getTextContent();
2283

    
2284
        NomenclaturalStatusType statusType = null;
2285
        for (int i=0;i<children.getLength();i++){
2286
            if(children.item(i).getNodeName().equalsIgnoreCase("tax:status")){
2287
                String status = children.item(i).getTextContent().trim();
2288
                if (!status.isEmpty()){
2289
                    try {
2290
                        statusType = nomStatusString2NomStatus(status);
2291
                    } catch (UnknownCdmTypeException e) {
2292
                        addProblematicStatusToFile(status);
2293
                        logger.warn("Problem with status");
2294
                    }
2295
                }
2296
            }
2297
        }
2298

    
2299
        boolean containsSynonyms=false;
2300
        for (int i=0;i<children.getLength();i++){
2301

    
2302
            if (children.item(i).getNodeName().equalsIgnoreCase("#text")) {
2303
                freetext=children.item(i).getTextContent();
2304
            }
2305
            if (children.item(i).getNodeName().equalsIgnoreCase("tax:collection_event")) {
2306
                //                System.out.println("COLLECTION EVENT INSIDE NOMENCLATURE");
2307
                extractMaterialsDirect(children.item(i), acceptedTaxon, refMods, "collection");
2308
            }
2309
            if(children.item(i).getNodeName().equalsIgnoreCase("tax:name")){
2310
                //System.out.println("HANDLE FIRST NAME OF THE LIST");
2311
                if(!containsSynonyms){
2312
                    //System.out.println("I : "+i);
2313
                    currentMyName = new MyName(false);
2314
                    try {
2315
                        currentMyName = extractScientificName(children.item(i),refMods);
2316
                        treatmentMainName = currentMyName.getNewName();
2317
                        originalTreatmentName = currentMyName.getOriginalName();
2318

    
2319
                    } catch (TransformerFactoryConfigurationError e1) {
2320
                        logger.warn(e1);
2321
                    } catch (TransformerException e1) {
2322
                        logger.warn(e1);
2323
                    }
2324

    
2325
                    if (currentMyName.getRank().equals(Rank.UNKNOWN_RANK()) || currentMyName.getRank().isLower(configState.getConfig().getMaxRank()) || currentMyName.getRank().equals(configState.getConfig().getMaxRank())){
2326
                        maxRankRespected=true;
2327

    
2328
                        nameToBeFilled=currentMyName.getTaxonNameBase();
2329

    
2330
                        //                        acceptedTaxon = importer.getTaxonService().findBestMatchingTaxon(treatmentMainName);
2331
                        acceptedTaxon=currentMyName.getTaxon();
2332
                        //System.out.println("TreatmentName "+treatmentMainName+" - "+acceptedTaxon);
2333

    
2334

    
2335
                        boolean statusMatch=false;
2336
                        if(acceptedTaxon !=null ){
2337
                            acceptedTaxon = CdmBase.deproxy(acceptedTaxon, Taxon.class);
2338
                            statusMatch=compareStatus(acceptedTaxon, statusType);
2339
                            //System.out.println("statusMatch: "+statusMatch);
2340
                        }
2341
                        if (acceptedTaxon ==null || (acceptedTaxon != null && !statusMatch)){
2342

    
2343
                            nameToBeFilled=currentMyName.getTaxonNameBase();
2344
                            if (nameToBeFilled!=null){
2345
                                if (!originalTreatmentName.isEmpty()) {
2346
                                    TaxonNameDescription td = TaxonNameDescription.NewInstance();
2347
                                    td.setTitleCache(originalTreatmentName, true);
2348
                                    nameToBeFilled.addDescription(td);
2349
                                }
2350

    
2351
                                if(statusType != null) {
2352
                                    nameToBeFilled.addStatus(NomenclaturalStatus.NewInstance(statusType));
2353
                                }
2354
                                sourceHandler.addSource(refMods, nameToBeFilled);
2355

    
2356
                                if (nameToBeFilled.getNomenclaturalReference() == null) {
2357
                                    acceptedTaxon= new Taxon(nameToBeFilled,refMods);
2358
                                    //System.out.println("NEW ACCEPTED HERE "+nameToBeFilled);
2359
                                }
2360
                                else {
2361
                                    acceptedTaxon= new Taxon(nameToBeFilled,(Reference<?>) nameToBeFilled.getNomenclaturalReference() );//TODO TOFIX reference
2362
                                    //System.out.println("NEW ACCEPTED HERE2 "+nameToBeFilled);
2363
                                }
2364

    
2365
                                sourceHandler.addSource(refMods, acceptedTaxon);
2366

    
2367
                                if(!configState.getConfig().doKeepOriginalSecundum()) {
2368
                                    acceptedTaxon.setSec(configState.getConfig().getSecundum());
2369
                                    //logger.info("SET SECUNDUM "+configState.getConfig().getSecundum());
2370
                                    //System.out.println("SET SECUNDUM "+configState.getConfig().getSecundum());
2371
                                }
2372

    
2373
                                if (!currentMyName.getIdentifier().isEmpty() && (currentMyName.getIdentifier().length()>2)){
2374
                                    setLSID(currentMyName.getIdentifier(), acceptedTaxon);
2375
                                }
2376

    
2377

    
2378
                                importer.getTaxonService().saveOrUpdate(acceptedTaxon);
2379
                                acceptedTaxon = CdmBase.deproxy(acceptedTaxon, Taxon.class);
2380
                            }
2381

    
2382
                        }else{
2383
                            acceptedTaxon = CdmBase.deproxy(acceptedTaxon, Taxon.class);
2384
                            Set<IdentifiableSource> sources = acceptedTaxon.getSources();
2385
                            boolean sourcelinked=false;
2386
                            for (IdentifiableSource source:sources){
2387
                                if (source.getCitation().getTitleCache().equalsIgnoreCase(refMods.getTitleCache())) {
2388
                                    sourcelinked=true;
2389
                                }
2390
                            }
2391
                            if (!configState.getConfig().doKeepOriginalSecundum()) {
2392
                                acceptedTaxon.setSec(configState.getConfig().getSecundum());
2393
                                //logger.info("SET SECUNDUM "+configState.getConfig().getSecundum());
2394
                                //System.out.println("SET SECUNDUM "+configState.getConfig().getSecundum());
2395
                            }
2396
                            importer.getTaxonService().saveOrUpdate(acceptedTaxon);
2397
                            acceptedTaxon = CdmBase.deproxy(acceptedTaxon, Taxon.class);
2398
                            if (!sourcelinked){
2399
                                sourceHandler.addSource(refMods, acceptedTaxon);
2400
                            }
2401
                            if (!sourcelinked || !configState.getConfig().doKeepOriginalSecundum()){
2402

    
2403
                                if (!currentMyName.getIdentifier().isEmpty() && (currentMyName.getIdentifier().length()>2)){
2404
                                    setLSID(currentMyName.getIdentifier(), acceptedTaxon);
2405
                                }
2406
                                importer.getTaxonService().saveOrUpdate(acceptedTaxon);
2407
                            }
2408
                        }
2409
                    }else{
2410
                        maxRankRespected=false;
2411
                    }
2412
                    containsSynonyms=true;
2413
                }else{
2414
                    //System.out.println("YOUHOUUU "+i);
2415
                    try{
2416
                        extractSynonyms(children.item(i), acceptedTaxon, refMods);
2417
                    }catch(NullPointerException e){
2418
                        logger.warn("nullpointerexception, the accepted taxon might be null");
2419
                    }
2420
                }
2421
                containsSynonyms=true;
2422
            }
2423
            if (children.item(i).getNodeName().equalsIgnoreCase("tax:ref_group") && maxRankRespected){
2424
                reloadClassification();
2425
                //extract the References within the document
2426
                extractReferences(children.item(i),nametosave,acceptedTaxon,refMods);
2427
            }
2428
            if(!stringIsEmpty(freetext.trim())) {
2429
                setParticularDescription(freetext.trim(),acceptedTaxon,acceptedTaxon, refMods,getNotMarkedUpFeatureObject());
2430
            }
2431

    
2432
        }
2433
        //        importer.getClassificationService().saveOrUpdate(classification);
2434
        return acceptedTaxon;
2435
    }
2436

    
2437

    
2438
    /**
2439
     * @return
2440
     */
2441

    
2442
    private boolean compareStatus(TaxonBase<?> t, NomenclaturalStatusType statusType) {
2443
        //logger.info("compareStatus");
2444
        boolean statusMatch=false;
2445
        //found one taxon
2446
        Set<NomenclaturalStatus> status = t.getName().getStatus();
2447
        if (statusType!=null && status.size()>0){ //the statusType is known for both taxon
2448
            for (NomenclaturalStatus st:status){
2449
                NomenclaturalStatusType stype = st.getType();
2450
                if (stype.toString().equalsIgnoreCase(statusType.toString())) {
2451
                    statusMatch=true;
2452
                }
2453
            }
2454
        }
2455
        else{
2456
            if(statusType == null && status.size()==0) {//there is no statusType, we can assume it's the same
2457
                statusMatch=true;
2458
            }
2459
        }
2460
        return statusMatch;
2461
    }
2462

    
2463
    /**
2464
     * @param acceptedTaxon: the current acceptedTaxon
2465
     * @param ref: the current reference extracted from the MODS
2466
     * @return the parent for the current accepted taxon
2467
     */
2468
    /*  private Taxon createParent(Taxon acceptedTaxon, Reference<?> ref) {
2469
        acceptedTaxon = CdmBase.deproxy(acceptedTaxon, Taxon.class);
2470

    
2471
        List<Rank> rankList = new ArrayList<Rank>();
2472
        rankList = importer.getTermService().listByTermClass(Rank.class, null, null, null, null);
2473

    
2474
        List<String> rankListStr = new ArrayList<String>();
2475
        for (Rank r:rankList) {
2476
            rankListStr.add(r.toString());
2477
        }
2478
        String r="";
2479
        String s = acceptedTaxon.getTitleCache();
2480
        Taxon tax = null;
2481
        if(!skippQuestion){
2482
            int addTaxon = askAddParent(s);
2483
            logger.info("ADD TAXON: "+addTaxon);
2484
            if (addTaxon == 0 ){
2485
                Taxon tmp = askParent(acceptedTaxon, classification);
2486
                if (tmp == null){
2487
                    s = askSetParent(s);
2488
                    r = askRank(s,rankListStr);
2489

    
2490
                    NonViralName<?> nameToBeFilled = null;
2491
                    if (nomenclaturalCode.equals(NomenclaturalCode.ICNAFP)){
2492
                        nameToBeFilled = BotanicalName.NewInstance(null);
2493
                    }
2494
                    if (nomenclaturalCode.equals(NomenclaturalCode.ICZN)){
2495
                        nameToBeFilled = ZoologicalName.NewInstance(null);
2496
                    }
2497
                    if (nomenclaturalCode.equals(NomenclaturalCode.ICNB)){
2498
                        nameToBeFilled = BacterialName.NewInstance(null);
2499
                    }
2500
                    nameToBeFilled.setTitleCache(s, true);
2501
                    nameToBeFilled.setRank(getRank(r), true);
2502

    
2503
                    tax = Taxon.NewInstance(nameToBeFilled, ref);
2504
                }
2505
                else{
2506
                    tax=tmp;
2507
                }
2508

    
2509
                createParent(tax, ref);
2510
                //            logger.info("add parent child "+tax.getTitleCache()+", "+acceptedTaxon.getTitleCache());
2511
                classification.addParentChild(tax, acceptedTaxon, ref, null);
2512
            }
2513
            else{
2514
                classification.addChildTaxon(acceptedTaxon, ref, null);
2515
                tax=acceptedTaxon;
2516
            }
2517
        } else{
2518
            classification.addChildTaxon(acceptedTaxon, ref, null);
2519
            tax=acceptedTaxon;
2520
        }
2521
        //        logger.info("RETURN: "+tax );
2522
        return tax;
2523

    
2524
    }
2525

    
2526
     */
2527

    
2528

    
2529
    private MyName  extractScientificNameSynonym(Node name, Reference<?> refMods) throws TransformerFactoryConfigurationError, TransformerException {
2530
        //System.out.println("extractScientificNameSynonym");
2531
        logger.info("extractScientificNameSynonym");
2532
        String[] rankListToPrint_tmp ={"dwc:genus","dwc:specificepithet","dwc:species","dwc:subspecies", "dwc:infraspecificepithet","dwc:scientificnameauthorship"};
2533
        List<String> rankListToPrint = new ArrayList<String>();
2534
        for (String r : rankListToPrint_tmp) {
2535
            rankListToPrint.add(r.toLowerCase());
2536
        }
2537

    
2538
        Rank rank = Rank.UNKNOWN_RANK();
2539
        NodeList children = name.getChildNodes();
2540
        String originalName="";
2541
        String fullName = "";
2542
        String newName="";
2543
        String identifier="";
2544
        HashMap<String, String> atomisedMap = new HashMap<String, String>();
2545
        List<String> atomisedName= new ArrayList<String>();
2546

    
2547
        String rankStr = "";
2548
        Rank tmpRank ;
2549

    
2550
        String status= extractStatus(children);
2551

    
2552
        for (int i=0;i<children.getLength();i++){
2553
            if(children.item(i).getNodeName().equalsIgnoreCase("tax:xmldata")){
2554
                NodeList atom = children.item(i).getChildNodes();
2555
                for (int k=0;k<atom.getLength();k++){
2556
                    identifier = extractIdentifier(identifier, atom.item(k));
2557
                    tmpRank = null;
2558
                    rankStr = atom.item(k).getNodeName().toLowerCase();
2559
                    //                    logger.info("RANKSTR:*"+rankStr+"*");
2560
                    if (rankStr.equalsIgnoreCase("dwc:taxonRank")) {
2561
                        rankStr=atom.item(k).getTextContent().trim();
2562
                        tmpRank = getRank(rankStr);
2563
                    }
2564
                    //                    if ((tmpRank != null) && (tmpRank.isLower(rank) || rank.equals(Rank.UNKNOWN_RANK()))) {
2565
                    if (tmpRank != null){
2566
                        rank=tmpRank;
2567
                    }
2568
                    atomisedMap.put(rankStr.toLowerCase(),atom.item(k).getTextContent().trim());
2569
                }
2570
                addAtomisedNamesToMap(rankListToPrint, rank, atomisedName, atom);
2571
            }
2572
            if(children.item(i).getNodeName().equalsIgnoreCase("#text") && !StringUtils.isBlank(children.item(i).getTextContent())){
2573
                //                logger.info("name non atomised: "+children.item(i).getTextContent());
2574
                fullName = children.item(i).getTextContent().trim();
2575
                //                logger.info("fullname: "+fullName);
2576
            }
2577
        }
2578
        originalName=fullName;
2579
        fullName = cleanName(fullName, atomisedName);
2580
        namesMap.put(fullName,atomisedMap);
2581

    
2582
        String atomisedNameStr = getAtomisedNameStr(atomisedName);
2583

    
2584
        if (fullName != null){
2585
            //            System.out.println("fullname: "+fullName);
2586
            //            System.out.println("atomised: "+atomisedNameStr);
2587
            if (!fullName.equalsIgnoreCase(atomisedNameStr)) {
2588
                if (skippQuestion){
2589
                    //                    String defaultN = "";
2590
                    if (atomisedNameStr.length()>fullName.length()) {
2591
                        newName=atomisedNameStr;
2592
                    } else {
2593
                        if (fullName.length()>atomisedNameStr.length() && (rank.isLower(Rank.SPECIES()) && fullName.length()>2 && !fullName.substring(0, 1).equals("."))) {
2594
                            newName=askWhichScientificName(fullName,atomisedNameStr,classification.getTitleCache(),name);
2595
                        } else {
2596
                            newName=fullName;
2597
                        }
2598
                    }
2599
                } else {
2600
                    newName=askWhichScientificName(fullName,atomisedNameStr,classification.getTitleCache(),name);
2601
                }
2602
            } else {
2603
                newName=fullName;
2604
            }
2605
        }
2606
        //not really needed
2607
        //        rank = askForRank(newName, rank, nomenclaturalCode);
2608
        //        System.out.println("atomised: "+atomisedMap.toString());
2609

    
2610
        //        String[] names = new String[5];
2611
        MyName myname = new MyName(true);
2612

    
2613
        //System.out.println("Handle "+newName+ "(rank: "+rank+")");
2614
        //        System.out.println(atomisedMap.keySet());
2615
        fullName = extractAuthorFromNames(rank, fullName, atomisedMap, myname);
2616
        myname.setOriginalName(fullName);
2617
        myname.setNewName(newName);
2618
        myname.setRank(rank);
2619
        myname.setIdentifier(identifier);
2620
        myname.setStatus(status);
2621
        myname.setSource(refMods);
2622

    
2623
        //        boolean higherAdded=false;
2624

    
2625

    
2626
        boolean parseNameManually=false;
2627
        INonViralNameParser<?> parser = NonViralNameParserImpl.NewInstance();
2628
        TaxonNameBase<?,?>  nameToBeFilledTest ;
2629

    
2630
        //if selected the atomised version
2631
        if(newName==atomisedNameStr){
2632
            nameToBeFilledTest = parser.parseFullName(atomisedNameStr, nomenclaturalCode, rank);
2633
            if (nameToBeFilledTest.hasProblem()){
2634
                addProblemNameToFile("ato",atomisedNameStr,nomenclaturalCode,rank, nameToBeFilledTest.getParsingProblems().toString());
2635
                nameToBeFilledTest = parser.parseFullName(fullName, nomenclaturalCode,rank);
2636
                if (nameToBeFilledTest.hasProblem()){
2637
                    addProblemNameToFile("full",fullName,nomenclaturalCode,rank, nameToBeFilledTest.getParsingProblems().toString());
2638
                    parseNameManually=true;
2639
                }
2640
            }
2641
        }else{
2642
            nameToBeFilledTest = parser.parseFullName(fullName, nomenclaturalCode, rank);
2643
            if (nameToBeFilledTest.hasProblem()){
2644
                addProblemNameToFile("fullversion",fullName,nomenclaturalCode,rank, nameToBeFilledTest.getParsingProblems().toString());
2645
                nameToBeFilledTest = parser.parseFullName(fullName, nomenclaturalCode,rank);
2646
                parseNameManually=true;
2647
                if(!originalName.equalsIgnoreCase(atomisedNameStr)) {
2648
                    addNameDifferenceToFile(originalName,atomisedNameStr);
2649
                }
2650
            }
2651
        }
2652

    
2653
        if(parseNameManually){
2654
            //System.out.println("DO IT MANUALLY");
2655
            createSynonym(rank, newName, atomisedMap, myname);
2656
        }
2657
        else{
2658
            //System.out.println("AUTOMATIC!");
2659
            //            createAtomisedTaxonString(newName, atomisedMap, myname);
2660
            myname.setParsedName(nameToBeFilledTest);
2661
            myname.buildTaxon();
2662
        }
2663
        //System.out.println("RETURN SYNONYM "+myname.getSyno().toString());
2664
        return myname;
2665
    }
2666
    /**
2667
     * @param name
2668
     * @throws TransformerFactoryConfigurationError
2669
     * @throws TransformerException
2670
     * @return a list of possible names
2671
     */
2672
    @SuppressWarnings({ "null", "rawtypes" })
2673
    private MyName extractScientificName(Node name, Reference<?> refMods) throws TransformerFactoryConfigurationError, TransformerException {
2674
        logger.info("extractScientificName");
2675

    
2676
        String[] rankListToPrint_tmp ={"dwc:genus","dwc:specificepithet","dwc:species","dwc:subspecies", "dwc:infraspecificepithet","dwc:scientificnameauthorship"};
2677
        List<String> rankListToPrint = new ArrayList<String>();
2678
        for (String r : rankListToPrint_tmp) {
2679
            rankListToPrint.add(r.toLowerCase());
2680
        }
2681

    
2682
        Rank rank = Rank.UNKNOWN_RANK();
2683
        NodeList children = name.getChildNodes();
2684
        String originalName="";
2685
        String fullName = "";
2686
        String newName="";
2687
        String identifier="";
2688
        HashMap<String, String> atomisedMap = new HashMap<String, String>();
2689
        List<String> atomisedName= new ArrayList<String>();
2690

    
2691
        String rankStr = "";
2692
        Rank tmpRank ;
2693

    
2694
        String status= extractStatus(children);
2695

    
2696
        for (int i=0;i<children.getLength();i++){
2697
            if(children.item(i).getNodeName().equalsIgnoreCase("tax:xmldata")){
2698
                NodeList atom = children.item(i).getChildNodes();
2699
                for (int k=0;k<atom.getLength();k++){
2700
                    identifier = extractIdentifier(identifier, atom.item(k));
2701
                    tmpRank = null;
2702
                    rankStr = atom.item(k).getNodeName().toLowerCase();
2703
                    //                    logger.info("RANKSTR:*"+rankStr+"*");
2704
                    if (rankStr.equalsIgnoreCase("dwc:taxonRank")) {
2705
                        rankStr=atom.item(k).getTextContent().trim();
2706
                        tmpRank = getRank(rankStr);
2707
                    }
2708
                    //                    if ((tmpRank != null) && (tmpRank.isLower(rank) || rank.equals(Rank.UNKNOWN_RANK()))) {
2709
                    if (tmpRank != null){
2710
                        rank=tmpRank;
2711
                    }
2712
                    atomisedMap.put(rankStr.toLowerCase(),atom.item(k).getTextContent().trim());
2713
                }
2714
                addAtomisedNamesToMap(rankListToPrint, rank, atomisedName, atom);
2715
            }
2716
            if(children.item(i).getNodeName().equalsIgnoreCase("#text") && !StringUtils.isBlank(children.item(i).getTextContent())){
2717
                //                logger.info("name non atomised: "+children.item(i).getTextContent());
2718
                fullName = children.item(i).getTextContent().trim();
2719
                //                logger.info("fullname: "+fullName);
2720
            }
2721
        }
2722
        originalName=fullName;
2723
        fullName = cleanName(fullName, atomisedName);
2724
        namesMap.put(fullName,atomisedMap);
2725

    
2726
        String atomisedNameStr = getAtomisedNameStr(atomisedName);
2727

    
2728
        if (fullName != null){
2729
            //            System.out.println("fullname: "+fullName);
2730
            //            System.out.println("atomised: "+atomisedNameStr);
2731
            if (!fullName.equalsIgnoreCase(atomisedNameStr)) {
2732
                //System.out.println("atomisedNameStr vs. fullName:"+atomisedNameStr+"--"+fullName);
2733
                if (skippQuestion){
2734
                    //                    String defaultN = "";
2735
                    if (atomisedNameStr.length()>fullName.length()) {
2736
                        newName=atomisedNameStr;
2737
                    } else {
2738
                        if (fullName.length()>atomisedNameStr.length() && (rank.isLower(Rank.SPECIES()) && fullName.length()>2 && !fullName.substring(0, 1).equals("."))) {
2739
                            //System.out.println("là");
2740
                            newName=askWhichScientificName(fullName,atomisedNameStr,classification.getTitleCache(),name);
2741
                        } else {
2742
                            //System.out.println("ici");
2743
                            newName=fullName;
2744
                        }
2745
                    }
2746
                } else {
2747
                    newName=askWhichScientificName(fullName,atomisedNameStr,classification.getTitleCache(),name);
2748
                }
2749
            } else {
2750
                newName=fullName;
2751
            }
2752
        }
2753
        //not really needed
2754
        //        rank = askForRank(newName, rank, nomenclaturalCode);
2755
        //        System.out.println("atomised: "+atomisedMap.toString());
2756

    
2757
        //        String[] names = new String[5];
2758
        MyName myname = new MyName(false);
2759

    
2760
        //System.out.println("\n\nBUILD "+newName+ "(rank: "+rank+")");
2761
        //        System.out.println(atomisedMap.keySet());
2762
        fullName = extractAuthorFromNames(rank, fullName, atomisedMap, myname);
2763
        myname.setOriginalName(fullName);
2764
        myname.setNewName(newName);
2765

    
2766
        myname.setRank(rank);
2767
        myname.setIdentifier(identifier);
2768
        myname.setStatus(status);
2769
        myname.setSource(refMods);
2770

    
2771
        //        boolean higherAdded=false;
2772

    
2773

    
2774
        boolean parseNameManually=false;
2775
        INonViralNameParser parser = NonViralNameParserImpl.NewInstance();
2776
        TaxonNameBase  nameToBeFilledTest = null;
2777

    
2778
        //if selected the atomised version
2779
        if(newName==atomisedNameStr){
2780
            nameToBeFilledTest = parser.parseFullName(atomisedNameStr, nomenclaturalCode, rank);
2781
            if (nameToBeFilledTest.hasProblem()){
2782
                addProblemNameToFile("ato",atomisedNameStr,nomenclaturalCode,rank, nameToBeFilledTest.getParsingProblems().toString());
2783
                nameToBeFilledTest = parser.parseFullName(fullName, nomenclaturalCode,rank);
2784
                if (nameToBeFilledTest.hasProblem()){
2785
                    addProblemNameToFile("full",fullName,nomenclaturalCode,rank, nameToBeFilledTest.getParsingProblems().toString());
2786
                    parseNameManually=true;
2787
                }
2788
            }
2789
        }else{
2790
            nameToBeFilledTest = parser.parseFullName(fullName, nomenclaturalCode, rank);
2791
            if (nameToBeFilledTest.hasProblem()){
2792
                addProblemNameToFile("fullversion",fullName,nomenclaturalCode,rank, nameToBeFilledTest.getParsingProblems().toString());
2793
                nameToBeFilledTest = parser.parseFullName(fullName, nomenclaturalCode,rank);
2794
                parseNameManually=true;
2795
                if(!originalName.equalsIgnoreCase(atomisedNameStr)) {
2796
                    addNameDifferenceToFile(originalName,atomisedNameStr);
2797
                }
2798
            }
2799
        }
2800

    
2801
        //System.out.println("parseNameManually: "+parseNameManually);
2802
        if(parseNameManually){
2803
            createAtomisedTaxon(rank, newName, atomisedMap, myname);
2804
        }
2805
        else{
2806
            createAtomisedTaxonString(newName, atomisedMap, myname);
2807
            myname.setParsedName(nameToBeFilledTest);
2808
            myname.buildTaxon();
2809
        }
2810
        return myname;
2811

    
2812
    }
2813

    
2814
    /**
2815
     * @param atomisedName
2816
     * @return
2817
     */
2818
    private String getAtomisedNameStr(List<String> atomisedName) {
2819
        //logger.info("getAtomisedNameStr");
2820
        String atomisedNameStr = StringUtils.join(atomisedName," ");
2821
        while(atomisedNameStr.contains("  ")) {
2822
            atomisedNameStr=atomisedNameStr.replace("  ", " ");
2823
        }
2824
        atomisedNameStr=atomisedNameStr.trim();
2825
        return atomisedNameStr;
2826
    }
2827

    
2828
    /**
2829
     * @param children
2830
     * @param status
2831
     * @return
2832
     */
2833
    private String extractStatus(NodeList children) {
2834
        logger.info("extractStatus");
2835
        String status="";
2836
        for (int i=0;i<children.getLength();i++){
2837
            if(children.item(i).getNodeName().equalsIgnoreCase("tax:status") ||
2838
                    (children.item(i).getNodeName().equalsIgnoreCase("tax:namePart") &&
2839
                            children.item(i).getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("status"))){
2840
                status = children.item(i).getTextContent().trim();
2841
            }
2842
        }
2843
        return status;
2844
    }
2845

    
2846
    /**
2847
     * @param identifier
2848
     * @param atom
2849
     * @param k
2850
     * @return
2851
     */
2852
    private String extractIdentifier(String identifier, Node atom) {
2853
        //logger.info("extractIdentifier");
2854
        if (atom.getNodeName().equalsIgnoreCase("tax:xid")){
2855
            try{
2856
                identifier = atom.getAttributes().getNamedItem("identifier").getNodeValue();
2857
            }catch(Exception e){
2858
                System.out.println("pb with identifier, maybe empty");
2859
            }
2860
            try{
2861
                identifier+="__"+atom.getAttributes().getNamedItem("source").getNodeValue();
2862
            }catch(Exception e){
2863
                System.out.println("pb with identifier, maybe empty");
2864
            }
2865
        }
2866
        return identifier;
2867
    }
2868

    
2869
    /**
2870
     * @param rankListToPrint
2871
     * @param rank
2872
     * @param atomisedName
2873
     * @param atom
2874
     */
2875
    private void addAtomisedNamesToMap(List<String> rankListToPrint, Rank rank, List<String> atomisedName, NodeList atom) {
2876
        logger.info("addAtomisedNamesToMap");
2877
        for (int k=0;k<atom.getLength();k++){
2878
            if (!atom.item(k).getNodeName().equalsIgnoreCase("dwc:taxonRank") ) {
2879
                if (atom.item(k).getNodeName().equalsIgnoreCase("dwc:subgenus") || atom.item(k).getNodeName().equalsIgnoreCase("dwcranks:subgenus")) {
2880
                    atomisedName.add("("+atom.item(k).getTextContent().trim()+")");
2881
                } else{
2882
                    if(atom.item(k).getNodeName().equalsIgnoreCase("dwcranks:varietyepithet") || atom.item(k).getNodeName().equalsIgnoreCase("dwc:Subspecies")) {
2883
                        if(atom.item(k).getNodeName().equalsIgnoreCase("dwcranks:varietyepithet")){
2884
                            atomisedName.add("var. "+atom.item(k).getTextContent().trim());
2885
                        }
2886
                        if(atom.item(k).getNodeName().equalsIgnoreCase("dwc:Subspecies") || atom.item(k).getNodeName().equalsIgnoreCase("dwc:infraspecificepithet")) {
2887
                            atomisedName.add("subsp. "+atom.item(k).getTextContent().trim());
2888
                        }
2889
                    }
2890
                    else{
2891
                        if(rankListToPrint.contains(atom.item(k).getNodeName().toLowerCase())) {
2892
                            atomisedName.add(atom.item(k).getTextContent().trim());
2893
                        }
2894
                        else{
2895
                            //                                    System.out.println("rank : "+rank.toString());
2896
                            if (rank.isHigher(Rank.GENUS()) && (atom.item(k).getNodeName().indexOf("dwcranks:")>-1 || atom.item(k).getNodeName().indexOf("dwc:Family")>-1)) {
2897
                                atomisedName.add(atom.item(k).getTextContent().trim());
2898
                            }
2899
                            //                                    else{
2900
                            //                                      System.out.println("on a oublie qqn "+atom.item(k).getNodeName());
2901
                            //                                  }
2902
                        }
2903
                        //                                else{
2904
                        //                                    System.out.println("on a oublie qqn "+atom.item(k).getNodeName());
2905
                        //                                }
2906
                    }
2907
                }
2908
            }
2909
        }
2910
    }
2911

    
2912
    /**
2913
     * @param fullName
2914
     * @param atomisedName
2915
     * @return
2916
     */
2917
    private String cleanName(String name, List<String> atomisedName) {
2918
        //logger.info("cleanName");
2919
        String fullName =name;
2920
        if (fullName != null){
2921
            fullName = fullName.replace("( ", "(");
2922
            fullName = fullName.replace(" )",")");
2923

    
2924
            if (fullName.trim().isEmpty()){
2925
                fullName=StringUtils.join(atomisedName," ");
2926
            }
2927

    
2928
            while(fullName.contains("  ")) {
2929
                fullName=fullName.replace("  ", " ");
2930
                //            logger.info("while");
2931
            }
2932
            fullName=fullName.trim();
2933
        }
2934
        return fullName;
2935
    }
2936

    
2937
    /**
2938
     * @param rank
2939
     * @param fullName
2940
     * @param atomisedMap
2941
     * @param myname
2942
     * @return
2943
     */
2944
    private String extractAuthorFromNames(Rank rank, String name, HashMap<String, String> atomisedMap,
2945
            MyName myname) {
2946
        logger.info("extractAuthorFromNames");
2947
        String fullName=name;
2948
        if (atomisedMap.get("dwc:scientificnameauthorship") == null && fullName!=null){
2949
            //            System.out.println("rank : "+rank.toString());
2950
            if(rank.isHigher(Rank.SPECIES())){
2951
                try{
2952
                    String author=null;
2953
                    if(atomisedMap.get("dwcranks:subgenus") != null) {
2954
                        author = fullName.split(atomisedMap.get("dwcranks:subgenus"))[1].trim();
2955
                    }
2956
                    if(atomisedMap.get("dwc:subgenus") != null) {
2957
                        author = fullName.split(atomisedMap.get("dwc:subgenus"))[1].trim();
2958
                    }
2959
                    if(author == null) {
2960
                        if(atomisedMap.get("dwc:genus") != null) {
2961
                            author = fullName.split(atomisedMap.get("dwc:genus"))[1].trim();
2962
                        }
2963
                    }
2964
                    if(author != null){
2965
                        fullName = fullName.substring(0, fullName.indexOf(author));
2966
                        author=author.replaceAll(",","").trim();
2967
                        myname.setAuthor(author);
2968
                    }
2969
                }catch(Exception e){
2970
                    //could not extract the author
2971
                }
2972
            }
2973
            if(rank.equals(Rank.SPECIES())){
2974
                try{
2975
                    String author=null;
2976
                    if(author == null) {
2977
                        if(atomisedMap.get("dwc:species") != null) {
2978
                            String[] t = fullName.split(atomisedMap.get("dwc:species"));
2979
                            //                            System.out.println("NB ELEMENTS "+t.length +"fullName "+fullName+", "+atomisedMap.get("dwc:species"));
2980
                            author = fullName.split(atomisedMap.get("dwc:species"))[1].trim();
2981
                            //                            System.out.println("AUTEUR "+author);
2982
                        }
2983
                    }
2984
                    if(author != null){
2985
                        fullName = fullName.substring(0, fullName.indexOf(author));
2986
                        author=author.replaceAll(",","").trim();
2987
                        myname.setAuthor(author);
2988
                    }
2989
                }catch(Exception e){
2990
                    //could not extract the author
2991
                }
2992
            }
2993
        }else{
2994
            myname.setAuthor(atomisedMap.get("dwc:scientificnameauthorship"));
2995
        }
2996
        return fullName;
2997
    }
2998

    
2999
    /**
3000
     * @param newName
3001
     * @param atomisedMap
3002
     * @param myname
3003
     */
3004
    private void createAtomisedTaxonString(String newName, HashMap<String, String> atomisedMap, MyName myname) {
3005
        logger.info("createAtomisedTaxonString "+atomisedMap);
3006
        if(atomisedMap.get("dwc:family") != null && checkRankValidForImport(Rank.FAMILY())){
3007
            myname.setFamilyStr(atomisedMap.get("dwc:family"));
3008
        }
3009
        if(atomisedMap.get("dwcranks:subfamily") != null  && checkRankValidForImport(Rank.SUBFAMILY())){
3010
            myname.setSubfamilyStr(atomisedMap.get("dwcranks:subfamily"));
3011
        }
3012
        if(atomisedMap.get("dwcranks:tribe") != null && checkRankValidForImport(Rank.TRIBE())){
3013
            myname.setTribeStr(atomisedMap.get("dwcranks:tribe"));
3014
        }
3015
        if(atomisedMap.get("dwcranks:subtribe") != null && checkRankValidForImport(Rank.SUBTRIBE())){
3016
            myname.setSubtribeStr(atomisedMap.get("dwcranks:subtribe"));
3017
        }
3018
        if(atomisedMap.get("dwc:genus") != null && checkRankValidForImport(Rank.GENUS())){
3019
            myname.setGenusStr(atomisedMap.get("dwc:genus"));
3020
        }
3021
        if(atomisedMap.get("dwcranks:subgenus") != null && checkRankValidForImport(Rank.SUBGENUS())){
3022
            myname.setSubgenusStr(atomisedMap.get("dwcranks:subgenus"));
3023
        }
3024
        if(atomisedMap.get("dwc:subgenus") != null && checkRankValidForImport(Rank.SUBGENUS())){
3025
            myname.setSubgenusStr(atomisedMap.get("dwc:subgenus"));
3026
        }
3027
        if(atomisedMap.get("dwc:species") != null && checkRankValidForImport(Rank.SPECIES())){
3028
            String n=newName;
3029
            if(atomisedMap.get("dwc:infraspecificepithet") != null) {
3030
                n=newName.split(atomisedMap.get("dwc:infraspecificepithet"))[0];
3031
                n=n.replace("subsp.","");
3032
            }
3033
            if(atomisedMap.get("dwc:subspecies") != null) {
3034
                n=newName.split(atomisedMap.get("dwc:subspecies"))[0];
3035
                n=n.replace("subsp.","");
3036
            }
3037
            if(atomisedMap.get("dwcranks:varietyepithet") != null) {
3038
                n=newName.split(atomisedMap.get("dwcranks:varietyepithet"))[0];
3039
                n=n.replace("var.","");
3040
                n=n.replace("v.","");
3041
            }
3042
            if(atomisedMap.get("dwcranks:formepithet") != null) {
3043
                //TODO
3044
                System.out.println("TODO FORMA");
3045
                n=newName.split(atomisedMap.get("dwcranks:formepithet"))[0];
3046
                n=n.replace("forma","");
3047
            }
3048
            n=n.trim();
3049
            String author = myname.getAuthor();
3050
            if(n.split(" ").length>2)
3051
            {
3052
                String n2=n.split(" ")[0]+" "+n.split(" ")[1];
3053
                String a= "";
3054
                try{
3055
                    a=n.split(n2)[1].trim();
3056
                }catch(Exception e){
3057
                    logger.info("no author in "+n+"?");}
3058

    
3059
                myname.setAuthor(a);
3060
                //System.out.println("FINDCREATESPECIES --"+n2+"--"+n+"**"+a+"##");
3061
                n=n2;
3062

    
3063
            }
3064

    
3065
            myname.setSpeciesStr(atomisedMap.get("dwc:species"));
3066
            myname.setAuthor(author);
3067
        }
3068
        if(atomisedMap.get("dwc:subspecies") != null && checkRankValidForImport(Rank.SUBSPECIES())){
3069
            myname.setSubspeciesStr(atomisedMap.get("dwc:subspecies"));
3070
        }
3071
        if(atomisedMap.get("dwc:infraspecificepithet") != null && checkRankValidForImport(Rank.SUBSPECIES())){
3072
            myname.setSubspeciesStr(atomisedMap.get("dwc:infraspecificepithet"));
3073
        }
3074
        if(atomisedMap.get("dwcranks:varietyepithet") != null && checkRankValidForImport(Rank.VARIETY())){
3075
            myname.setVarietyStr(atomisedMap.get("dwcranks:varietyepithet"));
3076
        }
3077
        if(atomisedMap.get("dwcranks:formepithet") != null && checkRankValidForImport(Rank.FORM())){
3078
            myname.setFormStr(atomisedMap.get("dwcranks:formepithet"));
3079
        }
3080
    }
3081

    
3082
    private void createSynonym(Rank rank, String newName, HashMap<String, String> atomisedMap, MyName myname) {
3083
        logger.info("createSynonym");
3084
        //System.out.println("createsynonym");
3085
        if(rank.equals(Rank.UNKNOWN_RANK())){
3086
            myname.setNotParsableTaxon(newName);
3087
        }else
3088
        {if(atomisedMap.get("dwc:family") != null && checkRankValidForImport(Rank.FAMILY()) && rank.equals(Rank.FAMILY())){
3089
            myname.setFamily(myname.findOrCreateTaxon(atomisedMap.get("dwc:family"),newName, Rank.FAMILY(),rank));
3090
        }
3091
        if(atomisedMap.get("dwcranks:subfamily") != null  && checkRankValidForImport(Rank.SUBFAMILY()) && rank.equals(Rank.SUBFAMILY())){
3092
            myname.setSubfamily(myname.findOrCreateTaxon(atomisedMap.get("dwcranks:subfamily"), newName,Rank.SUBFAMILY(),rank));
3093
        }
3094
        if(atomisedMap.get("dwcranks:tribe") != null && checkRankValidForImport(Rank.TRIBE()) && rank.equals(Rank.TRIBE())){
3095
            myname.setTribe(myname.findOrCreateTaxon(atomisedMap.get("dwcranks:tribe"),newName, Rank.TRIBE(),rank));
3096
        }
3097
        if(atomisedMap.get("dwcranks:subtribe") != null && checkRankValidForImport(Rank.SUBTRIBE()) && rank.equals(Rank.SUBTRIBE())){
3098
            myname.setSubtribe(myname.findOrCreateTaxon(atomisedMap.get("dwcranks:subtribe"),newName, Rank.SUBTRIBE(),rank));
3099
        }
3100
        if(atomisedMap.get("dwc:genus") != null && checkRankValidForImport(Rank.GENUS()) && rank.equals(Rank.GENUS())){
3101
            myname.setGenus(myname.findOrCreateTaxon(atomisedMap.get("dwc:genus"),newName, Rank.GENUS(),rank));
3102
        }
3103
        if(atomisedMap.get("dwcranks:subgenus") != null && checkRankValidForImport(Rank.SUBGENUS()) && rank.equals(Rank.SUBGENUS())){
3104
            myname.setSubgenus(myname.findOrCreateTaxon(atomisedMap.get("dwcranks:subgenus"),newName, Rank.SUBGENUS(),rank));
3105
        }
3106
        if(atomisedMap.get("dwc:subgenus") != null && checkRankValidForImport(Rank.SUBGENUS()) && rank.equals(Rank.SUBGENUS())){
3107
            myname.setSubgenus(myname.findOrCreateTaxon(atomisedMap.get("dwc:subgenus"),newName, Rank.SUBGENUS(),rank));
3108
        }
3109
        if(atomisedMap.get("dwc:species") != null && checkRankValidForImport(Rank.SPECIES()) && rank.equals(Rank.SPECIES())){
3110
            String n=newName;
3111
            if(atomisedMap.get("dwc:infraspecificepithet") != null) {
3112
                n=newName.split(atomisedMap.get("dwc:infraspecificepithet"))[0];
3113
                n=n.replace("subsp.","");
3114
            }
3115
            if(atomisedMap.get("dwc:subspecies") != null) {
3116
                n=newName.split(atomisedMap.get("dwc:subspecies"))[0];
3117
                n=n.replace("subsp.","");
3118
            }
3119
            if(atomisedMap.get("dwcranks:varietyepithet") != null) {
3120
                n=newName.split(atomisedMap.get("dwcranks:varietyepithet"))[0];
3121
                n=n.replace("var.","");
3122
                n=n.replace("v.","");
3123
            }
3124
            if(atomisedMap.get("dwcranks:formepithet") != null) {
3125
                //TODO
3126
                //System.out.println("TODO FORMA");
3127
                n=newName.split(atomisedMap.get("dwcranks:formepithet"))[0];
3128
                n=n.replace("forma","");
3129
            }
3130
            n=n.trim();
3131
            String author = myname.getAuthor();
3132
            if(n.split(" ").length>2)
3133
            {
3134
                String n2=n.split(" ")[0]+" "+n.split(" ")[1];
3135
                String a="";
3136
                try{
3137
                    a= n.split(n2)[1].trim();
3138
                }catch(Exception e){logger.info("no author in "+n);}
3139
                myname.setAuthor(a);
3140
                //System.out.println("FINDCREATESPECIES --"+n2+"--"+n+"**"+a+"##");
3141
                n=n2;
3142

    
3143
            }
3144

    
3145
            myname.setSpecies(myname.findOrCreateTaxon(atomisedMap.get("dwc:species"),n, Rank.SPECIES(),rank));
3146
            myname.setAuthor(author);
3147
        }
3148
        if(atomisedMap.get("dwc:subspecies") != null && checkRankValidForImport(Rank.SUBSPECIES()) && rank.equals(Rank.SUBSPECIES())){
3149
            myname.setSubspecies(myname.findOrCreateTaxon(atomisedMap.get("dwc:subspecies"), newName,Rank.SUBSPECIES(),rank));
3150
        }
3151
        if(atomisedMap.get("dwc:infraspecificepithet") != null && checkRankValidForImport(Rank.SUBSPECIES()) && rank.equals(Rank.SUBSPECIES())){
3152
            myname.setSubspecies(myname.findOrCreateTaxon(atomisedMap.get("dwc:infraspecificepithet"),newName, Rank.SUBSPECIES(),rank));
3153
        }
3154
        if(atomisedMap.get("dwcranks:varietyepithet") != null && checkRankValidForImport(Rank.VARIETY()) && rank.equals(Rank.VARIETY())){
3155
            myname.setVariety(myname.findOrCreateTaxon(atomisedMap.get("dwcranks:varietyepithet"),newName, Rank.VARIETY(),rank));
3156
        }
3157
        if(atomisedMap.get("dwcranks:formepithet") != null && checkRankValidForImport(Rank.FORM()) && rank.equals(Rank.FORM())){
3158
            myname.setForm(myname.findOrCreateTaxon(atomisedMap.get("dwcranks:formepithet"), newName,Rank.FORM(),rank));
3159
        }
3160
        }
3161

    
3162
    }
3163
    /**
3164
     * @param rank
3165
     * @param newName
3166
     * @param atomisedMap
3167
     * @param myname
3168
     */
3169
    private void createAtomisedTaxon(Rank rank, String newName, HashMap<String, String> atomisedMap, MyName myname) {
3170
        logger.info("createAtomisedTaxon "+atomisedMap);
3171
        if(rank.equals(Rank.UNKNOWN_RANK())){
3172
            myname.setNotParsableTaxon(newName);
3173
        }
3174
        else{
3175
            if(atomisedMap.get("dwc:family") != null && checkRankValidForImport(Rank.FAMILY())){
3176
                myname.setFamily(myname.findOrCreateTaxon(atomisedMap.get("dwc:family"),newName, Rank.FAMILY(),rank));
3177
            }
3178
            if(atomisedMap.get("dwcranks:subfamily") != null  && checkRankValidForImport(Rank.SUBFAMILY())){
3179
                myname.setSubfamily(myname.findOrCreateTaxon(atomisedMap.get("dwcranks:subfamily"), newName,Rank.SUBFAMILY(),rank));
3180
            }
3181
            if(atomisedMap.get("dwcranks:tribe") != null && checkRankValidForImport(Rank.TRIBE())){
3182
                myname.setTribe(myname.findOrCreateTaxon(atomisedMap.get("dwcranks:tribe"),newName, Rank.TRIBE(),rank));
3183
            }
3184
            if(atomisedMap.get("dwcranks:subtribe") != null && checkRankValidForImport(Rank.SUBTRIBE())){
3185
                myname.setSubtribe(myname.findOrCreateTaxon(atomisedMap.get("dwcranks:subtribe"),newName, Rank.SUBTRIBE(),rank));
3186
            }
3187
            if(atomisedMap.get("dwc:genus") != null && checkRankValidForImport(Rank.GENUS())){
3188
                myname.setGenus(myname.findOrCreateTaxon(atomisedMap.get("dwc:genus"),newName, Rank.GENUS(),rank));
3189
            }
3190
            if(atomisedMap.get("dwcranks:subgenus") != null && checkRankValidForImport(Rank.SUBGENUS())){
3191
                myname.setSubgenus(myname.findOrCreateTaxon(atomisedMap.get("dwcranks:subgenus"),newName, Rank.SUBGENUS(),rank));
3192
            }
3193
            if(atomisedMap.get("dwc:subgenus") != null && checkRankValidForImport(Rank.SUBGENUS())){
3194
                myname.setSubgenus(myname.findOrCreateTaxon(atomisedMap.get("dwc:subgenus"),newName, Rank.SUBGENUS(),rank));
3195
            }
3196
            if(atomisedMap.get("dwc:species") != null && checkRankValidForImport(Rank.SPECIES())){
3197
                String n=newName;
3198
                if(atomisedMap.get("dwc:infraspecificepithet") != null) {
3199
                    n=newName.split(atomisedMap.get("dwc:infraspecificepithet"))[0];
3200
                    n=n.replace("subsp.","");
3201
                }
3202
                if(atomisedMap.get("dwc:subspecies") != null) {
3203
                    n=newName.split(atomisedMap.get("dwc:subspecies"))[0];
3204
                    n=n.replace("subsp.","");
3205
                }
3206
                if(atomisedMap.get("dwcranks:varietyepithet") != null) {
3207
                    n=newName.split(atomisedMap.get("dwcranks:varietyepithet"))[0];
3208
                    n=n.replace("var.","");
3209
                    n=n.replace("v.","");
3210
                }
3211
                if(atomisedMap.get("dwcranks:formepithet") != null) {
3212
                    //TODO
3213
                    //System.out.println("TODO FORMA");
3214
                    n=newName.split(atomisedMap.get("dwcranks:formepithet"))[0];
3215
                    n=n.replace("forma","");
3216
                }
3217
                n=n.trim();
3218
                String author = myname.getAuthor();
3219
                if(n.split(" ").length>2)
3220
                {
3221
                    String n2=n.split(" ")[0]+" "+n.split(" ")[1];
3222
                    String a="";
3223
                    try{
3224
                        a= n.split(n2)[1].trim();
3225
                    }catch(Exception e){logger.info("no author  in "+n);}
3226
                    myname.setAuthor(a);
3227
                    //System.out.println("FINDCREATESPECIES --"+n2+"--"+n+"**"+a+"##");
3228
                    n=n2;
3229

    
3230
                }
3231

    
3232
                myname.setSpecies(myname.findOrCreateTaxon(atomisedMap.get("dwc:species"),n, Rank.SPECIES(),rank));
3233
                myname.setAuthor(author);
3234
            }
3235
            if(atomisedMap.get("dwc:subspecies") != null && checkRankValidForImport(Rank.SUBSPECIES())){
3236
                myname.setSubspecies(myname.findOrCreateTaxon(atomisedMap.get("dwc:subspecies"), newName,Rank.SUBSPECIES(),rank));
3237
            }
3238
            if(atomisedMap.get("dwc:infraspecificepithet") != null && checkRankValidForImport(Rank.SUBSPECIES())){
3239
                myname.setSubspecies(myname.findOrCreateTaxon(atomisedMap.get("dwc:infraspecificepithet"),newName, Rank.SUBSPECIES(),rank));
3240
            }
3241
            if(atomisedMap.get("dwcranks:varietyepithet") != null && checkRankValidForImport(Rank.VARIETY())){
3242
                myname.setVariety(myname.findOrCreateTaxon(atomisedMap.get("dwcranks:varietyepithet"),newName, Rank.VARIETY(),rank));
3243
            }
3244
            if(atomisedMap.get("dwcranks:formepithet") != null && checkRankValidForImport(Rank.FORM())){
3245
                myname.setForm(myname.findOrCreateTaxon(atomisedMap.get("dwcranks:formepithet"), newName,Rank.FORM(),rank));
3246
            }
3247
        }
3248
    }
3249

    
3250
    /**
3251
     * @return
3252
     */
3253
    private boolean checkRankValidForImport(Rank currentRank) {
3254
        //logger.info("checkRankValidForImport");
3255
        return currentRank.isLower(configState.getConfig().getMaxRank()) || currentRank.equals(configState.getConfig().getMaxRank());
3256
    }
3257

    
3258

    
3259

    
3260
    /**
3261
     * @param classification2
3262
     */
3263
    public void updateClassification(Classification classification2) {
3264
        //logger.info("updateClassification");
3265
        classification = classification2;
3266
    }
3267

    
3268
    /**
3269
     * @param tnb
3270
     * cast the current taxonnamebase into a botanical name or zoological or bacterial name
3271
     * if errors, cast into a classis nonviralname
3272
     * @param taxonnamebase2
3273
     */
3274
    @SuppressWarnings("rawtypes")
3275
    public NonViralName<?> castTaxonNameBase(TaxonNameBase tnb, NonViralName<?> nvn) {
3276
        //logger.info("castTaxonNameBase");
3277
        NonViralName<?> taxonnamebase2 = nvn;
3278
        if (nomenclaturalCode.equals(NomenclaturalCode.ICNAFP)) {
3279
            try{
3280
                taxonnamebase2=(BotanicalName) tnb;
3281
            }catch(Exception e){
3282
                taxonnamebase2= (NonViralName<?>) tnb;
3283
            }
3284
        }
3285
        if (nomenclaturalCode.equals(NomenclaturalCode.ICZN)) {
3286
            try{
3287
                taxonnamebase2=(ZoologicalName) tnb;
3288
            }catch(Exception e){
3289
                taxonnamebase2= (NonViralName<?>) tnb;
3290
            }
3291
        }
3292
        if (nomenclaturalCode.equals(NomenclaturalCode.ICNB)) {
3293
            try{
3294
                taxonnamebase2=(BacterialName) tnb;
3295
            }catch(Exception e){
3296
                taxonnamebase2= (NonViralName<?>) tnb;
3297
            }
3298
        }
3299
        return taxonnamebase2;
3300
    }
3301

    
3302
    /**
3303
     * @param tnb
3304
     * cast the current taxonnamebase into a botanical name or zoological or bacterial name
3305
     * if errors, cast into a classis nonviralname
3306
     * @param taxonnamebase2
3307
     */
3308
    @SuppressWarnings("rawtypes")
3309
    public NonViralName<?> castTaxonNameBase(TaxonNameBase tnb) {
3310
        //logger.info("castTaxonNameBase2");
3311
        NonViralName<?> taxonnamebase2 = null;
3312
        tnb=CdmBase.deproxy(tnb, TaxonNameBase.class);
3313
        if (nomenclaturalCode.equals(NomenclaturalCode.ICNAFP)) {
3314
            try{
3315
                taxonnamebase2=(BotanicalName) tnb;
3316
            }catch(Exception e){
3317
                taxonnamebase2= (NonViralName<?>) tnb;
3318
            }
3319
        }
3320
        if (nomenclaturalCode.equals(NomenclaturalCode.ICZN)) {
3321
            try{
3322
                taxonnamebase2=(ZoologicalName) tnb;
3323
            }catch(Exception e){
3324
                taxonnamebase2= (NonViralName<?>) tnb;
3325
            }
3326
        }
3327
        if (nomenclaturalCode.equals(NomenclaturalCode.ICNB)) {
3328
            try{
3329
                taxonnamebase2=(BacterialName) tnb;
3330
            }catch(Exception e){
3331
                taxonnamebase2= (NonViralName<?>) tnb;
3332
            }
3333
        }
3334
        return taxonnamebase2;
3335
    }
3336

    
3337
    public class MyName {
3338
        /**
3339
         * @param isSynonym
3340
         */
3341
        public MyName(boolean isSynonym) {
3342
            super();
3343
            this.isSynonym = isSynonym;
3344
        }
3345

    
3346
        String originalName="";
3347
        String newName="";
3348
        Rank rank=Rank.UNKNOWN_RANK();
3349
        String identifier="";
3350
        String status="";
3351
        String author=null;
3352

    
3353
        NonViralName<?> taxonnamebase;
3354

    
3355
        Reference<?> refMods ;
3356

    
3357
        Taxon family,subfamily,tribe,subtribe,genus,subgenus,species,subspecies, variety,form;
3358
        NonViralName<?> familyName, subfamilyName, tribeName,subtribeName,genusName,subgenusName,speciesName,subspeciesName;
3359
        String familyStr, subfamilyStr, tribeStr,subtribeStr,genusStr,subgenusStr,speciesStr,subspeciesStr,formStr,varietyStr;
3360
        Taxon higherTaxa;
3361
        Rank higherRank;
3362
        private Taxon taxon;
3363
        private Synonym syno;
3364

    
3365
        /**
3366
         * @return the syno
3367
         */
3368
        public Synonym getSyno() {
3369
            return syno;
3370
        }
3371

    
3372
        @Override
3373
        public String toString(){
3374
            List<String> tot=new ArrayList<String>();
3375
            String[] n= {familyStr, subfamilyStr, tribeStr,subtribeStr,genusStr,subgenusStr,speciesStr,subspeciesStr,formStr,varietyStr};
3376
            for (String elt:n){
3377
                if (!StringUtils.isEmpty(elt)) {
3378
                    tot.add(elt);
3379
                } else {
3380
                    tot.add("*");
3381
                }
3382
            }
3383
            return StringUtils.join(tot," ");
3384
        }
3385
        /**
3386
         * @param syno the syno to set
3387
         */
3388
        public void setSyno(Synonym syno) {
3389
            this.syno = syno;
3390
        }
3391

    
3392
        boolean isSynonym=false;
3393

    
3394
        /**
3395
         * @return the isSynonym
3396
         */
3397
        public boolean isSynonym() {
3398
            return isSynonym;
3399
        }
3400

    
3401
        /**
3402
         * @param isSynonym the isSynonym to set
3403
         */
3404
        public void setSynonym(boolean isSynonym) {
3405
            this.isSynonym = isSynonym;
3406
        }
3407

    
3408
        public void setSource(Reference<?> re){
3409
            refMods=re;
3410
        }
3411

    
3412
        /**
3413
         * @param string
3414
         */
3415
        public void setFormStr(String string) {
3416
            this.formStr=string;
3417

    
3418
        }
3419
        /**
3420
         * @param string
3421
         */
3422
        public void setVarietyStr(String string) {
3423
            this.varietyStr=string;
3424

    
3425
        }
3426
        /**
3427
         * @param string
3428
         */
3429
        public void setSubspeciesStr(String string) {
3430
            this.subspeciesStr=string;
3431

    
3432
        }
3433
        /**
3434
         * @param string
3435
         */
3436
        public void setSpeciesStr(String string) {
3437
            this.speciesStr=string;
3438

    
3439
        }
3440
        /**
3441
         * @param string
3442
         */
3443
        public void setSubgenusStr(String string) {
3444
            this.subgenusStr=string;
3445

    
3446
        }
3447
        /**
3448
         * @param string
3449
         */
3450
        public void setGenusStr(String string) {
3451
            this.genusStr=string;
3452

    
3453
        }
3454
        /**
3455
         * @param string
3456
         */
3457
        public void setSubtribeStr(String string) {
3458
            this.subtribeStr=string;
3459

    
3460
        }
3461
        /**
3462
         * @param string
3463
         */
3464
        public void setTribeStr(String string) {
3465
            this.tribeStr=string;
3466

    
3467
        }
3468
        /**
3469
         * @param string
3470
         */
3471
        public void setSubfamilyStr(String string) {
3472
            this.subfamilyStr=string;
3473

    
3474
        }
3475
        /**
3476
         * @param string
3477
         */
3478
        public void setFamilyStr(String string) {
3479
            this.familyStr=string;
3480

    
3481
        }
3482
        /**
3483
         * @return the familyStr
3484
         */
3485
        public String getFamilyStr() {
3486
            return familyStr;
3487
        }
3488
        /**
3489
         * @return the subfamilyStr
3490
         */
3491
        public String getSubfamilyStr() {
3492
            return subfamilyStr;
3493
        }
3494
        /**
3495
         * @return the tribeStr
3496
         */
3497
        public String getTribeStr() {
3498
            return tribeStr;
3499
        }
3500
        /**
3501
         * @return the subtribeStr
3502
         */
3503
        public String getSubtribeStr() {
3504
            return subtribeStr;
3505
        }
3506
        /**
3507
         * @return the genusStr
3508
         */
3509
        public String getGenusStr() {
3510
            return genusStr;
3511
        }
3512
        /**
3513
         * @return the subgenusStr
3514
         */
3515
        public String getSubgenusStr() {
3516
            return subgenusStr;
3517
        }
3518
        /**
3519
         * @return the speciesStr
3520
         */
3521
        public String getSpeciesStr() {
3522
            return speciesStr;
3523
        }
3524
        /**
3525
         * @return the subspeciesStr
3526
         */
3527
        public String getSubspeciesStr() {
3528
            return subspeciesStr;
3529
        }
3530
        /**
3531
         * @return the formStr
3532
         */
3533
        public String getFormStr() {
3534
            return formStr;
3535
        }
3536
        /**
3537
         * @return the varietyStr
3538
         */
3539
        public String getVarietyStr() {
3540
            return varietyStr;
3541
        }
3542

    
3543
        /**
3544
         * @param newName2
3545
         */
3546
        public void setNotParsableTaxon(String newName2) {
3547
            //takes too much time
3548
            //            List<TaxonBase> tmpList = importer.getTaxonService().list(Taxon.class, 0, 0, null, null);
3549

    
3550
            NomenclaturalStatusType statusType = null;
3551
            if (!getStatus().isEmpty()){
3552
                try {
3553
                    statusType = nomStatusString2NomStatus(getStatus());
3554
                } catch (UnknownCdmTypeException e) {
3555
                    addProblematicStatusToFile(getStatus());
3556
                    logger.warn("Problem with status");
3557
                }
3558
            }
3559
            List<TaxonBase> tmpList = new ArrayList<TaxonBase>();
3560

    
3561
            Pager<TaxonBase> taxontest = importer.getTaxonService().findByTitle(TaxonBase.class, newName2, MatchMode.BEGINNING, null, null, null, null, null);
3562
            tmpList.addAll(taxontest.getRecords());
3563

    
3564
            //logger.info("tmpList returned: "+tmpList.size());
3565

    
3566

    
3567
            boolean foundIdentic=false;
3568
            TaxonBase<?> tmptaxonbase=null;
3569
            //            Taxon tmpPartial=null;
3570
            for (TaxonBase<?> tmpb:tmpList){
3571
                if(tmpb !=null){
3572
                    TaxonNameBase<?,?> tnb =  tmpb.getName();
3573
                    Rank crank=null;
3574
                    if (tnb != null){
3575
                        if (tnb.getTitleCache().split("sec.")[0].trim().equalsIgnoreCase(newName2) ){
3576
                            crank =tnb.getRank();
3577
                            if (crank !=null && rank !=null){
3578
                                if (crank.equals(rank)){
3579
                                    foundIdentic=true;
3580
                                    try{
3581
                                        if(!isSynonym) {
3582
                                            tmptaxonbase=tmpb;
3583
                                        } else {
3584
                                            tmptaxonbase=tmpb;
3585
                                        }
3586
                                        break;
3587
                                    }catch(Exception e){
3588
                                        e.printStackTrace();
3589
                                    }
3590
                                }
3591
                            }
3592
                        }
3593
                    }
3594
                }
3595
            }
3596
            boolean statusMatch=false;
3597
            boolean appendedMatch=false;
3598
            if(tmptaxonbase !=null && foundIdentic){
3599
                statusMatch=compareStatus(tmptaxonbase, statusType);
3600
                if (!getStatus().isEmpty() && ! (tmptaxonbase.getAppendedPhrase() == null)) {
3601
                    appendedMatch=tmptaxonbase.getAppendedPhrase().equals(getStatus());
3602
                }
3603
                if (getStatus().isEmpty() && tmptaxonbase.getAppendedPhrase() == null) {
3604
                    appendedMatch=true;
3605
                }
3606

    
3607
            }
3608
            if ((tmptaxonbase == null || !foundIdentic) ||  (tmptaxonbase != null && !statusMatch) ||  (tmptaxonbase != null && !appendedMatch && !statusMatch)){
3609

    
3610
                NonViralName<?> tnb = getNonViralNameAccNomenclature();
3611
                tnb.setRank(rank);
3612

    
3613
                if(statusType != null) {
3614
                    tnb.addStatus(NomenclaturalStatus.NewInstance(statusType));
3615
                }
3616
                if(getStatus()!=null) {
3617
                    tnb.setAppendedPhrase(getStatus());
3618
                }
3619

    
3620
                tnb.setTitleCache(newName2,true);
3621
                tmptaxonbase = findMatchingTaxon(tnb,refMods);
3622
                if(tmptaxonbase==null){
3623
                    tmptaxonbase=Taxon.NewInstance(tnb, refMods);
3624
                    if(!configState.getConfig().doKeepOriginalSecundum()) {
3625
                        tmptaxonbase.setSec(configState.getConfig().getSecundum());
3626
                    }
3627
                    //                    tmptaxonbase.setSec(refMods);
3628
                    if(!isSynonym) {
3629
                        classification.addChildTaxon((Taxon)tmptaxonbase, null, null);
3630
                        sourceHandler.addSource(refMods, (Taxon)tmptaxonbase);
3631
                    }
3632
                }
3633
            }
3634
            if(!isSynonym) {
3635
                tmptaxonbase = CdmBase.deproxy(tmptaxonbase, Taxon.class);
3636
            } else {
3637
                tmptaxonbase = CdmBase.deproxy(tmptaxonbase, Synonym.class);
3638
            }
3639
            if (author != null) {
3640
                if (!getIdentifier().isEmpty() && (getIdentifier().length()>2)){
3641
                    setLSID(getIdentifier(), tmptaxonbase);
3642
                    importer.getTaxonService().saveOrUpdate(tmptaxonbase);
3643
                    if(!isSynonym) {
3644
                        tmptaxonbase = CdmBase.deproxy(tmptaxonbase, Taxon.class);
3645
                    } else {
3646
                        tmptaxonbase = CdmBase.deproxy(tmptaxonbase, Synonym.class);
3647
                    }
3648
                }
3649
            }
3650
            TaxonNameBase<?,?> tnb = CdmBase.deproxy(tmptaxonbase.getName(), TaxonNameBase.class);
3651

    
3652
            if(!isSynonym) {
3653
                this.taxon=(Taxon)tmptaxonbase;
3654
            } else {
3655
                this.syno=(Synonym)tmptaxonbase;
3656
            }
3657
            castTaxonNameBase(tnb, taxonnamebase);
3658

    
3659
        }
3660

    
3661
        /**
3662
         *
3663
         */
3664
        public void buildTaxon() {
3665
            //System.out.println("BUILD TAXON");
3666
            logger.info("buildTaxon");
3667
            NomenclaturalStatusType statusType = null;
3668
            if (!getStatus().isEmpty()){
3669
                try {
3670
                    statusType = nomStatusString2NomStatus(getStatus());
3671
                    taxonnamebase.addStatus(NomenclaturalStatus.NewInstance(statusType));
3672
                } catch (UnknownCdmTypeException e) {
3673
                    addProblematicStatusToFile(getStatus());
3674
                    logger.warn("Problem with status");
3675
                }
3676
            }
3677
            importer.getNameService().save(taxonnamebase);
3678

    
3679
            TaxonBase<?> tmptaxonbase;
3680
            if (!isSynonym) {
3681
                tmptaxonbase =Taxon.NewInstance(taxonnamebase, refMods); //sec set null
3682
            }
3683
            else {
3684
                tmptaxonbase =Synonym.NewInstance(taxonnamebase, refMods); //sec set null
3685
            }
3686
            boolean exist = false;
3687
            for (TaxonNode p : classification.getAllNodes()){
3688
                try{
3689
                    if(p.getTaxon().getTitleCache().equalsIgnoreCase(tmptaxonbase.getTitleCache())) {
3690
                        if(compareStatus(p.getTaxon(), statusType)){
3691
                            try{
3692
                                if (!isSynonym) {
3693
                                    tmptaxonbase=CdmBase.deproxy(p.getTaxon(), Taxon.class);
3694
                                } else {
3695
                                    tmptaxonbase=CdmBase.deproxy(p.getTaxon(), Synonym.class);
3696
                                }
3697
                                exist =true;
3698
                            }catch(Exception e){
3699
                                logger.warn("Found the same name but from another type (taxon/synonym)");
3700
                                TaxonNameBase<?,?> existingTnb = getTaxon().getName();
3701
                                if (isSynonym){
3702
                                    tmptaxonbase = new Synonym(existingTnb, refMods);
3703
                                    importer.getTaxonService().saveOrUpdate(tmptaxonbase);
3704
                                    tmptaxonbase=CdmBase.deproxy(tmptaxonbase, Synonym.class);
3705
                                    exist =true;
3706
                                }
3707
                                else{
3708
                                    tmptaxonbase = new Taxon(existingTnb, refMods);
3709
                                }
3710
                            }
3711
                        }
3712
                    }
3713
                }catch(NullPointerException n){logger.warn(" A taxon is either null or its titlecache is null - ignore it?");}
3714
            }
3715
            if (!exist){
3716

    
3717
                boolean insertAsExisting =false;
3718
                List<Taxon> existingTaxons=new ArrayList<Taxon>();
3719
                try {
3720
                    existingTaxons = getMatchingTaxon(taxonnamebase);
3721
                } catch (Exception e1) {
3722
                    // TODO Auto-generated catch block
3723
                    e1.printStackTrace();
3724
                }
3725
                double similarityScore=0.0;
3726
                double similarityAuthor=-1;
3727
                String author1="";
3728
                String author2="";
3729
                String t1="";
3730
                String t2="";
3731
                for (Taxon bestMatchingTaxon:existingTaxons){
3732
                    //System.out.println("tnbase "+taxonnamebase.getTitleCache());
3733
                    //System.out.println("bestex "+bestMatchingTaxon.getTitleCache());
3734
                    try {
3735
                        if(taxonnamebase.getAuthorshipCache()!=null) {
3736
                            author1=taxonnamebase.getAuthorshipCache();
3737
                        }
3738
                    } catch (Exception e) {
3739
                        // TODO Auto-generated catch block
3740
                        e.printStackTrace();
3741
                    }
3742
                    try {
3743
                        if(castTaxonNameBase(bestMatchingTaxon.getName()).getAuthorshipCache()!=null) {
3744
                            author2=castTaxonNameBase(bestMatchingTaxon.getName()).getAuthorshipCache();
3745
                        }
3746
                    } catch (Exception e) {
3747
                        // TODO Auto-generated catch block
3748
                        e.printStackTrace();
3749
                    }
3750
                    try {
3751
                        t1=taxonnamebase.getTitleCache().split("sec.")[0].trim();
3752
                        if (author1!=null && !StringUtils.isEmpty(author1)) {
3753
                            t1=t1.split(Pattern.quote(author1))[0];
3754
                        }
3755
                    } catch (Exception e) {
3756
                        // TODO Auto-generated catch block
3757
                        e.printStackTrace();
3758
                    }
3759
                    try {
3760
                        t2=bestMatchingTaxon.getTitleCache().split("sec.")[0].trim();
3761
                        if (author2!=null && !StringUtils.isEmpty(author2)) {
3762
                            t2=t2.split(Pattern.quote(author2))[0];
3763
                        }
3764
                    } catch (Exception e) {
3765
                        // TODO Auto-generated catch block
3766
                        e.printStackTrace();
3767
                    }
3768

    
3769
                    similarityScore=similarity(t1.trim(), t2.trim());
3770
                    //System.out.println("taxonscore "+similarityScore);
3771
                    similarityAuthor=similarity(author1.trim(), author2.trim());
3772
                    //System.out.println("authorscore "+similarityAuthor);
3773
                    insertAsExisting = compareAndCheckTaxon(taxonnamebase, refMods, similarityScore, bestMatchingTaxon,similarityAuthor);
3774
                    if(insertAsExisting) {
3775
                        tmptaxonbase=bestMatchingTaxon;
3776
                        break;
3777
                    }
3778
                }
3779
                if (!insertAsExisting){
3780
                    if(!configState.getConfig().doKeepOriginalSecundum()) {
3781
                        tmptaxonbase.setSec(configState.getConfig().getSecundum());
3782
                    }
3783

    
3784
                    //                    tmptaxonbase.setSec(refMods);
3785
                    if (taxonnamebase.getRank().equals(configState.getConfig().getMaxRank())) {
3786
                        //System.out.println("****************************"+tmptaxonbase);
3787
                        if (!isSynonym) {
3788
                            classification.addChildTaxon((Taxon)tmptaxonbase, refMods, null);
3789
                        }
3790
                    } else{
3791
                        hierarchy = new HashMap<Rank, Taxon>();
3792
                        //System.out.println("LOOK FOR PARENT "+taxonnamebase.toString()+", "+tmptaxonbase.toString());
3793
                        if (!isSynonym){
3794
                            lookForParentNode(taxonnamebase,(Taxon)tmptaxonbase, refMods,this);
3795
                            //System.out.println("HIERARCHY "+hierarchy);
3796
                            Taxon parent = buildHierarchy();
3797
                            if(!taxonExistsInClassification(parent,(Taxon)tmptaxonbase)){
3798
                                if(parent !=null) {
3799
                                    classification.addParentChild(parent, (Taxon)tmptaxonbase, refMods, null);
3800
                                } else {
3801
                                    classification.addChildTaxon((Taxon)tmptaxonbase, refMods, null);
3802
                                }
3803
                                importer.getClassificationService().saveOrUpdate(classification);
3804
                            }
3805
                        }
3806
                        //                        Set<TaxonNode> nodeList = classification.getAllNodes();
3807
                        //                        for(TaxonNode tn:nodeList) {
3808
                        //                            System.out.println(tn.getTaxon());
3809
                        //                        }
3810
                    }
3811
                }
3812
                importer.getClassificationService().saveOrUpdate(classification);
3813
                //            refreshTransaction();
3814
                if(isSynonym) {
3815
                    try{
3816
                        Synonym castTest=CdmBase.deproxy(tmptaxonbase, Synonym.class);
3817
                    }catch(Exception e){
3818
                        TaxonNameBase<?,?> existingTnb = tmptaxonbase.getName();
3819
                        Synonym castTest = new Synonym(existingTnb, refMods);
3820
                        importer.getTaxonService().saveOrUpdate(castTest);
3821
                        tmptaxonbase=CdmBase.deproxy(castTest, Synonym.class);
3822
                    }
3823
                }
3824
            }
3825
            if(!isSynonym) {
3826
                taxon=CdmBase.deproxy(tmptaxonbase, Taxon.class);
3827
            } else {
3828
                syno=CdmBase.deproxy(tmptaxonbase, Synonym.class);
3829
            }
3830

    
3831

    
3832

    
3833
        }
3834

    
3835

    
3836
        /**
3837
         *
3838
         */
3839
        private Taxon buildHierarchy() {
3840
            logger.info("buildHierarchy");
3841
            Taxon higherTaxon = null;
3842
            //add the maxRank as a root
3843
            if(hierarchy.containsKey(configState.getConfig().getMaxRank())){
3844
                Taxon ct=hierarchy.get(configState.getConfig().getMaxRank());
3845
                if(!taxonExistsInClassification(higherTaxon, ct)) {
3846
                    //System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"+hierarchy.get(configState.getConfig().getMaxRank()));
3847
                    classification.addChildTaxon(ct, refMods, null);
3848
                }
3849
                higherTaxon = hierarchy.get(configState.getConfig().getMaxRank());
3850
                //                return higherTaxon;
3851
            }
3852
            //add the relation to the highertaxon, except if the current rank to add IS the maxRank
3853
            if(hierarchy.containsKey(Rank.SUBFAMILY()) && !configState.getConfig().getMaxRank().equals(Rank.SUBFAMILY())){
3854
                higherTaxon=saveAndGetHigherTaxon(Rank.SUBFAMILY(),higherTaxon);
3855
            }
3856
            if(hierarchy.containsKey(Rank.TRIBE())&& !configState.getConfig().getMaxRank().equals(Rank.TRIBE())){
3857
                higherTaxon=saveAndGetHigherTaxon(Rank.TRIBE(),higherTaxon);
3858
            }
3859
            if(hierarchy.containsKey(Rank.SUBTRIBE())&& !configState.getConfig().getMaxRank().equals(Rank.SUBTRIBE())){
3860
                higherTaxon=saveAndGetHigherTaxon(Rank.SUBTRIBE(),higherTaxon);
3861
            }
3862
            if(hierarchy.containsKey(Rank.GENUS())&& !configState.getConfig().getMaxRank().equals(Rank.SUBGENUS())){
3863
                higherTaxon=saveAndGetHigherTaxon(Rank.GENUS(),higherTaxon);
3864
            }
3865
            if(hierarchy.containsKey(Rank.SUBGENUS())&& !configState.getConfig().getMaxRank().equals(Rank.SUBGENUS())){
3866
                higherTaxon=saveAndGetHigherTaxon(Rank.SUBGENUS(),higherTaxon);
3867
            }
3868
            importer.getClassificationService().saveOrUpdate(classification);
3869
            return higherTaxon;
3870
        }
3871

    
3872
        private Taxon saveAndGetHigherTaxon(Rank r, Taxon higherTaxon){
3873
            Taxon ct=hierarchy.get(r);
3874
            if(!taxonExistsInClassification(higherTaxon,ct )) {
3875
                if(higherTaxon != null && ct!=null) {
3876
                    classification.addParentChild(higherTaxon, ct, refMods, null);
3877
                } else
3878
                    if(higherTaxon == null && ct !=null) {
3879
                        classification.addChildTaxon(ct, refMods, null);
3880
                    }
3881
            }
3882
            return ct;
3883
        }
3884

    
3885
        private boolean taxonExistsInClassification(Taxon parent, Taxon child){
3886
            logger.info("taxonExistsInClassification");
3887
            //            System.out.println("LOOK IF TAXA EXIST "+parent+", "+child);
3888
            boolean found=false;
3889
            if(parent !=null){
3890
                for (TaxonNode p : classification.getAllNodes()){
3891
                    if(p.getTaxon().getTitleCache().equalsIgnoreCase(parent.getTitleCache())) {
3892
                        for (TaxonNode c : p.getChildNodes()) {
3893
                            if (c.getTaxon().getTitleCache().equalsIgnoreCase(child.getTitleCache())) {
3894
                                found=true;
3895
                                break;
3896
                            }
3897
                        }
3898
                    }
3899
                }
3900
            }
3901
            else{
3902
                for (TaxonNode p : classification.getAllNodes()){
3903
                    if(p.getTaxon().getTitleCache().equalsIgnoreCase(child.getTitleCache())) {
3904
                        found=true;
3905
                        break;
3906
                    }
3907
                }
3908
            }
3909
            //            System.out.println("LOOK IF TAXA EXIST? "+found);
3910
            return found;
3911
        }
3912
        /**
3913
         * @param nameToBeFilledTest
3914
         */
3915
        @SuppressWarnings("rawtypes")
3916
        public void setParsedName(TaxonNameBase nameToBeFilledTest) {
3917
            this.taxonnamebase = (NonViralName<?>) nameToBeFilledTest;
3918

    
3919
        }
3920
        //variety dwcranks:varietyEpithet
3921
        /**
3922
         * @return the author
3923
         */
3924
        public String getAuthor() {
3925
            return author;
3926
        }
3927
        /**
3928
         * @return
3929
         */
3930
        public Taxon getTaxon() {
3931
            return taxon;
3932
        }
3933
        /**
3934
         * @return
3935
         */
3936
        public NonViralName<?> getTaxonNameBase() {
3937
            return taxonnamebase;
3938
        }
3939

    
3940
        /**
3941
         * @param findOrCreateTaxon
3942
         */
3943
        public void setForm(Taxon form) {
3944
            this.form=form;
3945

    
3946
        }
3947
        /**
3948
         * @param findOrCreateTaxon
3949
         */
3950
        public void setVariety(Taxon variety) {
3951
            this.variety=variety;
3952

    
3953
        }
3954
        /**
3955
         * @param string
3956
         * @return
3957
         */
3958
        @SuppressWarnings("rawtypes")
3959
        public Taxon findOrCreateTaxon(String partialname,String fullname, Rank rank, Rank globalrank) {
3960
            logger.info("findOrCreateTaxon");
3961
            sourceUrlRef=CdmBase.deproxy(sourceUrlRef, Reference.class);
3962
            //takes too much time
3963
            //            List<TaxonBase> tmpList = importer.getTaxonService().list(Taxon.class, 0, 0, null, null);
3964
            //            logger.info("tmpList returned: "+tmpList.size());
3965

    
3966
            NomenclaturalStatusType statusType = null;
3967
            if (!getStatus().isEmpty()){
3968
                try {
3969
                    statusType = nomStatusString2NomStatus(getStatus());
3970
                } catch (UnknownCdmTypeException e) {
3971
                    addProblematicStatusToFile(getStatus());
3972
                    logger.warn("Problem with status");
3973
                }
3974
            }
3975

    
3976
            List<TaxonBase> tmpListFiltered = new ArrayList<TaxonBase>();
3977

    
3978
            Pager<TaxonBase> taxontest = importer.getTaxonService().findByTitle(TaxonBase.class, fullname, MatchMode.BEGINNING, null, null, null, null, null);
3979

    
3980
            tmpListFiltered.addAll(taxontest.getRecords());
3981
            taxontest = importer.getTaxonService().findByTitle(TaxonBase.class, partialname, MatchMode.BEGINNING, null, null, null, null, null);
3982
            tmpListFiltered.addAll(taxontest.getRecords());
3983

    
3984
            //logger.info("tmpListFiltered returned: "+tmpListFiltered.size());
3985

    
3986
            boolean nameCorrected=false;
3987
            if (fullname.indexOf(partialname)<0) {
3988
                nameCorrected=true;
3989
            }
3990

    
3991
            boolean foundIdentic=false;
3992
            Taxon tmp=null;
3993
            //            Taxon tmpPartial=null;
3994
            for (TaxonBase tmpb:tmpListFiltered){
3995
                if(tmpb !=null){
3996
                    TaxonNameBase tnb =  tmpb.getName();
3997
                    Rank crank=null;
3998
                    if (tnb != null){
3999
                        //                        //System.out.println(tnb.getTitleCache());
4000
                        //                        if (tnb.getTitleCache().split("sec.")[0].equals(partialname) ||tnb.getTitleCache().split("sec.")[0].equals(fullname) ){
4001
                        if(globalrank.equals(rank) || (globalrank.isLower(Rank.SPECIES()) && rank.equals(Rank.SPECIES()))){
4002
                            if (tnb.getTitleCache().split("sec.")[0].trim().equalsIgnoreCase(fullname) ){
4003
                                crank =tnb.getRank();
4004
                                if (crank !=null && rank !=null){
4005
                                    if (crank.equals(rank)){
4006
                                        foundIdentic=true;
4007
                                        try{
4008
                                            tmp=(Taxon)tmpb;
4009
                                            break;
4010
                                        }catch(Exception e){
4011
                                            e.printStackTrace();
4012
                                        }
4013
                                    }
4014
                                }
4015
                            }
4016
                            if(nameCorrected){ //for corrected names such as Anochetus -- A. blf-pat
4017
                                if (tnb.getTitleCache().split("sec.")[0].trim().equalsIgnoreCase(partialname) ){
4018
                                    crank =tnb.getRank();
4019
                                    if (crank !=null && rank !=null){
4020
                                        if (crank.equals(rank)){
4021
                                            foundIdentic=true;
4022
                                            try{
4023
                                                tmp=(Taxon)tmpb;
4024
                                                break;
4025
                                            }catch(Exception e){
4026
                                                e.printStackTrace();
4027
                                            }
4028
                                        }
4029
                                    }
4030
                                }
4031
                            }
4032
                        }
4033
                        else{
4034
                            if (tnb.getTitleCache().split("sec.")[0].trim().equalsIgnoreCase(partialname) ){
4035
                                crank =tnb.getRank();
4036
                                if (crank !=null && rank !=null){
4037
                                    if (crank.equals(rank)){
4038
                                        foundIdentic=true;
4039
                                        try{
4040
                                            tmp=(Taxon)tmpb;
4041
                                            break;
4042
                                        }catch(Exception e){
4043
                                            e.printStackTrace();
4044
                                        }
4045
                                    }
4046
                                }
4047
                            }
4048
                        }
4049
                    }
4050
                }
4051
            }
4052
            boolean statusMatch=false;
4053
            boolean appendedMatch=false;
4054
            if(tmp !=null && foundIdentic){
4055
                statusMatch=compareStatus(tmp, statusType);
4056
                if (!getStatus().isEmpty() && ! (tmp.getAppendedPhrase() == null)) {
4057
                    appendedMatch=tmp.getAppendedPhrase().equals(getStatus());
4058
                }
4059
                if (getStatus().isEmpty() && tmp.getAppendedPhrase() == null) {
4060
                    appendedMatch=true;
4061
                }
4062

    
4063
            }
4064
            if ((tmp == null || !foundIdentic) ||  (tmp != null && !statusMatch) ||  (tmp != null && !appendedMatch && !statusMatch)){
4065

    
4066
                NonViralName<?> tnb = getNonViralNameAccNomenclature();
4067
                tnb.setRank(rank);
4068

    
4069
                if(statusType != null) {
4070
                    tnb.addStatus(NomenclaturalStatus.NewInstance(statusType));
4071
                }
4072
                if(getStatus()!=null) {
4073
                    tnb.setAppendedPhrase(getStatus());
4074
                }
4075

    
4076
                if(rank.equals(Rank.UNKNOWN_RANK())){
4077
                    tnb.setTitleCache(fullname, true);
4078
                    //                    tnb.setGenusOrUninomial(fullname);
4079
                }
4080
                if(rank.isHigher(Rank.GENUS())) {
4081
                    tnb.setGenusOrUninomial(partialname);
4082
                }
4083

    
4084
                if(rank.isHigher(Rank.SPECIES())) {
4085
                    tnb.setTitleCache(partialname, true);
4086
                }
4087

    
4088
                if (rank.equals(globalrank) && author != null) {
4089
                    if(fullname.indexOf("opulifolium")>-1) {
4090
                        //System.out.println("AUTOR: "+author);
4091
                    }
4092
                    tnb.setCombinationAuthorTeam(findOrCreateAuthor(author));
4093
                    if (getIdentifier() !=null && !getIdentifier().isEmpty()){
4094
                        Taxon taxonLSID = getTaxonByLSID(getIdentifier());
4095
                        if (taxonLSID !=null) {
4096
                            tmp=taxonLSID;
4097
                        }
4098
                    }
4099
                }
4100

    
4101
                if(tmp == null){
4102
                    if (rank.equals(Rank.FAMILY())) {
4103
                        tmp = buildFamily(tnb);
4104
                    }
4105
                    if (rank.equals(Rank.SUBFAMILY())) {
4106
                        tmp = buildSubfamily(tnb);
4107
                    }
4108
                    if (rank.equals(Rank.TRIBE())) {
4109
                        tmp = buildTribe(tnb);
4110
                    }
4111
                    if (rank.equals(Rank.SUBTRIBE())) {
4112
                        tmp = buildSubtribe(tnb);
4113
                    }
4114
                    if (rank.equals(Rank.GENUS())) {
4115
                        tmp = buildGenus(partialname, tnb);
4116
                    }
4117

    
4118
                    if (rank.equals(Rank.SUBGENUS())) {
4119
                        tmp = buildSubgenus(partialname, tnb);
4120
                    }
4121
                    if (rank.equals(Rank.SPECIES())) {
4122
                        tmp = buildSpecies(partialname, tnb);
4123
                    }
4124

    
4125
                    if (rank.equals(Rank.SUBSPECIES())) {
4126
                        tmp = buildSubspecies(partialname, tnb);
4127
                    }
4128

    
4129
                    if (rank.equals(Rank.VARIETY())) {
4130
                        tmp = buildVariety(fullname, partialname, tnb);
4131
                    }
4132

    
4133
                    if (rank.equals(Rank.FORM())) {
4134
                        tmp = buildForm(fullname, partialname, tnb);
4135
                    }
4136

    
4137
                    importer.getClassificationService().saveOrUpdate(classification);
4138
                }
4139
            }
4140

    
4141
            tmp = CdmBase.deproxy(tmp, Taxon.class);
4142
            if (rank.equals(globalrank) && author != null) {
4143
                if (!getIdentifier().isEmpty() && (getIdentifier().length()>2)){
4144
                    setLSID(getIdentifier(), tmp);
4145
                    importer.getTaxonService().saveOrUpdate(tmp);
4146
                    tmp = CdmBase.deproxy(tmp, Taxon.class);
4147
                }
4148
            }
4149
            TaxonNameBase tnb = CdmBase.deproxy(tmp.getName(), TaxonNameBase.class);
4150

    
4151
            this.taxon=tmp;
4152
            castTaxonNameBase(tnb, taxonnamebase);
4153
            return tmp;
4154
        }
4155
        /**
4156
         * @param tnb
4157
         * @return
4158
         */
4159
        private Taxon buildSubfamily(NonViralName<?> tnb) {
4160
            Taxon tmp;
4161
            //            tnb.generateTitle();
4162
            tmp = findMatchingTaxon(tnb,refMods);
4163
            if(tmp ==null){
4164
                tmp = Taxon.NewInstance(tnb, sourceUrlRef);
4165
                if(!configState.getConfig().doKeepOriginalSecundum()) {
4166
                    tmp.setSec(configState.getConfig().getSecundum());
4167
                }
4168
                //                tmp.setSec(refMods);
4169
                //                sourceHandler.addSource(refMods, tmp);
4170
                if(family != null) {
4171
                    classification.addParentChild(family, tmp, null, null);
4172
                    higherRank=Rank.FAMILY();
4173
                    higherTaxa=family;
4174
                } else {
4175
                    //System.out.println("ADDCHILDTAXON SUBFAMILY "+tmp);
4176
                    classification.addChildTaxon(tmp, null, null);
4177
                }
4178
            }
4179
            return tmp;
4180
        }
4181
        /**
4182
         * @param tnb
4183
         * @return
4184
         */
4185
        private Taxon buildFamily(NonViralName<?> tnb) {
4186
            Taxon tmp;
4187
            //            tnb.generateTitle();
4188
            tmp = findMatchingTaxon(tnb,refMods);
4189
            if(tmp ==null){
4190
                tmp = Taxon.NewInstance(tnb, sourceUrlRef);
4191
                if(!configState.getConfig().doKeepOriginalSecundum()) {
4192
                    tmp.setSec(configState.getConfig().getSecundum());
4193
                }
4194
                //                tmp.setSec(refMods);
4195
                //sourceHandler.addSource(refMods, tmp);
4196
                //System.out.println("ADDCHILDTAXON FAMILY "+tmp);
4197
                classification.addChildTaxon(tmp, null, null);
4198
            }
4199
            return tmp;
4200
        }
4201
        /**
4202
         * @param fullname
4203
         * @param tnb
4204
         * @return
4205
         */
4206
        private Taxon buildForm(String fullname, String partialname, NonViralName<?> tnb) {
4207
            Taxon tmp;
4208
            if (genusName !=null) {
4209
                tnb.setGenusOrUninomial(genusName.getGenusOrUninomial());
4210
            }
4211
            if (subgenusName !=null) {
4212
                tnb.setInfraGenericEpithet(subgenusName.getInfraGenericEpithet());
4213
            }
4214
            if(speciesName !=null) {
4215
                tnb.setSpecificEpithet(speciesName.getSpecificEpithet());
4216
            }
4217
            if(subspeciesName != null) {
4218
                tnb.setInfraSpecificEpithet(subspeciesName.getInfraSpecificEpithet());
4219
            }
4220
            if(partialname!= null) {
4221
                tnb.setInfraSpecificEpithet(partialname);
4222
            }
4223
            tnb.generateTitle();
4224
            //TODO how to save form??
4225
            tnb.setTitleCache(fullname, true);
4226
            tmp = findMatchingTaxon(tnb,refMods);
4227
            if(tmp ==null){
4228
                tmp = Taxon.NewInstance(tnb, sourceUrlRef);
4229
                if(!configState.getConfig().doKeepOriginalSecundum()) {
4230
                    tmp.setSec(configState.getConfig().getSecundum());
4231
                }
4232
                //                tmp.setSec(refMods);
4233
                //sourceHandler.addSource(refMods, tmp);
4234
                if (subspecies !=null) {
4235
                    classification.addParentChild(subspecies, tmp, null, null);
4236
                    higherRank=Rank.SUBSPECIES();
4237
                    higherTaxa=subspecies;
4238
                } else {
4239
                    if (species !=null) {
4240
                        classification.addParentChild(species, tmp, null, null);
4241
                        higherRank=Rank.SPECIES();
4242
                        higherTaxa=species;
4243
                    }
4244
                    else{
4245
                        //                        System.out.println("ADDCHILDTAXON FORM "+tmp);
4246
                        classification.addChildTaxon(tmp, null, null);
4247
                    }
4248
                }
4249
            }
4250
            return tmp;
4251
        }
4252
        /**
4253
         * @param fullname
4254
         * @param tnb
4255
         * @return
4256
         */
4257
        private Taxon buildVariety(String fullname, String partialname, NonViralName<?> tnb) {
4258
            Taxon tmp;
4259
            if (genusName !=null) {
4260
                tnb.setGenusOrUninomial(genusName.getGenusOrUninomial());
4261
            }
4262
            if (subgenusName !=null) {
4263
                tnb.setInfraGenericEpithet(subgenusName.getInfraGenericEpithet());
4264
            }
4265
            if(speciesName !=null) {
4266
                tnb.setSpecificEpithet(speciesName.getSpecificEpithet());
4267
            }
4268
            if(subspeciesName != null) {
4269
                tnb.setInfraSpecificEpithet(subspeciesName.getSpecificEpithet());
4270
            }
4271
            if(partialname != null) {
4272
                tnb.setInfraSpecificEpithet(partialname);
4273
            }
4274
            //TODO how to save variety?
4275
            tnb.setTitleCache(fullname, true);
4276
            tmp = findMatchingTaxon(tnb,refMods);
4277
            if(tmp ==null){
4278
                tmp = Taxon.NewInstance(tnb, sourceUrlRef);
4279
                if(!configState.getConfig().doKeepOriginalSecundum()) {
4280
                    tmp.setSec(configState.getConfig().getSecundum());
4281
                }
4282
                //                tmp.setSec(refMods);
4283
                //sourceHandler.addSource(refMods, tmp);
4284
                if (subspecies !=null) {
4285
                    classification.addParentChild(subspecies, tmp, null, null);
4286
                    higherRank=Rank.SUBSPECIES();
4287
                    higherTaxa=subspecies;
4288
                } else {
4289
                    if(species !=null) {
4290
                        classification.addParentChild(species, tmp, null, null);
4291
                        higherRank=Rank.SPECIES();
4292
                        higherTaxa=species;
4293
                    }
4294
                    else{
4295
                        //System.out.println("ADDCHILDTAXON VARIETY "+tmp);
4296
                        classification.addChildTaxon(tmp, null, null);
4297
                    }
4298
                }
4299
            }
4300
            return tmp;
4301
        }
4302
        /**
4303
         * @param partialname
4304
         * @param tnb
4305
         * @return
4306
         */
4307
        private Taxon buildSubspecies(String partialname, NonViralName<?> tnb) {
4308
            Taxon tmp;
4309
            if (genusName !=null) {
4310
                tnb.setGenusOrUninomial(genusName.getGenusOrUninomial());
4311
            }
4312
            if (subgenusName !=null) {
4313
                //                            System.out.println("SUB:"+subgenusName.getInfraGenericEpithet());
4314
                tnb.setInfraGenericEpithet(subgenusName.getInfraGenericEpithet());
4315
            }
4316
            if(speciesName !=null) {
4317
                //                            System.out.println("SPE:"+speciesName.getSpecificEpithet());
4318
                tnb.setSpecificEpithet(speciesName.getSpecificEpithet());
4319
            }
4320
            tnb.setInfraSpecificEpithet(partialname);
4321
            tnb.generateTitle();
4322
            tmp = findMatchingTaxon(tnb,refMods);
4323
            if(tmp ==null){
4324
                tmp = Taxon.NewInstance(tnb, sourceUrlRef);
4325
                if(!configState.getConfig().doKeepOriginalSecundum())
4326
                 {
4327
                    tmp.setSec(configState.getConfig().getSecundum());
4328
                //                tmp.setSec(refMods);
4329
                //sourceHandler.addSource(refMods, tmp);
4330
                }
4331

    
4332
                if(species != null) {
4333
                    classification.addParentChild(species, tmp, null, null);
4334
                    higherRank=Rank.SPECIES();
4335
                    higherTaxa=species;
4336
                }
4337
                else{
4338
                    //System.out.println("ADDCHILDTAXON SUBSPECIES "+tmp);
4339
                    classification.addChildTaxon(tmp, null, null);
4340
                }
4341
            }
4342
            return tmp;
4343
        }
4344
        /**
4345
         * @param partialname
4346
         * @param tnb
4347
         * @return
4348
         */
4349
        private Taxon buildSpecies(String partialname, NonViralName<?> tnb) {
4350
            Taxon tmp;
4351
            if (genusName !=null) {
4352
                tnb.setGenusOrUninomial(genusName.getGenusOrUninomial());
4353
            }
4354
            if (subgenusName !=null) {
4355
                tnb.setInfraGenericEpithet(subgenusName.getInfraGenericEpithet());
4356
            }
4357
            tnb.setSpecificEpithet(partialname.toLowerCase());
4358
            tnb.generateTitle();
4359
            tmp = findMatchingTaxon(tnb,refMods);
4360
            if(tmp ==null){
4361
                tmp = Taxon.NewInstance(tnb, sourceUrlRef);
4362
                if(!configState.getConfig().doKeepOriginalSecundum()) {
4363
                    tmp.setSec(configState.getConfig().getSecundum());
4364
                }
4365
                //                tmp.setSec(refMods);
4366
                //sourceHandler.addSource(refMods, tmp);
4367
                if (subgenus !=null) {
4368
                    classification.addParentChild(subgenus, tmp, null, null);
4369
                    higherRank=Rank.SUBGENUS();
4370
                    higherTaxa=subgenus;
4371
                } else {
4372
                    if (genus !=null) {
4373
                        classification.addParentChild(genus, tmp, null, null);
4374
                        higherRank=Rank.GENUS();
4375
                        higherTaxa=genus;
4376
                    }
4377
                    else{
4378
                        //System.out.println("ADDCHILDTAXON SPECIES "+tmp);
4379
                        classification.addChildTaxon(tmp, null, null);
4380
                    }
4381
                }
4382
            }
4383
            return tmp;
4384
        }
4385
        /**
4386
         * @param partialname
4387
         * @param tnb
4388
         * @return
4389
         */
4390
        private Taxon buildSubgenus(String partialname, NonViralName<?> tnb) {
4391
            Taxon tmp;
4392
            tnb.setInfraGenericEpithet(partialname);
4393
            if (genusName !=null) {
4394
                tnb.setGenusOrUninomial(genusName.getGenusOrUninomial());
4395
            }
4396
            tnb.generateTitle();
4397
            tmp = findMatchingTaxon(tnb,refMods);
4398
            if(tmp ==null){
4399
                tmp = Taxon.NewInstance(tnb, sourceUrlRef);
4400
                if(!configState.getConfig().doKeepOriginalSecundum()) {
4401
                    tmp.setSec(configState.getConfig().getSecundum());
4402
                }
4403
                //                tmp.setSec(refMods);
4404
                //sourceHandler.addSource(refMods, tmp);
4405
                if(genus != null) {
4406
                    classification.addParentChild(genus, tmp, null, null);
4407
                    higherRank=Rank.GENUS();
4408
                    higherTaxa=genus;
4409
                } else{
4410
                    //System.out.println("ADDCHILDTAXON SUBGENUS "+tmp);
4411
                    classification.addChildTaxon(tmp, null, null);
4412
                }
4413
            }
4414
            return tmp;
4415
        }
4416
        /**
4417
         * @param partialname
4418
         * @param tnb
4419
         * @return
4420
         */
4421
        private Taxon buildGenus(String partialname, NonViralName<?> tnb) {
4422
            Taxon tmp;
4423
            tnb.setGenusOrUninomial(partialname);
4424
            tnb.generateTitle();
4425

    
4426
            tmp = findMatchingTaxon(tnb,refMods);
4427
            if(tmp ==null){
4428
                tmp = Taxon.NewInstance(tnb, sourceUrlRef);
4429
                if(!configState.getConfig().doKeepOriginalSecundum())
4430
                 {
4431
                    tmp.setSec(configState.getConfig().getSecundum());
4432
                //                tmp.setSec(refMods);
4433
                //sourceHandler.addSource(refMods, tmp);
4434
                }
4435

    
4436
                if(subtribe != null) {
4437
                    classification.addParentChild(subtribe, tmp, null, null);
4438
                    higherRank=Rank.SUBTRIBE();
4439
                    higherTaxa=subtribe;
4440
                } else{
4441
                    if(tribe !=null) {
4442
                        classification.addParentChild(tribe, tmp, null, null);
4443
                        higherRank=Rank.TRIBE();
4444
                        higherTaxa=tribe;
4445
                    } else{
4446
                        if(subfamily !=null) {
4447
                            classification.addParentChild(subfamily, tmp, null, null);
4448
                            higherRank=Rank.SUBFAMILY();
4449
                            higherTaxa=subfamily;
4450
                        } else
4451
                            if(family !=null) {
4452
                                classification.addParentChild(family, tmp, null, null);
4453
                                higherRank=Rank.FAMILY();
4454
                                higherTaxa=family;
4455
                            }
4456
                            else{
4457
                                //System.out.println("ADDCHILDTAXON GENUS "+tmp);
4458
                                classification.addChildTaxon(tmp, null, null);
4459
                            }
4460
                    }
4461
                }
4462
            }
4463
            return tmp;
4464
        }
4465

    
4466
        /**
4467
         * @param tnb
4468
         * @return
4469
         */
4470
        private Taxon buildSubtribe(NonViralName<?> tnb) {
4471
            Taxon tmp;
4472
            tnb.generateTitle();
4473
            tmp = findMatchingTaxon(tnb,refMods);
4474
            if(tmp==null){
4475
                tmp = Taxon.NewInstance(tnb, sourceUrlRef);
4476
                if(!configState.getConfig().doKeepOriginalSecundum()) {
4477
                    tmp.setSec(configState.getConfig().getSecundum());
4478
                }
4479
                //                tmp.setSec(refMods);
4480
                //sourceHandler.addSource(refMods, tmp);
4481
                if(tribe != null) {
4482
                    classification.addParentChild(tribe, tmp, null, null);
4483
                    higherRank=Rank.TRIBE();
4484
                    higherTaxa=tribe;
4485
                } else{
4486
                    //System.out.println("ADDCHILDTAXON SUBTRIBE "+tmp);
4487
                    classification.addChildTaxon(tmp, null, null);
4488
                }
4489
            }
4490
            return tmp;
4491
        }
4492
        /**
4493
         * @param tnb
4494
         * @return
4495
         */
4496
        private Taxon buildTribe(NonViralName<?> tnb) {
4497
            Taxon tmp;
4498
            tnb.generateTitle();
4499
            tmp = findMatchingTaxon(tnb,refMods);
4500
            if(tmp==null){
4501
                tmp = Taxon.NewInstance(tnb, sourceUrlRef);
4502
                if(!configState.getConfig().doKeepOriginalSecundum()) {
4503
                    tmp.setSec(configState.getConfig().getSecundum());
4504
                }
4505
                //                tmp.setSec(refMods);
4506
                //sourceHandler.addSource(refMods, tmp);
4507
                if (subfamily !=null) {
4508
                    classification.addParentChild(subfamily, tmp, null, null);
4509
                    higherRank=Rank.SUBFAMILY();
4510
                    higherTaxa=subfamily;
4511
                } else {
4512
                    if(family != null) {
4513
                        classification.addParentChild(family, tmp, null, null);
4514
                        higherRank=Rank.FAMILY();
4515
                        higherTaxa=family;
4516
                    }
4517
                    else{
4518
                        //System.out.println("ADDCHILDTAXON TRIBE "+tmp);
4519
                        classification.addChildTaxon(tmp, null, null);
4520
                    }
4521
                }
4522
            }
4523
            return tmp;
4524
        }
4525

    
4526
        /**
4527
         * @param identifier2
4528
         * @return
4529
         */
4530
        @SuppressWarnings("rawtypes")
4531
        private Taxon getTaxonByLSID(String identifier) {
4532
            //logger.info("getTaxonByLSID");
4533
            //            boolean lsidok=false;
4534
            String id = identifier.split("__")[0];
4535
            //            String source = identifier.split("__")[1];
4536
            LSID lsid = null;
4537
            if (id.indexOf("lsid")>-1){
4538
                try {
4539
                    lsid = new LSID(id);
4540
                    //                    lsidok=true;
4541
                } catch (MalformedLSIDException e) {
4542
                    logger.warn("Malformed LSID");
4543
                }
4544
            }
4545
            if (lsid !=null){
4546
                List<Taxon> taxa = importer.getTaxonService().list(Taxon.class, 0, 0, null, null);
4547
                LSID currentlsid=null;
4548
                for (Taxon t:taxa){
4549
                    currentlsid = t.getLsid();
4550
                    if (currentlsid !=null){
4551
                        if (currentlsid.getLsid().equals(lsid.getLsid())){
4552
                            try{
4553
                                return (Taxon) t;
4554
                            }
4555
                            catch(Exception e){logger.warn("Exception occurred while comparing LSIDs "+e );}
4556
                        }
4557
                    }
4558
                }
4559
            }
4560
            return null;
4561
        }
4562
        /**
4563
         * @param author2
4564
         * @return
4565
         */
4566
        @SuppressWarnings("rawtypes")
4567
        private Person findOrCreateAuthor(String author2) {
4568
            //logger.info("findOrCreateAuthor");
4569
            List<UuidAndTitleCache<Person>> hiberPersons = importer.getAgentService().getPersonUuidAndTitleCache();
4570
            for (UuidAndTitleCache<Person> hibernateP:hiberPersons){
4571
                if(hibernateP.getTitleCache().equals(author2)) {
4572
                    AgentBase existing = importer.getAgentService().find(hibernateP.getUuid());
4573
                    return CdmBase.deproxy(existing, Person.class);
4574
                }
4575
            }
4576
            Person p = Person.NewInstance();
4577
            p.setTitleCache(author2,true);
4578
            importer.getAgentService().saveOrUpdate(p);
4579
            return CdmBase.deproxy(p, Person.class);
4580
        }
4581
        /**
4582
         * @param author the author to set
4583
         */
4584
        public void setAuthor(String author) {
4585
            this.author = author;
4586
        }
4587

    
4588
        /**
4589
         * @return the higherTaxa
4590
         */
4591
        public Taxon getHigherTaxa() {
4592
            return higherTaxa;
4593
        }
4594
        /**
4595
         * @param higherTaxa the higherTaxa to set
4596
         */
4597
        public void setHigherTaxa(Taxon higherTaxa) {
4598
            this.higherTaxa = higherTaxa;
4599
        }
4600
        /**
4601
         * @return the higherRank
4602
         */
4603
        public Rank getHigherRank() {
4604
            return higherRank;
4605
        }
4606
        /**
4607
         * @param higherRank the higherRank to set
4608
         */
4609
        public void setHigherRank(Rank higherRank) {
4610
            this.higherRank = higherRank;
4611
        }
4612
        public String getName(){
4613
            if (newName.isEmpty()) {
4614
                return originalName;
4615
            } else {
4616
                return newName;
4617
            }
4618

    
4619
        }
4620
        /**
4621
         * @return the fullName
4622
         */
4623
        public String getOriginalName() {
4624
            return originalName;
4625
        }
4626
        /**
4627
         * @param fullName the fullName to set
4628
         */
4629
        public void setOriginalName(String fullName) {
4630
            this.originalName = fullName;
4631
        }
4632
        /**
4633
         * @return the newName
4634
         */
4635
        public String getNewName() {
4636
            return newName;
4637
        }
4638
        /**
4639
         * @param newName the newName to set
4640
         */
4641
        public void setNewName(String newName) {
4642
            this.newName = newName;
4643
        }
4644
        /**
4645
         * @return the rank
4646
         */
4647
        public Rank getRank() {
4648
            return rank;
4649
        }
4650
        /**
4651
         * @param rank the rank to set
4652
         */
4653
        public void setRank(Rank rank) {
4654
            this.rank = rank;
4655
        }
4656
        /**
4657
         * @return the idenfitiger
4658
         */
4659
        public String getIdentifier() {
4660
            return identifier;
4661
        }
4662
        /**
4663
         * @param idenfitiger the idenfitiger to set
4664
         */
4665
        public void setIdentifier(String identifier) {
4666
            this.identifier = identifier;
4667
        }
4668
        /**
4669
         * @return the status
4670
         */
4671
        public String getStatus() {
4672
            if (status == null) {
4673
                return "";
4674
            }
4675
            return status;
4676
        }
4677
        /**
4678
         * @param status the status to set
4679
         */
4680
        public void setStatus(String status) {
4681
            this.status = status;
4682
        }
4683
        /**
4684
         * @return the family
4685
         */
4686
        public Taxon getFamily() {
4687
            return family;
4688
        }
4689
        /**
4690
         * @param family the family to set
4691
         */
4692
        @SuppressWarnings("rawtypes")
4693
        public void setFamily(Taxon family) {
4694
            this.family = family;
4695
            TaxonNameBase taxonNameBase = CdmBase.deproxy(family.getName(), TaxonNameBase.class);
4696
            familyName = castTaxonNameBase(taxonNameBase,familyName);
4697
        }
4698
        /**
4699
         * @return the subfamily
4700
         */
4701
        public Taxon getSubfamily() {
4702
            return subfamily;
4703
        }
4704
        /**
4705
         * @param subfamily the subfamily to set
4706
         */
4707
        @SuppressWarnings("rawtypes")
4708
        public void setSubfamily(Taxon subfamily) {
4709
            this.subfamily = subfamily;
4710
            TaxonNameBase taxonNameBase = CdmBase.deproxy(subfamily.getName(), TaxonNameBase.class);
4711
            subfamilyName = castTaxonNameBase(taxonNameBase,subfamilyName);
4712
        }
4713
        /**
4714
         * @return the tribe
4715
         */
4716
        public Taxon getTribe() {
4717
            return tribe;
4718
        }
4719
        /**
4720
         * @param tribe the tribe to set
4721
         */
4722
        @SuppressWarnings("rawtypes")
4723
        public void setTribe(Taxon tribe) {
4724
            this.tribe = tribe;
4725
            TaxonNameBase taxonNameBase = CdmBase.deproxy(tribe.getName(), TaxonNameBase.class);
4726
            tribeName = castTaxonNameBase(taxonNameBase,tribeName);
4727
        }
4728
        /**
4729
         * @return the subtribe
4730
         */
4731
        public Taxon getSubtribe() {
4732
            return subtribe;
4733
        }
4734
        /**
4735
         * @param subtribe the subtribe to set
4736
         */
4737
        @SuppressWarnings("rawtypes")
4738
        public void setSubtribe(Taxon subtribe) {
4739
            this.subtribe = subtribe;
4740
            TaxonNameBase taxonNameBase = CdmBase.deproxy(subtribe.getName(), TaxonNameBase.class);
4741
            subtribeName =castTaxonNameBase(taxonNameBase,subtribeName);
4742
        }
4743
        /**
4744
         * @return the genus
4745
         */
4746
        public Taxon getGenus() {
4747
            return genus;
4748
        }
4749
        /**
4750
         * @param genus the genus to set
4751
         */
4752
        @SuppressWarnings("rawtypes")
4753
        public void setGenus(Taxon genus) {
4754
            this.genus = genus;
4755
            TaxonNameBase taxonNameBase = CdmBase.deproxy(genus.getName(), TaxonNameBase.class);
4756
            genusName = castTaxonNameBase(taxonNameBase,genusName);
4757
            //System.out.println("GENUSNAME: "+genusName.toString());
4758
        }
4759
        /**
4760
         * @return the subgenus
4761
         */
4762
        public Taxon getSubgenus() {
4763
            return subgenus;
4764
        }
4765
        /**
4766
         * @param subgenus the subgenus to set
4767
         */
4768
        @SuppressWarnings("rawtypes")
4769
        public void setSubgenus(Taxon subgenus) {
4770
            this.subgenus = subgenus;
4771
            TaxonNameBase taxonNameBase = CdmBase.deproxy(subgenus.getName(), TaxonNameBase.class);
4772
            subgenusName = castTaxonNameBase(taxonNameBase,subgenusName);
4773
        }
4774
        /**
4775
         * @return the species
4776
         */
4777
        public Taxon getSpecies() {
4778
            return species;
4779
        }
4780
        /**
4781
         * @param species the species to set
4782
         */
4783
        public void setSpecies(Taxon species) {
4784
            this.species = species;
4785
            @SuppressWarnings("rawtypes")
4786
            TaxonNameBase taxonNameBase = CdmBase.deproxy(species.getName(), TaxonNameBase.class);
4787
            speciesName = castTaxonNameBase(taxonNameBase,speciesName);
4788

    
4789
        }
4790
        /**
4791
         * @return the subspecies
4792
         */
4793
        public Taxon getSubspecies() {
4794
            return subspecies;
4795
        }
4796
        /**
4797
         * @param subspecies the subspecies to set
4798
         */
4799
        @SuppressWarnings("rawtypes")
4800
        public void setSubspecies(Taxon subspecies) {
4801
            this.subspecies = subspecies;
4802
            TaxonNameBase taxonNameBase = CdmBase.deproxy(subspecies.getName(), TaxonNameBase.class);
4803
            subspeciesName = castTaxonNameBase(taxonNameBase,subspeciesName);
4804

    
4805
        }
4806

    
4807

    
4808

    
4809
    }
4810

    
4811

    
4812
    /**
4813
     * @param status
4814
     */
4815
    private void addProblematicStatusToFile(String status) {
4816
        try{
4817
            FileWriter fstream = new FileWriter("/home/pkelbert/Bureau/StatusUnknown_"+classification.getTitleCache()+".txt",true);
4818
            BufferedWriter out = new BufferedWriter(fstream);
4819
            out.write(status+"\n");
4820
            //Close the output stream
4821
            out.close();
4822
        }catch (Exception e){//Catch exception if any
4823
            System.err.println("Error: " + e.getMessage());
4824
        }
4825

    
4826
    }
4827

    
4828

    
4829

    
4830
    /**
4831
     * @param tnb
4832
     * @return
4833
     */
4834
    private Taxon findMatchingTaxon(NonViralName<?> tnb, Reference refMods) {
4835
        logger.info("findMatchingTaxon");
4836
        Taxon tmp=null;
4837

    
4838
        refMods=CdmBase.deproxy(refMods, Reference.class);
4839
        boolean insertAsExisting =false;
4840
        List<Taxon> existingTaxons = new ArrayList<Taxon>();
4841
        try {
4842
            existingTaxons = getMatchingTaxon(tnb);
4843
        } catch (Exception e1) {
4844
            // TODO Auto-generated catch block
4845
            e1.printStackTrace();
4846
        }
4847
        double similarityScore=0.0;
4848
        double similarityAuthor=-1;
4849
        String author1="";
4850
        String author2="";
4851
        String t1="";
4852
        String t2="";
4853
        for (Taxon bestMatchingTaxon:existingTaxons){
4854
            if (!existingTaxons.isEmpty() && configState.getConfig().isInteractWithUser() && !insertAsExisting) {
4855
                //                System.out.println("tnb "+tnb.getTitleCache());
4856
                //                System.out.println("ext "+bestMatchingTaxon.getTitleCache());
4857
                try {
4858
                    if(tnb.getAuthorshipCache()!=null) {
4859
                        author1=tnb.getAuthorshipCache();
4860
                    }
4861
                } catch (Exception e) {
4862
                    // TODO Auto-generated catch block
4863
                    e.printStackTrace();
4864
                }
4865
                try {
4866
                    if(castTaxonNameBase(bestMatchingTaxon.getName()).getAuthorshipCache()!=null) {
4867
                        author2=castTaxonNameBase(bestMatchingTaxon.getName()).getAuthorshipCache();
4868
                    }
4869
                } catch (Exception e) {
4870
                    // TODO Auto-generated catch block
4871
                    e.printStackTrace();
4872
                }
4873
                try {
4874
                    t1=tnb.getTitleCache().split("sec.")[0].trim();
4875
                    if (author1!=null && !StringUtils.isEmpty(author1)) {
4876
                        t1=t1.split(Pattern.quote(author1))[0];
4877
                    }
4878
                } catch (Exception e) {
4879
                    // TODO Auto-generated catch block
4880
                    e.printStackTrace();
4881
                }
4882
                try {
4883
                    t2=bestMatchingTaxon.getTitleCache().split("sec.")[0].trim();
4884
                    if (author2!=null && !StringUtils.isEmpty(author2)) {
4885
                        t2=t2.split(Pattern.quote(author2))[0];
4886
                    }
4887
                } catch (Exception e) {
4888
                    // TODO Auto-generated catch block
4889
                    e.printStackTrace();
4890
                }
4891
                similarityScore=similarity(t1.trim(), t2.trim());
4892
                //                System.out.println("taxascore: "+similarityScore);
4893
                similarityAuthor=similarity(author1.trim(), author2.trim());
4894
                //                System.out.println("authorscore: "+similarityAuthor);
4895
                insertAsExisting = compareAndCheckTaxon(tnb, refMods, similarityScore, bestMatchingTaxon,similarityAuthor);
4896
            }
4897
            if(insertAsExisting) {
4898
                //System.out.println("KEEP "+bestMatchingTaxon.toString());
4899
                tmp=bestMatchingTaxon;
4900
                sourceHandler.addSource(refMods, tmp);
4901
                return tmp;
4902
            }
4903
        }
4904
        return tmp;
4905
    }
4906

    
4907

    
4908
    /**
4909
     * @param tnb
4910
     * @param refMods
4911
     * @param similarityScore
4912
     * @param bestMatchingTaxon
4913
     * @param similarityAuthor
4914
     * @return
4915
     */
4916
    private boolean compareAndCheckTaxon(NonViralName<?> tnb, Reference<?> refMods, double similarityScore,
4917
            Taxon bestMatchingTaxon, double similarityAuthor) {
4918
        //logger.info("compareAndCheckTaxon");
4919
        boolean insertAsExisting;
4920
        //        if (tnb.getTitleCache().split("sec.")[0].equalsIgnoreCase("Chenopodium") && bestMatchingTaxon.getTitleCache().split("sec.")[0].indexOf("Chenopodium album")>-1) {
4921
        //            insertAsExisting=false;
4922
        //        } else{
4923
        //a small hack/automatisation for Chenopodium only
4924
        if (tnb.getTitleCache().split("sec.")[0].trim().equalsIgnoreCase("Chenopodium") &&
4925
                bestMatchingTaxon.getTitleCache().split("sec.")[0].indexOf("Chenopodium L.")>-1) {
4926
            insertAsExisting=true;
4927
        } else {
4928
            insertAsExisting=askIfReuseBestMatchingTaxon(tnb, bestMatchingTaxon, refMods, similarityScore,similarityAuthor);
4929
        }
4930
        //        }
4931

    
4932
        logDecision(tnb,bestMatchingTaxon,insertAsExisting, refMods);
4933
        return insertAsExisting;
4934
    }
4935

    
4936
    /**
4937
     * @return
4938
     */
4939
    @SuppressWarnings("rawtypes")
4940
    private List<Taxon> getMatchingTaxon(TaxonNameBase tnb) {
4941
        //logger.info("getMatchingTaxon");
4942
        Pager<TaxonBase> pager=importer.getTaxonService().findByTitle(TaxonBase.class, tnb.getTitleCache().split("sec.")[0].trim(), MatchMode.BEGINNING, null, null, null, null, null);
4943
        List<TaxonBase>records = pager.getRecords();
4944

    
4945
        List<Taxon> existingTaxons = new ArrayList<Taxon>();
4946
        for (TaxonBase r:records){
4947
            try{
4948
                Taxon bestMatchingTaxon = (Taxon)r;
4949
                //                System.out.println("best: "+bestMatchingTaxon.getTitleCache());
4950
                if(compareTaxonNameLength(bestMatchingTaxon.getTitleCache().split(".sec")[0],tnb.getTitleCache().split(".sec")[0])) {
4951
                    existingTaxons.add(bestMatchingTaxon);
4952
                }
4953
            }catch(ClassCastException e){logger.warn("classcast exception, might be a synonym, ignore it");}
4954
        }
4955
        Taxon bmt = importer.getTaxonService().findBestMatchingTaxon(tnb.getTitleCache());
4956
        if (!existingTaxons.contains(bmt) && bmt!=null) {
4957
            if(compareTaxonNameLength(bmt.getTitleCache().split(".sec")[0],tnb.getTitleCache().split(".sec")[0])) {
4958
                existingTaxons.add(bmt);
4959
            }
4960
        }
4961
        return existingTaxons;
4962
    }
4963

    
4964
    /**
4965
     * Check if the found Taxon can reasonnably be the same
4966
     * example: with and without author should match, but the subspecies should not be suggested for a genus
4967
     * */
4968
    private boolean compareTaxonNameLength(String f, String o){
4969
        //logger.info("compareTaxonNameLength");
4970
        boolean lengthOk=false;
4971
        int sizeF = f.length();
4972
        int sizeO = o.length();
4973
        if (sizeO>=sizeF) {
4974
            lengthOk=true;
4975
        }
4976
        if(sizeF>sizeO) {
4977
            if (sizeF-sizeO>10) {
4978
                lengthOk=false;
4979
            } else {
4980
                lengthOk=true;
4981
            }
4982
        }
4983

    
4984
        //        System.out.println(lengthOk+": compare "+f+" ("+f.length()+") and "+o+" ("+o.length()+")");
4985
        return lengthOk;
4986
    }
4987

    
4988
    private double similarity(String s1, String s2) {
4989
        //logger.info("similarity");
4990
        //System.out.println("similarity *"+s1+"* vs. *"+s2+"*");
4991
        if(!StringUtils.isEmpty(s1) && !StringUtils.isEmpty(s2)){
4992
            String l1=s1.toLowerCase().trim();
4993
            String l2=s2.toLowerCase().trim();
4994
            if (l1.length() < l2.length()) { // s1 should always be bigger
4995
                String swap = l1; l1 = l2; l2 = swap;
4996
            }
4997
            int bigLen = l1.length();
4998
            if (bigLen == 0) { return 1.0; /* both strings are zero length */ }
4999
            return (bigLen - computeEditDistance(l1, l2)) / (double) bigLen;
5000
        }
5001
        else{
5002
            if(s1!=null && s2!=null){
5003
                if (s1.equalsIgnoreCase(s2)) {
5004
                    return 1;
5005
                }
5006
            }
5007
            return -1;
5008
        }
5009
    }
5010

    
5011
    private int computeEditDistance(String s1, String s2) {
5012
        //logger.info("computeEditDistance");
5013
        int[] costs = new int[s2.length() + 1];
5014
        for (int i = 0; i <= s1.length(); i++) {
5015
            int lastValue = i;
5016
            for (int j = 0; j <= s2.length(); j++) {
5017
                if (i == 0) {
5018
                    costs[j] = j;
5019
                } else {
5020
                    if (j > 0) {
5021
                        int newValue = costs[j - 1];
5022
                        if (s1.charAt(i - 1) != s2.charAt(j - 1)) {
5023
                            newValue = Math.min(Math.min(newValue, lastValue),
5024
                                    costs[j]) + 1;
5025
                        }
5026
                        costs[j - 1] = lastValue;
5027
                        lastValue = newValue;
5028
                    }
5029
                }
5030
            }
5031
            if (i > 0) {
5032
                costs[s2.length()] = lastValue;
5033
            }
5034
        }
5035
        return costs[s2.length()];
5036
    }
5037

    
5038
    Map<Rank, Taxon> hierarchy = new HashMap<Rank, Taxon>();
5039
    /**
5040
     * @param taxonnamebase
5041
     */
5042
    @SuppressWarnings("rawtypes")
5043
    public void lookForParentNode(NonViralName<?> taxonnamebase, Taxon tax, Reference<?> ref, MyName myName) {
5044
        logger.info("lookForParentNode "+taxonnamebase.getTitleCache()+" for "+myName.toString());
5045
        //System.out.println("LOOK FOR PARENT NODE "+taxonnamebase.toString()+"; "+tax.toString()+"; "+taxonnamebase.getRank());
5046
        INonViralNameParser parser = NonViralNameParserImpl.NewInstance();
5047
        if (taxonnamebase.getRank().equals(Rank.FORM())){
5048
            handleFormHierarchy(ref, myName, parser);
5049
        }
5050
        if (taxonnamebase.getRank().equals(Rank.VARIETY())){
5051
            handleVarietyHierarchy(ref, myName, parser);
5052
        }
5053
        if (taxonnamebase.getRank().equals(Rank.SUBSPECIES())){
5054
            handleSubSpeciesHierarchy(ref, myName, parser);
5055
        }
5056
        if (taxonnamebase.getRank().equals(Rank.SPECIES())){
5057
            handleSpeciesHierarchy(ref, myName, parser);
5058
        }
5059
        if (taxonnamebase.getRank().equals(Rank.SUBGENUS())){
5060
            handleSubgenusHierarchy(ref, myName, parser);
5061
        }
5062

    
5063
        if (taxonnamebase.getRank().equals(Rank.GENUS())){
5064
            handleGenusHierarchy(ref, myName, parser);
5065
        }
5066
        if (taxonnamebase.getRank().equals(Rank.SUBTRIBE())){
5067
            handleSubtribeHierarchy(ref, myName, parser);
5068
        }
5069
        if (taxonnamebase.getRank().equals(Rank.TRIBE())){
5070
            handleTribeHierarchy(ref, myName, parser);
5071
        }
5072

    
5073
        if (taxonnamebase.getRank().equals(Rank.SUBFAMILY())){
5074
            handleSubfamilyHierarchy(ref, myName, parser);
5075
        }
5076
    }
5077

    
5078
    /**
5079
     * @param ref
5080
     * @param myName
5081
     * @param parser
5082
     */
5083
    private void handleSubfamilyHierarchy(Reference<?> ref, MyName myName, INonViralNameParser<?> parser) {
5084
        System.out.println("handleSubfamilyHierarchy");
5085
        String parentStr = myName.getFamilyStr();
5086
        Rank r = Rank.FAMILY();
5087
        if(parentStr!=null){
5088

    
5089
            Taxon parent = null;
5090
            Pager<TaxonBase> taxontest = importer.getTaxonService().findByTitle(TaxonBase.class, parentStr, MatchMode.BEGINNING, null, null, null, null, null);
5091
            for(TaxonBase tb:taxontest.getRecords()){
5092
                try {
5093
                    if (tb.getName().getRank().equals(r)) {
5094
                        parent=CdmBase.deproxy(tb, Taxon.class);
5095
                    }
5096
                    break;
5097
                } catch (Exception e) {
5098
                    // TODO Auto-generated catch block
5099
                    e.printStackTrace();
5100
                }
5101
            }
5102
            if(parent == null) {
5103
                NonViralName<?> parentNameName =  (NonViralName<?>) parser.parseFullName(parentStr, nomenclaturalCode, r);
5104
                Taxon tmp = findMatchingTaxon(parentNameName,ref);
5105
                if(tmp ==null)
5106
                {
5107
                    parent=Taxon.NewInstance(parentNameName, ref);
5108
                    importer.getTaxonService().save(parent);
5109
                    parent = CdmBase.deproxy(parent, Taxon.class);
5110
                } else {
5111
                    parent=tmp;
5112
                }
5113
                lookForParentNode(parentNameName, parent, ref,myName);
5114

    
5115
            }
5116
            hierarchy.put(r,parent);
5117
        }
5118
    }
5119

    
5120
    /**
5121
     * @param ref
5122
     * @param myName
5123
     * @param parser
5124
     */
5125
    private void handleTribeHierarchy(Reference<?> ref, MyName myName, INonViralNameParser<?> parser) {
5126
        String parentStr = myName.getSubfamilyStr();
5127
        Rank r = Rank.SUBFAMILY();
5128
        if (parentStr == null){
5129
            parentStr = myName.getFamilyStr();
5130
            r = Rank.FAMILY();
5131
        }
5132
        if(parentStr!=null){
5133
            NonViralName<?> parentNameName =  (NonViralName<?>) parser.parseFullName(parentStr, nomenclaturalCode, r);
5134
            Taxon parent = Taxon.NewInstance(parentNameName, ref); //sec set null
5135
            //                    importer.getTaxonService().save(parent);
5136
            //                    parent = CdmBase.deproxy(parent, Taxon.class);
5137

    
5138
            boolean parentDoesNotExists = true;
5139
            for (TaxonNode p : classification.getAllNodes()){
5140
                if(p.getTaxon().getTitleCache().equalsIgnoreCase(parent.getTitleCache())) {
5141
                    parentDoesNotExists = false;
5142
                    parent=CdmBase.deproxy(p.getTaxon(),    Taxon.class);
5143
                    break;
5144
                }
5145
            }
5146
            //                if(parentDoesNotExists) {
5147
            //                    importer.getTaxonService().save(parent);
5148
            //                    parent = CdmBase.deproxy(parent, Taxon.class);
5149
            //                    lookForParentNode(parentNameName, parent, ref,myName);
5150
            //                }
5151
            if(parentDoesNotExists) {
5152
                Taxon tmp = findMatchingTaxon(parentNameName,ref);
5153
                if(tmp ==null)
5154
                {
5155
                    parent=Taxon.NewInstance(parentNameName, ref);
5156
                    importer.getTaxonService().save(parent);
5157
                    parent = CdmBase.deproxy(parent, Taxon.class);
5158
                } else {
5159
                    parent=tmp;
5160
                }
5161
                lookForParentNode(parentNameName, parent, ref,myName);
5162

    
5163
            }
5164
            hierarchy.put(r,parent);
5165
        }
5166
    }
5167

    
5168
    /**
5169
     * @param ref
5170
     * @param myName
5171
     * @param parser
5172
     */
5173
    private void handleSubtribeHierarchy(Reference<?> ref, MyName myName, INonViralNameParser<?> parser) {
5174
        String parentStr = myName.getTribeStr();
5175
        Rank r = Rank.TRIBE();
5176
        if (parentStr == null){
5177
            parentStr = myName.getSubfamilyStr();
5178
            r = Rank.SUBFAMILY();
5179
        }
5180
        if (parentStr == null){
5181
            parentStr = myName.getFamilyStr();
5182
            r = Rank.FAMILY();
5183
        }
5184
        if(parentStr!=null){
5185
            NonViralName<?> parentNameName =  (NonViralName<?>) parser.parseFullName(parentStr, nomenclaturalCode, r);
5186
            Taxon parent = Taxon.NewInstance(parentNameName, ref); //sec set null
5187
            //                    importer.getTaxonService().save(parent);
5188
            //                    parent = CdmBase.deproxy(parent, Taxon.class);
5189

    
5190
            boolean parentDoesNotExists = true;
5191
            for (TaxonNode p : classification.getAllNodes()){
5192
                if(p.getTaxon().getTitleCache().equalsIgnoreCase(parent.getTitleCache())) {
5193
                    parentDoesNotExists = false;
5194
                    parent=CdmBase.deproxy(p.getTaxon(),    Taxon.class);
5195

    
5196
                    break;
5197
                }
5198
            }
5199
            //                if(parentDoesNotExists) {
5200
            //                    importer.getTaxonService().save(parent);
5201
            //                    parent = CdmBase.deproxy(parent, Taxon.class);
5202
            //                    lookForParentNode(parentNameName, parent, ref,myName);
5203
            //                }
5204
            if(parentDoesNotExists) {
5205
                Taxon tmp = findMatchingTaxon(parentNameName,ref);
5206
                if(tmp ==null)
5207
                {
5208
                    parent=Taxon.NewInstance(parentNameName, ref);
5209
                    importer.getTaxonService().save(parent);
5210
                    parent = CdmBase.deproxy(parent, Taxon.class);
5211
                } else {
5212
                    parent=tmp;
5213
                }
5214
                lookForParentNode(parentNameName, parent, ref,myName);
5215

    
5216
            }
5217
            hierarchy.put(r,parent);
5218
        }
5219
    }
5220

    
5221
    /**
5222
     * @param ref
5223
     * @param myName
5224
     * @param parser
5225
     */
5226
    private void handleGenusHierarchy(Reference<?> ref, MyName myName, INonViralNameParser<?> parser) {
5227
        String parentStr = myName.getSubtribeStr();
5228
        Rank r = Rank.SUBTRIBE();
5229
        if (parentStr == null){
5230
            parentStr = myName.getTribeStr();
5231
            r = Rank.TRIBE();
5232
        }
5233
        if (parentStr == null){
5234
            parentStr = myName.getSubfamilyStr();
5235
            r = Rank.SUBFAMILY();
5236
        }
5237
        if (parentStr == null){
5238
            parentStr = myName.getFamilyStr();
5239
            r = Rank.FAMILY();
5240
        }
5241
        if(parentStr!=null){
5242
            NonViralName<?> parentNameName =  (NonViralName<?>) parser.parseFullName(parentStr, nomenclaturalCode, r);
5243
            Taxon parent = Taxon.NewInstance(parentNameName, ref); //sec set null
5244
            //                    importer.getTaxonService().save(parent);
5245
            //                    parent = CdmBase.deproxy(parent, Taxon.class);
5246

    
5247
            boolean parentDoesNotExists = true;
5248
            for (TaxonNode p : classification.getAllNodes()){
5249
                if(p.getTaxon().getTitleCache().equalsIgnoreCase(parent.getTitleCache())) {
5250
                    //                        System.out.println(p.getTaxon().getUuid());
5251
                    //                        System.out.println(parent.getUuid());
5252
                    parentDoesNotExists = false;
5253
                    parent=CdmBase.deproxy(p.getTaxon(),    Taxon.class);
5254
                    break;
5255
                }
5256
            }
5257
            //                if(parentDoesNotExists) {
5258
            //                    importer.getTaxonService().save(parent);
5259
            //                    parent = CdmBase.deproxy(parent, Taxon.class);
5260
            //                    lookForParentNode(parentNameName, parent, ref,myName);
5261
            //                }
5262
            if(parentDoesNotExists) {
5263
                Taxon tmp = findMatchingTaxon(parentNameName,ref);
5264
                if(tmp ==null)
5265
                {
5266
                    parent=Taxon.NewInstance(parentNameName, ref);
5267
                    importer.getTaxonService().save(parent);
5268
                    parent = CdmBase.deproxy(parent, Taxon.class);
5269
                } else {
5270
                    parent=tmp;
5271
                }
5272
                lookForParentNode(parentNameName, parent, ref,myName);
5273

    
5274
            }
5275
            hierarchy.put(r,parent);
5276
        }
5277
    }
5278

    
5279
    /**
5280
     * @param ref
5281
     * @param myName
5282
     * @param parser
5283
     */
5284
    private void handleSubgenusHierarchy(Reference<?> ref, MyName myName, INonViralNameParser<?> parser) {
5285
        String parentStr = myName.getGenusStr();
5286
        Rank r = Rank.GENUS();
5287

    
5288
        if(parentStr==null){
5289
            parentStr = myName.getSubtribeStr();
5290
            r = Rank.SUBTRIBE();
5291
        }
5292
        if (parentStr == null){
5293
            parentStr = myName.getTribeStr();
5294
            r = Rank.TRIBE();
5295
        }
5296
        if (parentStr == null){
5297
            parentStr = myName.getSubfamilyStr();
5298
            r = Rank.SUBFAMILY();
5299
        }
5300
        if (parentStr == null){
5301
            parentStr = myName.getFamilyStr();
5302
            r = Rank.FAMILY();
5303
        }
5304
        if(parentStr!=null){
5305
            NonViralName<?> parentNameName =  (NonViralName<?>) parser.parseFullName(parentStr, nomenclaturalCode, r);
5306
            Taxon parent = Taxon.NewInstance(parentNameName, ref); //sec set null
5307
            //                    importer.getTaxonService().save(parent);
5308
            //                    parent = CdmBase.deproxy(parent, Taxon.class);
5309

    
5310
            boolean parentDoesNotExists = true;
5311
            for (TaxonNode p : classification.getAllNodes()){
5312
                if(p.getTaxon().getTitleCache().equalsIgnoreCase(parent.getTitleCache())) {
5313
                    //                        System.out.println(p.getTaxon().getUuid());
5314
                    //                        System.out.println(parent.getUuid());
5315
                    parentDoesNotExists = false;
5316
                    parent=CdmBase.deproxy(p.getTaxon(),    Taxon.class);
5317
                    break;
5318
                }
5319
            }
5320
            //                if(parentDoesNotExists) {
5321
            //                    importer.getTaxonService().save(parent);
5322
            //                    parent = CdmBase.deproxy(parent, Taxon.class);
5323
            //                    lookForParentNode(parentNameName, parent, ref,myName);
5324
            //                }
5325
            if(parentDoesNotExists) {
5326
                Taxon tmp = findMatchingTaxon(parentNameName,ref);
5327
                if(tmp ==null)
5328
                {
5329
                    parent=Taxon.NewInstance(parentNameName, ref);
5330
                    importer.getTaxonService().save(parent);
5331
                    parent = CdmBase.deproxy(parent, Taxon.class);
5332
                } else {
5333
                    parent=tmp;
5334
                }
5335
                lookForParentNode(parentNameName, parent, ref,myName);
5336

    
5337
            }
5338
            hierarchy.put(r,parent);
5339
        }
5340
    }
5341

    
5342
    /**
5343
     * @param ref
5344
     * @param myName
5345
     * @param parser
5346
     */
5347
    private void handleSpeciesHierarchy(Reference<?> ref, MyName myName, INonViralNameParser<?> parser) {
5348
        String parentStr = myName.getSubgenusStr();
5349
        Rank r = Rank.SUBGENUS();
5350

    
5351
        if(parentStr==null){
5352
            parentStr = myName.getGenusStr();
5353
            r = Rank.GENUS();
5354
        }
5355

    
5356
        if(parentStr==null){
5357
            parentStr = myName.getSubtribeStr();
5358
            r = Rank.SUBTRIBE();
5359
        }
5360
        if (parentStr == null){
5361
            parentStr = myName.getTribeStr();
5362
            r = Rank.TRIBE();
5363
        }
5364
        if (parentStr == null){
5365
            parentStr = myName.getSubfamilyStr();
5366
            r = Rank.SUBFAMILY();
5367
        }
5368
        if (parentStr == null){
5369
            parentStr = myName.getFamilyStr();
5370
            r = Rank.FAMILY();
5371
        }
5372
        if(parentStr!=null){
5373
            Taxon parent = handleParentName(ref, myName, parser, parentStr, r);
5374
            //System.out.println("PUT IN HIERARCHY "+r+", "+parent);
5375
            hierarchy.put(r,parent);
5376
        }
5377
    }
5378

    
5379
    /**
5380
     * @param ref
5381
     * @param myName
5382
     * @param parser
5383
     */
5384
    private void handleSubSpeciesHierarchy(Reference<?> ref, MyName myName, INonViralNameParser<?> parser) {
5385
        String parentStr = myName.getSpeciesStr();
5386
        Rank r = Rank.SPECIES();
5387

    
5388

    
5389
        if(parentStr==null){
5390
            parentStr = myName.getSubgenusStr();
5391
            r = Rank.SUBGENUS();
5392
        }
5393

    
5394
        if(parentStr==null){
5395
            parentStr = myName.getGenusStr();
5396
            r = Rank.GENUS();
5397
        }
5398

    
5399
        if(parentStr==null){
5400
            parentStr = myName.getSubtribeStr();
5401
            r = Rank.SUBTRIBE();
5402
        }
5403
        if (parentStr == null){
5404
            parentStr = myName.getTribeStr();
5405
            r = Rank.TRIBE();
5406
        }
5407
        if (parentStr == null){
5408
            parentStr = myName.getSubfamilyStr();
5409
            r = Rank.SUBFAMILY();
5410
        }
5411
        if (parentStr == null){
5412
            parentStr = myName.getFamilyStr();
5413
            r = Rank.FAMILY();
5414
        }
5415
        if(parentStr!=null){
5416
            Taxon parent = handleParentName(ref, myName, parser, parentStr, r);
5417
            //System.out.println("PUT IN HIERARCHY "+r+", "+parent);
5418
            hierarchy.put(r,parent);
5419
        }
5420
    }
5421

    
5422

    
5423
    /**
5424
     * @param ref
5425
     * @param myName
5426
     * @param parser
5427
     */
5428
    private void handleFormHierarchy(Reference<?> ref, MyName myName, INonViralNameParser<?> parser) {
5429
        String parentStr = myName.getSubspeciesStr();
5430
        Rank r = Rank.SUBSPECIES();
5431

    
5432

    
5433
        if(parentStr==null){
5434
            parentStr = myName.getSpeciesStr();
5435
            r = Rank.SPECIES();
5436
        }
5437

    
5438
        if(parentStr==null){
5439
            parentStr = myName.getSubgenusStr();
5440
            r = Rank.SUBGENUS();
5441
        }
5442

    
5443
        if(parentStr==null){
5444
            parentStr = myName.getGenusStr();
5445
            r = Rank.GENUS();
5446
        }
5447

    
5448
        if(parentStr==null){
5449
            parentStr = myName.getSubtribeStr();
5450
            r = Rank.SUBTRIBE();
5451
        }
5452
        if (parentStr == null){
5453
            parentStr = myName.getTribeStr();
5454
            r = Rank.TRIBE();
5455
        }
5456
        if (parentStr == null){
5457
            parentStr = myName.getSubfamilyStr();
5458
            r = Rank.SUBFAMILY();
5459
        }
5460
        if (parentStr == null){
5461
            parentStr = myName.getFamilyStr();
5462
            r = Rank.FAMILY();
5463
        }
5464
        if(parentStr!=null){
5465
            Taxon parent = handleParentName(ref, myName, parser, parentStr, r);
5466
            //System.out.println("PUT IN HIERARCHY "+r+", "+parent);
5467
            hierarchy.put(r,parent);
5468
        }
5469
    }
5470

    
5471
    /**
5472
     * @param ref
5473
     * @param myName
5474
     * @param parser
5475
     */
5476
    private void handleVarietyHierarchy(Reference<?> ref, MyName myName, INonViralNameParser<?> parser) {
5477
        String parentStr = myName.getSubspeciesStr();
5478
        Rank r = Rank.SUBSPECIES();
5479

    
5480
        if(parentStr==null){
5481
            parentStr = myName.getSpeciesStr();
5482
            r = Rank.SPECIES();
5483
        }
5484

    
5485
        if(parentStr==null){
5486
            parentStr = myName.getSubgenusStr();
5487
            r = Rank.SUBGENUS();
5488
        }
5489

    
5490
        if(parentStr==null){
5491
            parentStr = myName.getGenusStr();
5492
            r = Rank.GENUS();
5493
        }
5494

    
5495
        if(parentStr==null){
5496
            parentStr = myName.getSubtribeStr();
5497
            r = Rank.SUBTRIBE();
5498
        }
5499
        if (parentStr == null){
5500
            parentStr = myName.getTribeStr();
5501
            r = Rank.TRIBE();
5502
        }
5503
        if (parentStr == null){
5504
            parentStr = myName.getSubfamilyStr();
5505
            r = Rank.SUBFAMILY();
5506
        }
5507
        if (parentStr == null){
5508
            parentStr = myName.getFamilyStr();
5509
            r = Rank.FAMILY();
5510
        }
5511
        if(parentStr!=null){
5512
            Taxon parent = handleParentName(ref, myName, parser, parentStr, r);
5513
            //System.out.println("PUT IN HIERARCHY "+r+", "+parent);
5514
            hierarchy.put(r,parent);
5515
        }
5516
    }
5517

    
5518
    /**
5519
     * @param ref
5520
     * @param myName
5521
     * @param parser
5522
     * @param parentStr
5523
     * @param r
5524
     * @return
5525
     */
5526
    private Taxon handleParentName(Reference<?> ref, MyName myName, INonViralNameParser<?> parser, String parentStr, Rank r) {
5527
        NonViralName<?> parentNameName =  (NonViralName<?>) parser.parseFullName(parentStr, nomenclaturalCode, r);
5528
        Taxon parent = Taxon.NewInstance(parentNameName, ref); //sec set null
5529
        //                    importer.getTaxonService().save(parent);
5530
        //                    parent = CdmBase.deproxy(parent, Taxon.class);
5531

    
5532
        boolean parentDoesNotExists = true;
5533
        for (TaxonNode p : classification.getAllNodes()){
5534
            if(p.getTaxon().getTitleCache().split("sec.")[0].trim().equalsIgnoreCase(parent.getTitleCache().split("sec.")[0].trim())) {
5535
                //                        System.out.println(p.getTaxon().getUuid());
5536
                //                        System.out.println(parent.getUuid());
5537
                parentDoesNotExists = false;
5538
                parent=CdmBase.deproxy(p.getTaxon(),    Taxon.class);
5539
                break;
5540
            }
5541
        }
5542
        if(parentDoesNotExists) {
5543
            Taxon tmp = findMatchingTaxon(parentNameName,ref);
5544
            //                    System.out.println("FOUND PARENT "+tmp.toString()+" for "+parentNameName.toString());
5545
            if(tmp ==null)
5546
            {
5547
                parent=Taxon.NewInstance(parentNameName, ref);
5548
                importer.getTaxonService().save(parent);
5549
                parent = CdmBase.deproxy(parent, Taxon.class);
5550
            } else {
5551
                parent=tmp;
5552
            }
5553
            lookForParentNode(parentNameName, parent, ref,myName);
5554

    
5555
        }
5556
        return parent;
5557
    }
5558

    
5559
    private void addNameDifferenceToFile(String originalname, String atomisedname){
5560
        try{
5561
            FileWriter fstream = new FileWriter("/home/pkelbert/Bureau/NamesDifferent_"+classification.getTitleCache()+".txt",true);
5562
            BufferedWriter out = new BufferedWriter(fstream);
5563
            out.write(originalname+" (original) versus "+replaceNull(atomisedname)+" (atomised) \n");
5564
            //Close the output stream
5565
            out.close();
5566
        }catch (Exception e){//Catch exception if any
5567
            System.err.println("Error: " + e.getMessage());
5568
        }
5569
    }
5570
    /**
5571
     * @param name
5572
     * @param author
5573
     * @param nomenclaturalCode2
5574
     * @param rank
5575
     */
5576
    private void addProblemNameToFile(String name, String author, NomenclaturalCode nomenclaturalCode2, Rank rank) {
5577
        try{
5578
            FileWriter fstream = new FileWriter("/home/pkelbert/Bureau/NameNotParsed.txt",true);
5579
            BufferedWriter out = new BufferedWriter(fstream);
5580
            out.write(name+"\t"+replaceNull(author)+"\t"+replaceNull(nomenclaturalCode2)+"\t"+replaceNull(rank)+"\n");
5581
            //Close the output stream
5582
            out.close();
5583
        }catch (Exception e){//Catch exception if any
5584
            System.err.println("Error: " + e.getMessage());
5585
        }
5586
    }
5587

    
5588

    
5589
    /**
5590
     * @param tnb
5591
     * @param bestMatchingTaxon
5592
     * @param insertAsExisting
5593
     * @param refMods
5594
     */
5595
    private void logDecision(NonViralName<?> tnb, Taxon bestMatchingTaxon, boolean insertAsExisting, Reference refMods) {
5596
        try{
5597
            FileWriter fstream = new FileWriter("/home/pkelbert/Bureau/Decisions_"+classification.toString()+".txt",true);
5598
            BufferedWriter out = new BufferedWriter(fstream);
5599
            out.write(tnb.getTitleCache()+" sec. "+refMods+"\t"+bestMatchingTaxon.getTitleCache()+"\t"+insertAsExisting+"\n");
5600
            //Close the output stream
5601
            out.close();
5602
        }catch (Exception e){//Catch exception if any
5603
            System.err.println("Error: " + e.getMessage());
5604
        }
5605
    }
5606

    
5607

    
5608
    @SuppressWarnings("unused")
5609
    private String replaceNull(Object in){
5610
        if (in == null) {
5611
            return "";
5612
        }
5613
        if (in.getClass().equals(NomenclaturalCode.class)) {
5614
            return ((NomenclaturalCode)in).getTitleCache();
5615
        }
5616
        return in.toString();
5617
    }
5618

    
5619
    /**
5620
     * @param fullName
5621
     * @param nomenclaturalCode2
5622
     * @param rank
5623
     */
5624
    private void addProblemNameToFile(String type, String name, NomenclaturalCode nomenclaturalCode2, Rank rank, String problems) {
5625
        try{
5626
            FileWriter fstream = new FileWriter("/home/pkelbert/Bureau/NameNotParsed_"+classification.getTitleCache()+".txt",true);
5627
            BufferedWriter out = new BufferedWriter(fstream);
5628
            out.write(type+"\t"+name+"\t"+replaceNull(nomenclaturalCode2)+"\t"+replaceNull(rank)+"\t"+problems+"\n");
5629
            //Close the output stream
5630
            out.close();
5631
        }catch (Exception e){//Catch exception if any
5632
            System.err.println("Error: " + e.getMessage());
5633
        }
5634

    
5635
    }
5636

    
5637
}
5638

    
5639

    
5640

    
(8-8/9)