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