Project

General

Profile

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

    
10
package eu.etaxonomy.cdm.io.sdd.in;
11

    
12
import java.io.File;
13
import java.net.MalformedURLException;
14
import java.net.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.List;
21
import java.util.Map;
22
import java.util.Set;
23

    
24
import org.apache.commons.lang.StringUtils;
25
import org.apache.log4j.Logger;
26
import org.jdom.Element;
27
import org.jdom.Namespace;
28
import org.joda.time.DateTime;
29
import org.springframework.stereotype.Component;
30
import org.springframework.transaction.TransactionStatus;
31

    
32
import eu.etaxonomy.cdm.api.service.IDescriptionService;
33
import eu.etaxonomy.cdm.common.mediaMetaData.ImageMetaData;
34
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
35
import eu.etaxonomy.cdm.io.common.CdmImportBase;
36
import eu.etaxonomy.cdm.io.common.ICdmImport;
37
import eu.etaxonomy.cdm.io.common.IImportConfigurator;
38
import eu.etaxonomy.cdm.io.common.ImportHelper;
39
import eu.etaxonomy.cdm.io.sdd.SDDTransformer;
40
import eu.etaxonomy.cdm.model.agent.Person;
41
import eu.etaxonomy.cdm.model.agent.Team;
42
import eu.etaxonomy.cdm.model.common.Annotation;
43
import eu.etaxonomy.cdm.model.common.AnnotationType;
44
import eu.etaxonomy.cdm.model.common.CdmBase;
45
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
46
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
47
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
48
import eu.etaxonomy.cdm.model.common.Language;
49
import eu.etaxonomy.cdm.model.common.LanguageString;
50
import eu.etaxonomy.cdm.model.common.Marker;
51
import eu.etaxonomy.cdm.model.common.MarkerType;
52
import eu.etaxonomy.cdm.model.common.Representation;
53
import eu.etaxonomy.cdm.model.common.TermBase;
54
import eu.etaxonomy.cdm.model.common.TermVocabulary;
55
import eu.etaxonomy.cdm.model.common.VersionableEntity;
56
import eu.etaxonomy.cdm.model.description.CategoricalData;
57
import eu.etaxonomy.cdm.model.description.Feature;
58
import eu.etaxonomy.cdm.model.description.FeatureNode;
59
import eu.etaxonomy.cdm.model.description.FeatureTree;
60
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
61
import eu.etaxonomy.cdm.model.description.Modifier;
62
import eu.etaxonomy.cdm.model.description.QuantitativeData;
63
import eu.etaxonomy.cdm.model.description.State;
64
import eu.etaxonomy.cdm.model.description.StateData;
65
import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
66
import eu.etaxonomy.cdm.model.description.StatisticalMeasurementValue;
67
import eu.etaxonomy.cdm.model.description.TaxonDescription;
68
import eu.etaxonomy.cdm.model.description.TextData;
69
import eu.etaxonomy.cdm.model.location.NamedArea;
70
import eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity;
71
import eu.etaxonomy.cdm.model.media.ImageFile;
72
import eu.etaxonomy.cdm.model.media.Media;
73
import eu.etaxonomy.cdm.model.media.MediaRepresentation;
74
import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
75
import eu.etaxonomy.cdm.model.media.Rights;
76
import eu.etaxonomy.cdm.model.name.NonViralName;
77
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
78
import eu.etaxonomy.cdm.model.occurrence.Specimen;
79
import eu.etaxonomy.cdm.model.reference.ReferenceBase;
80
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
81
import eu.etaxonomy.cdm.model.taxon.Synonym;
82
import eu.etaxonomy.cdm.model.taxon.Taxon;
83
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
84
import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;
85

    
86
/**
87
 * @author h.fradin
88
 * @created 24.10.2008
89
 * @version 1.0
90
 */
