f22f398072d62bbfdbb4f4e8d200eb61a9803ec8
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / sdd / in / SDDImport.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.cdm.io.sdd.in;
11
12 import java.io.File;
13 import java.net.MalformedURLException;
14 import java.net.URI;
15 import java.net.URL;
16 import java.text.SimpleDateFormat;
17 import java.util.ArrayList;
18 import java.util.Date;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24
25 import org.apache.commons.lang.StringUtils;
26 import org.apache.log4j.Logger;
27 import org.jdom.Element;
28 import org.jdom.Namespace;
29 import org.joda.time.DateTime;
30 import org.springframework.stereotype.Component;
31 import org.springframework.transaction.TransactionStatus;
32
33 import eu.etaxonomy.cdm.api.service.IDescriptionService;
34 import eu.etaxonomy.cdm.common.IProgressMonitor;
35 import eu.etaxonomy.cdm.common.mediaMetaData.ImageMetaData;
36 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
37 import eu.etaxonomy.cdm.io.common.CdmImportBase;
38 import eu.etaxonomy.cdm.io.common.ICdmImport;
39 import eu.etaxonomy.cdm.io.common.IImportConfigurator;
40 import eu.etaxonomy.cdm.io.common.ImportHelper;
41 import eu.etaxonomy.cdm.io.sdd.SDDTransformer;
42 import eu.etaxonomy.cdm.model.agent.Person;
43 import eu.etaxonomy.cdm.model.agent.Team;
44 import eu.etaxonomy.cdm.model.common.Annotation;
45 import eu.etaxonomy.cdm.model.common.AnnotationType;
46 import eu.etaxonomy.cdm.model.common.CdmBase;
47 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
48 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
49 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
50 import eu.etaxonomy.cdm.model.common.Language;
51 import eu.etaxonomy.cdm.model.common.LanguageString;
52 import eu.etaxonomy.cdm.model.common.Marker;
53 import eu.etaxonomy.cdm.model.common.MarkerType;
54 import eu.etaxonomy.cdm.model.common.Representation;
55 import eu.etaxonomy.cdm.model.common.TermBase;
56 import eu.etaxonomy.cdm.model.common.TermVocabulary;
57 import eu.etaxonomy.cdm.model.common.VersionableEntity;
58 import eu.etaxonomy.cdm.model.description.CategoricalData;
59 import eu.etaxonomy.cdm.model.description.Feature;
60 import eu.etaxonomy.cdm.model.description.FeatureNode;
61 import eu.etaxonomy.cdm.model.description.FeatureTree;
62 import eu.etaxonomy.cdm.model.description.MeasurementUnit;
63 import eu.etaxonomy.cdm.model.description.Modifier;
64 import eu.etaxonomy.cdm.model.description.QuantitativeData;
65 import eu.etaxonomy.cdm.model.description.State;
66 import eu.etaxonomy.cdm.model.description.StateData;
67 import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
68 import eu.etaxonomy.cdm.model.description.StatisticalMeasurementValue;
69 import eu.etaxonomy.cdm.model.description.TaxonDescription;
70 import eu.etaxonomy.cdm.model.description.TextData;
71 import eu.etaxonomy.cdm.model.description.WorkingSet;
72 import eu.etaxonomy.cdm.model.location.NamedArea;
73 import eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity;
74 import eu.etaxonomy.cdm.model.media.ImageFile;
75 import eu.etaxonomy.cdm.model.media.Media;
76 import eu.etaxonomy.cdm.model.media.MediaRepresentation;
77 import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
78 import eu.etaxonomy.cdm.model.media.Rights;
79 import eu.etaxonomy.cdm.model.name.NonViralName;
80 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
81 import eu.etaxonomy.cdm.model.occurrence.Specimen;
82 import eu.etaxonomy.cdm.model.reference.Reference;
83 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
84 import eu.etaxonomy.cdm.model.taxon.Classification;
85 import eu.etaxonomy.cdm.model.taxon.Synonym;
86 import eu.etaxonomy.cdm.model.taxon.Taxon;
87 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
88
89 /**
90 * @author h.fradin
91 * @created 24.10.2008
92 * @version 1.0
93 */
94 @Component("sddImport")
95 public class SDDImport extends CdmImportBase<SDDImportConfigurator, SDDImportState> implements ICdmImport<SDDImportConfigurator, SDDImportState> {
96 private static final Logger logger = Logger.getLogger(SDDImport.class);
97
98 private static int modCount = 1000;
99
100 private Map<String,Person> authors = new HashMap<String,Person>();
101 private Map<String,String> citations = new HashMap<String,String>();
102 private Map<String,String> defaultUnitPrefixes = new HashMap<String,String>();
103 private Map<String,Person> editors = new HashMap<String,Person>();
104 private Map<String,FeatureNode> featureNodes = new HashMap<String,FeatureNode>();
105 private Map<String,Feature> features = new HashMap<String,Feature>();
106 private Map<String,String> locations = new HashMap<String,String>();
107 private Map<String,List<CdmBase>> mediaObject_ListCdmBase = new HashMap<String,List<CdmBase>>();
108 private Map<String,String> mediaObject_Role = new HashMap<String,String>();
109 private Map<String,Reference> publications = new HashMap<String,Reference>();
110 private Map<String,State> states = new HashMap<String,State>();
111 private Map<String,TaxonDescription> taxonDescriptions = new HashMap<String,TaxonDescription>();
112 private Map<String,NonViralName> taxonNameBases = new HashMap<String,NonViralName>();
113 private Map<String,MeasurementUnit> units = new HashMap<String,MeasurementUnit>();
114 private Map<String,TaxonNode> taxonNodes = new HashMap<String,TaxonNode>();
115 private Map<String,NamedArea> namedAreas = new HashMap<String,NamedArea>();
116 private Map<String,Specimen> specimens = new HashMap<String,Specimen>();
117 private Map<String,Modifier> modifiers = new HashMap<String,Modifier>();
118
119 private Set<MarkerType> markerTypes = new HashSet<MarkerType>();
120 private Set<TermVocabulary> vocabularies = new HashSet<TermVocabulary>();
121
122 private Set<Feature> descriptiveConcepts = new HashSet<Feature>();
123 private Set<AnnotationType> annotationTypes = new HashSet<AnnotationType>();
124 // private Set<Feature> featureSet = new HashSet<Feature>();
125 private Set<Reference> sources = new HashSet<Reference>();
126 private Reference sec = ReferenceFactory.newDatabase();
127 private Reference sourceReference = null;
128
129 private Language datasetLanguage = null;
130 private WorkingSet workingSet = null;
131
132 private Namespace xmlNamespace = Namespace.getNamespace("xml","http://www.w3.org/XML/1998/namespace");
133
134 private String generatorName = "";
135 private String generatorVersion = "";
136
137
138 private Set<StatisticalMeasure> statisticalMeasures = new HashSet<StatisticalMeasure>();
139 private Set<VersionableEntity> featureData = new HashSet<VersionableEntity>();
140 private Set<FeatureTree> featureTrees = new HashSet<FeatureTree>();
141 private Set<Classification> classifications = new HashSet<Classification>();
142
143 private Rights copyright = null;
144
145 private int taxonNamesCount = 0;
146
147 public SDDImport(){
148 super();
149 }
150
151 @Override
152 public boolean doCheck(SDDImportState state){
153 boolean result = true;
154 logger.warn("No check implemented for SDD");
155 return result;
156 }
157
158 // @Override
159 // public boolean doInvoke(IImportConfigurator config, Map<String, MapWrapper<? extends CdmBase>> stores){
160 @Override
161 public boolean doInvoke(SDDImportState state){
162 boolean success = true;
163
164 TransactionStatus ts = startTransaction();
165 SDDImportConfigurator sddConfig = state.getConfig();
166 IProgressMonitor progressMonitor = sddConfig.getProgressMonitor();
167
168 logger.info("start Datasets ...");
169
170 // <Datasets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://rs.tdwg.org/UBIF/2006/" xsi:schemaLocation="http://rs.tdwg.org/UBIF/2006/ ../SDD.xsd">
171 Element root = sddConfig.getSourceRoot();
172 Namespace sddNamespace = sddConfig.getSddNamespace();
173
174 logger.info("start TechnicalMetadata ...");
175 // <TechnicalMetadata created="2006-04-20T10:00:00">
176 importTechnicalMetadata(root, sddNamespace, sddConfig);
177 List<Element> elDatasets = root.getChildren("Dataset",sddNamespace);
178 int i = 0;
179
180 //for each Dataset
181 logger.info("start Dataset ...");
182 progressMonitor.beginTask("Importing SDD data", elDatasets.size());
183 for (Element elDataset : elDatasets){
184 success &= importDataset(elDataset, sddNamespace, state);
185 // if ((++i % modCount) == 0){ logger.info("dataset(s) handled: " + i);}
186 // logger.info(i + " dataset(s) handled");
187 progressMonitor.worked(1);
188 }
189 commitTransaction(ts);
190 progressMonitor.done();
191 logger.info("End of transaction");
192 return success;
193 }
194
195 /* (non-Javadoc)
196 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
197 */
198 protected boolean isIgnore(SDDImportState state){
199 return false;
200 }
201
202
203 // associates the reference of a media object in SDD with a CdmBase Object
204 protected void associateImageWithCdmBase(String refMO, CdmBase cb){
205 if ((refMO != null) && (cb!=null)) {
206 if (! refMO.equals("")) {
207 if (! mediaObject_ListCdmBase.containsKey(refMO)) {
208 List<CdmBase> lcb = new ArrayList<CdmBase>();
209 lcb.add(cb);
210 mediaObject_ListCdmBase.put(refMO,lcb);
211 } else {
212 List<CdmBase> lcb = mediaObject_ListCdmBase.get(refMO);
213 lcb.add(cb);
214 mediaObject_ListCdmBase.put(refMO,lcb);
215 }
216 }
217 }
218 }
219
220 // imports information about the Dataset
221 protected void importDatasetRepresentation(Element parent, Namespace sddNamespace){
222 logger.info("start Representation ...");
223 /* <Representation>
224 <Label>The Genus Viola</Label>
225 <Detail>This is an example for a very simple SDD file, representing a single description with categorical, quantitative, and text character. Compare also the "Fragment*" examples, which contain more complex examples in the form of document fragments. Intended for version="SDD 1.1".</Detail>
226 </Representation>
227 */
228
229
230
231 Element elRepresentation = parent.getChild("Representation",sddNamespace);
232 String label = (String)ImportHelper.getXmlInputValue(elRepresentation, "Label",sddNamespace);
233 String detail = (String)ImportHelper.getXmlInputValue(elRepresentation, "Detail",sddNamespace);
234
235 //new
236 Representation representation = Representation.NewInstance(detail, label, null, datasetLanguage);
237 workingSet.addRepresentation(representation);
238
239
240 //old
241 // sec.setTitleCache(label, true);
242 //
243 // if (detail != null) {
244 // Annotation annotation = Annotation.NewInstance(detail, datasetLanguage);
245 // annotation.setAnnotationType(AnnotationType.EDITORIAL());
246 // sec.addAnnotation(annotation);
247 // }
248
249
250 List<Element> listMediaObjects = elRepresentation.getChildren("MediaObject",sddNamespace);
251
252 for (Element elMediaObject : listMediaObjects) {
253 String ref = null;
254 String role = null;
255 if (elMediaObject != null) {
256 ref = elMediaObject.getAttributeValue("ref");
257 role = elMediaObject.getAttributeValue("role");
258 }
259 if (ref != null) {
260 if (!ref.equals("")) {
261 this.associateImageWithCdmBase(ref,sourceReference);
262 this.associateImageWithCdmBase(ref,sec);
263 mediaObject_Role.put(ref,role);
264 }
265 }
266 }
267 }
268
269 // imports the representation (label, detail, lang) of a particular SDD element
270 protected void importRepresentation(Element parent, Namespace sddNamespace, VersionableEntity ve, String id, IImportConfigurator config){
271 Element elRepresentation = parent.getChild("Representation",sddNamespace);
272
273 Map<Language,List<String>> langLabDet = new HashMap<Language,List<String>>();
274
275 handleRepresentationLabels(sddNamespace, elRepresentation, langLabDet);
276 handleRepresentationDetails(sddNamespace, elRepresentation, langLabDet);
277
278 if (ve instanceof TermBase) {
279 makeRepresentationForTerms((TermBase)ve, langLabDet);
280 }else if (ve instanceof Media) {
281 makeRepresentationForMedia((Media)ve, langLabDet);
282 }else if (ve instanceof IdentifiableEntity<?>) {
283 IdentifiableEntity<?> ie = (IdentifiableEntity<?>)ve;
284 makeRepresentationForIdentifiableEntity(sddNamespace, ie, elRepresentation, langLabDet);
285 if (ve instanceof IdentifiableMediaEntity<?>){
286 makeRepresentationForIdentifiableMediaEntity(parent, sddNamespace, (IdentifiableMediaEntity<?>)ve);
287 }
288 }
289
290 makeRepresentationMediaObjects(sddNamespace, ve, elRepresentation);//FIXME
291
292 }
293
294
295 /**
296 * Handles the "Detail" children of representations. Adds the result to the langLabDet.
297 * @param sddNamespace
298 * @param elRepresentation
299 * @param langLabDet
300 */
301 private void handleRepresentationDetails(Namespace sddNamespace,
302 Element elRepresentation, Map<Language, List<String>> langLabDet) {
303 List<Element> listDetails = elRepresentation.getChildren("Detail",sddNamespace);
304 for (Element elDetail : listDetails){
305 Language language = getLanguage(elDetail);
306 String role = elDetail.getAttributeValue("role");
307 String detail = elDetail.getText();
308 List<String> labDet = langLabDet.get(language);
309 labDet.add(detail);
310 labDet.add(role);
311 langLabDet.put(language, labDet);
312 }
313 }
314
315 /**
316 * Handles the "Label" children of representations. Adds the result to the langLabDet.
317 * @param sddNamespace
318 * @param elRepresentation
319 * @param langLabDet
320 */
321 private void handleRepresentationLabels(Namespace sddNamespace,
322 Element elRepresentation, Map<Language, List<String>> langLabDet) {
323 // <Label xml:lang="la">Viola hederacea Labill.</Label>
324 List<Element> listLabels = elRepresentation.getChildren("Label",sddNamespace);
325 for (Element elLabel : listLabels){
326 Language language = getLanguage(elLabel);
327 String label = elLabel.getText();
328 List<String> labDet = new ArrayList<String>(3);
329 labDet.add(label);
330 langLabDet.put(language, labDet);
331 }
332 }
333
334 /**
335 *
336 * @param ve
337 * @param langLabDet
338 */
339 private void makeRepresentationForMedia(Media m, Map<Language, List<String>> langLabDet) {
340 for (Language lang : langLabDet.keySet()){
341 List<String> labDet = langLabDet.get(lang);
342 if (labDet.get(0) != null){
343 m.putTitle(LanguageString.NewInstance(labDet.get(0), lang));
344 }
345 if (labDet.size()>1) {
346 m.addDescription(labDet.get(1), lang);
347 }
348 }
349 }
350
351 /**
352 * Handles representations for terms. Adds one representation per language in langLabDet.
353 *
354 * @param ve
355 * @param langLabDet
356 */
357 private void makeRepresentationForTerms(TermBase tb, Map<Language, List<String>> langLabDet) {
358 for (Language lang : langLabDet.keySet()){
359 List<String> labDet = langLabDet.get(lang);
360 if (labDet.size()>0){
361 if (labDet.size()>1) {
362 tb.addRepresentation(Representation.NewInstance(labDet.get(1), labDet.get(0), labDet.get(0), lang));
363 } else {
364 tb.addRepresentation(Representation.NewInstance(labDet.get(0), labDet.get(0), labDet.get(0), lang));
365 }
366 }
367 }
368 }
369
370
371 /**
372 * Handles the "MediaObject" children of representations.
373 * @param sddNamespace
374 * @param ve
375 * @param elRepresentation
376 */
377 private void makeRepresentationMediaObjects(Namespace sddNamespace, VersionableEntity ve, Element elRepresentation) {
378 List <Element> listMediaObjects = elRepresentation.getChildren("MediaObject", sddNamespace);
379 for (Element elMediaObject : listMediaObjects) {
380 String ref = null;
381 //TODO
382 String role = null;
383 if (elMediaObject != null) {
384 ref = elMediaObject.getAttributeValue("ref");
385 role = elMediaObject.getAttributeValue("role");
386 }
387 if (StringUtils.isNotBlank(ref)) {
388 if (ve instanceof TaxonDescription) {
389 TaxonDescription td = (TaxonDescription) ve;
390 if (td.getDescriptionSources().size() > 0) {
391 this.associateImageWithCdmBase(ref,(Reference) td.getDescriptionSources().toArray()[0]);
392 } else {
393 Reference descriptionSource = ReferenceFactory.newGeneric();
394 sources.add(descriptionSource);
395 td.addDescriptionSource(descriptionSource);
396 this.associateImageWithCdmBase(ref,descriptionSource);
397 }
398 } else {
399 this.associateImageWithCdmBase(ref,ve);
400 }
401 }
402 }
403 }
404
405 /**
406 * Handles the "Links" element
407 * @param parent
408 * @param sddNamespace
409 * @param ve
410 */
411 private void makeRepresentationForIdentifiableMediaEntity(Element parent,
412 Namespace sddNamespace, IdentifiableMediaEntity ime) {
413 Element elLinks = parent.getChild("Links",sddNamespace);
414
415 if (elLinks != null) {
416
417 // <Link rel="Alternate" href="http://www.diversitycampus.net/people/hagedorn"/>
418 List<Element> listLinks = elLinks.getChildren("Link", sddNamespace);
419 Media link = Media.NewInstance();
420 MediaRepresentation mr = MediaRepresentation.NewInstance();
421 int k = 0;
422 //for each Link
423 for (Element elLink : listLinks){
424
425 try {
426 //TODO
427 String rel = elLink.getAttributeValue("rel");
428 String href = elLink.getAttributeValue("href");
429 URI uri = new URI(href);
430 mr.addRepresentationPart(MediaRepresentationPart.NewInstance(uri, null));
431 link.addRepresentation(mr);
432 ime.addMedia(link);
433
434 } catch (Exception e) {
435 //FIXME
436 logger.warn("Import of Link " + k + " failed.");
437 }
438
439 if ((++k % modCount) == 0){ logger.info("Links handled: " + k);}
440
441 }
442 }
443 }
444
445 /**
446 * @param sddNamespace
447 * @param ve
448 * @param elRepresentation
449 * @param langLabDet
450 * @return
451 */
452 private void makeRepresentationForIdentifiableEntity(Namespace sddNamespace, IdentifiableEntity<?> ie,
453 Element elRepresentation, Map<Language, List<String>> langLabDet) {
454 List<String> labDet = null;
455
456 if (ie instanceof TaxonNameBase) {
457 if (langLabDet.keySet().contains(getTermService().getLanguageByIso("la"))) {
458 labDet = langLabDet.get(getTermService().getLanguageByIso("la"));
459 } else if (langLabDet.keySet().contains(datasetLanguage)) {
460 labDet = langLabDet.get(datasetLanguage);
461 logger.info("TaxonName " + (String)ImportHelper.getXmlInputValue(elRepresentation, "Label",sddNamespace) + " is not specified as a latin name.");
462 } else {
463 labDet = langLabDet.get(langLabDet.keySet().iterator().next());
464 logger.info("TaxonName " + (String)ImportHelper.getXmlInputValue(elRepresentation, "Label",sddNamespace) + " is not specified as a latin name.");
465 }
466 } else {
467 labDet = langLabDet.get(langLabDet.keySet().iterator().next());
468 }
469
470 //FIXME labDet is != null only for TaxonNameBase
471 ie.setTitleCache(labDet.get(0), true);
472
473 if (labDet.size()>1) {
474 Annotation annotation = null;
475 if (labDet.get(1) != null) {
476 if (labDet.get(2) != null) {
477 annotation = Annotation.NewInstance(labDet.get(2) + " - " + labDet.get(1), datasetLanguage);
478 } else {
479 annotation = Annotation.NewInstance(labDet.get(1), datasetLanguage);
480 }
481 }
482 ie.addAnnotation(annotation);
483 }
484 return;
485 }
486
487 /**
488 * @param elLabel
489 * @return
490 */
491 private Language getLanguage(Element elLanguage) {
492 String lang = elLanguage.getAttributeValue("lang",xmlNamespace);
493 Language language = null;
494 if (StringUtils.isNotBlank(lang)) {
495 language = getTermService().getLanguageByIso(lang.substring(0, 2));
496 } else {
497 language = datasetLanguage;
498 }
499 return language;
500 }
501
502
503 // imports the representation (label, detail, lang) of a particular SDD element
504 protected void importTechnicalMetadata(Element root, Namespace sddNamespace, SDDImportConfigurator sddConfig){
505 Element elTechnicalMetadata = root.getChild("TechnicalMetadata", sddNamespace);
506 String nameCreated = elTechnicalMetadata.getAttributeValue("created");
507 sourceReference = sddConfig.getSourceReference();
508
509 if (nameCreated != null) {
510 if (!nameCreated.equals("")) {
511 int year = Integer.parseInt(nameCreated.substring(0,4));
512 int monthOfYear = Integer.parseInt(nameCreated.substring(5,7));
513 int dayOfMonth = Integer.parseInt(nameCreated.substring(8,10));
514 int hourOfDay = Integer.parseInt(nameCreated.substring(11,13));
515 int minuteOfHour = Integer.parseInt(nameCreated.substring(14,16));
516 int secondOfMinute = Integer.parseInt(nameCreated.substring(17,19));
517 DateTime created = new DateTime(year,monthOfYear,dayOfMonth,hourOfDay,minuteOfHour,secondOfMinute,0);
518 sourceReference.setCreated(created);
519 sec.setCreated(created);
520 }
521 }
522
523 // <Generator name="n/a, handcrafted instance document" version="n/a"/>
524 Element elGenerator = elTechnicalMetadata.getChild("Generator", sddNamespace);
525 generatorName = elGenerator.getAttributeValue("name");
526 generatorVersion = elGenerator.getAttributeValue("version");
527
528 sec.addAnnotation(Annotation.NewDefaultLanguageInstance(generatorName + " - " + generatorVersion));
529 sourceReference.addAnnotation(Annotation.NewDefaultLanguageInstance(generatorName + " - " + generatorVersion));
530
531 }
532
533 // imports the complete dataset information
534 protected boolean importDataset(Element elDataset, Namespace sddNamespace, SDDImportState state){ // <Dataset xml:lang="en-us">
535 boolean success = true;
536 SDDImportConfigurator sddConfig = state.getConfig();
537
538 workingSet = WorkingSet.NewInstance();
539 importDatasetLanguage(elDataset,sddConfig);
540 importDatasetRepresentation(elDataset, sddNamespace);
541 importRevisionData(elDataset, sddNamespace);
542 importIPRStatements(elDataset, sddNamespace, sddConfig);
543 importTaxonNames(elDataset, sddNamespace, sddConfig);
544
545 importDescriptiveConcepts(elDataset, sddNamespace, sddConfig);
546 success &= importCharacters(elDataset, sddNamespace, sddConfig);
547 importCharacterTrees(elDataset, sddNamespace, sddConfig, success);
548
549 MarkerType editorMarkerType = getMarkerType(state, SDDTransformer.uuidMarkerEditor, "editor", "Editor", "edt");
550 MarkerType geographicAreaMarkerType = getMarkerType(state, SDDTransformer.uuidMarkerSDDGeographicArea, "SDDGeographicArea", "SDDGeographicArea", "ga");
551 MarkerType descriptiveConceptMarkerType = getMarkerType(state, SDDTransformer.uuidMarkerDescriptiveConcept, "DescriptiveConcept", "Descriptive Concept", "DC");
552 markerTypes.add(editorMarkerType);
553 markerTypes.add(geographicAreaMarkerType);
554 markerTypes.add(descriptiveConceptMarkerType);
555
556 //saving of all imported data into the CDM db
557 saveVocabularies();
558 saveFeatures();
559 saveModifiers();
560 saveStates();
561 saveMarkerType();
562 saveAreas(geographicAreaMarkerType);
563 saveUnits();
564 saveStatisticalMeasure();
565 saveAnnotationType();
566
567 success &= importCodedDescriptions(elDataset, sddNamespace, sddConfig);
568 importAgents(elDataset, sddNamespace, sddConfig, success);
569 importPublications(elDataset, sddNamespace, sddConfig, success);
570 importMediaObjects(elDataset, sddNamespace, sddConfig, success);
571 importTaxonHierarchies(elDataset, sddNamespace, sddConfig, success);
572 importGeographicAreas(elDataset, sddNamespace, sddConfig);
573 importSpecimens(elDataset,sddNamespace, sddConfig);
574
575
576 if ((authors != null)||(editors != null)) {
577 Team team = Team.NewInstance();
578 if (authors != null) {
579 for (Person author : authors.values()){
580 team.addTeamMember(author);
581 }
582 }
583 if (editors != null) {
584 Marker marker = Marker.NewInstance();
585 marker.setMarkerType(editorMarkerType);
586 for (Person editor : editors.values()){
587 Person edit = editor;
588 edit.addMarker(marker);
589 team.addTeamMember(edit);
590 }
591 }
592 sec.setAuthorTeam(team);
593 sourceReference.setAuthorTeam(team);
594 }
595
596 if (copyright != null) {
597 sourceReference.addRights(copyright);
598 sec.addRights(copyright);
599 }
600
601 // Returns a CdmApplicationController created by the values of this configuration.
602 IDescriptionService descriptionService = getDescriptionService();
603
604 for (TaxonDescription taxonDescription : taxonDescriptions.values()){
605 // Persists a Description
606 descriptionService.save(taxonDescription);
607 }
608
609 for (String ref : taxonDescriptions.keySet()){
610 TaxonDescription td = taxonDescriptions.get(ref);
611 if (citations.containsKey(ref)) {
612 Reference publication = publications.get(citations.get(ref));
613 if (locations.containsKey(ref)) {
614 Annotation location = Annotation.NewInstance(locations.get(ref), datasetLanguage);
615 AnnotationType annotationType = AnnotationType.NewInstance("", "location", "");
616 annotationTypes.add(annotationType);
617 location.setAnnotationType(annotationType);
618 (publication).addAnnotation(location);
619 }
620 td.addDescriptionSource(publication);
621 }
622 }
623 logger.info("end makeTaxonDescriptions ...");
624
625 if (descriptiveConcepts != null) {
626 for (Feature feature : descriptiveConcepts) {
627 Marker marker = Marker.NewInstance();
628 marker.setMarkerType(descriptiveConceptMarkerType);
629 feature.addMarker(marker);
630 }
631 }
632 saveFeatures();
633
634 for (Reference publication : publications.values()){
635 getReferenceService().save(publication);
636 }
637
638 for (Reference source : sources){
639 getReferenceService().save(source);
640 }
641
642 for (FeatureTree featureTree : featureTrees) {
643 getFeatureTreeService().save(featureTree);
644 }
645 getWorkingSetService().save(workingSet);
646 for (Classification classification : classifications) {
647 getClassificationService().save(classification);
648 }
649 for (Specimen specimen : specimens.values()) {
650 getOccurrenceService().save(specimen);
651 }
652 logger.info("end of persistence ...");
653
654 return success;
655 }
656
657 /**
658 *
659 */
660 private void saveVocabularies() {
661 for (TermVocabulary vocabulary : vocabularies ){
662 getVocabularyService().save(vocabulary);
663 }
664
665 }
666
667 private void saveAnnotationType() {
668 for (AnnotationType annotationType: annotationTypes){
669 getTermService().save(annotationType);
670 }
671 }
672
673 private void saveStatisticalMeasure() {
674 for (StatisticalMeasure sm : statisticalMeasures){
675 getTermService().save(sm);
676 }
677 }
678
679 private void saveUnits() {
680 if (units != null) {
681 for (MeasurementUnit unit : units.values()){
682 if (unit != null) {
683 getTermService().save(unit);
684 }
685 }
686 }
687 }
688
689 private void saveAreas(MarkerType geographicAreaMarkerType) {
690 for (NamedArea area : namedAreas.values() ){
691 Marker marker = Marker.NewInstance();
692 marker.setMarkerType(geographicAreaMarkerType);
693 area.addMarker(marker);
694 getTermService().save(area);
695 }
696 }
697
698 private void saveStates() {
699 for (State state : states.values() ){
700 getTermService().save(state);
701 }
702 }
703
704 private void saveMarkerType() {
705 for (MarkerType markerType : markerTypes){
706 getTermService().save(markerType);
707 }
708 }
709
710 private void saveModifiers() {
711 for (Modifier modifier : modifiers.values() ){
712 getTermService().save(modifier);
713 }
714 }
715
716 private void saveFeatures() {
717 for (Feature feature : features.values() ){
718 getTermService().save(feature);
719 }
720 }
721
722 // imports the default language of the dataset
723 protected void importDatasetLanguage(Element elDataset, SDDImportConfigurator sddConfig){
724 String nameLang = elDataset.getAttributeValue("lang",xmlNamespace);
725
726 if (StringUtils.isNotBlank(nameLang)) {
727 String iso = nameLang.substring(0, 2);
728 datasetLanguage = getTermService().getLanguageByIso(iso);
729 } else {
730 datasetLanguage = Language.DEFAULT();
731 }
732 if (datasetLanguage == null) {
733 datasetLanguage = Language.DEFAULT();
734 }
735 }
736
737 // imports the specimens
738 protected void importSpecimens(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig) {
739 logger.info("start Specimens ...");
740 /* <Specimens>
741 <Specimen id="sp1">
742 <Representation>
743 <Label>TJM45337</Label>
744 </Representation>
745 </Specimen>
746 </Specimens>
747 */
748 Element elSpecimens = elDataset.getChild("Specimens",sddNamespace);
749 if (elSpecimens != null){
750 List<Element> listSpecimens = elSpecimens.getChildren("Specimen", sddNamespace);
751 int j = 0;
752 for (Element elSpecimen : listSpecimens) {
753 String id = elSpecimen.getAttributeValue("id");
754 Specimen specimen = null;
755 if (!id.equals("")) {
756 specimen = Specimen.NewInstance();
757 specimens.put(id,specimen);
758 importRepresentation(elSpecimen, sddNamespace, specimen, id, sddConfig);
759 }
760 }
761
762 }
763 }
764
765 // imports the revision data associated with the Dataset (authors, modifications)
766 protected void importRevisionData(Element elDataset, Namespace sddNamespace){
767 // <RevisionData>
768 logger.info("start RevisionData ...");
769 Element elRevisionData = elDataset.getChild("RevisionData",sddNamespace);
770 if (elRevisionData != null){
771 // <Creators>
772 Element elCreators = elRevisionData.getChild("Creators",sddNamespace);
773
774 // <Agent role="aut" ref="a1"/>
775 List<Element> listAgents = elCreators.getChildren("Agent", sddNamespace);
776
777 int j = 0;
778 //for each Agent
779 for (Element elAgent : listAgents){
780
781 String role = elAgent.getAttributeValue("role");
782 String ref = elAgent.getAttributeValue("ref");
783 if (role.equals("aut")) {
784 if(!ref.equals("")) {
785 authors.put(ref, null);
786 }
787 }
788 if (role.equals("edt")) {
789 if(!ref.equals("")) {
790 editors.put(ref, null);
791 }
792 }
793 if ((++j % modCount) == 0){ logger.info("Agents handled: " + j);}
794
795 }
796
797 // <DateModified>2006-04-08T00:00:00</DateModified>
798 String stringDateModified = (String)ImportHelper.getXmlInputValue(elRevisionData, "DateModified",sddNamespace);
799
800 if (stringDateModified != null) {
801 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
802 Date d = null;
803 try {
804 d = sdf.parse(stringDateModified);
805 } catch(Exception e) {
806 System.err.println("Exception :");
807 e.printStackTrace();
808 }
809
810 DateTime updated = null;
811 if (d != null) {
812 updated = new DateTime(d);
813 sourceReference.setUpdated(updated);
814 sec.setUpdated(updated);
815 }
816 }
817 }
818 }
819
820 // imports ipr statements associated with a dataset
821 protected void importIPRStatements(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig){
822 // <IPRStatements>
823 logger.info("start IPRStatements ...");
824 Element elIPRStatements = elDataset.getChild("IPRStatements",sddNamespace);
825 // <IPRStatement role="Copyright">
826 if (elIPRStatements != null) {
827 List<Element> listIPRStatements = elIPRStatements.getChildren("IPRStatement", sddNamespace);
828 int j = 0;
829 //for each IPRStatement
830
831 for (Element elIPRStatement : listIPRStatements){
832
833 String role = elIPRStatement.getAttributeValue("role");
834 // <Label xml:lang="en-au">(c) 2003-2006 Centre for Occasional Botany.</Label>
835 Element elLabel = elIPRStatement.getChild("Label",sddNamespace);
836 String lang = "";
837 if (elLabel != null) {
838 lang = elLabel.getAttributeValue("lang",xmlNamespace);
839 }
840 String label = (String)ImportHelper.getXmlInputValue(elIPRStatement, "Label",sddNamespace);
841
842 if (role.equals("Copyright")) {
843 Language iprLanguage = null;
844 if (lang != null) {
845 if (!lang.equals("")) {
846 iprLanguage = getTermService().getLanguageByIso(lang.substring(0, 2));
847 } else {
848 iprLanguage = datasetLanguage;
849 }
850 }
851 if (iprLanguage == null) {
852 iprLanguage = datasetLanguage;
853 }
854 copyright = Rights.NewInstance(label, iprLanguage);
855 }
856
857 if (copyright != null) {
858 sourceReference.addRights(copyright);
859 sec.addRights(copyright);
860 }
861
862 if ((++j % modCount) == 0){ logger.info("IPRStatements handled: " + j);}
863
864 }
865 }
866 }
867
868 // imports the taxon names
869 protected void importTaxonNames(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig){
870 // <TaxonNames>
871 logger.info("start TaxonNames ...");
872 Element elTaxonNames = elDataset.getChild("TaxonNames",sddNamespace);
873 // <TaxonName id="t1" uri="urn:lsid:authority:namespace:my-own-id">
874 if (elTaxonNames != null) {
875 List<Element> listTaxonNames = elTaxonNames.getChildren("TaxonName", sddNamespace);
876 int j = 0;
877 //for each TaxonName
878 for (Element elTaxonName : listTaxonNames){
879
880 String id = elTaxonName.getAttributeValue("id");
881 String uri = elTaxonName.getAttributeValue("uri");
882
883 NonViralName tnb = null;
884 if (!id.equals("")) {
885 tnb = NonViralName.NewInstance(null);
886 IdentifiableSource source = null;
887 if (uri != null) {
888 if (!uri.equals("")) {
889 source = IdentifiableSource.NewInstance(id, "TaxonName", ReferenceFactory.newGeneric(), uri);
890 }
891 } else {
892 source = IdentifiableSource.NewInstance(id, "TaxonName");
893 }
894 tnb.addSource(source);
895 taxonNameBases.put(id,tnb);
896 }
897
898 // <Representation>
899 // <Label xml:lang="la">Viola hederacea Labill.</Label>
900 importRepresentation(elTaxonName, sddNamespace, tnb, id, sddConfig);
901
902 if ((++j % modCount) == 0){ logger.info("TaxonNames handled: " + j);}
903
904 }
905 }
906 }
907
908 // imports the characters (categorical, quantitative and text ; sequence characters not supported) which correspond to CDM Features
909 protected boolean importCharacters(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig){
910 boolean success = true;
911 // <Characters>
912 logger.info("start Characters ...");
913 Element elCharacters = elDataset.getChild("Characters", sddNamespace);
914
915 // <CategoricalCharacter id="c1">
916 if (elCharacters != null) {
917 success &= handleCategoricalData(sddNamespace, sddConfig, elCharacters);
918 success &= handleQuantitativeData(sddNamespace, sddConfig, elCharacters);
919 success &= handleTextCharacters(sddNamespace, sddConfig, elCharacters);
920 }
921
922 /*for (Iterator<Feature> f = features.values().iterator() ; f.hasNext() ;){
923 featureSet.add(f.next()); //XIM Why this line ?
924 }*/
925
926 return success;
927
928 }
929
930 /**
931 * @param sddNamespace
932 * @param sddConfig
933 * @param success
934 * @param elCharacters
935 * @return
936 */
937 private boolean handleCategoricalData(Namespace sddNamespace, SDDImportConfigurator sddConfig, Element elCharacters) {
938 boolean success = true;
939 List<Element> elCategoricalCharacters = elCharacters.getChildren("CategoricalCharacter", sddNamespace);
940 int j = 0;
941 for (Element elCategoricalCharacter : elCategoricalCharacters){
942 try {
943
944 String idCC = elCategoricalCharacter.getAttributeValue("id");
945 Feature categoricalCharacter = Feature.NewInstance();
946 categoricalCharacter.setKindOf(Feature.DESCRIPTION());
947 importRepresentation(elCategoricalCharacter, sddNamespace, categoricalCharacter, idCC, sddConfig);
948 categoricalCharacter.setSupportsCategoricalData(true);
949
950 // <States>
951 Element elStates = elCategoricalCharacter.getChild("States",sddNamespace);
952
953 // <StateDefinition id="s1">
954 List<Element> elStateDefinitions = elStates.getChildren("StateDefinition",sddNamespace);
955 TermVocabulary<State> termVocabularyState = new TermVocabulary<State>();
956
957 vocabularies.add(termVocabularyState);
958
959 int k = 0;
960 //for each StateDefinition
961 for (Element elStateDefinition : elStateDefinitions){
962
963 if ((++k % modCount) == 0){ logger.info("StateDefinitions handled: " + (k-1));}
964
965 String idS = elStateDefinition.getAttributeValue("id");
966 State state = states.get(idS);
967 if (state == null){
968 state = State.NewInstance();
969 }else{
970 logger.debug("State duplicate found");
971 }
972 importRepresentation(elStateDefinition, sddNamespace, state, idS, sddConfig);
973
974 termVocabularyState.addTerm(state);
975 states.put(idS,state);
976 }
977 categoricalCharacter.addSupportedCategoricalEnumeration(termVocabularyState);
978 features.put(idCC, categoricalCharacter);
979
980 } catch (Exception e) {
981 logger.warn("Import of CategoricalCharacter " + j + " failed.");
982 success = false;
983 }
984
985 if ((++j % modCount) == 0){ logger.info("CategoricalCharacters handled: " + j);}
986
987 }
988 return success;
989 }
990
991 /**
992 * @param sddNamespace
993 * @param sddConfig
994 * @param elCharacters
995 */
996 private boolean handleQuantitativeData(Namespace sddNamespace, SDDImportConfigurator sddConfig, Element elCharacters) {
997 boolean success = true;
998 int j;
999 // <QuantitativeCharacter id="c2">
1000 List<Element> elQuantitativeCharacters = elCharacters.getChildren("QuantitativeCharacter", sddNamespace);
1001 j = 0;
1002 //for each QuantitativeCharacter
1003 for (Element elQuantitativeCharacter : elQuantitativeCharacters){
1004
1005 try {
1006
1007 String idQC = elQuantitativeCharacter.getAttributeValue("id");
1008
1009 // <Representation>
1010 // <Label>Leaf length</Label>
1011 // </Representation>
1012 Feature quantitativeCharacter = Feature.NewInstance();
1013 quantitativeCharacter.setKindOf(Feature.DESCRIPTION());
1014 importRepresentation(elQuantitativeCharacter, sddNamespace, quantitativeCharacter, idQC, sddConfig);
1015
1016 quantitativeCharacter.setSupportsQuantitativeData(true);
1017
1018 // <MeasurementUnit>
1019 // <Label role="Abbrev">m</Label>
1020 // </MeasurementUnit>
1021 Element elMeasurementUnit = elQuantitativeCharacter.getChild("MeasurementUnit",sddNamespace);
1022 String label = "";
1023 String role = "";
1024 if (elMeasurementUnit != null) {
1025 Element elLabel = elMeasurementUnit.getChild("Label",sddNamespace);
1026 role = elLabel.getAttributeValue("role");
1027 label = (String)ImportHelper.getXmlInputValue(elMeasurementUnit, "Label",sddNamespace);
1028 }
1029
1030 MeasurementUnit unit = null;
1031 if (!label.equals("")){
1032 if (role != null) {
1033 if (role.equals("Abbrev")){
1034 unit = MeasurementUnit.NewInstance(label,label,label);
1035 }
1036 } else {
1037 unit = MeasurementUnit.NewInstance(label,label,label);
1038 }
1039 }
1040
1041 if (unit != null) {
1042 units.put(idQC, unit);
1043 }
1044
1045 //<Default>
1046 // <MeasurementUnitPrefix>milli</MeasurementUnitPrefix>
1047 //</Default>
1048 Element elDefault = elQuantitativeCharacter.getChild("Default",sddNamespace);
1049 if (elDefault != null) {
1050 String measurementUnitPrefix = (String)ImportHelper.getXmlInputValue(elDefault, "MeasurementUnitPrefix",sddNamespace);
1051 if (! measurementUnitPrefix.equals("")){
1052 defaultUnitPrefixes.put(idQC, measurementUnitPrefix);
1053 }
1054 }
1055
1056 features.put(idQC, quantitativeCharacter);
1057
1058 } catch (Exception e) {
1059 //FIXME
1060 logger.warn("Import of QuantitativeCharacter " + j + " failed.");
1061 success = false;
1062 }
1063
1064 if ((++j % modCount) == 0){ logger.info("QuantitativeCharacters handled: " + j);}
1065
1066 }
1067 return success;
1068 }
1069
1070 private boolean handleTextCharacters(Namespace sddNamespace, SDDImportConfigurator sddConfig, Element elCharacters) {
1071 boolean success = true;
1072 int j;
1073 // <TextCharacter id="c3">
1074 List<Element> elTextCharacters = elCharacters.getChildren("TextCharacter", sddNamespace);
1075 j = 0;
1076 //for each TextCharacter
1077 for (Element elTextCharacter : elTextCharacters){
1078
1079 try {
1080
1081 String idTC = elTextCharacter.getAttributeValue("id");
1082
1083 // <Representation>
1084 // <Label xml:lang="en">Leaf features not covered by other characters</Label>
1085 // </Representation>
1086 Feature textCharacter = Feature.NewInstance();
1087 textCharacter.setKindOf(Feature.DESCRIPTION());
1088 importRepresentation(elTextCharacter, sddNamespace, textCharacter, idTC, sddConfig);
1089
1090 textCharacter.setSupportsTextData(true);
1091
1092 features.put(idTC, textCharacter);
1093
1094 } catch (Exception e) {
1095 //FIXME
1096 logger.warn("Import of TextCharacter " + j + " failed.");
1097 success = false;
1098 }
1099
1100 if ((++j % modCount) == 0){ logger.info("TextCharacters handled: " + j);}
1101
1102 }
1103 return success;
1104 }
1105
1106 // imports the descriptions of taxa
1107 protected boolean importCodedDescriptions(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig){
1108 boolean success = true;
1109
1110 // <CodedDescriptions>
1111 logger.info("start CodedDescriptions ...");
1112 Element elCodedDescriptions = elDataset.getChild("CodedDescriptions",sddNamespace);
1113
1114 // <CodedDescription id="D101">
1115 if (elCodedDescriptions != null) {
1116 List<Element> listCodedDescriptions = elCodedDescriptions.getChildren("CodedDescription", sddNamespace);
1117 int j = 0;
1118 //for each CodedDescription
1119 for (Element elCodedDescription : listCodedDescriptions){
1120 success &= handleCodedDescription(sddNamespace, sddConfig, elCodedDescription, j);
1121 if ((++j % modCount) == 0){ logger.info("CodedDescriptions handled: " + j);}
1122 }
1123 }
1124 return success;
1125 }
1126
1127 /**
1128 * @param sddNamespace
1129 * @param sddConfig
1130 * @param j
1131 * @param elCodedDescription
1132 * @return
1133 */
1134 private boolean handleCodedDescription(Namespace sddNamespace, SDDImportConfigurator sddConfig, Element elCodedDescription, int j) {
1135 boolean success = true ;
1136 try {
1137
1138 String idCD = elCodedDescription.getAttributeValue("id");
1139
1140 // <Representation>
1141 // <Label>&lt;i&gt;Viola hederacea&lt;/i&gt; Labill. as revised by R. Morris April 8, 2006</Label>
1142 // </Representation>
1143 TaxonDescription taxonDescription = TaxonDescription.NewInstance();
1144 if (!generatorName.isEmpty()){
1145 Annotation annotation = Annotation.NewInstance(generatorName, AnnotationType.TECHNICAL(),Language.DEFAULT());
1146 taxonDescription.addAnnotation(annotation);
1147 }
1148 importRepresentation(elCodedDescription, sddNamespace, taxonDescription, idCD, sddConfig);
1149
1150 // <Scope>
1151 // <TaxonName ref="t1"/>
1152 // <Citation ref="p1" location="p. 30"/>
1153 // </Scope>
1154 Element elScope = elCodedDescription.getChild("Scope", sddNamespace);
1155 Taxon taxon;
1156 if (elScope != null) {
1157 taxon = handleCDScope(sddNamespace, sddConfig, idCD, elScope);
1158 } else {//in case no taxon is linked to the description, a new one is created
1159 taxon = handleCDNoScope(sddNamespace, sddConfig, elCodedDescription);
1160 }
1161
1162 // <SummaryData>
1163 Element elSummaryData = elCodedDescription.getChild("SummaryData",sddNamespace);
1164 if (elSummaryData != null) {
1165 handleSummaryCategoricalData(sddNamespace, taxonDescription, elSummaryData);
1166 handleSummaryQuantitativeData(sddNamespace, taxonDescription, elSummaryData);
1167 handleSummaryTextData(sddNamespace, taxonDescription, elSummaryData);
1168 }
1169
1170 if (taxon != null) {
1171 taxon.addDescription(taxonDescription);
1172 }
1173 //
1174 workingSet.addDescription(taxonDescription);
1175
1176 //OLD taxonDescription.setDescriptiveSystem(featureSet);
1177
1178 taxonDescriptions.put(idCD, taxonDescription);//FIXME
1179
1180 } catch (Exception e) {
1181 //FIXME
1182 logger.warn("Import of CodedDescription " + j + " failed.", e);
1183 success = false;
1184 }
1185 return success;
1186 }
1187
1188 /**
1189 * @param sddNamespace
1190 * @param sddConfig
1191 * @param elCodedDescription
1192 * @param taxon
1193 * @return
1194 */
1195 private Taxon handleCDNoScope(Namespace sddNamespace,
1196 SDDImportConfigurator sddConfig, Element elCodedDescription ) {
1197 Taxon taxon = null;
1198 NonViralName nonViralName = NonViralName.NewInstance(null);
1199 String id = new String("" + taxonNamesCount);
1200 IdentifiableSource source = IdentifiableSource.NewInstance(id, "TaxonName");
1201 importRepresentation(elCodedDescription, sddNamespace, nonViralName, id, sddConfig);
1202
1203 if(sddConfig.isDoMatchTaxa()){
1204 taxon = getTaxonService().findBestMatchingTaxon(nonViralName.getTitleCache());
1205 }
1206
1207 if(taxon != null){
1208 nonViralName = HibernateProxyHelper.deproxy(taxon.getName(), NonViralName.class);
1209 // taxonNameBases.put(id ,tnb);
1210 // taxonNamesCount++;
1211 logger.info("using existing Taxon " + taxon.getTitleCache());
1212 } else {
1213 nonViralName.addSource(source);
1214 taxonNameBases.put(id ,nonViralName);
1215 taxonNamesCount++;
1216 logger.info("creating new Taxon from TaxonName " + nonViralName.getTitleCache());
1217 taxon = Taxon.NewInstance(nonViralName, sec);
1218 }
1219 return taxon;
1220 }
1221
1222 /**
1223 * @param sddNamespace
1224 * @param sddConfig
1225 * @param idCD
1226 * @param elScope
1227 * @param taxon
1228 * @return
1229 */
1230 private Taxon handleCDScope(Namespace sddNamespace, SDDImportConfigurator sddConfig,
1231 String idCD, Element elScope) {
1232 Taxon taxon = null;
1233 Element elTaxonName = elScope.getChild("TaxonName", sddNamespace);
1234 String ref = elTaxonName.getAttributeValue("ref");
1235 NonViralName nonViralName = taxonNameBases.get(ref);
1236
1237 if(sddConfig.isDoMatchTaxa()){
1238 taxon = getTaxonService().findBestMatchingTaxon(nonViralName.getTitleCache());
1239 }
1240
1241 if(taxon != null){
1242 logger.info("using existing Taxon" + taxon.getTitleCache());
1243 if(!nonViralName.getUuid().equals(taxon.getName().getUuid())){
1244 logger.warn("TaxonNameBase entity of existing taxon does not match Name in list -> replacing Name in list");
1245 nonViralName = HibernateProxyHelper.deproxy(taxon.getName(), NonViralName.class);
1246 }
1247 } else {
1248 logger.info("creating new Taxon from TaxonName '" + nonViralName.getTitleCache()+"'");
1249 taxon = Taxon.NewInstance(nonViralName, sec);
1250 }
1251
1252 //citation
1253 Element elCitation = elScope.getChild("Citation",sddNamespace);
1254 if (elCitation != null) {
1255 String refCitation = elCitation.getAttributeValue("ref");
1256 if (! refCitation.equals("")){
1257 citations.put(idCD, refCitation);
1258 }
1259 String location = elCitation.getAttributeValue("location");
1260 if (! location.equals("")){
1261 locations.put(idCD, location);
1262 }
1263 }
1264 return taxon;
1265 }
1266
1267 /**
1268 * @param sddNamespace
1269 * @param taxonDescription
1270 * @param elSummaryData
1271 */
1272 private void handleSummaryTextData(Namespace sddNamespace,
1273 TaxonDescription taxonDescription, Element elSummaryData) {
1274 String ref;
1275 int k;
1276 // <TextChar ref="c3">
1277 List<Element> elTextChars = elSummaryData.getChildren("TextChar", sddNamespace);
1278 k = 0;
1279 //for each TextChar
1280 for (Element elTextChar : elTextChars){
1281 if ((++k % modCount) == 0){ logger.info("TextChar handled: " + (k-1));}
1282 ref = elTextChar.getAttributeValue("ref");
1283 Feature feature = features.get(ref);
1284 TextData textData = TextData.NewInstance();
1285 textData.setFeature(feature);
1286
1287 // <Content>Free form text</Content>
1288 String content = (String)ImportHelper.getXmlInputValue(elTextChar, "Content",sddNamespace);
1289 textData.putText(datasetLanguage, content);
1290 taxonDescription.addElement(textData);
1291 }
1292 }
1293
1294 /**
1295 * @param sddNamespace
1296 * @param taxonDescription
1297 * @param elSummaryData
1298 */
1299 private void handleSummaryQuantitativeData(Namespace sddNamespace,
1300 TaxonDescription taxonDescription, Element elSummaryData) {
1301 String ref;
1302 int k;
1303 // <Quantitative ref="c2">
1304 List<Element> elQuantitatives = elSummaryData.getChildren("Quantitative", sddNamespace);
1305 k = 0;
1306 //for each Quantitative
1307 for (Element elQuantitative : elQuantitatives){
1308 if ((++k % modCount) == 0){ logger.warn("Quantitative handled: " + (k-1));}
1309 ref = elQuantitative.getAttributeValue("ref");
1310 Feature feature = features.get(ref);
1311 QuantitativeData quantitativeData = QuantitativeData.NewInstance();
1312 quantitativeData.setFeature(feature);
1313
1314 MeasurementUnit unit = units.get(ref);
1315 String prefix = defaultUnitPrefixes.get(ref);
1316 if (unit != null) {
1317 String u = unit.getLabel();
1318 if (prefix != null) {
1319 u = prefix + u;
1320 }
1321 unit.setLabel(u);
1322 quantitativeData.setUnit(unit);
1323 }
1324
1325 // <Measure type="Min" value="2.3"/>
1326 List<Element> elMeasures = elQuantitative.getChildren("Measure", sddNamespace);
1327 int l = 0;
1328
1329 //for each State
1330 for (Element elMeasure : elMeasures){
1331 if ((++l % modCount) == 0){ logger.info("States handled: " + (l-1));}
1332 String type = elMeasure.getAttributeValue("type");
1333 String value = elMeasure.getAttributeValue("value");
1334 if (value.contains(",")) {
1335 value = value.replace(',', '.');
1336 }
1337 Float v = Float.parseFloat(value);
1338 //Float v = new Float(0);
1339 StatisticalMeasure t = null;
1340 if (type.equals("Min")) {
1341 t = StatisticalMeasure.MIN();
1342 } else if (type.equals("Mean")) {
1343 t = StatisticalMeasure.AVERAGE();
1344 } else if (type.equals("Max")) {
1345 t = StatisticalMeasure.MAX();
1346 } else if (type.equals("SD")) {
1347 t = StatisticalMeasure.STANDARD_DEVIATION();
1348 } else if (type.equals("N")) {
1349 t = StatisticalMeasure.SAMPLE_SIZE();
1350 } else if (type.equals("UMethLower")) {
1351 t = StatisticalMeasure.TYPICAL_LOWER_BOUNDARY();
1352 } else if (type.equals("UMethUpper")) {
1353 t = StatisticalMeasure.TYPICAL_UPPER_BOUNDARY();
1354 } else if (type.equals("Var")) {
1355 t = StatisticalMeasure.VARIANCE();
1356 } else {
1357 t = StatisticalMeasure.NewInstance(type,type,type);
1358 statisticalMeasures.add(t);
1359 }
1360
1361 StatisticalMeasurementValue statisticalValue = StatisticalMeasurementValue.NewInstance();
1362 statisticalValue.setValue(v);
1363 statisticalValue.setType(t);
1364 quantitativeData.addStatisticalValue(statisticalValue);
1365 featureData.add(statisticalValue);
1366 }
1367 taxonDescription.addElement(quantitativeData);
1368 }
1369 }
1370
1371 /**
1372 * @param sddNamespace
1373 * @param taxonDescription
1374 * @param elSummaryData
1375 */
1376 private void handleSummaryCategoricalData(Namespace sddNamespace,
1377 TaxonDescription taxonDescription, Element elSummaryData) {
1378 String ref;
1379 // <Categorical ref="c4">
1380 List<Element> elCategoricals = elSummaryData.getChildren("Categorical", sddNamespace);
1381 int k = 0;
1382 //for each Categorical
1383 for (Element elCategorical : elCategoricals){
1384 if ((++k % modCount) == 0){ logger.warn("Categorical handled: " + (k-1));}
1385 ref = elCategorical.getAttributeValue("ref");
1386 Feature feature = features.get(ref);
1387 CategoricalData categoricalData = CategoricalData.NewInstance();
1388 categoricalData.setFeature(feature);
1389
1390 // <State ref="s3"/>
1391 List<Element> elStates = elCategorical.getChildren("State", sddNamespace);
1392 int l = 0;
1393
1394 //for each State
1395 for (Element elState : elStates){
1396 if ((++l % modCount) == 0){ logger.info("States handled: " + (l-1));}
1397 ref = elState.getAttributeValue("ref");
1398 State state = states.get(ref);
1399 if (state != null) {
1400 StateData stateData = StateData.NewInstance();
1401 stateData.setState(state);
1402 List<Element> elModifiers = elState.getChildren("Modifier", sddNamespace);
1403 for (Element elModifier : elModifiers){
1404 ref = elModifier.getAttributeValue("ref");
1405 Modifier modifier = modifiers.get(ref);
1406 if (modifier != null) {
1407 stateData.addModifier(modifier);
1408 }
1409 }
1410 categoricalData.addState(stateData);
1411 }
1412 taxonDescription.addElement(categoricalData);
1413 }
1414 }
1415 }
1416
1417 // imports the persons associated with the dataset creation, modification, related publications
1418 protected void importAgents(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig, boolean success){
1419 // <Agents>
1420 logger.info("start Agents ...");
1421 Element elAgents = elDataset.getChild("Agents",sddNamespace);
1422 if (elAgents != null) {
1423 // <Agent id="a1">
1424 List <Element> listAgents = elAgents.getChildren("Agent", sddNamespace);
1425 int j = 0;
1426 //for each Agent
1427 for (Element elAgent : listAgents){
1428
1429 try {
1430
1431 String idA = elAgent.getAttributeValue("id");
1432
1433 // <Representation>
1434 // <Label>Kevin Thiele</Label>
1435 // <Detail role="Description">Ali Baba is also known as r.a.m.</Detail>
1436 // </Representation>
1437 Person person = Person.NewInstance();
1438 importRepresentation(elAgent, sddNamespace, person, idA, sddConfig);
1439 person.addSource(IdentifiableSource.NewInstance(idA, "Agent"));
1440
1441 /*XIM <Links>
1442 Element elLinks = elAgent.getChild("Links",sddNamespace);
1443
1444 if (elLinks != null) {
1445
1446 // <Link rel="Alternate" href="http://www.diversitycampus.net/people/hagedorn"/>
1447 List<Element> listLinks = elLinks.getChildren("Link", sddNamespace);
1448 int k = 0;
1449 //for each Link
1450 for (Element elLink : listLinks){
1451
1452 try {
1453
1454 String rel = elLink.getAttributeValue("rel");
1455 String href = elLink.getAttributeValue("href");
1456
1457 Media link = Media.NewInstance();
1458 MediaRepresentation mr = MediaRepresentation.NewInstance();
1459 mr.addRepresentationPart(MediaRepresentationPart.NewInstance(href, null));
1460 link.addRepresentation(mr);
1461 person.addMedia(link);
1462
1463 } catch (Exception e) {
1464 //FIXME
1465 logger.warn("Import of Link " + k + " failed.");
1466 success = false;
1467 }
1468
1469 if ((++k % modCount) == 0){ logger.info("Links handled: " + k);}
1470
1471 }
1472 }
1473 */
1474 if (authors.containsKey(idA)) {
1475 authors.put(idA,person);
1476 }
1477
1478 if (editors.containsKey(idA)) {
1479 editors.put(idA, person);
1480 }
1481
1482 } catch (Exception e) {
1483 //FIXME
1484 logger.warn("Import of Agent " + j + " failed.");
1485 success = false;
1486 }
1487
1488 if ((++j % modCount) == 0){ logger.info("Agents handled: " + j);}
1489
1490 }
1491 }
1492 }
1493
1494 // imports publications related with the data set
1495 protected void importPublications(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig, boolean success){
1496 /* <Publications>
1497 <Publication id="p112">
1498 <Representation>
1499 <Label>Gee, X. & Haa, Y. (2003). How to be happy in five minutes. Instant Gratifications, Palm Beach.</Label>
1500 </Representation>
1501 <Links>
1502 <Link rel="BasedOn" href="doi:10.1992/32311"/>
1503 <Link rel="Alternate" href="http://some.service.net/providing/bibliographic.data"/>
1504 </Links>
1505 </Publications>
1506 */
1507 logger.info("start Publications ...");
1508 Element elPublications = elDataset.getChild("Publications",sddNamespace);
1509
1510 if (elPublications != null) {
1511 List<Element> listPublications = elPublications.getChildren("Publication", sddNamespace);
1512 int j = 0;
1513 for (Element elPublication : listPublications){
1514
1515 try {
1516
1517 String idP = elPublication.getAttributeValue("id");
1518 Reference publication = ReferenceFactory.newArticle();
1519 importRepresentation(elPublication, sddNamespace, publication, idP, sddConfig);
1520
1521 publications.put(idP,publication);
1522
1523 } catch (Exception e) {
1524 logger.warn("Import of Publication " + j + " failed.");
1525 success = false;
1526 }
1527
1528 if ((++j % modCount) == 0){ logger.info("Publications handled: " + j);}
1529
1530 }
1531 }
1532 }
1533
1534 // imports media objects such as images //FIXME check mediaobj
1535 protected void importMediaObjects(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig, boolean success){
1536 // <MediaObjects>
1537 logger.info("start MediaObjects ...");
1538 Element elMediaObjects = elDataset.getChild("MediaObjects",sddNamespace);
1539
1540 if (elMediaObjects != null) {
1541 // <MediaObject id="m1">
1542 List<Element> listMediaObjects = elMediaObjects.getChildren("MediaObject", sddNamespace);
1543 int j = 0;
1544 for (Element elMO : listMediaObjects){
1545
1546 String id = "";
1547
1548 try {
1549 String idMO = elMO.getAttributeValue("id");
1550 id = idMO;
1551
1552 // <Representation>
1553 // <Label>Image description, e.g. to be used for alt-attribute in html.</Label>
1554 // </Representation>
1555 Media media = Media.NewInstance();
1556 importRepresentation(elMO, sddNamespace, media, idMO, sddConfig);
1557
1558 // <Type>Image</Type>
1559 // <Source href="http://test.edu/test.jpg"/>
1560 String type = (String)ImportHelper.getXmlInputValue(elMO,"Type",sddNamespace);
1561
1562 if ((type != null) && (type.equals("Image"))) {
1563 Element elSource = elMO.getChild("Source",sddNamespace);
1564 String href = elSource.getAttributeValue("href");
1565
1566 ImageMetaData imageMetaData = ImageMetaData.newInstance();
1567 ImageFile image = null;
1568 if (href.substring(0,7).equals("http://")) {
1569 try{
1570 URL url = new URL(href);
1571
1572 imageMetaData.readMetaData(url.toURI(), 0);
1573 image = ImageFile.NewInstance(url.toURI(), null, imageMetaData);
1574 } catch (MalformedURLException e) {
1575 logger.error("Malformed URL", e);
1576 }
1577 } else {
1578 String sns = sddConfig.getSourceNameString();
1579 File f = new File(sns);
1580 File parent = f.getParentFile();
1581 String fi = parent.toString() + File.separator + href;
1582 File file = new File(fi);
1583 imageMetaData.readMetaData(new URI(fi), 0); //file
1584 image = ImageFile.NewInstance(file.toURI(), null, imageMetaData);
1585 }
1586 MediaRepresentation representation = MediaRepresentation.NewInstance(imageMetaData.getMimeType(), null);
1587 representation.addRepresentationPart(image);
1588
1589 media.addRepresentation(representation);
1590
1591 ArrayList<CdmBase> lcb = (ArrayList<CdmBase>) mediaObject_ListCdmBase.get(idMO);
1592 if (lcb != null) {
1593 for (int k = 0; k < lcb.size(); k++) {
1594 if (lcb.get(k) instanceof DefinedTermBase) {
1595 DefinedTermBase dtb = (DefinedTermBase) lcb.get(k);
1596 // if (lcb.get(0) instanceof DefinedTermBase) {
1597 // DefinedTermBase dtb = (DefinedTermBase) lcb.get(0);
1598 // if (dtb!=null) {
1599 // if (k == 0) {
1600 dtb.addMedia(media);
1601 //System.out.println(dtb.getLabel());
1602 // } else {
1603 // Media me = (Media) media.clone();
1604 // dtb.addMedia(me);
1605 // }
1606 // }
1607 } else if (lcb.get(k) instanceof Reference) {
1608 Reference rb = (Reference) lcb.get(k);
1609 //} else if (lcb.get(0) instanceof Reference) {
1610 //Reference rb = (Reference) lcb.get(0);
1611 // rb.setTitleCache(label);
1612 // if (rb!=null) {
1613 // if (k == 0) {
1614 rb.addMedia(media);
1615 //System.out.println(rb.getTitle());
1616 // } else {
1617 // Media me = (Media) media.clone();
1618 // rb.addMedia(me);
1619 // }
1620 // }
1621 // else if (lcb.get(k) instanceof TaxonNameBase){
1622 // TaxonNameBase tb = (TaxonNameBase) lcb.get(k);
1623 // tb.addMedia(media);
1624 } else {
1625 logger.warn("Can't handle associated media for " + lcb.get(k).getId() + "(" + lcb.get(k).getClass().getSimpleName()+")" );
1626 }
1627 }
1628 }
1629 }
1630
1631 } catch (Exception e) {
1632 //FIXME
1633 logger.warn("Could not attach MediaObject " + j + "(SDD: " + id + ") to several objects.");
1634 success = false;
1635 }
1636
1637 if ((++j % modCount) == 0){ logger.info("MediaObjects handled: " + j);
1638
1639 }
1640 }
1641 }
1642 }
1643
1644 // imports the <DescriptiveConcepts> block ; DescriptiveConcepts are used as nodes in CharacterTrees and Characters as leaves
1645 // but since Modifiers can be linked to DescriptiveConcepts they are stored as features with a particular Marker
1646 protected void importDescriptiveConcepts(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig){
1647 /* <DescriptiveConcepts>
1648 <DescriptiveConcept id="dc0">
1649 <Representation>
1650 <Label>Fixed set of modifiers supported in Lucid3</Label>
1651 </Representation>
1652 <Modifiers>
1653 <Modifier id="mod1">
1654 <Representation>
1655 <Label>rarely</Label>
1656 </Representation>
1657 <ModifierClass>Frequency</ModifierClass>
1658 <ProportionRange lowerestimate="0.0" upperestimate="0.25"/>
1659 </Modifier>
1660 </Modifiers>
1661 </DescriptiveConcept>
1662 </DescriptiveConcepts>
1663 */
1664 logger.info("start DescriptiveConcepts ...");
1665 Element elDescriptiveConcepts = elDataset.getChild("DescriptiveConcepts",sddNamespace);
1666 if (elDescriptiveConcepts != null) {
1667 List<Element> listDescriptiveConcepts = elDescriptiveConcepts.getChildren("DescriptiveConcept", sddNamespace);
1668 int j = 0;
1669
1670 for (Element elDescriptiveConcept : listDescriptiveConcepts){
1671 try {
1672 String id = elDescriptiveConcept.getAttributeValue("id");
1673 Feature feature = Feature.NewInstance();
1674 feature.setKindOf(Feature.DESCRIPTION());
1675 if (!id.equals("")) {
1676 // <Representation>
1677 // <Label>Body</Label>
1678 importRepresentation(elDescriptiveConcept, sddNamespace, feature, id, sddConfig);
1679 features.put(id, feature);
1680 getTermService().save(feature);//XIM
1681 descriptiveConcepts.add(feature);
1682 // imports the modifiers
1683 Element elModifiers = elDescriptiveConcept.getChild("Modifiers", sddNamespace);
1684 if (elModifiers !=null){
1685 List<Element> listModifiers = elModifiers.getChildren("Modifier", sddNamespace);
1686 TermVocabulary<Modifier> termVocabularyState = new TermVocabulary<Modifier>();
1687 for (Element elModifier : listModifiers) {
1688 Modifier modif = Modifier.NewInstance();
1689 String idmod = elModifier.getAttributeValue("id");
1690 importRepresentation(elModifier, sddNamespace, modif, idmod, sddConfig);
1691 termVocabularyState.addTerm(modif);
1692 //termVocabularyStates.add(termVocabularyState);
1693 getVocabularyService().save(termVocabularyState);//XIM
1694 modifiers.put(idmod, modif);
1695 }
1696 feature.addRecommendedModifierEnumeration(termVocabularyState);
1697 }
1698
1699 }
1700 }
1701 catch (Exception e) {
1702 logger.warn("Import of DescriptiveConcept " + j + " failed: " + e.getMessage());
1703 }
1704 if ((++j % modCount) == 0){ logger.info("DescriptiveConcepts handled: " + j);}
1705
1706 }
1707 }
1708 }
1709
1710 // imports the <CharacterTrees> block
1711 protected void importCharacterTrees(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig, boolean success){
1712 // <CharacterTrees>
1713 logger.info("start CharacterTrees ...");
1714 Element elCharacterTrees = elDataset.getChild("CharacterTrees",sddNamespace);
1715
1716 if (elCharacterTrees != null) {
1717 List<Element> listCharacterTrees = elCharacterTrees.getChildren("CharacterTree", sddNamespace);
1718 int j = 0;
1719 for (Element elCharacterTree : listCharacterTrees){
1720 try {
1721 Element elRepresentation = elCharacterTree.getChild("Representation",sddNamespace);
1722 String label = (String)ImportHelper.getXmlInputValue(elRepresentation,"Label",sddNamespace);
1723 //Element elDesignedFor = elCharacterTree.getChild("DesignedFor",sddNamespace);//TODO ?
1724
1725 FeatureTree featureTree = FeatureTree.NewInstance();
1726 importRepresentation(elCharacterTree, sddNamespace, featureTree, "", sddConfig);
1727 FeatureNode root = featureTree.getRoot();
1728 List<Element> listeOfNodes = elCharacterTree.getChildren("Nodes", sddNamespace);
1729
1730 //Nodes of CharacterTrees in SDD always refer to DescriptiveConcepts
1731 for (Element elNodes : listeOfNodes) {
1732 handleCharacterNodes(sddNamespace, root, elNodes);
1733 }
1734 featureTrees.add(featureTree);
1735 if (workingSet.getDescriptiveSystem() != null){
1736 //TODO how to handle multiple
1737 logger.warn("Multiple feature trees not yet supported");
1738 }else{
1739 workingSet.setDescriptiveSystem(featureTree);
1740 }
1741 }
1742
1743 catch (Exception e) {
1744 logger.warn("Import of Character tree " + j + " failed.");
1745 success = false;
1746 }
1747 if ((++j % modCount) == 0){ logger.info("CharacterTrees handled: " + j);}
1748
1749 }
1750
1751 }
1752 }
1753
1754 /**
1755 * @param sddNamespace
1756 * @param root
1757 * @param elNodes
1758 */
1759 private void handleCharacterNodes(Namespace sddNamespace, FeatureNode root, Element elNodes) {
1760 List<Element> listNodes = elNodes.getChildren("Node", sddNamespace);
1761 if (listNodes != null) {
1762 for (Element elNode : listNodes){
1763 String idN = elNode.getAttributeValue("id");
1764 FeatureNode fn = null;
1765 Feature dc = null;
1766 if (idN!=null) {
1767 // DescriptiveConcepts are used as nodes in CharacterTrees
1768 Element elDescriptiveConcept = elNode.getChild("DescriptiveConcept", sddNamespace);
1769 if (elDescriptiveConcept != null){
1770 String refDC = elDescriptiveConcept.getAttributeValue("ref");
1771 dc = features.get(refDC);
1772 fn = FeatureNode.NewInstance(dc);
1773 }
1774 if (fn==null){
1775 fn = FeatureNode.NewInstance();
1776 }
1777 Element elParent = elNode.getChild("Parent", sddNamespace);
1778 // in SDD links between Nodes are referenced by the <Parent> tag
1779 if (elParent!=null){
1780 String refP = elParent.getAttributeValue("ref");
1781 if (refP!=null) {
1782 FeatureNode parent = featureNodes.get(refP);
1783 if (parent==null){
1784 root.addChild(fn); // if no parent found or the reference is broken, add the node to the root of the tree
1785 }
1786 else {
1787 parent.addChild(fn);
1788 }
1789 }
1790 }
1791 else {
1792 root.addChild(fn); // if no parent found or the reference is broken, add the node to the root of the tree
1793 }
1794 }
1795 featureNodes.put(idN, fn);
1796 }
1797 }
1798
1799 // Leaves of CharacterTrees in SDD are always CharNodes (referring to Characters)
1800 List<Element> listCharNodes = elNodes.getChildren("CharNode", sddNamespace);
1801 if (listCharNodes != null) {
1802 for (Element elCharNode : listCharNodes){
1803 Element elParent = elCharNode.getChild("Parent", sddNamespace);
1804 Element elCharacter = elCharNode.getChild("Character", sddNamespace);
1805 Element elDependencyRules = elCharNode.getChild("DependencyRules", sddNamespace);
1806 FeatureNode fn = FeatureNode.NewInstance();
1807
1808 if (elDependencyRules!=null){
1809 Element elInapplicableIf = elCharNode.getChild("InapplicableIf", sddNamespace);
1810 if (elInapplicableIf!=null){
1811 List<Element> listStates = elInapplicableIf.getChildren("State", sddNamespace);
1812 for (Element stateElement : listStates) {
1813 String refState = stateElement.getAttributeValue("ref");
1814 if ((refState!=null)&&(!refState.equals(""))) {
1815 State state = states.get(refState);
1816 fn.addInapplicableState(state);
1817 }
1818 }
1819 }
1820 Element elOnlyapplicableIf = elCharNode.getChild("OnlyApplicableIf", sddNamespace);
1821 if (elOnlyapplicableIf!=null){
1822 List<Element> listStates = elInapplicableIf.getChildren("State", sddNamespace);
1823 for (Element stateElement : listStates) {
1824 String refState = stateElement.getAttributeValue("ref");
1825 if ((refState!=null)&&(!refState.equals(""))) {
1826 State state = states.get(refState);
1827 fn.addApplicableState(state);
1828 }
1829 }
1830 }
1831 }
1832
1833 if (elParent!=null){
1834 String refP = elParent.getAttributeValue("ref");
1835 if ((refP!=null)&&(!refP.equals(""))) {
1836 FeatureNode parent = featureNodes.get(refP);
1837 if (parent==null){
1838 parent = root; // if no parent found or the reference is broken, add the node to the root of the tree
1839 }
1840 parent.addChild(fn);
1841 }
1842 }
1843 String refC = elCharacter.getAttributeValue("ref");
1844 if ((refC!=null)&&(!refC.equals(""))){
1845 Feature character = features.get(refC);
1846 fn.setFeature(character);
1847 featureNodes.put(refC, fn);
1848 }
1849 }
1850 }
1851 }
1852
1853 // imports the <TaxonHierarchies> block
1854 protected void importTaxonHierarchies(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig, boolean success){
1855
1856 logger.info("start TaxonHierarchies ...");
1857 Element elTaxonHierarchies = elDataset.getChild("TaxonHierarchies",sddNamespace);
1858
1859 if (elTaxonHierarchies != null) {
1860 List<Element> listTaxonHierarchies = elTaxonHierarchies.getChildren("TaxonHierarchy", sddNamespace);
1861 int j = 0;
1862 for (Element elTaxonHierarchy : listTaxonHierarchies){
1863 try {
1864 Element elRepresentation = elTaxonHierarchy.getChild("Representation",sddNamespace);
1865 String label = (String)ImportHelper.getXmlInputValue(elRepresentation,"Label",sddNamespace);
1866 Classification classification = Classification.NewInstance(label);
1867 importRepresentation(elTaxonHierarchy, sddNamespace, classification, "", sddConfig);
1868
1869 Set<TaxonNode> root = classification.getChildNodes();
1870 Element elNodes = elTaxonHierarchy.getChild("Nodes", sddNamespace); // There can be only one <Nodes> block for TaxonHierarchies
1871 List<Element> listNodes = elNodes.getChildren("Node", sddNamespace);
1872
1873 for (Element elNode : listNodes){
1874 String idN = elNode.getAttributeValue("id");
1875 TaxonNameBase tnb = null;
1876 if (!idN.equals("")) {
1877 Element elTaxonName = elNode.getChild("TaxonName", sddNamespace);
1878 String refTN = elTaxonName.getAttributeValue("ref");
1879 tnb = taxonNameBases.get(refTN);
1880 Taxon taxon = (Taxon) tnb.getTaxa().iterator().next() ;
1881 Element elParent = elNode.getChild("Parent", sddNamespace);
1882 if (elParent!=null){
1883 String refP = elParent.getAttributeValue("ref");
1884 if (!refP.equals("")) {
1885 TaxonNode parent = taxonNodes.get(refP);
1886 TaxonNode child = parent.addChildTaxon(taxon, sec, "", Synonym.NewInstance(tnb, sec));
1887 taxonNodes.put(idN,child);
1888 }
1889 }
1890 else {
1891 TaxonNode tn = classification.addChildTaxon(taxon, sec, "", Synonym.NewInstance(tnb, sec)); // if no parent found or the reference is broken, add the node to the root of the tree
1892 taxonNodes.put(idN,tn);
1893 }
1894 }
1895 }
1896
1897 classifications.add(classification);
1898 }
1899
1900 catch (Exception e) {
1901 //FIXME
1902 logger.warn("Import of Taxon Hierarchy " + j + " failed.");
1903 success = false;
1904 }
1905
1906 if ((++j % modCount) == 0){ logger.info("TaxonHierarchies handled: " + j);}
1907
1908 }
1909
1910 }
1911 }
1912
1913
1914 // imports the <GeographicAreas> block
1915 protected void importGeographicAreas(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig) {
1916 Element elGeographicAreas = elDataset.getChild("GeographicAreas",sddNamespace);
1917 if (elGeographicAreas != null) {
1918 List<Element> listGeographicAreas = elGeographicAreas.getChildren("GeographicArea", sddNamespace);
1919 int j = 0;
1920
1921 for (Element elGeographicArea : listGeographicAreas){
1922
1923 String id = elGeographicArea.getAttributeValue("id");
1924 NamedArea na = new NamedArea();
1925 importRepresentation(elGeographicArea, sddNamespace, na, id, sddConfig);
1926 namedAreas.put(id,na);
1927 }
1928 if ((++j % modCount) == 0){ logger.info("GeographicAreas handled: " + j);}
1929 }
1930 }
1931 }