View Javadoc

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