91
@Component("sddImport")
92
public class SDDImport extends CdmImportBase<SDDImportConfigurator, SDDImportState> implements ICdmImport<SDDImportConfigurator, SDDImportState> {
93
	private static final Logger logger = Logger.getLogger(SDDImport.class);
94

    
95
	private static int modCount = 1000;
96

    
97
	private Map<String,Person> authors = new HashMap<String,Person>();
98
	private Map<String,String> citations = new HashMap<String,String>();
99
	private Map<String,String> defaultUnitPrefixes = new HashMap<String,String>();
100
	private Map<String,Person> editors = new HashMap<String,Person>();
101
	private Map<String,FeatureNode> featureNodes = new HashMap<String,FeatureNode>();
102
	private Map<String,Feature> features = new HashMap<String,Feature>();
103
	private Map<String,String> locations = new HashMap<String,String>();
104
	private Map<String,List<CdmBase>> mediaObject_ListCdmBase = new HashMap<String,List<CdmBase>>();
105
	private Map<String,String> mediaObject_Role = new HashMap<String,String>();
106
	private Map<String,ReferenceBase> publications = new HashMap<String,ReferenceBase>();
107
	private Map<String,State> states = new HashMap<String,State>();
108
	private Map<String,TaxonDescription> taxonDescriptions = new HashMap<String,TaxonDescription>();
109
	private Map<String,NonViralName> taxonNameBases = new HashMap<String,NonViralName>();
110
	private Map<String,MeasurementUnit> units = new HashMap<String,MeasurementUnit>();
111
	private Map<String,TaxonNode> taxonNodes = new HashMap<String,TaxonNode>();
112
	private Map<String,NamedArea> namedAreas = new HashMap<String,NamedArea>();
113
	private Map<String,Specimen> specimens = new HashMap<String,Specimen>();
114
	private Map<String,Modifier> modifiers = new HashMap<String,Modifier>();
115
	
116
	private Set<MarkerType> markerTypes = new HashSet<MarkerType>();
117

    
118
	private Set<Feature> descriptiveConcepts = new HashSet<Feature>();
119
	private Set<AnnotationType> annotationTypes = new HashSet<AnnotationType>();
120
	private Set<Feature> featureSet = new HashSet<Feature>();
121
	private ReferenceBase sec = ReferenceFactory.newDatabase();
122
	private ReferenceBase sourceReference = null;
123

    
124
	private Language datasetLanguage = null;
125

    
126
	private Namespace xmlNamespace = Namespace.getNamespace("xml","http://www.w3.org/XML/1998/namespace");
127

    
128
	private String generatorName = "";
129
	private String generatorVersion = "";
130

    
131
	private Set<StatisticalMeasure> statisticalMeasures = new HashSet<StatisticalMeasure>();
132
	private Set<VersionableEntity> featureData = new HashSet<VersionableEntity>();
133
	private Set<FeatureTree> featureTrees = new HashSet<FeatureTree>();
134
	private Set<TaxonomicTree> taxonomicTrees = new HashSet<TaxonomicTree>();
135

    
136
	private Rights copyright = null;
137

    
138
	private int taxonNamesCount = 0; //XIM ajout
139
	
140
	public SDDImport(){
141
		super();
142
	}
143

    
144
	@Override
145
	public boolean doCheck(SDDImportState state){
146
		boolean result = true;
147
		logger.warn("No check implemented for SDD");
148
		return result;
149
	}
150

    
151
	//	@Override
152
	//	public boolean doInvoke(IImportConfigurator config, Map<String, MapWrapper<? extends CdmBase>> stores){
153
	@Override
154
	public boolean doInvoke(SDDImportState state){
155
		boolean success = true;
156
		
157
		TransactionStatus ts = startTransaction();
158
		SDDImportConfigurator sddConfig = state.getConfig();
159

    
160
		logger.info("start Datasets ...");
161
		// <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">
162
		Element root = sddConfig.getSourceRoot();
163
		Namespace sddNamespace = sddConfig.getSddNamespace();
164

    
165
		logger.info("start TechnicalMetadata ...");
166
		// <TechnicalMetadata created="2006-04-20T10:00:00">
167
		importTechnicalMetadata(root, sddNamespace, sddConfig);
168
		List<Element> elDatasets = root.getChildren("Dataset",sddNamespace);
169
		int i = 0;
170

    
171
		//for each Dataset
172
		logger.info("start Dataset ...");
173
		for (Element elDataset : elDatasets){
174
			success &= importDataset(elDataset, sddNamespace, state);			
175
			if ((++i % modCount) == 0){ logger.info("Datasets handled: " + i);}
176
			logger.info(i + " Datasets handled");
177
		}
178
		commitTransaction(ts);
179
		return success;
180
	}
181

    
182
	/* (non-Javadoc)
183
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
184
	 */
185
	protected boolean isIgnore(SDDImportState state){
186
		return false;
187
	}
188

    
189

    
190
	// associates the reference of a media object in SDD with a CdmBase Object
191
	protected void associateImageWithCdmBase(String refMO, CdmBase cb){
192
		if ((refMO != null) && (cb!=null)) {
193
			if (! refMO.equals("")) {
194
				if (! mediaObject_ListCdmBase.containsKey(refMO)) {
195
					List<CdmBase> lcb = new ArrayList<CdmBase>();
196
					lcb.add(cb);
197
					mediaObject_ListCdmBase.put(refMO,lcb);
198
				} else {
199
					List<CdmBase> lcb = mediaObject_ListCdmBase.get(refMO);
200
					lcb.add(cb);
201
					mediaObject_ListCdmBase.put(refMO,lcb);
202
				}
203
			}
204
		}
205
	}
206

    
207
	// imports information about the Dataset
208
	protected void importDatasetRepresentation(Element parent, Namespace sddNamespace){
209
		logger.info("start Representation ...");
210
		/* <Representation>
211
			<Label>The Genus Viola</Label>
212
			<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>
213
	       </Representation>
214
		 */
215
		Element elRepresentation = parent.getChild("Representation",sddNamespace);
216
		String label = (String)ImportHelper.getXmlInputValue(elRepresentation, "Label",sddNamespace);
217
		String detail = (String)ImportHelper.getXmlInputValue(elRepresentation, "Detail",sddNamespace);
218

    
219
		sec.setTitleCache(label, true);
220

    
221
		if (detail != null) {
222
			Annotation annotation = Annotation.NewInstance(detail, datasetLanguage);
223
			annotation.setAnnotationType(AnnotationType.EDITORIAL());
224
			sec.addAnnotation(annotation);
225
		}
226

    
227
		List<Element> listMediaObjects = elRepresentation.getChildren("MediaObject",sddNamespace);
228

    
229
		for (Element elMediaObject : listMediaObjects) {
230
			String ref = null;
231
			String role = null;
232
			if (elMediaObject != null) {
233
				ref = elMediaObject.getAttributeValue("ref");
234
				role = elMediaObject.getAttributeValue("role");
235
			}
236
			if (ref != null) {
237
				if (!ref.equals("")) {
238
					this.associateImageWithCdmBase(ref,sourceReference);
239
					this.associateImageWithCdmBase(ref,sec);
240
					mediaObject_Role.put(ref,role);
241
				}
242
			}
243
		}
244
	}
245

    
246
	// imports the representation (label, detail, lang) of a particular SDD element
247
	protected void importRepresentation(Element parent, Namespace sddNamespace, VersionableEntity ve, String id, IImportConfigurator config){
248
		Element elRepresentation = parent.getChild("Representation",sddNamespace);
249
		
250
		Map<Language,List<String>> langLabDet = new HashMap<Language,List<String>>();
251

    
252
		handleRepresentationLabels(sddNamespace, elRepresentation, langLabDet);
253
		handleRepresentationDetails(sddNamespace, elRepresentation, langLabDet);
254

    
255
		if (ve instanceof TermBase) {
256
			makeRepresentationForTerms((TermBase)ve, langLabDet);
257
		}else if (ve instanceof Media) {
258
			makeRepresentationForMedia((Media)ve, langLabDet);
259
		}else if (ve instanceof IdentifiableEntity<?>) {
260
			IdentifiableEntity<?> ie = (IdentifiableEntity<?>)ve;
261
			makeRepresentationForIdentifiableEntity(sddNamespace, ie, elRepresentation, langLabDet);
262
			if (ve instanceof IdentifiableMediaEntity<?>){
263
				makeRepresentationForIdentifiableMediaEntity(parent, sddNamespace, (IdentifiableMediaEntity<?>)ve);
264
			}
265
		}
266

    
267
		makeRepresentationMediaObjects(sddNamespace, ve, elRepresentation);
268

    
269
	}
270

    
271

    
272
	/**
273
	 * Handles the "Detail" children of representations. Adds the result to the langLabDet.
274
	 * @param sddNamespace
275
	 * @param elRepresentation
276
	 * @param langLabDet
277
	 */
278
	private void handleRepresentationDetails(Namespace sddNamespace,
279
			Element elRepresentation, Map<Language, List<String>> langLabDet) {
280
		List<Element> listDetails = elRepresentation.getChildren("Detail",sddNamespace);
281
		for (Element elDetail : listDetails){
282
			Language language = getLanguage(elDetail);
283
			String role = elDetail.getAttributeValue("role");
284
			String detail = elDetail.getText();
285
			List<String> labDet = langLabDet.get(language);
286
			labDet.add(detail);
287
			labDet.add(role);
288
			langLabDet.put(language, labDet);
289
		}
290
	}
291

    
292
	/**
293
	 * Handles the "Label" children of representations. Adds the result to the langLabDet.
294
	 * @param sddNamespace
295
	 * @param elRepresentation
296
	 * @param langLabDet
297
	 */
298
	private void handleRepresentationLabels(Namespace sddNamespace,
299
				Element elRepresentation, Map<Language, List<String>> langLabDet) {
300
		// <Label xml:lang="la">Viola hederacea Labill.</Label>
301
		List<Element> listLabels = elRepresentation.getChildren("Label",sddNamespace);
302
		for (Element elLabel : listLabels){
303
			Language language = getLanguage(elLabel);
304
			String label = elLabel.getText();
305
			List<String> labDet = new ArrayList<String>(3);
306
			labDet.add(label);
307
			langLabDet.put(language, labDet);
308
		}
309
	}
310
	
311
	/**
312
	 * 
313
	 * @param ve
314
	 * @param langLabDet
315
	 */
316
	private void makeRepresentationForMedia(Media m, Map<Language, List<String>> langLabDet) {
317
		for (Language lang : langLabDet.keySet()){
318
			List<String> labDet = langLabDet.get(lang);
319
			if (labDet.get(0) != null){
320
				m.addTitle(LanguageString.NewInstance(labDet.get(0), lang));
321
			}
322
			if (labDet.size()>1) {
323
				m.addDescription(labDet.get(1), lang);
324
			}
325
		}
326
	}
327

    
328
	/**
329
	 * Handles representations for terms. Adds one representation per language in langLabDet.
330
	 * 
331
	 * @param ve
332
	 * @param langLabDet
333
	 */
334
	private void makeRepresentationForTerms(TermBase tb, Map<Language, List<String>> langLabDet) {
335
			for (Language lang : langLabDet.keySet()){
336
				List<String> labDet = langLabDet.get(lang);
337
				if (labDet.size()>0){
338
					if (labDet.size()>1) {
339
						tb.addRepresentation(Representation.NewInstance(labDet.get(1), labDet.get(0), labDet.get(0), lang));
340
					} else {
341
						tb.addRepresentation(Representation.NewInstance(labDet.get(0), labDet.get(0), labDet.get(0), lang));
342
					}
343
				}
344
			}
345
	}
346

    
347

    
348
	/**
349
	 * Handles the "MediaObject" children of representations.
350
	 * @param sddNamespace
351
	 * @param ve
352
	 * @param elRepresentation
353
	 */
354
	private void makeRepresentationMediaObjects(Namespace sddNamespace,
355
			VersionableEntity ve, Element elRepresentation) {
356
		List <Element> listMediaObjects = elRepresentation.getChildren("MediaObject", sddNamespace);
357
		for (Element elMediaObject : listMediaObjects) {
358
			String ref = null;
359
			//TODO
360
			String role = null;
361
			if (elMediaObject != null) {
362
				ref = elMediaObject.getAttributeValue("ref");
363
				role = elMediaObject.getAttributeValue("role");
364
			}
365
			if (StringUtils.isNotBlank(ref)) {
366
				if (ve instanceof TaxonDescription) {
367
					TaxonDescription td = (TaxonDescription) ve;
368
					//TODO: ensure that all images are imported
369
					if (td.getDescriptionSources().size() > 0) {
370
						this.associateImageWithCdmBase(ref,(ReferenceBase) td.getDescriptionSources().toArray()[0]);
371
					} else {
372
						ReferenceBase descriptionSource = ReferenceFactory.newGeneric();
373
						td.addDescriptionSource(descriptionSource);
374
						this.associateImageWithCdmBase(ref,descriptionSource);
375
					}
376
				} else {
377
					this.associateImageWithCdmBase(ref,ve);
378
				}
379
			}
380
		}
381
	}
382

    
383
	/**
384
	 * Handles the "Links" element
385
	 * @param parent
386
	 * @param sddNamespace
387
	 * @param ve
388
	 */
389
	private void makeRepresentationForIdentifiableMediaEntity(Element parent,
390
			Namespace sddNamespace, IdentifiableMediaEntity ime) {
391
		Element elLinks = parent.getChild("Links",sddNamespace);
392

    
393
		if (elLinks != null) {
394

    
395
			//  <Link rel="Alternate" href="http://www.diversitycampus.net/people/hagedorn"/>
396
			List<Element> listLinks = elLinks.getChildren("Link", sddNamespace);
397
			Media link = Media.NewInstance();
398
			MediaRepresentation mr = MediaRepresentation.NewInstance();
399
			int k = 0;
400
			//for each Link
401
			for (Element elLink : listLinks){
402

    
403
				try {
404
					//TODO
405
					String rel = elLink.getAttributeValue("rel");
406
					String href = elLink.getAttributeValue("href");
407

    
408
					mr.addRepresentationPart(MediaRepresentationPart.NewInstance(href, null));
409
					link.addRepresentation(mr);
410
					ime.addMedia(link);
411

    
412
				} catch (Exception e) {
413
					//FIXME
414
					logger.warn("Import of Link " + k + " failed.");
415
				}
416

    
417
				if ((++k % modCount) == 0){ logger.info("Links handled: " + k);}
418

    
419
			}
420
		}
421
	}
422

    
423
	/**
424
	 * @param sddNamespace
425
	 * @param ve
426
	 * @param elRepresentation
427
	 * @param langLabDet
428
	 * @return
429
	 */
430
	private void makeRepresentationForIdentifiableEntity(Namespace sddNamespace, IdentifiableEntity<?> ie, 
431
					Element elRepresentation, Map<Language, List<String>> langLabDet) {
432
		List<String> labDet = null;
433

    
434
		if (ie instanceof TaxonNameBase) {
435
			if (langLabDet.keySet().contains(getTermService().getLanguageByIso("la"))) {
436
				labDet = langLabDet.get(getTermService().getLanguageByIso("la"));
437
			} else if (langLabDet.keySet().contains(datasetLanguage)) {
438
				labDet = langLabDet.get(datasetLanguage);
439
				logger.info("TaxonName " + (String)ImportHelper.getXmlInputValue(elRepresentation, "Label",sddNamespace) + " is not specified as a latin name.");
440
			} else {
441
				labDet = langLabDet.get(langLabDet.keySet().iterator().next());
442
				logger.info("TaxonName " + (String)ImportHelper.getXmlInputValue(elRepresentation, "Label",sddNamespace) + " is not specified as a latin name.");
443
			}
444
		} else {
445
			labDet = langLabDet.get(langLabDet.keySet().iterator().next());
446
		}
447

    
448
		//FIXME labDet is != null only for TaxonNameBase
449
		ie.setTitleCache(labDet.get(0), true);
450

    
451
		if (labDet.size()>1) {
452
			Annotation annotation = null;
453
			if (labDet.get(1) != null) {
454
				if (labDet.get(2) != null) {
455
					annotation = Annotation.NewInstance(labDet.get(2) + " - " + labDet.get(1), datasetLanguage);
456
				} else {
457
					annotation = Annotation.NewInstance(labDet.get(1), datasetLanguage);
458
				}
459
			}
460
			ie.addAnnotation(annotation);
461
		}
462
		return;
463
	}
464

    
465
	/**
466
	 * @param elLabel
467
	 * @return
468
	 */
469
	private Language getLanguage(Element elLanguage) {
470
		String lang = elLanguage.getAttributeValue("lang",xmlNamespace);
471
		Language language = null;
472
		if (StringUtils.isNotBlank(lang)) {
473
			language = getTermService().getLanguageByIso(lang.substring(0, 2));
474
		} else {
475
			language = datasetLanguage;
476
		}
477
		return language;
478
	}
479
	
480

    
481
	// imports the representation (label, detail, lang) of a particular SDD element
482
	protected void importTechnicalMetadata(Element root, Namespace sddNamespace, SDDImportConfigurator sddConfig){
483
		Element elTechnicalMetadata = root.getChild("TechnicalMetadata", sddNamespace);
484
		String nameCreated = elTechnicalMetadata.getAttributeValue("created");
485
		sourceReference = sddConfig.getSourceReference();
486

    
487
		if (nameCreated != null) {
488
			if (!nameCreated.equals("")) {
489
				int year = Integer.parseInt(nameCreated.substring(0,4));
490
				int monthOfYear = Integer.parseInt(nameCreated.substring(5,7));
491
				int dayOfMonth = Integer.parseInt(nameCreated.substring(8,10));
492
				int hourOfDay = Integer.parseInt(nameCreated.substring(11,13));
493
				int minuteOfHour = Integer.parseInt(nameCreated.substring(14,16));
494
				int secondOfMinute = Integer.parseInt(nameCreated.substring(17,19));
495
				DateTime created = new DateTime(year,monthOfYear,dayOfMonth,hourOfDay,minuteOfHour,secondOfMinute,0);
496
				sourceReference.setCreated(created);
497
				sec.setCreated(created);
498
			}
499
		}
500

    
501
		// <Generator name="n/a, handcrafted instance document" version="n/a"/>
502
		Element elGenerator = elTechnicalMetadata.getChild("Generator", sddNamespace);
503
		generatorName = elGenerator.getAttributeValue("name");
504
		generatorVersion = elGenerator.getAttributeValue("version");
505

    
506
		sec.addAnnotation(Annotation.NewDefaultLanguageInstance(generatorName + " - " + generatorVersion));
507
		sourceReference.addAnnotation(Annotation.NewDefaultLanguageInstance(generatorName + " - " + generatorVersion));
508

    
509
	}
510

    
511
	// imports the complete dataset information
512
	protected boolean importDataset(Element elDataset, Namespace sddNamespace, SDDImportState state){			// <Dataset xml:lang="en-us">
513
		boolean success = true;
514
		SDDImportConfigurator sddConfig = state.getConfig();
515
		importDatasetLanguage(elDataset,sddConfig);
516
		importDatasetRepresentation(elDataset, sddNamespace);
517
		importRevisionData(elDataset, sddNamespace);
518
		importIPRStatements(elDataset, sddNamespace, sddConfig);
519
		importTaxonNames(elDataset, sddNamespace, sddConfig);
520
		importDescriptiveConcepts(elDataset, sddNamespace, sddConfig);
521
		success &= importCharacters(elDataset, sddNamespace, sddConfig);
522
		importCharacterTrees(elDataset, sddNamespace, sddConfig, success);
523
		
524
		MarkerType editorMarkerType = getMarkerType(state, SDDTransformer.uuidMarkerEditor, "editor", "Editor", "edt");
525
		MarkerType geographicAreaMarkerType = getMarkerType(state, SDDTransformer.uuidMarkerSDDGeographicArea, "SDDGeographicArea", "SDDGeographicArea", "ga"); 
526
		MarkerType descriptiveConceptMarkerType = getMarkerType(state, SDDTransformer.uuidMarkerDescriptiveConcept, "DescriptiveConcept", "Descriptive Concept", "DC");
527
		markerTypes.add(editorMarkerType);
528
		markerTypes.add(geographicAreaMarkerType);
529
		markerTypes.add(descriptiveConceptMarkerType);
530

    
531
		//saving of all imported data into the CDM db
532
		saveFeatures();
533
		saveModifiers();
534
		saveStates();
535
		saveMarkerType();
536
		saveAreas(geographicAreaMarkerType);		
537
		saveUnits();
538
		saveStatisticalMeasure();		
539
		saveAnnotationType();
540
		
541
		success &= importCodedDescriptions(elDataset, sddNamespace, sddConfig);
542
		importAgents(elDataset, sddNamespace, sddConfig, success);
543
		importPublications(elDataset, sddNamespace, sddConfig, success);
544
		importMediaObjects(elDataset, sddNamespace, sddConfig, success);
545
		importTaxonHierarchies(elDataset, sddNamespace, sddConfig, success);
546
		importGeographicAreas(elDataset, sddNamespace, sddConfig);
547
		importSpecimens(elDataset,sddNamespace, sddConfig);
548
			
549
		
550
		
551
		if ((authors != null)||(editors != null)) {
552
			Team team = Team.NewInstance();
553
			if (authors != null) {
554
				for (Person author : authors.values()){
555
					team.addTeamMember(author);
556
				}
557
			}
558
			if (editors != null) {
559
				Marker marker = Marker.NewInstance();
560
				marker.setMarkerType(editorMarkerType);
561
				for (Person editor : editors.values()){
562
					Person edit = editor;
563
					edit.addMarker(marker);
564
					team.addTeamMember(edit);
565
				}
566
				}
567
			sec.setAuthorTeam(team);
568
			sourceReference.setAuthorTeam(team);
569
		}
570

    
571
		if (copyright != null) {
572
			sourceReference.addRights(copyright);
573
			sec.addRights(copyright);
574
		}
575
		
576
		// Returns a CdmApplicationController created by the values of this configuration.
577
		IDescriptionService descriptionService = getDescriptionService();
578

    
579
		for (TaxonDescription taxonDescription : taxonDescriptions.values()){
580
			// Persists a Description
581
			descriptionService.save(taxonDescription);
582
		}
583
		
584
		for (String ref : taxonDescriptions.keySet()){
585
			TaxonDescription td = taxonDescriptions.get(ref);
586
			if (citations.containsKey(ref)) {
587
				ReferenceBase publication = publications.get(citations.get(ref));
588
				if (locations.containsKey(ref)) {
589
					Annotation location = Annotation.NewInstance(locations.get(ref), datasetLanguage);
590
					AnnotationType annotationType = AnnotationType.NewInstance("", "location", "");
591
					annotationTypes.add(annotationType);
592
					location.setAnnotationType(annotationType);
593
					(publication).addAnnotation(location);
594
				}
595
				td.addDescriptionSource(publication);
596
			}
597
		}
598
		logger.info("end makeTaxonDescriptions ...");
599
		
600
		
601
//		for (Iterator<TermVocabulary<Modifier>> k = termVocabularyStates.iterator() ; k.hasNext() ;){
602
//			TermVocabulary<Modifier> termVocabulary = k.next();
603
//			getVocabularyService().save(termVocabulary); //XIM
604
//		}
605
		
606

    
607
		//sddConfig.setSourceReference(sourceReference);
608

    
609

    
610
		if (descriptiveConcepts != null) {
611
			for (Feature feature : descriptiveConcepts) {
612
				Marker marker = Marker.NewInstance();
613
				marker.setMarkerType(descriptiveConceptMarkerType);
614
				feature.addMarker(marker);
615
			}
616
		}
617
		saveFeatures();
618
		
619
		/*Marker markerd = Marker.NewInstance();
620
		markerd.setMarkerType(descriptiveConceptMarker);
621
		Feature fiture = Feature.NewInstance("Fitoure","Fitoure","Fitoure");
622
		fiture.addMarker(markerd);
623
		TermVocabulary<Modifier> termVocabularyState = new TermVocabulary<Modifier>("test","test","test","test");
624
		Modifier modif = new Modifier("zoub","zab","zib");
625
		termVocabularyState.addTerm(modif);
626
		getVocabularyService().save(termVocabularyState);
627
		fiture.addRecommendedModifierEnumeration(termVocabularyState);
628
		termService.save(modif);
629
		termService.save(fiture);*/
630
	
631
		//XIMtermService.save(editorMarkerType);
632
		
633
		//XIMtermService.save(geographicAreaMarkerType);
634

    
635
		// referenceService.saveReference(sourceReference); 
636
		for (ReferenceBase publication : publications.values()){
637
			getReferenceService().save(publication); 
638
		}
639

    
640
		for (FeatureTree featureTree : featureTrees) {
641
			getFeatureTreeService().save(featureTree);
642
		}
643
		for (TaxonomicTree taxonomicTree : taxonomicTrees) {
644
			getTaxonTreeService().save(taxonomicTree);
645
		}
646
		for (Specimen specimen : specimens.values()) {
647
			getOccurrenceService().save(specimen);
648
		}
649
		logger.info("end of persistence ...");
650
		
651
		return success;
652
	}
653

    
654
	private void saveAnnotationType() {
655
		for (AnnotationType annotationType: annotationTypes){
656
			getTermService().save(annotationType); 
657
		}
658
	}
659

    
660
	private void saveStatisticalMeasure() {
661
		for (StatisticalMeasure sm : statisticalMeasures){
662
			getTermService().save(sm); 
663
		}
664
	}
665

    
666
	private void saveUnits() {
667
		if (units != null) {
668
			for (MeasurementUnit unit : units.values()){
669
				if (unit != null) {
670
					getTermService().save(unit); 
671
				}
672
			}
673
		}
674
	}
675

    
676
	private void saveAreas(MarkerType geographicAreaMarkerType) {
677
		for (NamedArea area : namedAreas.values() ){
678
			Marker marker = Marker.NewInstance();
679
			marker.setMarkerType(geographicAreaMarkerType);
680
			area.addMarker(marker);
681
			getTermService().save(area);
682
		}
683
	}
684

    
685
	private void saveStates() {
686
		for (State state : states.values() ){
687
			getTermService().save(state);
688
		}
689
	}
690

    
691
	private void saveMarkerType() {
692
		for (MarkerType markerType : markerTypes){
693
			getTermService().save(markerType);
694
		}
695
	}
696

    
697
	private void saveModifiers() {
698
		for (Modifier modifier : modifiers.values() ){
699
			getTermService().save(modifier);
700
		}
701
	}
702

    
703
	private void saveFeatures() {
704
		for (Feature feature : features.values() ){
705
			getTermService().save(feature);
706
		}
707
	}
708

    
709
	// imports the default language of the dataset
710
	protected void importDatasetLanguage(Element elDataset, SDDImportConfigurator sddConfig){
711
		String nameLang = elDataset.getAttributeValue("lang",xmlNamespace);
712

    
713
		if (!nameLang.equals("")) {
714
			String iso = nameLang.substring(0, 2);
715
			datasetLanguage = getTermService().getLanguageByIso(iso);
716
		} else {
717
			datasetLanguage = Language.DEFAULT();
718
		}
719
		if (datasetLanguage == null) {
720
			datasetLanguage = Language.DEFAULT();
721
		}
722
	}
723
	
724
	// imports the specimens
725
	protected void importSpecimens(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig) {
726
		logger.info("start Specimens ...");
727
		/*	<Specimens>
728
        		<Specimen id="sp1">
729
           			<Representation>
730
              			<Label>TJM45337</Label>
731
           			</Representation>
732
        		</Specimen>
733
     		</Specimens>
734
		 */
735
		Element elSpecimens = elDataset.getChild("Specimens",sddNamespace);
736
		if (elSpecimens != null){
737
			List<Element> listSpecimens = elSpecimens.getChildren("Specimen", sddNamespace);
738
			int j = 0;
739
			for (Element elSpecimen : listSpecimens) {
740
				String id = elSpecimen.getAttributeValue("id");
741
				Specimen specimen = null;
742
				if (!id.equals("")) {
743
					specimen = Specimen.NewInstance();
744
					specimens.put(id,specimen);
745
					importRepresentation(elSpecimen, sddNamespace, specimen, id, sddConfig);
746
				}
747
			}
748

    
749
		}
750
	}
751

    
752
	// imports the revision data associated with the Dataset (authors, modifications)
753
	protected void importRevisionData(Element elDataset, Namespace sddNamespace){
754
		// <RevisionData>
755
		logger.info("start RevisionData ...");
756
		Element elRevisionData = elDataset.getChild("RevisionData",sddNamespace);
757
		if (elRevisionData != null){
758
			// <Creators>
759
			Element elCreators = elRevisionData.getChild("Creators",sddNamespace);
760

    
761
			// <Agent role="aut" ref="a1"/>
762
			List<Element> listAgents = elCreators.getChildren("Agent", sddNamespace);
763

    
764
			int j = 0;
765
			//for each Agent
766
			for (Element elAgent : listAgents){
767

    
768
				String role = elAgent.getAttributeValue("role");
769
				String ref = elAgent.getAttributeValue("ref");
770
				if (role.equals("aut")) {
771
					if(!ref.equals("")) {
772
						authors.put(ref, null);
773
					}
774
				}
775
				if (role.equals("edt")) {
776
					if(!ref.equals("")) {
777
						editors.put(ref, null);
778
					}
779
				}
780
				if ((++j % modCount) == 0){ logger.info("Agents handled: " + j);}
781

    
782
			}
783

    
784
			// <DateModified>2006-04-08T00:00:00</DateModified>
785
			String stringDateModified = (String)ImportHelper.getXmlInputValue(elRevisionData, "DateModified",sddNamespace);
786

    
787
			if (stringDateModified != null) {
788
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
789
				Date d = null;
790
				try {
791
					d = sdf.parse(stringDateModified);
792
				} catch(Exception e) {
793
					System.err.println("Exception :");
794
					e.printStackTrace();
795
				}
796

    
797
				DateTime updated = null;
798
				if (d != null) {
799
					updated = new DateTime(d);
800
					sourceReference.setUpdated(updated);
801
					sec.setUpdated(updated);
802
				}
803
			}
804
		}
805
	}
806

    
807
	// imports ipr statements associated with a dataset
808
	protected void importIPRStatements(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig){
809
		// <IPRStatements>
810
		logger.info("start IPRStatements ...");
811
		Element elIPRStatements = elDataset.getChild("IPRStatements",sddNamespace);
812
		// <IPRStatement role="Copyright">
813
		if (elIPRStatements != null) {
814
			List<Element> listIPRStatements = elIPRStatements.getChildren("IPRStatement", sddNamespace);
815
			int j = 0;
816
			//for each IPRStatement
817

    
818
			for (Element elIPRStatement : listIPRStatements){
819

    
820
				String role = elIPRStatement.getAttributeValue("role");
821
				// <Label xml:lang="en-au">(c) 2003-2006 Centre for Occasional Botany.</Label>
822
				Element elLabel = elIPRStatement.getChild("Label",sddNamespace);
823
				String lang = "";
824
				if (elLabel != null) {
825
					lang = elLabel.getAttributeValue("lang",xmlNamespace);
826
				}
827
				String label = (String)ImportHelper.getXmlInputValue(elIPRStatement, "Label",sddNamespace);
828

    
829
				if (role.equals("Copyright")) {
830
					Language iprLanguage = null;
831
					if (lang != null) {
832
						if (!lang.equals("")) {
833
							iprLanguage = getTermService().getLanguageByIso(lang.substring(0, 2));
834
						} else {
835
							iprLanguage = datasetLanguage;
836
						}
837
					}
838
					if (iprLanguage == null) {
839
						iprLanguage = datasetLanguage;
840
					}
841
					copyright = Rights.NewInstance(label, iprLanguage);
842
				}
843

    
844
				if (copyright != null) {
845
					sourceReference.addRights(copyright);
846
					sec.addRights(copyright);
847
				}
848

    
849
				if ((++j % modCount) == 0){ logger.info("IPRStatements handled: " + j);}
850

    
851
			}
852
		}
853
	}
854

    
855
	// imports the taxon names
856
	protected void importTaxonNames(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig){
857
		// <TaxonNames>
858
		logger.info("start TaxonNames ...");
859
		Element elTaxonNames = elDataset.getChild("TaxonNames",sddNamespace);
860
		// <TaxonName id="t1" uri="urn:lsid:authority:namespace:my-own-id">
861
		if (elTaxonNames != null) {
862
			List<Element> listTaxonNames = elTaxonNames.getChildren("TaxonName", sddNamespace);
863
			int j = 0;
864
			//for each TaxonName
865
			for (Element elTaxonName : listTaxonNames){
866

    
867
				String id = elTaxonName.getAttributeValue("id");
868
				String uri = elTaxonName.getAttributeValue("uri");
869

    
870
				NonViralName tnb = null;
871
				if (!id.equals("")) {
872
					tnb = NonViralName.NewInstance(null);
873
					IdentifiableSource source = null;
874
					if (uri != null) {
875
						if (!uri.equals("")) {
876
							source = IdentifiableSource.NewInstance(id, "TaxonName", ReferenceFactory.newGeneric(), uri);
877
						}
878
					} else {
879
						source = IdentifiableSource.NewInstance(id, "TaxonName");
880
					}
881
					tnb.addSource(source);
882
					taxonNameBases.put(id,tnb);
883
				}
884

    
885
				// <Representation>
886
				// <Label xml:lang="la">Viola hederacea Labill.</Label>
887
				importRepresentation(elTaxonName, sddNamespace, tnb, id, sddConfig);
888

    
889
				if ((++j % modCount) == 0){ logger.info("TaxonNames handled: " + j);}
890

    
891
			}
892
		}
893
	}
894

    
895
	// imports the characters (categorical, quantitative and text ; sequence characters not supported) which correspond to CDM Features
896
	protected boolean importCharacters(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig){
897
		boolean success = true;
898
		// <Characters>
899
		logger.info("start Characters ...");
900
		Element elCharacters = elDataset.getChild("Characters", sddNamespace);
901

    
902
		// <CategoricalCharacter id="c1">
903
		if (elCharacters != null) {
904
			success &= handleCategoricalData(sddNamespace, sddConfig, elCharacters);
905
			success &= handleQuantitativeData(sddNamespace, sddConfig, elCharacters);
906
			success &= handleTextCharacters(sddNamespace, sddConfig, elCharacters);
907
		}
908

    
909
		/*for (Iterator<Feature> f = features.values().iterator() ; f.hasNext() ;){
910
			featureSet.add(f.next()); //XIM Why this line ?
911
		}*/
912
		
913
		return success;
914

    
915
	}
916

    
917
	/**
918
	 * @param sddNamespace
919
	 * @param sddConfig
920
	 * @param success
921
	 * @param elCharacters
922
	 * @return
923
	 */
924
	private boolean handleCategoricalData(Namespace sddNamespace, SDDImportConfigurator sddConfig, Element elCharacters) {
925
		boolean success = true;
926
		List<Element> elCategoricalCharacters = elCharacters.getChildren("CategoricalCharacter", sddNamespace);
927
		int j = 0;
928
		for (Element elCategoricalCharacter : elCategoricalCharacters){
929
			try {
930

    
931
				String idCC = elCategoricalCharacter.getAttributeValue("id");
932
				Feature categoricalCharacter = Feature.NewInstance();
933
				categoricalCharacter.setKindOf(Feature.DESCRIPTION());
934
				importRepresentation(elCategoricalCharacter, sddNamespace, categoricalCharacter, idCC, sddConfig);
935
				categoricalCharacter.setSupportsCategoricalData(true);
936

    
937
				// <States>
938
				Element elStates = elCategoricalCharacter.getChild("States",sddNamespace);
939

    
940
				// <StateDefinition id="s1">
941
				List<Element> elStateDefinitions = elStates.getChildren("StateDefinition",sddNamespace);
942
				TermVocabulary<State> termVocabularyState = new TermVocabulary<State>();
943
				int k = 0;
944
				//for each StateDefinition
945
				for (Element elStateDefinition : elStateDefinitions){
946

    
947
					if ((++k % modCount) == 0){ logger.info("StateDefinitions handled: " + (k-1));}
948

    
949
					String idS = elStateDefinition.getAttributeValue("id");
950
					State state = states.get(idS);
951
					if (state == null){
952
						state = State.NewInstance();
953
					}else{
954
						logger.debug("State duplicate found");
955
					}
956
					importRepresentation(elStateDefinition, sddNamespace, state, idS, sddConfig);
957

    
958
					//StateData stateData = StateData.NewInstance();
959
					//stateData.setState(state);
960
					termVocabularyState.addTerm(state);
961
					states.put(idS,state);
962
				}
963
				categoricalCharacter.addSupportedCategoricalEnumeration(termVocabularyState);
964
				features.put(idCC, categoricalCharacter);
965

    
966
			} catch (Exception e) {
967
				logger.warn("Import of CategoricalCharacter " + j + " failed.");
968
				success = false; 
969
			}
970

    
971
			if ((++j % modCount) == 0){ logger.info("CategoricalCharacters handled: " + j);}
972

    
973
		}
974
		return success;
975
	}
976

    
977
	/**
978
	 * @param sddNamespace
979
	 * @param sddConfig
980
	 * @param elCharacters
981
	 */
982
	private boolean handleQuantitativeData(Namespace sddNamespace,	SDDImportConfigurator sddConfig, Element elCharacters) {
983
		boolean success = true;
984
		int j;
985
		// <QuantitativeCharacter id="c2">
986
		List<Element> elQuantitativeCharacters = elCharacters.getChildren("QuantitativeCharacter", sddNamespace);
987
		j = 0;
988
		//for each QuantitativeCharacter
989
		for (Element elQuantitativeCharacter : elQuantitativeCharacters){
990

    
991
			try {
992

    
993
				String idQC = elQuantitativeCharacter.getAttributeValue("id");
994

    
995
				// <Representation>
996
				//  <Label>Leaf length</Label>
997
				// </Representation>
998
				Feature quantitativeCharacter = Feature.NewInstance();
999
				quantitativeCharacter.setKindOf(Feature.DESCRIPTION());
1000
				importRepresentation(elQuantitativeCharacter, sddNamespace, quantitativeCharacter, idQC, sddConfig);
1001

    
1002
				quantitativeCharacter.setSupportsQuantitativeData(true);
1003

    
1004
				// <MeasurementUnit>
1005
				//  <Label role="Abbrev">m</Label>
1006
				// </MeasurementUnit>
1007
				Element elMeasurementUnit = elQuantitativeCharacter.getChild("MeasurementUnit",sddNamespace);
1008
				String label = "";
1009
				String role = "";
1010
				if (elMeasurementUnit != null) {
1011
					Element elLabel = elMeasurementUnit.getChild("Label",sddNamespace);
1012
					role = elLabel.getAttributeValue("role");
1013
					label = (String)ImportHelper.getXmlInputValue(elMeasurementUnit, "Label",sddNamespace);
1014
				}
1015

    
1016
				MeasurementUnit unit = null;
1017
				if (!label.equals("")){
1018
					if (role != null) {
1019
						if (role.equals("Abbrev")){
1020
							unit = MeasurementUnit.NewInstance(label,label,label);
1021
						}
1022
					} else {
1023
						unit = MeasurementUnit.NewInstance(label,label,label);
1024
					}
1025
				}
1026

    
1027
				if (unit != null) {
1028
					units.put(idQC, unit);
1029
				}
1030

    
1031
				//<Default>
1032
				//  <MeasurementUnitPrefix>milli</MeasurementUnitPrefix>
1033
				//</Default>
1034
				Element elDefault = elQuantitativeCharacter.getChild("Default",sddNamespace);
1035
				if (elDefault != null) {
1036
					String measurementUnitPrefix = (String)ImportHelper.getXmlInputValue(elDefault, "MeasurementUnitPrefix",sddNamespace);
1037
					if (! measurementUnitPrefix.equals("")){
1038
						defaultUnitPrefixes.put(idQC, measurementUnitPrefix);
1039
					}
1040
				}
1041

    
1042
				features.put(idQC, quantitativeCharacter);
1043

    
1044
			} catch (Exception e) {
1045
				//FIXME
1046
				logger.warn("Import of QuantitativeCharacter " + j + " failed.");
1047
				success = false; 
1048
			}
1049

    
1050
			if ((++j % modCount) == 0){ logger.info("QuantitativeCharacters handled: " + j);}
1051

    
1052
		}
1053
		return success;
1054
	}
1055

    
1056
	private boolean handleTextCharacters(Namespace sddNamespace, SDDImportConfigurator sddConfig, Element elCharacters) {
1057
		boolean success = true;
1058
		int j;
1059
		// <TextCharacter id="c3">
1060
		List<Element> elTextCharacters = elCharacters.getChildren("TextCharacter", sddNamespace);
1061
		j = 0;
1062
		//for each TextCharacter
1063
		for (Element elTextCharacter : elTextCharacters){
1064

    
1065
			try {
1066

    
1067
				String idTC = elTextCharacter.getAttributeValue("id");
1068

    
1069
				// <Representation>
1070
				//  <Label xml:lang="en">Leaf features not covered by other characters</Label>
1071
				// </Representation>
1072
				Feature textCharacter = Feature.NewInstance();
1073
				textCharacter.setKindOf(Feature.DESCRIPTION());
1074
				importRepresentation(elTextCharacter, sddNamespace, textCharacter, idTC, sddConfig);
1075

    
1076
				textCharacter.setSupportsTextData(true);
1077

    
1078
				features.put(idTC, textCharacter);
1079

    
1080
			} catch (Exception e) {
1081
				//FIXME
1082
				logger.warn("Import of TextCharacter " + j + " failed.");
1083
				success = false; 
1084
			}
1085

    
1086
			if ((++j % modCount) == 0){ logger.info("TextCharacters handled: " + j);}
1087

    
1088
		}
1089
		return success;
1090
	}
1091

    
1092
	// imports the descriptions of taxa
1093
	protected boolean importCodedDescriptions(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig){
1094
		boolean success = true;
1095
		
1096
		// <CodedDescriptions>
1097
		logger.info("start CodedDescriptions ...");
1098
		Element elCodedDescriptions = elDataset.getChild("CodedDescriptions",sddNamespace);
1099

    
1100
		// <CodedDescription id="D101">
1101
		if (elCodedDescriptions != null) {
1102
			List<Element> listCodedDescriptions = elCodedDescriptions.getChildren("CodedDescription", sddNamespace);
1103
			int j = 0;
1104
			//for each CodedDescription
1105
			for (Element elCodedDescription : listCodedDescriptions){
1106
				success &= handleCodedDescription(sddNamespace, sddConfig, elCodedDescription, j);
1107
				if ((++j % modCount) == 0){ logger.info("CodedDescriptions handled: " + j);}
1108
			}
1109
		}
1110
		return success;
1111
	}
1112

    
1113
	/**
1114
	 * @param sddNamespace
1115
	 * @param sddConfig
1116
	 * @param j
1117
	 * @param elCodedDescription
1118
	 * @return
1119
	 */
1120
	private boolean handleCodedDescription(Namespace sddNamespace, SDDImportConfigurator sddConfig, Element elCodedDescription, int j) {
1121
		boolean success = true ;
1122
		try {
1123

    
1124
			String idCD = elCodedDescription.getAttributeValue("id");
1125

    
1126
			// <Representation>
1127
			//  <Label>&lt;i&gt;Viola hederacea&lt;/i&gt; Labill. as revised by R. Morris April 8, 2006</Label>
1128
			// </Representation>
1129
			TaxonDescription taxonDescription = TaxonDescription.NewInstance();
1130
			importRepresentation(elCodedDescription, sddNamespace, taxonDescription, idCD, sddConfig);
1131

    
1132
			// <Scope>
1133
			//  <TaxonName ref="t1"/>
1134
			//  <Citation ref="p1" location="p. 30"/>
1135
			// </Scope>
1136
			Element elScope = elCodedDescription.getChild("Scope", sddNamespace);
1137
			Taxon taxon;
1138
			if (elScope != null) {
1139
				taxon = handleCDScope(sddNamespace, sddConfig, idCD, elScope);
1140
			} else {//in case no taxon is linked to the description, a new one is created
1141
				taxon = handleCDNoScope(sddNamespace, sddConfig, elCodedDescription);
1142
			}
1143

    
1144
			// <SummaryData>
1145
			Element elSummaryData = elCodedDescription.getChild("SummaryData",sddNamespace);
1146
			if (elSummaryData != null) {
1147
				handleSummaryCategoricalData(sddNamespace, taxonDescription, elSummaryData);
1148
				handleSummaryQuantitativeData(sddNamespace, taxonDescription, elSummaryData);
1149
				handleSummaryTextData(sddNamespace, taxonDescription, elSummaryData);
1150
			}
1151

    
1152
			if (taxon != null) {
1153
				taxon.addDescription(taxonDescription);
1154
			}
1155
			
1156
			taxonDescription.setDescriptiveSystem(featureSet);
1157

    
1158
			taxonDescriptions.put(idCD, taxonDescription);//FIXME
1159

    
1160
		} catch (Exception e) {
1161
			//FIXME
1162
			logger.warn("Import of CodedDescription " + j + " failed.", e);
1163
			success = false;
1164
		}
1165
		return success;
1166
	}
1167

    
1168
	/**
1169
	 * @param sddNamespace
1170
	 * @param sddConfig
1171
	 * @param elCodedDescription
1172
	 * @param taxon
1173
	 * @return
1174
	 */
1175
	private Taxon handleCDNoScope(Namespace sddNamespace,
1176
			SDDImportConfigurator sddConfig, Element elCodedDescription	) {
1177
		Taxon taxon = null;
1178
		NonViralName nonViralName = NonViralName.NewInstance(null);
1179
		String id = new String("" + taxonNamesCount);
1180
		IdentifiableSource source = IdentifiableSource.NewInstance(id, "TaxonName");
1181
		importRepresentation(elCodedDescription, sddNamespace, nonViralName, id, sddConfig);
1182
		
1183
		if(sddConfig.isDoMatchTaxa()){
1184
			taxon = getTaxonService().findBestMatchingTaxon(nonViralName.getTitleCache());
1185
		}
1186
		
1187
		if(taxon != null){
1188
			nonViralName = HibernateProxyHelper.deproxy(taxon.getName(), NonViralName.class);
1189
//							taxonNameBases.put(id ,tnb);
1190
//							taxonNamesCount++;
1191
			logger.info("using existing Taxon" + taxon.getTitleCache());
1192
		} else {
1193
			nonViralName.addSource(source);
1194
			taxonNameBases.put(id ,nonViralName);
1195
			taxonNamesCount++;						
1196
			logger.info("creating new Taxon from TaxonName" + nonViralName.getTitleCache());
1197
			taxon = Taxon.NewInstance(nonViralName, sec);
1198
		}
1199
		return taxon;
1200
	}
1201

    
1202
	/**
1203
	 * @param sddNamespace
1204
	 * @param sddConfig
1205
	 * @param idCD
1206
	 * @param elScope
1207
	 * @param taxon
1208
	 * @return
1209
	 */
1210
	private Taxon handleCDScope(Namespace sddNamespace, SDDImportConfigurator sddConfig, 
1211
			String idCD, Element elScope) {
1212
		Taxon taxon = null;
1213
		Element elTaxonName = elScope.getChild("TaxonName", sddNamespace);
1214
		String ref = elTaxonName.getAttributeValue("ref");
1215
		NonViralName nonViralName = taxonNameBases.get(ref);
1216
		
1217
		if(sddConfig.isDoMatchTaxa()){
1218
			taxon = getTaxonService().findBestMatchingTaxon(nonViralName.getTitleCache());
1219
		}
1220
		
1221
		if(taxon != null){
1222
			logger.info("using existing Taxon" + taxon.getTitleCache());
1223
			if(!nonViralName.getUuid().equals(taxon.getName().getUuid())){
1224
				logger.warn("TaxonNameBase entity of existing taxon does not match Name in list -> replacing Name in list");
1225
				nonViralName = HibernateProxyHelper.deproxy(taxon.getName(), NonViralName.class);
1226
			}				
1227
		} else {							
1228
			logger.info("creating new Taxon from TaxonName" + nonViralName.getTitleCache());
1229
			taxon = Taxon.NewInstance(nonViralName, sec);
1230
		}
1231
		
1232
		//citation
1233
		Element elCitation = elScope.getChild("Citation",sddNamespace);
1234
		if (elCitation != null) {
1235
			String refCitation = elCitation.getAttributeValue("ref");
1236
			if (! refCitation.equals("")){
1237
				citations.put(idCD, refCitation);
1238
			}
1239
			String location = elCitation.getAttributeValue("location");
1240
			if (! location.equals("")){
1241
				locations.put(idCD, location);
1242
			}
1243
		}
1244
		return taxon;
1245
	}
1246

    
1247
	/**
1248
	 * @param sddNamespace
1249
	 * @param taxonDescription
1250
	 * @param elSummaryData
1251
	 */
1252
	private void handleSummaryTextData(Namespace sddNamespace,
1253
			TaxonDescription taxonDescription, Element elSummaryData) {
1254
		String ref;
1255
		int k;
1256
		// <TextChar ref="c3">
1257
		List<Element> elTextChars = elSummaryData.getChildren("TextChar", sddNamespace);
1258
		k = 0;
1259
		//for each TextChar
1260
		for (Element elTextChar : elTextChars){
1261
			if ((++k % modCount) == 0){ logger.info("TextChar handled: " + (k-1));}
1262
			ref = elTextChar.getAttributeValue("ref");
1263
			Feature feature = features.get(ref);
1264
			TextData textData = TextData.NewInstance();
1265
			textData.setFeature(feature);
1266

    
1267
			// <Content>Free form text</Content>
1268
			String content = (String)ImportHelper.getXmlInputValue(elTextChar, "Content",sddNamespace);
1269
			textData.putText(content, datasetLanguage);
1270
			taxonDescription.addElement(textData);
1271
		}
1272
	}
1273

    
1274
	/**
1275
	 * @param sddNamespace
1276
	 * @param taxonDescription
1277
	 * @param elSummaryData
1278
	 */
1279
	private void handleSummaryQuantitativeData(Namespace sddNamespace,
1280
			TaxonDescription taxonDescription, Element elSummaryData) {
1281
		String ref;
1282
		int k;
1283
		// <Quantitative ref="c2">
1284
		List<Element> elQuantitatives = elSummaryData.getChildren("Quantitative", sddNamespace);
1285
		k = 0;
1286
		//for each Quantitative
1287
		for (Element elQuantitative : elQuantitatives){
1288
			if ((++k % modCount) == 0){ logger.warn("Quantitative handled: " + (k-1));}
1289
			ref = elQuantitative.getAttributeValue("ref");
1290
			Feature feature = features.get(ref);
1291
			QuantitativeData quantitativeData = QuantitativeData.NewInstance();
1292
			quantitativeData.setFeature(feature);
1293

    
1294
			MeasurementUnit unit = units.get(ref);
1295
			String prefix = defaultUnitPrefixes.get(ref);
1296
			if (unit != null) {
1297
				String u = unit.getLabel();
1298
				if (prefix != null) {
1299
					u = prefix + u;
1300
				}
1301
				unit.setLabel(u);
1302
				quantitativeData.setUnit(unit);
1303
			}
1304

    
1305
			// <Measure type="Min" value="2.3"/>
1306
			List<Element> elMeasures = elQuantitative.getChildren("Measure", sddNamespace);
1307
			int l = 0;
1308
			
1309
			//for each State
1310
			for (Element elMeasure : elMeasures){
1311
				if ((++l % modCount) == 0){ logger.info("States handled: " + (l-1));}
1312
				String type = elMeasure.getAttributeValue("type");
1313
				String value = elMeasure.getAttributeValue("value");
1314
				if (value.contains(",")) {
1315
					value = value.replace(',', '.');
1316
				}
1317
				Float v = Float.parseFloat(value);
1318
				//Float v = new Float(0);
1319
				StatisticalMeasure t = null;
1320
				if (type.equals("Min")) {
1321
					t = StatisticalMeasure.MIN();
1322
				} else if (type.equals("Mean")) {
1323
					t = StatisticalMeasure.AVERAGE();
1324
				} else if (type.equals("Max")) {
1325
					t = StatisticalMeasure.MAX();
1326
				} else if (type.equals("SD")) {
1327
					t = StatisticalMeasure.STANDARD_DEVIATION();
1328
				} else if (type.equals("N")) {
1329
					t = StatisticalMeasure.SAMPLE_SIZE();
1330
				} else if (type.equals("UMethLower")) {
1331
					t = StatisticalMeasure.TYPICAL_LOWER_BOUNDARY();
1332
				} else if (type.equals("UMethUpper")) {
1333
					t = StatisticalMeasure.TYPICAL_UPPER_BOUNDARY();
1334
				} else if (type.equals("Var")) {
1335
					t = StatisticalMeasure.VARIANCE();
1336
				} else {
1337
					t = StatisticalMeasure.NewInstance(type,type,type);
1338
					statisticalMeasures.add(t);
1339
				}
1340

    
1341
				StatisticalMeasurementValue statisticalValue = StatisticalMeasurementValue.NewInstance();
1342
				statisticalValue.setValue(v);
1343
				statisticalValue.setType(t);
1344
				quantitativeData.addStatisticalValue(statisticalValue);
1345
				featureData.add(statisticalValue);
1346
			}
1347
			taxonDescription.addElement(quantitativeData);
1348
		}
1349
	}
1350

    
1351
	/**
1352
	 * @param sddNamespace
1353
	 * @param taxonDescription
1354
	 * @param elSummaryData
1355
	 */
1356
	private void handleSummaryCategoricalData(Namespace sddNamespace,
1357
			TaxonDescription taxonDescription, Element elSummaryData) {
1358
		String ref;
1359
		// <Categorical ref="c4">
1360
		List<Element> elCategoricals = elSummaryData.getChildren("Categorical", sddNamespace);
1361
		int k = 0;
1362
		//for each Categorical
1363
		for (Element elCategorical : elCategoricals){
1364
			if ((++k % modCount) == 0){ logger.warn("Categorical handled: " + (k-1));}
1365
			ref = elCategorical.getAttributeValue("ref");
1366
			Feature feature = features.get(ref);
1367
			CategoricalData categoricalData = CategoricalData.NewInstance();
1368
			categoricalData.setFeature(feature);
1369

    
1370
			// <State ref="s3"/>
1371
			List<Element> elStates = elCategorical.getChildren("State", sddNamespace);
1372
			int l = 0;
1373
			
1374
			//for each State
1375
			for (Element elState : elStates){
1376
				if ((++l % modCount) == 0){ logger.info("States handled: " + (l-1));}
1377
				ref = elState.getAttributeValue("ref");
1378
				State state = states.get(ref);
1379
				if (state != null) {
1380
					StateData stateData = StateData.NewInstance();
1381
					stateData.setState(state);
1382
					List<Element> elModifiers = elState.getChildren("Modifier", sddNamespace);
1383
					for (Element elModifier : elModifiers){
1384
						ref = elModifier.getAttributeValue("ref");
1385
						Modifier modifier = modifiers.get(ref);
1386
						if (modifier != null) {
1387
							stateData.addModifier(modifier);
1388
						}
1389
					}
1390
					categoricalData.addState(stateData);
1391
				}
1392
				taxonDescription.addElement(categoricalData);
1393
			}
1394
		}
1395
	}
1396

    
1397
	// imports the persons associated with the dataset creation, modification, related publications
1398
	protected void importAgents(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig, boolean success){
1399
		// <Agents>
1400
		logger.info("start Agents ...");
1401
		Element elAgents = elDataset.getChild("Agents",sddNamespace);
1402
		if (elAgents != null) {
1403
			// <Agent id="a1">
1404
			List <Element> listAgents = elAgents.getChildren("Agent", sddNamespace);
1405
			int j = 0;
1406
			//for each Agent
1407
			for (Element elAgent : listAgents){
1408

    
1409
				try {
1410

    
1411
					String idA = elAgent.getAttributeValue("id");
1412

    
1413
					//  <Representation>
1414
					//   <Label>Kevin Thiele</Label>
1415
					//   <Detail role="Description">Ali Baba is also known as r.a.m.</Detail>
1416
					//  </Representation>
1417
					Person person = Person.NewInstance();
1418
					importRepresentation(elAgent, sddNamespace, person, idA, sddConfig);
1419
					person.addSource(IdentifiableSource.NewInstance(idA, "Agent"));
1420

    
1421
					/*XIM <Links>
1422
					Element elLinks = elAgent.getChild("Links",sddNamespace);
1423

    
1424
					if (elLinks != null) {
1425

    
1426
						//  <Link rel="Alternate" href="http://www.diversitycampus.net/people/hagedorn"/>
1427
						List<Element> listLinks = elLinks.getChildren("Link", sddNamespace);
1428
						int k = 0;
1429
						//for each Link
1430
						for (Element elLink : listLinks){
1431

    
1432
							try {
1433

    
1434
								String rel = elLink.getAttributeValue("rel");
1435
								String href = elLink.getAttributeValue("href");
1436

    
1437
								Media link = Media.NewInstance();
1438
								MediaRepresentation mr = MediaRepresentation.NewInstance();
1439
								mr.addRepresentationPart(MediaRepresentationPart.NewInstance(href, null));
1440
								link.addRepresentation(mr);
1441
								person.addMedia(link);
1442

    
1443
							} catch (Exception e) {
1444
								//FIXME
1445
								logger.warn("Import of Link " + k + " failed.");
1446
								success = false; 
1447
							}
1448

    
1449
							if ((++k % modCount) == 0){ logger.info("Links handled: " + k);}
1450

    
1451
						}
1452
					}
1453
					*/
1454
					if (authors.containsKey(idA)) {
1455
						authors.put(idA,person);
1456
					}
1457

    
1458
					if (editors.containsKey(idA)) {
1459
						editors.put(idA, person);
1460
					}
1461

    
1462
				} catch (Exception e) {
1463
					//FIXME
1464
					logger.warn("Import of Agent " + j + " failed.");
1465
					success = false; 
1466
				}
1467

    
1468
				if ((++j % modCount) == 0){ logger.info("Agents handled: " + j);}
1469

    
1470
			}
1471
		}
1472
	}
1473

    
1474
	// imports publications related with the data set
1475
	protected void importPublications(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig, boolean success){
1476
		/* <Publications>
1477
			  <Publication id="p112">
1478
			    <Representation>
1479
			      <Label>Gee, X. & Haa, Y. (2003). How to be happy in five minutes. Instant Gratifications, Palm Beach.</Label>
1480
			    </Representation>
1481
			    <Links>
1482
			    <Link rel="BasedOn" href="doi:10.1992/32311"/>
1483
			    <Link rel="Alternate" href="http://some.service.net/providing/bibliographic.data"/>
1484
			    </Links>
1485
			</Publications>
1486
*/
1487
		logger.info("start Publications ...");
1488
		Element elPublications = elDataset.getChild("Publications",sddNamespace);
1489

    
1490
		if (elPublications != null) {
1491
			List<Element> listPublications = elPublications.getChildren("Publication", sddNamespace);
1492
			int j = 0;
1493
			for (Element elPublication : listPublications){
1494

    
1495
				try {
1496

    
1497
					String idP = elPublication.getAttributeValue("id");
1498
					ReferenceBase publication = ReferenceFactory.newArticle();
1499
					importRepresentation(elPublication, sddNamespace, publication, idP, sddConfig);
1500

    
1501
					publications.put(idP,publication);
1502

    
1503
				} catch (Exception e) {
1504
					logger.warn("Import of Publication " + j + " failed.");
1505
					success = false; 
1506
				}
1507

    
1508
				if ((++j % modCount) == 0){ logger.info("Publications handled: " + j);}
1509

    
1510
			}
1511
		}
1512
	}
1513

    
1514
	// imports media objects such as images //FIXME check mediaobj
1515
	protected void importMediaObjects(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig, boolean success){
1516
		// <MediaObjects>
1517
		logger.info("start MediaObjects ...");
1518
		Element elMediaObjects = elDataset.getChild("MediaObjects",sddNamespace);
1519

    
1520
		if (elMediaObjects != null) {
1521
			// <MediaObject id="m1">
1522
			List<Element> listMediaObjects = elMediaObjects.getChildren("MediaObject", sddNamespace);
1523
			int j = 0;
1524
			for (Element elMO : listMediaObjects){
1525

    
1526
				String id = "";
1527

    
1528
				try {
1529
					String idMO = elMO.getAttributeValue("id");
1530
					id = idMO;
1531

    
1532
					//  <Representation>
1533
					//   <Label>Image description, e.g. to be used for alt-attribute in html.</Label>
1534
					//  </Representation>
1535
					Media media = Media.NewInstance();
1536
					importRepresentation(elMO, sddNamespace, media, idMO, sddConfig);
1537

    
1538
					// <Type>Image</Type>
1539
					// <Source href="http://test.edu/test.jpg"/>
1540
					String type = (String)ImportHelper.getXmlInputValue(elMO,"Type",sddNamespace);
1541

    
1542
					if ((type != null) && (type.equals("Image"))) {
1543
						Element elSource = elMO.getChild("Source",sddNamespace);
1544
						String href = elSource.getAttributeValue("href");
1545

    
1546
						ImageMetaData imageMetaData = ImageMetaData.newInstance();
1547
						ImageFile image = null;
1548
						if (href.substring(0,7).equals("http://")) {
1549
							try{
1550
								URL url = new URL(href);
1551
								
1552
								imageMetaData.readMetaData(url.toURI(), 0);
1553
								image = ImageFile.NewInstance(url.toString(), null, imageMetaData);
1554
							} catch (MalformedURLException e) {
1555
								logger.error("Malformed URL", e);
1556
							}
1557
						} else {
1558
							String sns = sddConfig.getSourceNameString();
1559
							File f = new File(sns);
1560
							File parent = f.getParentFile();
1561
							String fi = href;
1562
							//String fi = parent.toString() + File.separator + href; //TODO erase file:/
1563
							File file = new File(fi);
1564
							imageMetaData.readMetaData(file.toURI(), 0);
1565
							image = ImageFile.NewInstance(file.toString(), null, imageMetaData);
1566
						}
1567
						MediaRepresentation representation = MediaRepresentation.NewInstance(imageMetaData.getMimeType(), null);
1568
						representation.addRepresentationPart(image);
1569

    
1570
						media.addRepresentation(representation);
1571

    
1572
						ArrayList<CdmBase> lcb = (ArrayList<CdmBase>) mediaObject_ListCdmBase.get(idMO);
1573
						if (lcb != null) {
1574
							for (int k = 0; k < lcb.size(); k++) {
1575
								if (lcb.get(k) instanceof DefinedTermBase) {
1576
									DefinedTermBase dtb = (DefinedTermBase) lcb.get(k);
1577
									// if (lcb.get(0) instanceof DefinedTermBase) {
1578
									// DefinedTermBase dtb = (DefinedTermBase) lcb.get(0);
1579
									//									if (dtb!=null) {
1580
									//										if (k == 0) {
1581
									dtb.addMedia(media);
1582
									//System.out.println(dtb.getLabel());
1583
									//										} else {
1584
									//											Media me = (Media) media.clone();
1585
									//											dtb.addMedia(me);
1586
									//										}
1587
									//									}
1588
								} else if (lcb.get(k) instanceof ReferenceBase) {
1589
									ReferenceBase rb = (ReferenceBase) lcb.get(k);
1590
									//} else if (lcb.get(0) instanceof ReferenceBase) {
1591
									//ReferenceBase rb = (ReferenceBase) lcb.get(0);
1592
									// rb.setTitleCache(label);
1593
									//									if (rb!=null) {
1594
									//										if (k == 0) {
1595
									rb.addMedia(media);
1596
									//System.out.println(rb.getTitle());
1597
									//										} else {
1598
									//											Media me = (Media) media.clone();
1599
									//											rb.addMedia(me);
1600
									//										}
1601
									//									}
1602
								}/* else if (lcb.get(k) instanceof TaxonNameBase){
1603
									TaxonNameBase tb = (TaxonNameBase) lcb.get(k);
1604
									tb.addMedia(media);
1605
							}*/
1606
							}
1607
						}
1608
					}
1609

    
1610
				} catch (Exception e) {
1611
					//FIXME
1612
					logger.warn("Could not attach MediaObject " + j + "(SDD: " + id + ") to several objects.");
1613
					success = false; 
1614
				}
1615

    
1616
				if ((++j % modCount) == 0){ logger.info("MediaObjects handled: " + j);
1617

    
1618
				}
1619
			}
1620
		}
1621
	}
1622

    
1623
	// imports the <DescriptiveConcepts> block ; DescriptiveConcepts are used as nodes in CharacterTrees and Characters as leaves
1624
	// but since Modifiers can be linked to DescriptiveConcepts they are stored as features with a particular Marker
1625
	protected void importDescriptiveConcepts(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig){
1626
		/* <DescriptiveConcepts>
1627
		      <DescriptiveConcept id="dc0">
1628
			        <Representation>
1629
			          <Label>Fixed set of modifiers supported in Lucid3</Label>
1630
			        </Representation>
1631
			        <Modifiers>
1632
			          <Modifier id="mod1">
1633
			            <Representation>
1634
			              <Label>rarely</Label>
1635
			            </Representation>
1636
			            <ModifierClass>Frequency</ModifierClass>
1637
			            <ProportionRange lowerestimate="0.0" upperestimate="0.25"/>
1638
			          </Modifier>
1639
		          </Modifiers>
1640
		        </DescriptiveConcept>
1641
	         </DescriptiveConcepts>
1642
		 */
1643
		logger.info("start DescriptiveConcepts ...");
1644
		Element elDescriptiveConcepts = elDataset.getChild("DescriptiveConcepts",sddNamespace);
1645
		if (elDescriptiveConcepts != null) {
1646
			List<Element> listDescriptiveConcepts = elDescriptiveConcepts.getChildren("DescriptiveConcept", sddNamespace);
1647
			int j = 0;
1648

    
1649
			for (Element elDescriptiveConcept : listDescriptiveConcepts){
1650
				try {
1651
				String id = elDescriptiveConcept.getAttributeValue("id");
1652
					Feature feature = Feature.NewInstance();
1653
					feature.setKindOf(Feature.DESCRIPTION());
1654
					if (!id.equals("")) {
1655
					//	 <Representation>
1656
					//       <Label>Body</Label>
1657
					importRepresentation(elDescriptiveConcept, sddNamespace, feature, id, sddConfig);
1658
						features.put(id, feature);
1659
						getTermService().save(feature);//XIM
1660
						descriptiveConcepts.add(feature);
1661
						// imports the modifiers
1662
						Element elModifiers = elDescriptiveConcept.getChild("Modifiers", sddNamespace);
1663
					if (elModifiers !=null){
1664
						List<Element> listModifiers = elModifiers.getChildren("Modifier", sddNamespace);
1665
							TermVocabulary<Modifier> termVocabularyState = new TermVocabulary<Modifier>();
1666
						for (Element elModifier : listModifiers) {
1667
								Modifier modif = Modifier.NewInstance();
1668
								String idmod = elModifier.getAttributeValue("id");
1669
								importRepresentation(elModifier, sddNamespace, modif, idmod, sddConfig);
1670
								termVocabularyState.addTerm(modif);
1671
								//termVocabularyStates.add(termVocabularyState);
1672
								getVocabularyService().save(termVocabularyState);//XIM
1673
								modifiers.put(idmod, modif);
1674
						}
1675
							feature.addRecommendedModifierEnumeration(termVocabularyState);
1676
				}
1677

    
1678
					}
1679
				}
1680
				catch (Exception e) {
1681
					logger.warn("Import of DescriptiveConcept " + j + " failed.");
1682
				}
1683
				if ((++j % modCount) == 0){ logger.info("DescriptiveConcepts handled: " + j);}
1684

    
1685
			}
1686
		}
1687
	}
1688

    
1689
	// imports the <CharacterTrees> block
1690
	protected void importCharacterTrees(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig, boolean success){
1691
		// <CharacterTrees>
1692
		logger.info("start CharacterTrees ...");
1693
		Element elCharacterTrees = elDataset.getChild("CharacterTrees",sddNamespace);
1694

    
1695
		if (elCharacterTrees != null) {
1696
			List<Element> listCharacterTrees = elCharacterTrees.getChildren("CharacterTree", sddNamespace);
1697
			int j = 0;
1698
			for (Element elCharacterTree : listCharacterTrees){
1699
				try {
1700
					Element elRepresentation = elCharacterTree.getChild("Representation",sddNamespace);
1701
					String label = (String)ImportHelper.getXmlInputValue(elRepresentation,"Label",sddNamespace);
1702
					//Element elDesignedFor = elCharacterTree.getChild("DesignedFor",sddNamespace);//TODO ?
1703

    
1704
						FeatureTree feattree =  FeatureTree.NewInstance();
1705
						importRepresentation(elCharacterTree, sddNamespace, feattree, "", sddConfig);
1706
						FeatureNode root = feattree.getRoot();
1707
						List<Element> listelNodes = elCharacterTree.getChildren("Nodes", sddNamespace);
1708

    
1709
					//Nodes of CharacterTrees in SDD always refer to DescriptiveConcepts
1710
						for (Element elNodes : listelNodes) {
1711
							List<Element> listNodes = elNodes.getChildren("Node", sddNamespace);
1712
							if (listNodes != null) {
1713
								for (Element elNode : listNodes){
1714
									String idN = elNode.getAttributeValue("id");
1715
									FeatureNode fn = null;
1716
								Feature dc = null;
1717
								if (idN!=null) {
1718
									// DescriptiveConcepts are used as nodes in CharacterTrees
1719
										Element elDescriptiveConcept = elNode.getChild("DescriptiveConcept", sddNamespace);
1720
										if (elDescriptiveConcept != null){
1721
											String refDC = elDescriptiveConcept.getAttributeValue("ref");
1722
										dc = features.get(refDC);
1723
										fn = FeatureNode.NewInstance(dc);
1724
										}
1725
									if (fn==null){
1726
											fn = FeatureNode.NewInstance();
1727
										}
1728
										Element elParent = elNode.getChild("Parent", sddNamespace);
1729
									// in SDD links between Nodes are referenced by the <Parent> tag
1730
										if (elParent!=null){
1731
											String refP = elParent.getAttributeValue("ref");
1732
										if (refP!=null) {
1733
											FeatureNode parent = featureNodes.get(refP);
1734
											if (parent==null){
1735
												root.addChild(fn); // if no parent found or the reference is broken, add the node to the root of the tree
1736
											}
1737
											else {
1738
												parent.addChild(fn);
1739
											}
1740
										}
1741
									}
1742
										else {
1743
										root.addChild(fn); // if no parent found or the reference is broken, add the node to the root of the tree
1744
										}
1745
									}
1746
								featureNodes.put(idN, fn);
1747
								}
1748
						}
1749

    
1750
						// Leaves of CharacterTrees in SDD are always CharNodes (referring to Characters)
1751
								List<Element> listCharNodes = elNodes.getChildren("CharNode", sddNamespace);
1752
						if (listCharNodes != null) {
1753
								for (Element elCharNode : listCharNodes){
1754
									Element elParent = elCharNode.getChild("Parent", sddNamespace);
1755
									Element elCharacter = elCharNode.getChild("Character", sddNamespace);							
1756
									FeatureNode fn = FeatureNode.NewInstance();
1757
									if (elParent!=null){
1758
										String refP = elParent.getAttributeValue("ref");
1759
										if ((refP!=null)&&(!refP.equals(""))) {
1760
										FeatureNode parent = featureNodes.get(refP);
1761
											if (parent==null){
1762
											parent = root; // if no parent found or the reference is broken, add the node to the root of the tree
1763
											}
1764
											parent.addChild(fn);
1765
										}
1766
									}
1767
									String refC = elCharacter.getAttributeValue("ref");
1768
									if ((refC!=null)&&(!refC.equals(""))){
1769
										Feature character = features.get(refC);
1770
										fn.setFeature(character);
1771
								featureNodes.put(refC, fn);
1772
									}
1773
							}		
1774
									}
1775
								}
1776
						featureTrees.add(feattree);
1777
					}
1778

    
1779
				catch (Exception e) {
1780
					logger.warn("Import of Character tree " + j + " failed.");
1781
					success = false; 
1782
				}
1783
				if ((++j % modCount) == 0){ logger.info("CharacterTrees handled: " + j);}
1784

    
1785
			}
1786

    
1787
		}
1788
	}
1789

    
1790
	// imports the <TaxonHierarchies> block
1791
	protected void importTaxonHierarchies(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig, boolean success){
1792

    
1793
		logger.info("start TaxonHierarchies ...");
1794
		Element elTaxonHierarchies = elDataset.getChild("TaxonHierarchies",sddNamespace);
1795

    
1796
		if (elTaxonHierarchies != null) {
1797
			List<Element> listTaxonHierarchies = elTaxonHierarchies.getChildren("TaxonHierarchy", sddNamespace);
1798
			int j = 0;
1799
			for (Element elTaxonHierarchy : listTaxonHierarchies){
1800
				try {
1801
					Element elRepresentation = elTaxonHierarchy.getChild("Representation",sddNamespace);
1802
					String label = (String)ImportHelper.getXmlInputValue(elRepresentation,"Label",sddNamespace);
1803
						TaxonomicTree taxonomicTree =  TaxonomicTree.NewInstance(label);
1804
						importRepresentation(elTaxonHierarchy, sddNamespace, taxonomicTree, "", sddConfig);
1805
					
1806
						Set<TaxonNode> root = taxonomicTree.getChildNodes();
1807
						Element elNodes = elTaxonHierarchy.getChild("Nodes", sddNamespace); // There can be only one <Nodes> block for TaxonHierarchies
1808
						List<Element> listNodes = elNodes.getChildren("Node", sddNamespace);
1809
						
1810
						for (Element elNode : listNodes){
1811
							String idN = elNode.getAttributeValue("id");
1812
							TaxonNameBase tnb = null;
1813
							if (!idN.equals("")) {
1814
								Element elTaxonName = elNode.getChild("TaxonName", sddNamespace);
1815
								String refTN = elTaxonName.getAttributeValue("ref");
1816
								tnb = taxonNameBases.get(refTN);
1817
								Taxon taxon = (Taxon) tnb.getTaxa().iterator().next() ;
1818
								Element elParent = elNode.getChild("Parent", sddNamespace);
1819
								if (elParent!=null){
1820
									String refP = elParent.getAttributeValue("ref");
1821
									if (!refP.equals("")) {
1822
										TaxonNode parent = taxonNodes.get(refP);
1823
										TaxonNode child = parent.addChildTaxon(taxon, sec, "", Synonym.NewInstance(tnb, sec));
1824
										taxonNodes.put(idN,child);
1825
									}
1826
								}
1827
								else {
1828
									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
1829
									taxonNodes.put(idN,tn);
1830
								}
1831
							}
1832
						}
1833

    
1834
						taxonomicTrees.add(taxonomicTree);
1835
					}
1836

    
1837
				catch (Exception e) {
1838
					//FIXME
1839
					logger.warn("Import of Taxon Hierarchy " + j + " failed.");
1840
					success = false; 
1841
				}
1842

    
1843
				if ((++j % modCount) == 0){ logger.info("TaxonHierarchies handled: " + j);}
1844

    
1845
			}
1846

    
1847
		}
1848
	}
1849
	
1850
	
1851
	// imports the <GeographicAreas> block 
1852
	protected void importGeographicAreas(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig) {
1853
		Element elGeographicAreas = elDataset.getChild("GeographicAreas",sddNamespace);
1854
		if (elGeographicAreas != null) {
1855
			List<Element> listGeographicAreas = elGeographicAreas.getChildren("GeographicArea", sddNamespace);
1856
			int j = 0;
1857
						
1858
			for (Element elGeographicArea : listGeographicAreas){
1859

    
1860
				String id = elGeographicArea.getAttributeValue("id");
1861
				NamedArea na = new NamedArea();
1862
				importRepresentation(elGeographicArea, sddNamespace, na, id, sddConfig);
1863
				namedAreas.put(id,na);
1864
								}
1865
			if ((++j % modCount) == 0){ logger.info("GeographicAreas handled: " + j);}
1866
							}
1867
							}
1868
}
(1-1/3)