Project

General

Profile

Download (68.6 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.URI;
15
import java.net.URL;
16
import java.text.SimpleDateFormat;
17
import java.util.ArrayList;
18
import java.util.Date;
19
import java.util.HashMap;
20
import java.util.HashSet;
21
import java.util.List;
22
import java.util.Map;
23
import java.util.Set;
24

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

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

    
91
/**
92
 * This class is not used yet. It is meant for refactoring the SDD import.
93
 *
94
 * @author a.mueller
95
 * @created 06.01.2011
96
 * @version 1.0
97
 */
98
@Component
99
public class SDDDataSetImport extends CdmImportBase<SDDImportConfigurator, SDDImportState> implements ICdmImport<SDDImportConfigurator, SDDImportState> {
100
	private static final Logger logger = Logger.getLogger(SDDDataSetImport.class);
101

    
102
	private static int modCount = 1000;
103

    
104
	private Map<String,Person> authors = new HashMap<String,Person>();
105
	private Map<String,String> citations = new HashMap<String,String>();
106
	private Map<String,String> defaultUnitPrefixes = new HashMap<String,String>();
107
	private Map<String,Person> editors = new HashMap<String,Person>();
108
	private Map<String,FeatureNode> featureNodes = new HashMap<String,FeatureNode>();
109
	private Map<String,Feature> features = new HashMap<String,Feature>();
110
	private Map<String,String> locations = new HashMap<String,String>();
111
	private Map<String,List<CdmBase>> mediaObject_ListCdmBase = new HashMap<String,List<CdmBase>>();
112
	private Map<String,String> mediaObject_Role = new HashMap<String,String>();
113
	private Map<String,Reference> publications = new HashMap<String,Reference>();
114
	private Map<String,State> states = new HashMap<String,State>();
115
	private Map<String,TaxonDescription> taxonDescriptions = new HashMap<String,TaxonDescription>();
116
	private Map<String,NonViralName> taxonNameBases = new HashMap<String,NonViralName>();
117
	private Map<String,MeasurementUnit> units = new HashMap<String,MeasurementUnit>();
118
	private Map<String,TaxonNode> taxonNodes = new HashMap<String,TaxonNode>();
119
	private Map<String,NamedArea> namedAreas = new HashMap<String,NamedArea>();
120
	private Map<String,DerivedUnit> specimens = new HashMap<String,DerivedUnit>();
121
	private Map<String,DefinedTerm> modifiers = new HashMap<String,DefinedTerm>();
122

    
123
	private Set<MarkerType> markerTypes = new HashSet<MarkerType>();
124
	private Set<TermVocabulary> vocabularies = new HashSet<TermVocabulary>();
125

    
126
	private Set<Feature> descriptiveConcepts = new HashSet<Feature>();
127
	private Set<AnnotationType> annotationTypes = new HashSet<AnnotationType>();
128
//	private Set<Feature> featureSet = new HashSet<Feature>();
129
	private Set<Reference> sources = new HashSet<Reference>();
130
	private Reference sec = ReferenceFactory.newDatabase();
131
	private Reference sourceReference = null;
132

    
133
	private Language datasetLanguage = null;
134
	private WorkingSet workingSet = null;
135

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

    
138
	private String generatorName = "";
139
	private String generatorVersion = "";
140

    
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<Classification> classifications = new HashSet<Classification>();
146

    
147
	private Rights copyright = null;
148

    
149
	private int taxonNamesCount = 0;
150

    
151
	protected Class<ICdmIO>[] ioClassList;
152

    
153
	public SDDDataSetImport(){
154
		super();
155
	}
156

    
157
	protected void makeIoClassList(){
158
		ioClassList = new Class[]{
159
				SDDImport.class
160
		};
161
	};
162

    
163
	@Override
164
	public boolean doCheck(SDDImportState state){
165
		boolean result = true;
166
		makeIoClassList();
167
		logger.warn("No check implemented for SDD");
168
		return result;
169
	}
170

    
171
	//	@Override
172
	//	public boolean doInvoke(IImportConfigurator config, Map<String, MapWrapper<? extends CdmBase>> stores){
173
	@Override
174
	public void doInvoke(SDDImportState state){
175

    
176
		TransactionStatus ts = startTransaction();
177
		SDDImportConfigurator sddConfig = state.getConfig();
178
		IProgressMonitor progressMonitor = sddConfig.getProgressMonitor();
179

    
180
		logger.info("start Datasets ...");
181

    
182
		// <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">
183
		Element root = sddConfig.getSourceRoot();
184
		Namespace sddNamespace = sddConfig.getSddNamespace();
185

    
186
		logger.info("start TechnicalMetadata ...");
187
		// <TechnicalMetadata created="2006-04-20T10:00:00">
188
		importTechnicalMetadata(root, sddNamespace, sddConfig);
189
		List<Element> elDatasets = root.getChildren("Dataset",sddNamespace);
190
		int i = 0;
191

    
192
		//for each Dataset
193
		logger.info("start Dataset ...");
194
		progressMonitor.beginTask("Importing SDD data", elDatasets.size());
195
		for (Element elDataset : elDatasets){
196
			importDataset(elDataset, sddNamespace, state);
197
//			if ((++i % modCount) == 0){ logger.info("dataset(s) handled: " + i);}
198
//			logger.info(i + " dataset(s) handled");
199
			progressMonitor.worked(1);
200
		}
201
		commitTransaction(ts);
202
		progressMonitor.done();
203
		logger.info("End of transaction");
204
		return;
205
	}
206

    
207
	/* (non-Javadoc)
208
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
209
	 */
210
	@Override
211
    protected boolean isIgnore(SDDImportState state){
212
		return false;
213
	}
214

    
215

    
216
	// associates the reference of a media object in SDD with a CdmBase Object
217
	protected void associateImageWithCdmBase(String refMO, CdmBase cb){
218
		if ((refMO != null) && (cb!=null)) {
219
			if (! refMO.equals("")) {
220
				if (! mediaObject_ListCdmBase.containsKey(refMO)) {
221
					List<CdmBase> lcb = new ArrayList<CdmBase>();
222
					lcb.add(cb);
223
					mediaObject_ListCdmBase.put(refMO,lcb);
224
				} else {
225
					List<CdmBase> lcb = mediaObject_ListCdmBase.get(refMO);
226
					lcb.add(cb);
227
					mediaObject_ListCdmBase.put(refMO,lcb);
228
				}
229
			}
230
		}
231
	}
232

    
233
	// imports information about the Dataset
234
	protected void importDatasetRepresentation(Element parent, Namespace sddNamespace){
235
		logger.info("start Representation ...");
236
		/* <Representation>
237
			<Label>The Genus Viola</Label>
238
			<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>
239
	       </Representation>
240
		 */
241

    
242

    
243

    
244
		Element elRepresentation = parent.getChild("Representation",sddNamespace);
245
		String label = (String)ImportHelper.getXmlInputValue(elRepresentation, "Label",sddNamespace);
246
		String detail = (String)ImportHelper.getXmlInputValue(elRepresentation, "Detail",sddNamespace);
247

    
248
		//new
249
		Representation representation = Representation.NewInstance(detail, label, null, datasetLanguage);
250
		workingSet.addRepresentation(representation);
251

    
252

    
253
		//old
254
//		sec.setTitleCache(label, true);
255
//
256
//		if (detail != null) {
257
//			Annotation annotation = Annotation.NewInstance(detail, datasetLanguage);
258
//			annotation.setAnnotationType(AnnotationType.EDITORIAL());
259
//			sec.addAnnotation(annotation);
260
//		}
261

    
262

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

    
265
		for (Element elMediaObject : listMediaObjects) {
266
			String ref = null;
267
			String role = null;
268
			if (elMediaObject != null) {
269
				ref = elMediaObject.getAttributeValue("ref");
270
				role = elMediaObject.getAttributeValue("role");
271
			}
272
			if (ref != null) {
273
				if (!ref.equals("")) {
274
					this.associateImageWithCdmBase(ref,sourceReference);
275
					this.associateImageWithCdmBase(ref,sec);
276
					mediaObject_Role.put(ref,role);
277
				}
278
			}
279
		}
280
	}
281

    
282
	// imports the representation (label, detail, lang) of a particular SDD element
283
	protected void importRepresentation(Element parent, Namespace sddNamespace, VersionableEntity ve, String id, SDDImportState state){
284
		Element elRepresentation = parent.getChild("Representation",sddNamespace);
285

    
286
		Map<Language,List<String>> langLabDet = new HashMap<Language,List<String>>();
287

    
288
		handleRepresentationLabels(sddNamespace, elRepresentation, langLabDet);
289
		handleRepresentationDetails(sddNamespace, elRepresentation, langLabDet);
290

    
291
		if (ve instanceof TermBase) {
292
			makeRepresentationForTerms((TermBase)ve, langLabDet);
293
		}else if (ve instanceof Media) {
294
			makeRepresentationForMedia((Media)ve, langLabDet);
295
		}else if (ve instanceof IdentifiableEntity<?>) {
296
			IdentifiableEntity<?> ie = (IdentifiableEntity<?>)ve;
297
			makeRepresentationForIdentifiableEntity(sddNamespace, ie, elRepresentation, langLabDet);
298
			if (ve instanceof IdentifiableMediaEntity<?>){
299
				makeRepresentationForIdentifiableMediaEntity(parent, sddNamespace, (IdentifiableMediaEntity<?>)ve);
300
			}
301
		}
302

    
303
		makeRepresentationMediaObjects(sddNamespace, ve, elRepresentation);//FIXME
304

    
305
	}
306

    
307

    
308
	/**
309
	 * Handles the "Detail" children of representations. Adds the result to the langLabDet.
310
	 * @param sddNamespace
311
	 * @param elRepresentation
312
	 * @param langLabDet
313
	 */
314
	private void handleRepresentationDetails(Namespace sddNamespace,
315
			Element elRepresentation, Map<Language, List<String>> langLabDet) {
316
		List<Element> listDetails = elRepresentation.getChildren("Detail",sddNamespace);
317
		for (Element elDetail : listDetails){
318
			Language language = getLanguage(elDetail);
319
			String role = elDetail.getAttributeValue("role");
320
			String detail = elDetail.getText();
321
			List<String> labDet = langLabDet.get(language);
322
			labDet.add(detail);
323
			labDet.add(role);
324
			langLabDet.put(language, labDet);
325
		}
326
	}
327

    
328
	/**
329
	 * Handles the "Label" children of representations. Adds the result to the langLabDet.
330
	 * @param sddNamespace
331
	 * @param elRepresentation
332
	 * @param langLabDet
333
	 */
334
	private void handleRepresentationLabels(Namespace sddNamespace,
335
				Element elRepresentation, Map<Language, List<String>> langLabDet) {
336
		// <Label xml:lang="la">Viola hederacea Labill.</Label>
337
		List<Element> listLabels = elRepresentation.getChildren("Label",sddNamespace);
338
		for (Element elLabel : listLabels){
339
			Language language = getLanguage(elLabel);
340
			String label = elLabel.getText();
341
			List<String> labDet = new ArrayList<String>(3);
342
			labDet.add(label);
343
			langLabDet.put(language, labDet);
344
		}
345
	}
346

    
347
	/**
348
	 *
349
	 * @param media
350
	 * @param langLabDet
351
	 */
352
	private void makeRepresentationForMedia(Media media, Map<Language, List<String>> langLabDet) {
353
		for (Language lang : langLabDet.keySet()){
354
			List<String> labDet = langLabDet.get(lang);
355
			if (labDet.get(0) != null){
356
				media.putTitle(LanguageString.NewInstance(labDet.get(0), lang));
357
			}
358
			if (labDet.size()>1) {
359
				media.putDescription(lang, labDet.get(1));
360
			}
361
		}
362
	}
363

    
364
	/**
365
	 * Handles representations for terms. Adds one representation per language in langLabDet.
366
	 *
367
	 * @param ve
368
	 * @param langLabDet
369
	 */
370
	private void makeRepresentationForTerms(TermBase tb, Map<Language, List<String>> langLabDet) {
371
			for (Language lang : langLabDet.keySet()){
372
				List<String> labDet = langLabDet.get(lang);
373
				if (labDet.size()>0){
374
					if (labDet.size()>1) {
375
						tb.addRepresentation(Representation.NewInstance(labDet.get(1), labDet.get(0), labDet.get(0), lang));
376
					} else {
377
						tb.addRepresentation(Representation.NewInstance(labDet.get(0), labDet.get(0), labDet.get(0), lang));
378
					}
379
				}
380
			}
381
	}
382

    
383

    
384
	/**
385
	 * Handles the "MediaObject" children of representations.
386
	 * @param sddNamespace
387
	 * @param ve
388
	 * @param elRepresentation
389
	 */
390
	private void makeRepresentationMediaObjects(Namespace sddNamespace,	VersionableEntity ve, Element elRepresentation) {
391
		List <Element> listMediaObjects = elRepresentation.getChildren("MediaObject", sddNamespace);
392
		for (Element elMediaObject : listMediaObjects) {
393
			String ref = null;
394
			//TODO
395
			String role = null;
396
			if (elMediaObject != null) {
397
				ref = elMediaObject.getAttributeValue("ref");
398
				role = elMediaObject.getAttributeValue("role");
399
			}
400
			if (StringUtils.isNotBlank(ref)) {
401
				if (ve instanceof TaxonDescription) {
402
					TaxonDescription td = (TaxonDescription) ve;
403
					if (td.getSources().size() > 0) {
404
						this.associateImageWithCdmBase(ref, td.getSources().iterator().next().getCitation());
405
					} else {
406
						Reference descriptionSource = ReferenceFactory.newGeneric();
407
						sources.add(descriptionSource);
408
						//TODO type
409
						td.addSource(OriginalSourceType.Unknown, null, null, descriptionSource, null);
410
						this.associateImageWithCdmBase(ref,descriptionSource);
411
					}
412
				} else {
413
					this.associateImageWithCdmBase(ref,ve);
414
				}
415
			}
416
		}
417
	}
418

    
419
	/**
420
	 * Handles the "Links" element
421
	 * @param parent
422
	 * @param sddNamespace
423
	 * @param ve
424
	 */
425
	private void makeRepresentationForIdentifiableMediaEntity(Element parent,
426
			Namespace sddNamespace, IdentifiableMediaEntity ime) {
427
		Element elLinks = parent.getChild("Links",sddNamespace);
428

    
429
		if (elLinks != null) {
430

    
431
			//  <Link rel="Alternate" href="http://www.diversitycampus.net/people/hagedorn"/>
432
			List<Element> listLinks = elLinks.getChildren("Link", sddNamespace);
433
			Media link = Media.NewInstance();
434
			MediaRepresentation mr = MediaRepresentation.NewInstance();
435
			int k = 0;
436
			//for each Link
437
			for (Element elLink : listLinks){
438

    
439
				try {
440
					//TODO
441
					String rel = elLink.getAttributeValue("rel");
442
					String href = elLink.getAttributeValue("href");
443
					URI uri = new URI(href);
444
					mr.addRepresentationPart(MediaRepresentationPart.NewInstance(uri, null));
445
					link.addRepresentation(mr);
446
					ime.addMedia(link);
447

    
448
				} catch (Exception e) {
449
					//FIXME
450
					logger.warn("Import of Link " + k + " failed.");
451
				}
452

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

    
455
			}
456
		}
457
	}
458

    
459
	/**
460
	 * @param sddNamespace
461
	 * @param ve
462
	 * @param elRepresentation
463
	 * @param langLabDet
464
	 * @return
465
	 */
466
	private void makeRepresentationForIdentifiableEntity(Namespace sddNamespace, IdentifiableEntity<?> ie,
467
					Element elRepresentation, Map<Language, List<String>> langLabDet) {
468
		List<String> labDet = null;
469

    
470
		if (ie instanceof TaxonNameBase) {
471
			if (langLabDet.keySet().contains(getTermService().getLanguageByIso("la"))) {
472
				labDet = langLabDet.get(getTermService().getLanguageByIso("la"));
473
			} else if (langLabDet.keySet().contains(datasetLanguage)) {
474
				labDet = langLabDet.get(datasetLanguage);
475
				logger.info("TaxonName " + (String)ImportHelper.getXmlInputValue(elRepresentation, "Label",sddNamespace) + " is not specified as a latin name.");
476
			} else {
477
				labDet = langLabDet.get(langLabDet.keySet().iterator().next());
478
				logger.info("TaxonName " + (String)ImportHelper.getXmlInputValue(elRepresentation, "Label",sddNamespace) + " is not specified as a latin name.");
479
			}
480
		} else {
481
			labDet = langLabDet.get(langLabDet.keySet().iterator().next());
482
		}
483

    
484
		//FIXME labDet is != null only for TaxonNameBase
485
		ie.setTitleCache(labDet.get(0), true);
486

    
487
		if (labDet.size()>1) {
488
			Annotation annotation = null;
489
			if (labDet.get(1) != null) {
490
				if (labDet.get(2) != null) {
491
					annotation = Annotation.NewInstance(labDet.get(2) + " - " + labDet.get(1), datasetLanguage);
492
				} else {
493
					annotation = Annotation.NewInstance(labDet.get(1), datasetLanguage);
494
				}
495
			}
496
			ie.addAnnotation(annotation);
497
		}
498
		return;
499
	}
500

    
501
	/**
502
	 * @param elLabel
503
	 * @return
504
	 */
505
	private Language getLanguage(Element elLanguage) {
506
		String lang = elLanguage.getAttributeValue("lang",xmlNamespace);
507
		Language language = null;
508
		if (StringUtils.isNotBlank(lang)) {
509
			language = getTermService().getLanguageByIso(lang.substring(0, 2));
510
		} else {
511
			language = datasetLanguage;
512
		}
513
		return language;
514
	}
515

    
516

    
517
	// imports the representation (label, detail, lang) of a particular SDD element
518
	protected void importTechnicalMetadata(Element root, Namespace sddNamespace, SDDImportConfigurator sddConfig){
519
		Element elTechnicalMetadata = root.getChild("TechnicalMetadata", sddNamespace);
520
		String nameCreated = elTechnicalMetadata.getAttributeValue("created");
521
		sourceReference = sddConfig.getSourceReference();
522

    
523
		if (nameCreated != null) {
524
			if (!nameCreated.equals("")) {
525
				int year = Integer.parseInt(nameCreated.substring(0,4));
526
				int monthOfYear = Integer.parseInt(nameCreated.substring(5,7));
527
				int dayOfMonth = Integer.parseInt(nameCreated.substring(8,10));
528
				int hourOfDay = Integer.parseInt(nameCreated.substring(11,13));
529
				int minuteOfHour = Integer.parseInt(nameCreated.substring(14,16));
530
				int secondOfMinute = Integer.parseInt(nameCreated.substring(17,19));
531
				DateTime created = new DateTime(year,monthOfYear,dayOfMonth,hourOfDay,minuteOfHour,secondOfMinute,0);
532
				sourceReference.setCreated(created);
533
				sec.setCreated(created);
534
			}
535
		}
536

    
537
		// <Generator name="n/a, handcrafted instance document" version="n/a"/>
538
		Element elGenerator = elTechnicalMetadata.getChild("Generator", sddNamespace);
539
		generatorName = elGenerator.getAttributeValue("name");
540
		generatorVersion = elGenerator.getAttributeValue("version");
541

    
542
		sec.addAnnotation(Annotation.NewDefaultLanguageInstance(generatorName + " - " + generatorVersion));
543
		sourceReference.addAnnotation(Annotation.NewDefaultLanguageInstance(generatorName + " - " + generatorVersion));
544

    
545
	}
546

    
547
	// imports the complete dataset information
548
	protected void importDataset(Element elDataset, Namespace sddNamespace, SDDImportState state){			// <Dataset xml:lang="en-us">
549
//		SDDImportConfigurator sddConfig = state.getConfig();
550

    
551
		workingSet = WorkingSet.NewInstance();
552
		importDatasetLanguage(elDataset,state);
553
		importDatasetRepresentation(elDataset, sddNamespace);
554
		importRevisionData(elDataset, sddNamespace);
555
		importIPRStatements(elDataset, sddNamespace, state);
556
		importTaxonNames(elDataset, sddNamespace, state);
557

    
558
		importDescriptiveConcepts(elDataset, sddNamespace, state);
559
		importCharacters(elDataset, sddNamespace, state);
560
		importCharacterTrees(elDataset, sddNamespace, state);
561

    
562
		MarkerType editorMarkerType = getMarkerType(state, SDDTransformer.uuidMarkerEditor, "editor", "Editor", "edt");
563
		MarkerType geographicAreaMarkerType = getMarkerType(state, SDDTransformer.uuidMarkerSDDGeographicArea, "SDDGeographicArea", "SDDGeographicArea", "ga");
564
		MarkerType descriptiveConceptMarkerType = getMarkerType(state, SDDTransformer.uuidMarkerDescriptiveConcept, "DescriptiveConcept", "Descriptive Concept", "DC");
565
		markerTypes.add(editorMarkerType);
566
		markerTypes.add(geographicAreaMarkerType);
567
		markerTypes.add(descriptiveConceptMarkerType);
568

    
569
		//saving of all imported data into the CDM db
570
		saveVocabularies();
571
		saveFeatures();
572
		saveModifiers();
573
		saveStates();
574
		saveMarkerType();
575
		saveAreas(geographicAreaMarkerType);
576
		saveUnits();
577
		saveStatisticalMeasure();
578
		saveAnnotationType();
579

    
580
		importCodedDescriptions(elDataset, sddNamespace, state);
581
		importAgents(elDataset, sddNamespace, state);
582
		importPublications(elDataset, sddNamespace, state);
583
		importMediaObjects(elDataset, sddNamespace, state);
584
		importTaxonHierarchies(elDataset, sddNamespace, state);
585
		importGeographicAreas(elDataset, sddNamespace, state);
586
		importSpecimens(elDataset,sddNamespace, state);
587

    
588

    
589
		if ((authors != null)||(editors != null)) {
590
			Team team = Team.NewInstance();
591
			if (authors != null) {
592
				for (Person author : authors.values()){
593
					team.addTeamMember(author);
594
				}
595
			}
596
			if (editors != null) {
597
				Marker marker = Marker.NewInstance();
598
				marker.setMarkerType(editorMarkerType);
599
				for (Person editor : editors.values()){
600
					Person edit = editor;
601
					edit.addMarker(marker);
602
					team.addTeamMember(edit);
603
				}
604
			}
605
			sec.setAuthorship(team);
606
			sourceReference.setAuthorship(team);
607
		}
608

    
609
		if (copyright != null) {
610
			sourceReference.addRights(copyright);
611
			sec.addRights(copyright);
612
		}
613

    
614
		// Returns a CdmApplicationController created by the values of this configuration.
615
		IDescriptionService descriptionService = getDescriptionService();
616

    
617
		for (TaxonDescription taxonDescription : taxonDescriptions.values()){
618
			// Persists a Description
619
			descriptionService.save(taxonDescription);
620
		}
621

    
622
		for (String ref : taxonDescriptions.keySet()){
623
			TaxonDescription td = taxonDescriptions.get(ref);
624
			if (citations.containsKey(ref)) {
625
				Reference publication = publications.get(citations.get(ref));
626
				if (locations.containsKey(ref)) {
627
					Annotation location = Annotation.NewInstance(locations.get(ref), datasetLanguage);
628
					AnnotationType annotationType = AnnotationType.NewInstance("", "location", "");
629
					annotationTypes.add(annotationType);
630
					location.setAnnotationType(annotationType);
631
					(publication).addAnnotation(location);
632
				}
633
				//TODO type
634
				td.addSource(OriginalSourceType.Unknown, null, null, publication, null);
635
			}
636
		}
637
		logger.info("end makeTaxonDescriptions ...");
638

    
639
		if (descriptiveConcepts != null) {
640
			for (Feature feature : descriptiveConcepts) {
641
				Marker marker = Marker.NewInstance();
642
				marker.setMarkerType(descriptiveConceptMarkerType);
643
				feature.addMarker(marker);
644
			}
645
		}
646
		saveFeatures();
647

    
648
		for (Reference publication : publications.values()){
649
			getReferenceService().save(publication);
650
		}
651

    
652
		for (Reference source : sources){
653
			getReferenceService().save(source);
654
		}
655

    
656
		for (FeatureTree featureTree : featureTrees) {
657
			getFeatureTreeService().save(featureTree);
658
		}
659
		getWorkingSetService().save(workingSet);
660
		for (Classification classification : classifications) {
661
			getClassificationService().save(classification);
662
		}
663
		for (DerivedUnit specimen : specimens.values()) {
664
			getOccurrenceService().save(specimen);
665
		}
666
		logger.info("end of persistence ...");
667

    
668
		return;
669
	}
670

    
671
	/**
672
	 *
673
	 */
674
	private void saveVocabularies() {
675
		for (TermVocabulary vocabulary : vocabularies ){
676
			getVocabularyService().save(vocabulary);
677
		}
678

    
679
	}
680

    
681
	private void saveAnnotationType() {
682
		for (AnnotationType annotationType: annotationTypes){
683
			getTermService().save(annotationType);
684
		}
685
	}
686

    
687
	private void saveStatisticalMeasure() {
688
		for (StatisticalMeasure sm : statisticalMeasures){
689
			getTermService().save(sm);
690
		}
691
	}
692

    
693
	private void saveUnits() {
694
		if (units != null) {
695
			for (MeasurementUnit unit : units.values()){
696
				if (unit != null) {
697
					getTermService().save(unit);
698
				}
699
			}
700
		}
701
	}
702

    
703
	private void saveAreas(MarkerType geographicAreaMarkerType) {
704
		for (NamedArea area : namedAreas.values() ){
705
			Marker marker = Marker.NewInstance();
706
			marker.setMarkerType(geographicAreaMarkerType);
707
			area.addMarker(marker);
708
			getTermService().save(area);
709
		}
710
	}
711

    
712
	private void saveStates() {
713
		for (State state : states.values() ){
714
			getTermService().save(state);
715
		}
716
	}
717

    
718
	private void saveMarkerType() {
719
		for (MarkerType markerType : markerTypes){
720
			getTermService().save(markerType);
721
		}
722
	}
723

    
724
	private void saveModifiers() {
725
		for (DefinedTerm modifier : modifiers.values() ){
726
			getTermService().save(modifier);
727
		}
728
	}
729

    
730
	private void saveFeatures() {
731
		for (Feature feature : features.values() ){
732
			getTermService().save(feature);
733
		}
734
	}
735

    
736
	// imports the default language of the dataset
737
	protected void importDatasetLanguage(Element elDataset, SDDImportState state){
738
		String nameLang = elDataset.getAttributeValue("lang",xmlNamespace);
739

    
740
		if (StringUtils.isNotBlank(nameLang)) {
741
			String iso = nameLang.substring(0, 2);
742
			datasetLanguage = getTermService().getLanguageByIso(iso);
743
		} else {
744
			datasetLanguage = Language.DEFAULT();
745
		}
746
		if (datasetLanguage == null) {
747
			datasetLanguage = Language.DEFAULT();
748
		}
749
	}
750

    
751
	// imports the specimens
752
	protected void importSpecimens(Element elDataset, Namespace sddNamespace, SDDImportState cdmState) {
753
		logger.info("start Specimens ...");
754
		/*	<Specimens>
755
        		<Specimen id="sp1">
756
           			<Representation>
757
              			<Label>TJM45337</Label>
758
           			</Representation>
759
        		</Specimen>
760
     		</Specimens>
761
		 */
762
		Element elSpecimens = elDataset.getChild("Specimens",sddNamespace);
763
		if (elSpecimens != null){
764
			List<Element> listSpecimens = elSpecimens.getChildren("Specimen", sddNamespace);
765
			int j = 0;
766
			for (Element elSpecimen : listSpecimens) {
767
				String id = elSpecimen.getAttributeValue("id");
768
				DerivedUnit specimen = null;
769
				if (!id.equals("")) {
770
					specimen = DerivedUnit.NewPreservedSpecimenInstance();
771
					specimens.put(id,specimen);
772
					importRepresentation(elSpecimen, sddNamespace, specimen, id, cdmState);
773
				}
774
			}
775

    
776
		}
777
	}
778

    
779
	// imports the revision data associated with the Dataset (authors, modifications)
780
	protected void importRevisionData(Element elDataset, Namespace sddNamespace){
781
		// <RevisionData>
782
		logger.info("start RevisionData ...");
783
		Element elRevisionData = elDataset.getChild("RevisionData",sddNamespace);
784
		if (elRevisionData != null){
785
			// <Creators>
786
			Element elCreators = elRevisionData.getChild("Creators",sddNamespace);
787

    
788
			// <Agent role="aut" ref="a1"/>
789
			List<Element> listAgents = elCreators.getChildren("Agent", sddNamespace);
790

    
791
			int j = 0;
792
			//for each Agent
793
			for (Element elAgent : listAgents){
794

    
795
				String role = elAgent.getAttributeValue("role");
796
				String ref = elAgent.getAttributeValue("ref");
797
				if (role.equals("aut")) {
798
					if(!ref.equals("")) {
799
						authors.put(ref, null);
800
					}
801
				}
802
				if (role.equals("edt")) {
803
					if(!ref.equals("")) {
804
						editors.put(ref, null);
805
					}
806
				}
807
				if ((++j % modCount) == 0){ logger.info("Agents handled: " + j);}
808

    
809
			}
810

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

    
814
			if (stringDateModified != null) {
815
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
816
				Date d = null;
817
				try {
818
					d = sdf.parse(stringDateModified);
819
				} catch(Exception e) {
820
					System.err.println("Exception :");
821
					e.printStackTrace();
822
				}
823

    
824
				DateTime updated = null;
825
				if (d != null) {
826
					updated = new DateTime(d);
827
					sourceReference.setUpdated(updated);
828
					sec.setUpdated(updated);
829
				}
830
			}
831
		}
832
	}
833

    
834
	// imports ipr statements associated with a dataset
835
	protected void importIPRStatements(Element elDataset, Namespace sddNamespace, SDDImportState state){
836
		// <IPRStatements>
837
		logger.info("start IPRStatements ...");
838
		Element elIPRStatements = elDataset.getChild("IPRStatements",sddNamespace);
839
		// <IPRStatement role="Copyright">
840
		if (elIPRStatements != null) {
841
			List<Element> listIPRStatements = elIPRStatements.getChildren("IPRStatement", sddNamespace);
842
			int j = 0;
843
			//for each IPRStatement
844

    
845
			for (Element elIPRStatement : listIPRStatements){
846

    
847
				String role = elIPRStatement.getAttributeValue("role");
848
				// <Label xml:lang="en-au">(c) 2003-2006 Centre for Occasional Botany.</Label>
849
				Element elLabel = elIPRStatement.getChild("Label",sddNamespace);
850
				String lang = "";
851
				if (elLabel != null) {
852
					lang = elLabel.getAttributeValue("lang",xmlNamespace);
853
				}
854
				String label = (String)ImportHelper.getXmlInputValue(elIPRStatement, "Label",sddNamespace);
855

    
856
				if (role.equals("Copyright")) {
857
					Language iprLanguage = null;
858
					if (lang != null) {
859
						if (!lang.equals("")) {
860
							iprLanguage = getTermService().getLanguageByIso(lang.substring(0, 2));
861
						} else {
862
							iprLanguage = datasetLanguage;
863
						}
864
					}
865
					if (iprLanguage == null) {
866
						iprLanguage = datasetLanguage;
867
					}
868
					copyright = Rights.NewInstance(label, iprLanguage);
869
				}
870

    
871
				if (copyright != null) {
872
					sourceReference.addRights(copyright);
873
					sec.addRights(copyright);
874
				}
875

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

    
878
			}
879
		}
880
	}
881

    
882
	// imports the taxon names
883
	protected void importTaxonNames(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
884
		// <TaxonNames>
885
		logger.info("start TaxonNames ...");
886
		Element elTaxonNames = elDataset.getChild("TaxonNames",sddNamespace);
887
		// <TaxonName id="t1" uri="urn:lsid:authority:namespace:my-own-id">
888
		if (elTaxonNames != null) {
889
			List<Element> listTaxonNames = elTaxonNames.getChildren("TaxonName", sddNamespace);
890
			int j = 0;
891
			//for each TaxonName
892
			for (Element elTaxonName : listTaxonNames){
893

    
894
				String id = elTaxonName.getAttributeValue("id");
895
				String uri = elTaxonName.getAttributeValue("uri");
896

    
897
				NonViralName tnb = null;
898
				if (!id.equals("")) {
899
					tnb = NonViralName.NewInstance(null);
900
					IdentifiableSource source = null;
901
					if (isNotBlank(uri)) {
902
						//TODO type
903
						source = IdentifiableSource.NewInstance(OriginalSourceType.Unknown, id, "TaxonName", ReferenceFactory.newGeneric(), uri);
904
					} else {
905
						source = IdentifiableSource.NewDataImportInstance(id, "TaxonName");
906
					}
907
					tnb.addSource(source);
908
					taxonNameBases.put(id,tnb);
909
				}
910

    
911
				// <Representation>
912
				// <Label xml:lang="la">Viola hederacea Labill.</Label>
913
				importRepresentation(elTaxonName, sddNamespace, tnb, id, cdmState);
914

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

    
917
			}
918
		}
919
	}
920

    
921
	// imports the characters (categorical, quantitative and text ; sequence characters not supported) which correspond to CDM Features
922
	protected void importCharacters(Element elDataset, Namespace sddNamespace, SDDImportState state){
923
		// <Characters>
924
		logger.info("start Characters ...");
925
		Element elCharacters = elDataset.getChild("Characters", sddNamespace);
926

    
927
		// <CategoricalCharacter id="c1">
928
		if (elCharacters != null) {
929
			handleCategoricalData(sddNamespace, state, elCharacters);
930
			handleQuantitativeData(sddNamespace, state, elCharacters);
931
			handleTextCharacters(sddNamespace, state, elCharacters);
932
		}
933

    
934
		/*for (Iterator<Feature> f = features.values().iterator() ; f.hasNext() ;){
935
			featureSet.add(f.next()); //XIM Why this line ?
936
		}*/
937

    
938
		return;
939

    
940
	}
941

    
942
	/**
943
	 * @param sddNamespace
944
	 * @param cdmState
945
	 * @param elCharacters
946
	 * @return
947
	 */
948
	private void handleCategoricalData(Namespace sddNamespace, SDDImportState cdmState, Element elCharacters) {
949
		List<Element> elCategoricalCharacters = elCharacters.getChildren("CategoricalCharacter", sddNamespace);
950
		int j = 0;
951
		for (Element elCategoricalCharacter : elCategoricalCharacters){
952
			try {
953

    
954
				String idCC = elCategoricalCharacter.getAttributeValue("id");
955
				Feature categoricalCharacter = Feature.NewInstance();
956
				categoricalCharacter.setKindOf(Feature.DESCRIPTION());
957
				importRepresentation(elCategoricalCharacter, sddNamespace, categoricalCharacter, idCC, cdmState);
958
				categoricalCharacter.setSupportsCategoricalData(true);
959

    
960
				// <States>
961
				Element elStates = elCategoricalCharacter.getChild("States",sddNamespace);
962

    
963
				// <StateDefinition id="s1">
964
				List<Element> elStateDefinitions = elStates.getChildren("StateDefinition",sddNamespace);
965
				TermVocabulary<State> termVocabularyState = TermVocabulary.NewInstance(TermType.State, null, null, null, null);
966

    
967
				vocabularies.add(termVocabularyState);
968

    
969
				int k = 0;
970
				//for each StateDefinition
971
				for (Element elStateDefinition : elStateDefinitions){
972

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

    
975
					String idS = elStateDefinition.getAttributeValue("id");
976
					State state = states.get(idS);
977
					if (state == null){
978
						state = State.NewInstance();
979
					}else{
980
						logger.debug("State duplicate found");
981
					}
982
					importRepresentation(elStateDefinition, sddNamespace, state, idS, cdmState);
983

    
984
					termVocabularyState.addTerm(state);
985
					states.put(idS,state);
986
				}
987
				categoricalCharacter.addSupportedCategoricalEnumeration(termVocabularyState);
988
				features.put(idCC, categoricalCharacter);
989

    
990
			} catch (Exception e) {
991
				logger.warn("Import of CategoricalCharacter " + j + " failed.");
992
				cdmState.setUnsuccessfull();
993
			}
994

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

    
997
		}
998
		return;
999
	}
1000

    
1001
	/**
1002
	 * @param sddNamespace
1003
	 * @param sddConfig
1004
	 * @param elCharacters
1005
	 */
1006
	private void handleQuantitativeData(Namespace sddNamespace,	SDDImportState cdmState, Element elCharacters) {
1007
		int j;
1008
		// <QuantitativeCharacter id="c2">
1009
		List<Element> elQuantitativeCharacters = elCharacters.getChildren("QuantitativeCharacter", sddNamespace);
1010
		j = 0;
1011
		//for each QuantitativeCharacter
1012
		for (Element elQuantitativeCharacter : elQuantitativeCharacters){
1013

    
1014
			try {
1015

    
1016
				String idQC = elQuantitativeCharacter.getAttributeValue("id");
1017

    
1018
				// <Representation>
1019
				//  <Label>Leaf length</Label>
1020
				// </Representation>
1021
				Feature quantitativeCharacter = Feature.NewInstance();
1022
				quantitativeCharacter.setKindOf(Feature.DESCRIPTION());
1023
				importRepresentation(elQuantitativeCharacter, sddNamespace, quantitativeCharacter, idQC, cdmState);
1024

    
1025
				quantitativeCharacter.setSupportsQuantitativeData(true);
1026

    
1027
				// <MeasurementUnit>
1028
				//  <Label role="Abbrev">m</Label>
1029
				// </MeasurementUnit>
1030
				Element elMeasurementUnit = elQuantitativeCharacter.getChild("MeasurementUnit",sddNamespace);
1031
				String label = "";
1032
				String role = "";
1033
				if (elMeasurementUnit != null) {
1034
					Element elLabel = elMeasurementUnit.getChild("Label",sddNamespace);
1035
					role = elLabel.getAttributeValue("role");
1036
					label = (String)ImportHelper.getXmlInputValue(elMeasurementUnit, "Label",sddNamespace);
1037
				}
1038

    
1039
				MeasurementUnit unit = null;
1040
				if (!label.equals("")){
1041
					if (role != null) {
1042
						if (role.equals("Abbrev")){
1043
							unit = MeasurementUnit.NewInstance(label,label,label);
1044
						}
1045
					} else {
1046
						unit = MeasurementUnit.NewInstance(label,label,label);
1047
					}
1048
				}
1049

    
1050
				if (unit != null) {
1051
					units.put(idQC, unit);
1052
				}
1053

    
1054
				//<Default>
1055
				//  <MeasurementUnitPrefix>milli</MeasurementUnitPrefix>
1056
				//</Default>
1057
				Element elDefault = elQuantitativeCharacter.getChild("Default",sddNamespace);
1058
				if (elDefault != null) {
1059
					String measurementUnitPrefix = (String)ImportHelper.getXmlInputValue(elDefault, "MeasurementUnitPrefix",sddNamespace);
1060
					if (! measurementUnitPrefix.equals("")){
1061
						defaultUnitPrefixes.put(idQC, measurementUnitPrefix);
1062
					}
1063
				}
1064

    
1065
				features.put(idQC, quantitativeCharacter);
1066

    
1067
			} catch (Exception e) {
1068
				//FIXME
1069
				logger.warn("Import of QuantitativeCharacter " + j + " failed.");
1070
				cdmState.setUnsuccessfull();
1071
			}
1072

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

    
1075
		}
1076
		return;
1077
	}
1078

    
1079
	private void handleTextCharacters(Namespace sddNamespace, SDDImportState cdmState, Element elCharacters) {
1080
		int j;
1081
		// <TextCharacter id="c3">
1082
		List<Element> elTextCharacters = elCharacters.getChildren("TextCharacter", sddNamespace);
1083
		j = 0;
1084
		//for each TextCharacter
1085
		for (Element elTextCharacter : elTextCharacters){
1086

    
1087
			try {
1088

    
1089
				String idTC = elTextCharacter.getAttributeValue("id");
1090

    
1091
				// <Representation>
1092
				//  <Label xml:lang="en">Leaf features not covered by other characters</Label>
1093
				// </Representation>
1094
				Feature textCharacter = Feature.NewInstance();
1095
				textCharacter.setKindOf(Feature.DESCRIPTION());
1096
				importRepresentation(elTextCharacter, sddNamespace, textCharacter, idTC, cdmState);
1097

    
1098
				textCharacter.setSupportsTextData(true);
1099

    
1100
				features.put(idTC, textCharacter);
1101

    
1102
			} catch (Exception e) {
1103
				//FIXME
1104
				logger.warn("Import of TextCharacter " + j + " failed.");
1105
				cdmState.setUnsuccessfull();
1106
			}
1107

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

    
1110
		}
1111
		return;
1112
	}
1113

    
1114
	// imports the descriptions of taxa
1115
	protected void importCodedDescriptions(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1116

    
1117
		// <CodedDescriptions>
1118
		logger.info("start CodedDescriptions ...");
1119
		Element elCodedDescriptions = elDataset.getChild("CodedDescriptions",sddNamespace);
1120

    
1121
		// <CodedDescription id="D101">
1122
		if (elCodedDescriptions != null) {
1123
			List<Element> listCodedDescriptions = elCodedDescriptions.getChildren("CodedDescription", sddNamespace);
1124
			int j = 0;
1125
			//for each CodedDescription
1126
			for (Element elCodedDescription : listCodedDescriptions){
1127
				handleCodedDescription(sddNamespace, cdmState, elCodedDescription, j);
1128
				if ((++j % modCount) == 0){ logger.info("CodedDescriptions handled: " + j);}
1129
			}
1130
		}
1131
		return;
1132
	}
1133

    
1134
	/**
1135
	 * @param sddNamespace
1136
	 * @param sddConfig
1137
	 * @param j
1138
	 * @param elCodedDescription
1139
	 * @return
1140
	 */
1141
	private void handleCodedDescription(Namespace sddNamespace, SDDImportState cdmState, Element elCodedDescription, int j) {
1142
		try {
1143

    
1144
			String idCD = elCodedDescription.getAttributeValue("id");
1145

    
1146
			// <Representation>
1147
			//  <Label>&lt;i&gt;Viola hederacea&lt;/i&gt; Labill. as revised by R. Morris April 8, 2006</Label>
1148
			// </Representation>
1149
			TaxonDescription taxonDescription = TaxonDescription.NewInstance();
1150
			if (!generatorName.isEmpty()){
1151
				Annotation annotation = Annotation.NewInstance(generatorName, AnnotationType.TECHNICAL(),Language.DEFAULT());
1152
				taxonDescription.addAnnotation(annotation);
1153
			}
1154
			importRepresentation(elCodedDescription, sddNamespace, taxonDescription, idCD, cdmState);
1155

    
1156
			// <Scope>
1157
			//  <TaxonName ref="t1"/>
1158
			//  <Citation ref="p1" location="p. 30"/>
1159
			// </Scope>
1160
			Element elScope = elCodedDescription.getChild("Scope", sddNamespace);
1161
			Taxon taxon;
1162
			if (elScope != null) {
1163
				taxon = handleCDScope(sddNamespace, cdmState, idCD, elScope);
1164
			} else {//in case no taxon is linked to the description, a new one is created
1165
				taxon = handleCDNoScope(sddNamespace, cdmState, elCodedDescription);
1166
			}
1167

    
1168
			// <SummaryData>
1169
			Element elSummaryData = elCodedDescription.getChild("SummaryData",sddNamespace);
1170
			if (elSummaryData != null) {
1171
				handleSummaryCategoricalData(sddNamespace, taxonDescription, elSummaryData);
1172
				handleSummaryQuantitativeData(sddNamespace, taxonDescription, elSummaryData);
1173
				handleSummaryTextData(sddNamespace, taxonDescription, elSummaryData);
1174
			}
1175

    
1176
			if (taxon != null) {
1177
				taxon.addDescription(taxonDescription);
1178
			}
1179
//
1180
			workingSet.addDescription(taxonDescription);
1181

    
1182
//OLD			taxonDescription.setDescriptiveSystem(featureSet);
1183

    
1184
			taxonDescriptions.put(idCD, taxonDescription);//FIXME
1185

    
1186
		} catch (Exception e) {
1187
			//FIXME
1188
			logger.warn("Import of CodedDescription " + j + " failed.", e);
1189
			cdmState.setUnsuccessfull();
1190
		}
1191
		return;
1192
	}
1193

    
1194
	/**
1195
	 * @param sddNamespace
1196
	 * @param sddConfig
1197
	 * @param elCodedDescription
1198
	 * @param taxon
1199
	 * @return
1200
	 */
1201
	private Taxon handleCDNoScope(Namespace sddNamespace,
1202
			SDDImportState cdmState, Element elCodedDescription	) {
1203
		Taxon taxon = null;
1204
		NonViralName<?> nonViralName = NonViralName.NewInstance(null);
1205
		String id = new String("" + taxonNamesCount);
1206
		IdentifiableSource source = IdentifiableSource.NewDataImportInstance( id, "TaxonName");
1207
		importRepresentation(elCodedDescription, sddNamespace, nonViralName, id, cdmState);
1208

    
1209
		if(cdmState.getConfig().isReuseExistingTaxaWhenPossible()){
1210
			taxon = getTaxonService().findBestMatchingTaxon(nonViralName.getTitleCache());
1211
		}
1212

    
1213
		if(taxon != null){
1214
			nonViralName = HibernateProxyHelper.deproxy(taxon.getName(), NonViralName.class);
1215
//							taxonNameBases.put(id ,tnb);
1216
//							taxonNamesCount++;
1217
			logger.info("using existing Taxon " + taxon.getTitleCache());
1218
		} else {
1219
			nonViralName.addSource(source);
1220
			taxonNameBases.put(id ,nonViralName);
1221
			taxonNamesCount++;
1222
			logger.info("creating new Taxon from TaxonName " + nonViralName.getTitleCache());
1223
			taxon = Taxon.NewInstance(nonViralName, sec);
1224
		}
1225
		return taxon;
1226
	}
1227

    
1228
	/**
1229
	 * @param sddNamespace
1230
	 * @param sddConfig
1231
	 * @param idCD
1232
	 * @param elScope
1233
	 * @param taxon
1234
	 * @return
1235
	 */
1236
	private Taxon handleCDScope(Namespace sddNamespace, SDDImportState cdmState,
1237
			String idCD, Element elScope) {
1238
		Taxon taxon = null;
1239
		Element elTaxonName = elScope.getChild("TaxonName", sddNamespace);
1240
		String ref = elTaxonName.getAttributeValue("ref");
1241
		NonViralName nonViralName = taxonNameBases.get(ref);
1242

    
1243
		if(cdmState.getConfig().isReuseExistingTaxaWhenPossible()){
1244
			taxon = getTaxonService().findBestMatchingTaxon(nonViralName.getTitleCache());
1245
		}
1246

    
1247
		if(taxon != null){
1248
			logger.info("using existing Taxon" + taxon.getTitleCache());
1249
			if(!nonViralName.getUuid().equals(taxon.getName().getUuid())){
1250
				logger.warn("TaxonNameBase entity of existing taxon does not match Name in list -> replacing Name in list");
1251
				nonViralName = HibernateProxyHelper.deproxy(taxon.getName(), NonViralName.class);
1252
			}
1253
		} else {
1254
			logger.info("creating new Taxon from TaxonName '" + nonViralName.getTitleCache()+"'");
1255
			taxon = Taxon.NewInstance(nonViralName, sec);
1256
		}
1257

    
1258
		//citation
1259
		Element elCitation = elScope.getChild("Citation",sddNamespace);
1260
		if (elCitation != null) {
1261
			String refCitation = elCitation.getAttributeValue("ref");
1262
			if (! refCitation.equals("")){
1263
				citations.put(idCD, refCitation);
1264
			}
1265
			String location = elCitation.getAttributeValue("location");
1266
			if (! location.equals("")){
1267
				locations.put(idCD, location);
1268
			}
1269
		}
1270
		return taxon;
1271
	}
1272

    
1273
	/**
1274
	 * @param sddNamespace
1275
	 * @param taxonDescription
1276
	 * @param elSummaryData
1277
	 */
1278
	private void handleSummaryTextData(Namespace sddNamespace,
1279
			TaxonDescription taxonDescription, Element elSummaryData) {
1280
		String ref;
1281
		int k;
1282
		// <TextChar ref="c3">
1283
		List<Element> elTextChars = elSummaryData.getChildren("TextChar", sddNamespace);
1284
		k = 0;
1285
		//for each TextChar
1286
		for (Element elTextChar : elTextChars){
1287
			if ((++k % modCount) == 0){ logger.info("TextChar handled: " + (k-1));}
1288
			ref = elTextChar.getAttributeValue("ref");
1289
			Feature feature = features.get(ref);
1290
			TextData textData = TextData.NewInstance();
1291
			textData.setFeature(feature);
1292

    
1293
			// <Content>Free form text</Content>
1294
			String content = (String)ImportHelper.getXmlInputValue(elTextChar, "Content",sddNamespace);
1295
			textData.putText(datasetLanguage, content);
1296
			taxonDescription.addElement(textData);
1297
		}
1298
	}
1299

    
1300
	/**
1301
	 * @param sddNamespace
1302
	 * @param taxonDescription
1303
	 * @param elSummaryData
1304
	 */
1305
	private void handleSummaryQuantitativeData(Namespace sddNamespace,
1306
			TaxonDescription taxonDescription, Element elSummaryData) {
1307
		String ref;
1308
		int k;
1309
		// <Quantitative ref="c2">
1310
		List<Element> elQuantitatives = elSummaryData.getChildren("Quantitative", sddNamespace);
1311
		k = 0;
1312
		//for each Quantitative
1313
		for (Element elQuantitative : elQuantitatives){
1314
			if ((++k % modCount) == 0){ logger.warn("Quantitative handled: " + (k-1));}
1315
			ref = elQuantitative.getAttributeValue("ref");
1316
			Feature feature = features.get(ref);
1317
			QuantitativeData quantitativeData = QuantitativeData.NewInstance();
1318
			quantitativeData.setFeature(feature);
1319

    
1320
			MeasurementUnit unit = units.get(ref);
1321
			String prefix = defaultUnitPrefixes.get(ref);
1322
			if (unit != null) {
1323
				String u = unit.getLabel();
1324
				if (prefix != null) {
1325
					u = prefix + u;
1326
				}
1327
				unit.setLabel(u);
1328
				quantitativeData.setUnit(unit);
1329
			}
1330

    
1331
			// <Measure type="Min" value="2.3"/>
1332
			List<Element> elMeasures = elQuantitative.getChildren("Measure", sddNamespace);
1333
			int l = 0;
1334

    
1335
			//for each State
1336
			for (Element elMeasure : elMeasures){
1337
				if ((++l % modCount) == 0){ logger.info("States handled: " + (l-1));}
1338
				String type = elMeasure.getAttributeValue("type");
1339
				String value = elMeasure.getAttributeValue("value");
1340
				if (value.contains(",")) {
1341
					value = value.replace(',', '.');
1342
				}
1343
				Float v = Float.parseFloat(value);
1344
				//Float v = new Float(0);
1345
				StatisticalMeasure t = null;
1346
				if (type.equals("Min")) {
1347
					t = StatisticalMeasure.MIN();
1348
				} else if (type.equals("Mean")) {
1349
					t = StatisticalMeasure.AVERAGE();
1350
				} else if (type.equals("Max")) {
1351
					t = StatisticalMeasure.MAX();
1352
				} else if (type.equals("SD")) {
1353
					t = StatisticalMeasure.STANDARD_DEVIATION();
1354
				} else if (type.equals("N")) {
1355
					t = StatisticalMeasure.SAMPLE_SIZE();
1356
				} else if (type.equals("UMethLower")) {
1357
					t = StatisticalMeasure.TYPICAL_LOWER_BOUNDARY();
1358
				} else if (type.equals("UMethUpper")) {
1359
					t = StatisticalMeasure.TYPICAL_UPPER_BOUNDARY();
1360
				} else if (type.equals("Var")) {
1361
					t = StatisticalMeasure.VARIANCE();
1362
				} else {
1363
					t = StatisticalMeasure.NewInstance(type,type,type);
1364
					statisticalMeasures.add(t);
1365
				}
1366

    
1367
				StatisticalMeasurementValue statisticalValue = StatisticalMeasurementValue.NewInstance();
1368
				statisticalValue.setValue(v);
1369
				statisticalValue.setType(t);
1370
				quantitativeData.addStatisticalValue(statisticalValue);
1371
				featureData.add(statisticalValue);
1372
			}
1373
			taxonDescription.addElement(quantitativeData);
1374
		}
1375
	}
1376

    
1377
	/**
1378
	 * @param sddNamespace
1379
	 * @param taxonDescription
1380
	 * @param elSummaryData
1381
	 */
1382
	private void handleSummaryCategoricalData(Namespace sddNamespace,
1383
			TaxonDescription taxonDescription, Element elSummaryData) {
1384
		String ref;
1385
		// <Categorical ref="c4">
1386
		List<Element> elCategoricals = elSummaryData.getChildren("Categorical", sddNamespace);
1387
		int k = 0;
1388
		//for each Categorical
1389
		for (Element elCategorical : elCategoricals){
1390
			if ((++k % modCount) == 0){ logger.warn("Categorical handled: " + (k-1));}
1391
			ref = elCategorical.getAttributeValue("ref");
1392
			Feature feature = features.get(ref);
1393
			CategoricalData categoricalData = CategoricalData.NewInstance();
1394
			categoricalData.setFeature(feature);
1395

    
1396
			// <State ref="s3"/>
1397
			List<Element> elStates = elCategorical.getChildren("State", sddNamespace);
1398
			int l = 0;
1399

    
1400
			//for each State
1401
			for (Element elState : elStates){
1402
				if ((++l % modCount) == 0){ logger.info("States handled: " + (l-1));}
1403
				ref = elState.getAttributeValue("ref");
1404
				State state = states.get(ref);
1405
				if (state != null) {
1406
					StateData stateData = StateData.NewInstance();
1407
					stateData.setState(state);
1408
					List<Element> elModifiers = elState.getChildren("Modifier", sddNamespace);
1409
					for (Element elModifier : elModifiers){
1410
						ref = elModifier.getAttributeValue("ref");
1411
						DefinedTerm modifier = modifiers.get(ref);
1412
						if (modifier != null) {
1413
							stateData.addModifier(modifier);
1414
						}
1415
					}
1416
					categoricalData.addStateData(stateData);
1417
				}
1418
				taxonDescription.addElement(categoricalData);
1419
			}
1420
		}
1421
	}
1422

    
1423
	// imports the persons associated with the dataset creation, modification, related publications
1424
	protected void importAgents(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1425
		// <Agents>
1426
		logger.info("start Agents ...");
1427
		Element elAgents = elDataset.getChild("Agents",sddNamespace);
1428
		if (elAgents != null) {
1429
			// <Agent id="a1">
1430
			List <Element> listAgents = elAgents.getChildren("Agent", sddNamespace);
1431
			int j = 0;
1432
			//for each Agent
1433
			for (Element elAgent : listAgents){
1434

    
1435
				try {
1436

    
1437
					String idA = elAgent.getAttributeValue("id");
1438

    
1439
					//  <Representation>
1440
					//   <Label>Kevin Thiele</Label>
1441
					//   <Detail role="Description">Ali Baba is also known as r.a.m.</Detail>
1442
					//  </Representation>
1443
					Person person = Person.NewInstance();
1444
					importRepresentation(elAgent, sddNamespace, person, idA, cdmState);
1445
					person.addSource(IdentifiableSource.NewDataImportInstance(idA, "Agent"));
1446

    
1447
					/*XIM <Links>
1448
					Element elLinks = elAgent.getChild("Links",sddNamespace);
1449

    
1450
					if (elLinks != null) {
1451

    
1452
						//  <Link rel="Alternate" href="http://www.diversitycampus.net/people/hagedorn"/>
1453
						List<Element> listLinks = elLinks.getChildren("Link", sddNamespace);
1454
						int k = 0;
1455
						//for each Link
1456
						for (Element elLink : listLinks){
1457

    
1458
							try {
1459

    
1460
								String rel = elLink.getAttributeValue("rel");
1461
								String href = elLink.getAttributeValue("href");
1462

    
1463
								Media link = Media.NewInstance();
1464
								MediaRepresentation mr = MediaRepresentation.NewInstance();
1465
								mr.addRepresentationPart(MediaRepresentationPart.NewInstance(href, null));
1466
								link.addRepresentation(mr);
1467
								person.addMedia(link);
1468

    
1469
							} catch (Exception e) {
1470
								//FIXME
1471
								logger.warn("Import of Link " + k + " failed.");
1472
								success = false;
1473
							}
1474

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

    
1477
						}
1478
					}
1479
					*/
1480
					if (authors.containsKey(idA)) {
1481
						authors.put(idA,person);
1482
					}
1483

    
1484
					if (editors.containsKey(idA)) {
1485
						editors.put(idA, person);
1486
					}
1487

    
1488
				} catch (Exception e) {
1489
					//FIXME
1490
					logger.warn("Import of Agent " + j + " failed.");
1491
					cdmState.setUnsuccessfull();
1492
				}
1493

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

    
1496
			}
1497
		}
1498
	}
1499

    
1500
	// imports publications related with the data set
1501
	protected void importPublications(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1502
		/* <Publications>
1503
			  <Publication id="p112">
1504
			    <Representation>
1505
			      <Label>Gee, X. & Haa, Y. (2003). How to be happy in five minutes. Instant Gratifications, Palm Beach.</Label>
1506
			    </Representation>
1507
			    <Links>
1508
			    <Link rel="BasedOn" href="doi:10.1992/32311"/>
1509
			    <Link rel="Alternate" href="http://some.service.net/providing/bibliographic.data"/>
1510
			    </Links>
1511
			</Publications>
1512
*/
1513
		logger.info("start Publications ...");
1514
		Element elPublications = elDataset.getChild("Publications",sddNamespace);
1515

    
1516
		if (elPublications != null) {
1517
			List<Element> listPublications = elPublications.getChildren("Publication", sddNamespace);
1518
			int j = 0;
1519
			for (Element elPublication : listPublications){
1520

    
1521
				try {
1522

    
1523
					String idP = elPublication.getAttributeValue("id");
1524
					Reference publication = ReferenceFactory.newArticle();
1525
					importRepresentation(elPublication, sddNamespace, publication, idP, cdmState);
1526

    
1527
					publications.put(idP,publication);
1528

    
1529
				} catch (Exception e) {
1530
					logger.warn("Import of Publication " + j + " failed.");
1531
					cdmState.setUnsuccessfull();
1532
				}
1533

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

    
1536
			}
1537
		}
1538
	}
1539

    
1540
	// imports media objects such as images //FIXME check mediaobj
1541
	protected void importMediaObjects(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1542
		// <MediaObjects>
1543
		logger.info("start MediaObjects ...");
1544
		Element elMediaObjects = elDataset.getChild("MediaObjects",sddNamespace);
1545

    
1546
		if (elMediaObjects != null) {
1547
			// <MediaObject id="m1">
1548
			List<Element> listMediaObjects = elMediaObjects.getChildren("MediaObject", sddNamespace);
1549
			int j = 0;
1550
			for (Element elMO : listMediaObjects){
1551

    
1552
				String id = "";
1553

    
1554
				try {
1555
					String idMO = elMO.getAttributeValue("id");
1556
					id = idMO;
1557

    
1558
					//  <Representation>
1559
					//   <Label>Image description, e.g. to be used for alt-attribute in html.</Label>
1560
					//  </Representation>
1561
					Media media = Media.NewInstance();
1562
					importRepresentation(elMO, sddNamespace, media, idMO, cdmState);
1563

    
1564
					// <Type>Image</Type>
1565
					// <Source href="http://test.edu/test.jpg"/>
1566
					String type = (String)ImportHelper.getXmlInputValue(elMO,"Type",sddNamespace);
1567

    
1568
					if ((type != null) && (type.equals("Image"))) {
1569
						Element elSource = elMO.getChild("Source",sddNamespace);
1570
						String href = elSource.getAttributeValue("href");
1571

    
1572
						ImageInfo imageMetaData = null;
1573
						ImageFile image = null;
1574
						if (href.substring(0,7).equals("http://")) {
1575
							try{
1576
								URL url = new URL(href);
1577

    
1578
								imageMetaData = ImageInfo.NewInstance(url.toURI(), 0);
1579
								image = ImageFile.NewInstance(url.toURI(), null, imageMetaData);
1580
							} catch (MalformedURLException e) {
1581
								logger.error("Malformed URL", e);
1582
							}
1583
						} else {
1584
							String sns = cdmState.getConfig().getSourceNameString();
1585
							File f = new File(sns);
1586
							File parent = f.getParentFile();
1587
							String fi = parent.toString() + File.separator + href;
1588
							File file = new File(fi);
1589
							imageMetaData = ImageInfo.NewInstance(new URI(fi), 0); //file
1590
							image = ImageFile.NewInstance(file.toURI(), null, imageMetaData);
1591
						}
1592
						MediaRepresentation representation = MediaRepresentation.NewInstance(imageMetaData.getMimeType(), null);
1593
						representation.addRepresentationPart(image);
1594

    
1595
						media.addRepresentation(representation);
1596

    
1597
						ArrayList<CdmBase> lcb = (ArrayList<CdmBase>) mediaObject_ListCdmBase.get(idMO);
1598
						if (lcb != null) {
1599
							for (int k = 0; k < lcb.size(); k++) {
1600
								if (lcb.get(k) instanceof DefinedTermBase) {
1601
									DefinedTermBase dtb = (DefinedTermBase) lcb.get(k);
1602
									// if (lcb.get(0) instanceof DefinedTermBase) {
1603
									// DefinedTermBase dtb = (DefinedTermBase) lcb.get(0);
1604
									//									if (dtb!=null) {
1605
									//										if (k == 0) {
1606
									dtb.addMedia(media);
1607
									//System.out.println(dtb.getLabel());
1608
									//										} else {
1609
									//											Media me = (Media) media.clone();
1610
									//											dtb.addMedia(me);
1611
									//										}
1612
									//									}
1613
								} else if (lcb.get(k) instanceof Reference) {
1614
									Reference rb = (Reference) lcb.get(k);
1615
									//} else if (lcb.get(0) instanceof Reference) {
1616
									//Reference rb = (Reference) lcb.get(0);
1617
									// rb.setTitleCache(label);
1618
									//									if (rb!=null) {
1619
									//										if (k == 0) {
1620
									rb.addMedia(media);
1621
									//System.out.println(rb.getTitle());
1622
									//										} else {
1623
									//											Media me = (Media) media.clone();
1624
									//											rb.addMedia(me);
1625
									//										}
1626
									//									}
1627
								}/* else if (lcb.get(k) instanceof TaxonNameBase){
1628
									TaxonNameBase tb = (TaxonNameBase) lcb.get(k);
1629
									tb.addMedia(media);
1630
							}*/
1631
							}
1632
						}
1633
					}
1634

    
1635
				} catch (Exception e) {
1636
					//FIXME
1637
					logger.warn("Could not attach MediaObject " + j + "(SDD: " + id + ") to several objects.");
1638
					cdmState.setUnsuccessfull();
1639
				}
1640

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

    
1643
				}
1644
			}
1645
		}
1646
	}
1647

    
1648
	// imports the <DescriptiveConcepts> block ; DescriptiveConcepts are used as nodes in CharacterTrees and Characters as leaves
1649
	// but since Modifiers can be linked to DescriptiveConcepts they are stored as features with a particular Marker
1650
	protected void importDescriptiveConcepts(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1651
		/* <DescriptiveConcepts>
1652
		      <DescriptiveConcept id="dc0">
1653
			        <Representation>
1654
			          <Label>Fixed set of modifiers supported in Lucid3</Label>
1655
			        </Representation>
1656
			        <Modifiers>
1657
			          <Modifier id="mod1">
1658
			            <Representation>
1659
			              <Label>rarely</Label>
1660
			            </Representation>
1661
			            <ModifierClass>Frequency</ModifierClass>
1662
			            <ProportionRange lowerestimate="0.0" upperestimate="0.25"/>
1663
			          </Modifier>
1664
		          </Modifiers>
1665
		        </DescriptiveConcept>
1666
	         </DescriptiveConcepts>
1667
		 */
1668
		logger.info("start DescriptiveConcepts ...");
1669
		Element elDescriptiveConcepts = elDataset.getChild("DescriptiveConcepts",sddNamespace);
1670
		if (elDescriptiveConcepts != null) {
1671
			List<Element> listDescriptiveConcepts = elDescriptiveConcepts.getChildren("DescriptiveConcept", sddNamespace);
1672
			int j = 0;
1673

    
1674
			for (Element elDescriptiveConcept : listDescriptiveConcepts){
1675
				try {
1676
				String id = elDescriptiveConcept.getAttributeValue("id");
1677
					Feature feature = Feature.NewInstance();
1678
					feature.setKindOf(Feature.DESCRIPTION());
1679
					if (!id.equals("")) {
1680
					//	 <Representation>
1681
					//       <Label>Body</Label>
1682
					importRepresentation(elDescriptiveConcept, sddNamespace, feature, id, cdmState);
1683
						features.put(id, feature);
1684
						getTermService().save(feature);//XIM
1685
						descriptiveConcepts.add(feature);
1686
						// imports the modifiers
1687
						Element elModifiers = elDescriptiveConcept.getChild("Modifiers", sddNamespace);
1688
					if (elModifiers !=null){
1689
						List<Element> listModifiers = elModifiers.getChildren("Modifier", sddNamespace);
1690
							TermVocabulary<DefinedTerm> termVocabularyState = TermVocabulary.NewInstance(TermType.Modifier, null, null, null, null);
1691
						for (Element elModifier : listModifiers) {
1692
							DefinedTerm modif = DefinedTerm.NewModifierInstance(null, null, null);
1693
							String idmod = elModifier.getAttributeValue("id");
1694
							importRepresentation(elModifier, sddNamespace, modif, idmod, cdmState);
1695
							termVocabularyState.addTerm(modif);
1696
							//termVocabularyStates.add(termVocabularyState);
1697
							getVocabularyService().save(termVocabularyState);//XIM
1698
							modifiers.put(idmod, modif);
1699
						}
1700
						feature.addRecommendedModifierEnumeration(termVocabularyState);
1701
					}
1702

    
1703
					}
1704
				}
1705
				catch (Exception e) {
1706
					logger.warn("Import of DescriptiveConcept " + j + " failed: " + e.getMessage());
1707
				}
1708
				if ((++j % modCount) == 0){ logger.info("DescriptiveConcepts handled: " + j);}
1709

    
1710
			}
1711
		}
1712
	}
1713

    
1714
	// imports the <CharacterTrees> block
1715
	protected void importCharacterTrees(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1716
		// <CharacterTrees>
1717
		logger.info("start CharacterTrees ...");
1718
		Element elCharacterTrees = elDataset.getChild("CharacterTrees",sddNamespace);
1719

    
1720
		if (elCharacterTrees != null) {
1721
			List<Element> listCharacterTrees = elCharacterTrees.getChildren("CharacterTree", sddNamespace);
1722
			int j = 0;
1723
			for (Element elCharacterTree : listCharacterTrees){
1724
				try {
1725
					Element elRepresentation = elCharacterTree.getChild("Representation",sddNamespace);
1726
					String label = (String)ImportHelper.getXmlInputValue(elRepresentation,"Label",sddNamespace);
1727
					//Element elDesignedFor = elCharacterTree.getChild("DesignedFor",sddNamespace);//TODO ?
1728

    
1729
					FeatureTree featureTree =  FeatureTree.NewInstance();
1730
					importRepresentation(elCharacterTree, sddNamespace, featureTree, "", cdmState);
1731
					FeatureNode root = featureTree.getRoot();
1732
					List<Element> listeOfNodes = elCharacterTree.getChildren("Nodes", sddNamespace);
1733

    
1734
					//Nodes of CharacterTrees in SDD always refer to DescriptiveConcepts
1735
					for (Element elNodes : listeOfNodes) {
1736
						handleCharacterNodes(sddNamespace, root, elNodes);
1737
					}
1738
					featureTrees.add(featureTree);
1739
					if (workingSet.getDescriptiveSystem() != null){
1740
						//TODO how to handle multiple
1741
						logger.warn("Multiple feature trees not yet supported");
1742
					}else{
1743
						workingSet.setDescriptiveSystem(featureTree);
1744
					}
1745
				}
1746

    
1747
				catch (Exception e) {
1748
					logger.warn("Import of Character tree " + j + " failed.");
1749
					cdmState.setUnsuccessfull();
1750
				}
1751
				if ((++j % modCount) == 0){ logger.info("CharacterTrees handled: " + j);}
1752

    
1753
			}
1754

    
1755
		}
1756
	}
1757

    
1758
	/**
1759
	 * @param sddNamespace
1760
	 * @param root
1761
	 * @param elNodes
1762
	 */
1763
	private void handleCharacterNodes(Namespace sddNamespace, FeatureNode root, Element elNodes) {
1764
		List<Element> listNodes = elNodes.getChildren("Node", sddNamespace);
1765
		if (listNodes != null) {
1766
			for (Element elNode : listNodes){
1767
				String idN = elNode.getAttributeValue("id");
1768
				FeatureNode fn = null;
1769
				Feature dc = null;
1770
				if (idN!=null) {
1771
					// DescriptiveConcepts are used as nodes in CharacterTrees
1772
					Element elDescriptiveConcept = elNode.getChild("DescriptiveConcept", sddNamespace);
1773
					if (elDescriptiveConcept != null){
1774
						String refDC = elDescriptiveConcept.getAttributeValue("ref");
1775
						dc = features.get(refDC);
1776
						fn = FeatureNode.NewInstance(dc);
1777
					}
1778
					if (fn==null){
1779
						fn = FeatureNode.NewInstance();
1780
					}
1781
					Element elParent = elNode.getChild("Parent", sddNamespace);
1782
					// in SDD links between Nodes are referenced by the <Parent> tag
1783
					if (elParent!=null){
1784
						String refP = elParent.getAttributeValue("ref");
1785
						if (refP!=null) {
1786
							FeatureNode parent = featureNodes.get(refP);
1787
							if (parent==null){
1788
								root.addChild(fn); // if no parent found or the reference is broken, add the node to the root of the tree
1789
							}
1790
							else {
1791
								parent.addChild(fn);
1792
							}
1793
						}
1794
					}
1795
					else {
1796
						root.addChild(fn); // if no parent found or the reference is broken, add the node to the root of the tree
1797
					}
1798
				}
1799
				featureNodes.put(idN, fn);
1800
			}
1801
		}
1802

    
1803
		// Leaves of CharacterTrees in SDD are always CharNodes (referring to Characters)
1804
		List<Element> listCharNodes = elNodes.getChildren("CharNode", sddNamespace);
1805
		if (listCharNodes != null) {
1806
			for (Element elCharNode : listCharNodes){
1807
				Element elParent = elCharNode.getChild("Parent", sddNamespace);
1808
				Element elCharacter = elCharNode.getChild("Character", sddNamespace);
1809
				Element elDependencyRules = elCharNode.getChild("DependencyRules", sddNamespace);
1810
				FeatureNode fn = FeatureNode.NewInstance();
1811

    
1812
				if (elDependencyRules!=null){
1813
					Element elInapplicableIf = elCharNode.getChild("InapplicableIf", sddNamespace);
1814
					if (elInapplicableIf!=null){
1815
						List<Element> listStates = elInapplicableIf.getChildren("State", sddNamespace);
1816
						for (Element stateElement : listStates) {
1817
							String refState = stateElement.getAttributeValue("ref");
1818
							if ((refState!=null)&&(!refState.equals(""))) {
1819
								State state = states.get(refState);
1820
								fn.addInapplicableState(state);
1821
							}
1822
						}
1823
					}
1824
					Element elOnlyapplicableIf = elCharNode.getChild("OnlyApplicableIf", sddNamespace);
1825
					if (elOnlyapplicableIf!=null){
1826
						List<Element> listStates = elInapplicableIf.getChildren("State", sddNamespace);
1827
						for (Element stateElement : listStates) {
1828
							String refState = stateElement.getAttributeValue("ref");
1829
							if ((refState!=null)&&(!refState.equals(""))) {
1830
								State state = states.get(refState);
1831
								fn.addApplicableState(state);
1832
							}
1833
						}
1834
					}
1835
				}
1836

    
1837
				if (elParent!=null){
1838
					String refP = elParent.getAttributeValue("ref");
1839
					if ((refP!=null)&&(!refP.equals(""))) {
1840
					FeatureNode parent = featureNodes.get(refP);
1841
						if (parent==null){
1842
						parent = root; // if no parent found or the reference is broken, add the node to the root of the tree
1843
						}
1844
						parent.addChild(fn);
1845
					}
1846
				}
1847
				String refC = elCharacter.getAttributeValue("ref");
1848
				if ((refC!=null)&&(!refC.equals(""))){
1849
					Feature character = features.get(refC);
1850
					fn.setFeature(character);
1851
					featureNodes.put(refC, fn);
1852
				}
1853
			}
1854
		}
1855
	}
1856

    
1857
	// imports the <TaxonHierarchies> block
1858
	protected void importTaxonHierarchies(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1859

    
1860
		logger.info("start TaxonHierarchies ...");
1861
		Element elTaxonHierarchies = elDataset.getChild("TaxonHierarchies",sddNamespace);
1862

    
1863
		if (elTaxonHierarchies != null) {
1864
			List<Element> listTaxonHierarchies = elTaxonHierarchies.getChildren("TaxonHierarchy", sddNamespace);
1865
			int j = 0;
1866
			for (Element elTaxonHierarchy : listTaxonHierarchies){
1867
				try {
1868
					Element elRepresentation = elTaxonHierarchy.getChild("Representation",sddNamespace);
1869
					String label = (String)ImportHelper.getXmlInputValue(elRepresentation,"Label",sddNamespace);
1870
						Classification classification =  Classification.NewInstance(label);
1871
						importRepresentation(elTaxonHierarchy, sddNamespace, classification, "", cdmState);
1872

    
1873
						List<TaxonNode> root = classification.getChildNodes();
1874
						Element elNodes = elTaxonHierarchy.getChild("Nodes", sddNamespace); // There can be only one <Nodes> block for TaxonHierarchies
1875
						List<Element> listNodes = elNodes.getChildren("Node", sddNamespace);
1876

    
1877
						for (Element elNode : listNodes){
1878
							String idN = elNode.getAttributeValue("id");
1879
							TaxonNameBase tnb = null;
1880
							if (!idN.equals("")) {
1881
								Element elTaxonName = elNode.getChild("TaxonName", sddNamespace);
1882
								String refTN = elTaxonName.getAttributeValue("ref");
1883
								tnb = taxonNameBases.get(refTN);
1884
								Taxon taxon = (Taxon) tnb.getTaxa().iterator().next() ;
1885
								Element elParent = elNode.getChild("Parent", sddNamespace);
1886
								if (elParent!=null){
1887
									String refP = elParent.getAttributeValue("ref");
1888
									if (!refP.equals("")) {
1889
										TaxonNode parent = taxonNodes.get(refP);
1890
										TaxonNode child = parent.addChildTaxon(taxon, sec, null);
1891
										child.setSynonymToBeUsed( Synonym.NewInstance(tnb, sec)); //TODO is this required??
1892
										taxonNodes.put(idN,child);
1893
									}
1894
								}
1895
								else {
1896
									TaxonNode tn = classification.addChildTaxon(taxon, sec, null); // if no parent found or the reference is broken, add the node to the root of the tree
1897
									tn.setSynonymToBeUsed( Synonym.NewInstance(tnb, sec));  //TODO is this required??
1898
									taxonNodes.put(idN,tn);
1899
								}
1900
							}
1901
						}
1902

    
1903
						classifications.add(classification);
1904
					}
1905

    
1906
				catch (Exception e) {
1907
					//FIXME
1908
					logger.warn("Import of Taxon Hierarchy " + j + " failed.");
1909
					cdmState.setUnsuccessfull();
1910
				}
1911

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

    
1914
			}
1915

    
1916
		}
1917
	}
1918

    
1919

    
1920
	// imports the <GeographicAreas> block
1921
	protected void importGeographicAreas(Element elDataset, Namespace sddNamespace, SDDImportState cdmState) {
1922
		Element elGeographicAreas = elDataset.getChild("GeographicAreas",sddNamespace);
1923
		if (elGeographicAreas != null) {
1924
			List<Element> listGeographicAreas = elGeographicAreas.getChildren("GeographicArea", sddNamespace);
1925
			int j = 0;
1926

    
1927
			for (Element elGeographicArea : listGeographicAreas){
1928

    
1929
				String id = elGeographicArea.getAttributeValue("id");
1930
				NamedArea na = NamedArea.NewInstance();
1931
				importRepresentation(elGeographicArea, sddNamespace, na, id, cdmState);
1932
				namedAreas.put(id,na);
1933
								}
1934
			if ((++j % modCount) == 0){ logger.info("GeographicAreas handled: " + j);}
1935
							}
1936
							}
1937
}
(1-1/4)