Project

General

Profile

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

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

    
35
import eu.etaxonomy.cdm.api.service.IDescriptionService;
36
import eu.etaxonomy.cdm.common.media.ImageInfo;
37
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
38
import eu.etaxonomy.cdm.io.common.ICdmImport;
39
import eu.etaxonomy.cdm.io.common.ImportHelper;
40
import eu.etaxonomy.cdm.io.common.XmlImportBase;
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.DescriptiveDataSet;
63
import eu.etaxonomy.cdm.model.description.Feature;
64
import eu.etaxonomy.cdm.model.description.FeatureNode;
65
import eu.etaxonomy.cdm.model.description.FeatureTree;
66
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
67
import eu.etaxonomy.cdm.model.description.QuantitativeData;
68
import eu.etaxonomy.cdm.model.description.State;
69
import eu.etaxonomy.cdm.model.description.StateData;
70
import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
71
import eu.etaxonomy.cdm.model.description.StatisticalMeasurementValue;
72
import eu.etaxonomy.cdm.model.description.TaxonDescription;
73
import eu.etaxonomy.cdm.model.description.TextData;
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.INonViralName;
82
import eu.etaxonomy.cdm.model.name.Rank;
83
import eu.etaxonomy.cdm.model.name.TaxonName;
84
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
85
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
86
import eu.etaxonomy.cdm.model.reference.Reference;
87
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
88
import eu.etaxonomy.cdm.model.taxon.Classification;
89
import eu.etaxonomy.cdm.model.taxon.Synonym;
90
import eu.etaxonomy.cdm.model.taxon.Taxon;
91
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
92

    
93
/**
94
 * @author h.fradin
95
 * @since 24.10.2008
96
 */
97
@Component("sddImport")
98
public class SDDImport extends XmlImportBase<SDDImportConfigurator, SDDImportState> implements ICdmImport<SDDImportConfigurator, SDDImportState> {
99
    private static final long serialVersionUID = 5492939941309574059L;
100

    
101
    private static final Logger logger = Logger.getLogger(SDDImport.class);
102

    
103
	private static int modCount = 1000;
104

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

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

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

    
134
	private Language datasetLanguage = null;
135
	private DescriptiveDataSet descriptiveDataSet = null;
136

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

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

    
142

    
143
	private Set<StatisticalMeasure> statisticalMeasures = new HashSet<>();
144
	private Set<VersionableEntity> featureData = new HashSet<>();
145
	private Set<FeatureTree> featureTrees = new HashSet<>();
146
	private Set<Classification> classifications = new HashSet<>();
147

    
148
	private final UUID uuidAnnotationTypeLocation = UUID.fromString("a3737e07-72e3-46d2-986d-fa4cf5de0b63");
149
    private Rank defaultRank = Rank.UNKNOWN_RANK();  //TODO handle by configurator, better null?
150

    
151
	private Rights copyright = null;
152

    
153
	private int taxonNamesCount = 0;
154

    
155
	public SDDImport(){
156
		super();
157
	}
158

    
159
	private void init() {
160
	    authors = new HashMap<>();
161
	    citations = new HashMap<>();
162
	    defaultUnitPrefixes = new HashMap<>();
163
	    editors = new HashMap<>();
164
	    featureNodes = new HashMap<>();
165
	    features = new HashMap<>();
166
	    locations = new HashMap<>();
167
	    mediaObject_ListCdmBase = new HashMap<>();
168
	    mediaObject_Role = new HashMap<>();
169
	    publications = new HashMap<>();
170
	    states = new HashMap<>();
171
	    taxonDescriptions = new HashMap<>();
172
	    taxonNames = new HashMap<>();
173
	    units = new HashMap<>();
174
	    taxonNodes = new HashMap<>();
175
	    namedAreas = new HashMap<>();
176
	    specimens = new HashMap<>();
177
	    modifiers = new HashMap<>();
178

    
179
	    markerTypes = new HashSet<>();
180
	    vocabularies = new HashSet<>();
181

    
182
	    descriptiveConcepts = new HashSet<>();
183
	    annotationTypes = new HashSet<>();
184
	    sources = new HashSet<>();
185
	    statisticalMeasures = new HashSet<>();
186
	    featureData = new HashSet<>();
187
	    featureTrees = new HashSet<>();
188
	    classifications = new HashSet<>();
189
	}
190

    
191
	@Override
192
	public boolean doCheck(SDDImportState state){
193
		boolean result = true;
194
		logger.warn("No check implemented for SDD");
195
		return result;
196
	}
197

    
198
	@Override
199
	public void doInvoke(SDDImportState state){
200
	    init();
201
		TransactionStatus ts = startTransaction();
202
		SDDImportConfigurator sddConfig = state.getConfig();
203
		IProgressMonitor progressMonitor = sddConfig.getProgressMonitor();
204

    
205
		logger.info("start Datasets ...");
206

    
207
		// <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">
208
		Element root = sddConfig.getSourceRoot();
209
		Namespace sddNamespace = sddConfig.getSddNamespace();
210

    
211
		logger.info("start TechnicalMetadata ...");
212
		// <TechnicalMetadata created="2006-04-20T10:00:00">
213
		importTechnicalMetadata(root, sddNamespace, sddConfig);
214
		List<Element> elDatasets = root.getChildren("Dataset",sddNamespace);
215
//		int i = 0;
216

    
217
		//for each Dataset
218
		logger.info("start Dataset ...");
219
		progressMonitor.beginTask("Importing SDD data", elDatasets.size());
220
		for (Element elDataset : elDatasets){
221
			importDataset(elDataset, sddNamespace, state);
222
//			if ((++i % modCount) == 0){ logger.info("dataset(s) handled: " + i);}
223
//			logger.info(i + " dataset(s) handled");
224
			progressMonitor.worked(1);
225
		}
226
		commitTransaction(ts);
227
		progressMonitor.done();
228
		logger.info("End of transaction");
229
		return;
230
	}
231

    
232
	@Override
233
    protected boolean isIgnore(SDDImportState state){
234
		return false;
235
	}
236

    
237

    
238
	// associates the reference of a media object in SDD with a CdmBase Object
239
	protected void associateImageWithCdmBase(String refMO, CdmBase cb){
240
		if ((refMO != null) && (cb!=null)) {
241
			if (! refMO.equals("")) {
242
				if (! mediaObject_ListCdmBase.containsKey(refMO)) {
243
					List<CdmBase> lcb = new ArrayList<CdmBase>();
244
					lcb.add(cb);
245
					mediaObject_ListCdmBase.put(refMO,lcb);
246
				} else {
247
					List<CdmBase> lcb = mediaObject_ListCdmBase.get(refMO);
248
					lcb.add(cb);
249
					mediaObject_ListCdmBase.put(refMO,lcb);
250
				}
251
			}
252
		}
253
	}
254

    
255
	// imports information about the Dataset
256
	protected void importDatasetRepresentation(Element parent, Namespace sddNamespace){
257
		logger.info("start Representation ...");
258
		/* <Representation>
259
			<Label>The Genus Viola</Label>
260
			<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>
261
	       </Representation>
262
		 */
263

    
264

    
265

    
266
		Element elRepresentation = parent.getChild("Representation",sddNamespace);
267
		String label = (String)ImportHelper.getXmlInputValue(elRepresentation, "Label",sddNamespace);
268
		String detail = (String)ImportHelper.getXmlInputValue(elRepresentation, "Detail",sddNamespace);
269

    
270
		//new
271
		Representation representation = Representation.NewInstance(detail, label, null, datasetLanguage);
272
		descriptiveDataSet.addRepresentation(representation);
273

    
274

    
275
		//old
276
//		sec.setTitleCache(label, true);
277
//
278
//		if (detail != null) {
279
//			Annotation annotation = Annotation.NewInstance(detail, datasetLanguage);
280
//			annotation.setAnnotationType(AnnotationType.EDITORIAL());
281
//			sec.addAnnotation(annotation);
282
//		}
283

    
284

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

    
287
		for (Element elMediaObject : listMediaObjects) {
288
			String ref = null;
289
			String role = null;
290
			if (elMediaObject != null) {
291
				ref = elMediaObject.getAttributeValue("ref");
292
				role = elMediaObject.getAttributeValue("role");
293
			}
294
			if (ref != null) {
295
				if (!ref.equals("")) {
296
					this.associateImageWithCdmBase(ref,sourceReference);
297
					this.associateImageWithCdmBase(ref,sec);
298
					mediaObject_Role.put(ref,role);
299
				}
300
			}
301
		}
302
	}
303

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

    
308
		Map<Language,List<String>> langLabDet = new HashMap<Language,List<String>>();
309

    
310
		handleRepresentationLabels(sddNamespace, elRepresentation, langLabDet);
311
		handleRepresentationDetails(sddNamespace, elRepresentation, langLabDet);
312

    
313
		if (ve instanceof TermBase) {
314
			makeRepresentationForTerms((TermBase)ve, langLabDet);
315
		}else if (ve instanceof Media) {
316
			makeRepresentationForMedia((Media)ve, langLabDet);
317
		}else if (ve instanceof IdentifiableEntity<?>) {
318
			IdentifiableEntity<?> ie = (IdentifiableEntity<?>)ve;
319
			makeRepresentationForIdentifiableEntity(sddNamespace, ie, elRepresentation, langLabDet);
320
			if (ve instanceof IdentifiableMediaEntity<?>){
321
				makeRepresentationForIdentifiableMediaEntity(parent, sddNamespace, (IdentifiableMediaEntity<?>)ve);
322
			}
323
		}
324

    
325
		makeRepresentationMediaObjects(sddNamespace, ve, elRepresentation);//FIXME
326

    
327
	}
328

    
329

    
330
	/**
331
	 * Handles the "Detail" children of representations. Adds the result to the langLabDet.
332
	 * @param sddNamespace
333
	 * @param elRepresentation
334
	 * @param langLabDet
335
	 */
336
	private void handleRepresentationDetails(Namespace sddNamespace,
337
			Element elRepresentation, Map<Language, List<String>> langLabDet) {
338
		List<Element> listDetails = elRepresentation.getChildren("Detail",sddNamespace);
339
		for (Element elDetail : listDetails){
340
			Language language = getLanguage(elDetail);
341
			String role = elDetail.getAttributeValue("role");
342
			String detail = elDetail.getText();
343
			List<String> labDet = langLabDet.get(language);
344
			labDet.add(detail);
345
			labDet.add(role);
346
			langLabDet.put(language, labDet);
347
		}
348
	}
349

    
350
	/**
351
	 * Handles the "Label" children of representations. Adds the result to the langLabDet.
352
	 * @param sddNamespace
353
	 * @param elRepresentation
354
	 * @param langLabDet
355
	 */
356
	private void handleRepresentationLabels(Namespace sddNamespace,
357
				Element elRepresentation, Map<Language, List<String>> langLabDet) {
358
		// <Label xml:lang="la">Viola hederacea Labill.</Label>
359
		List<Element> listLabels = elRepresentation.getChildren("Label",sddNamespace);
360
		for (Element elLabel : listLabels){
361
			Language language = getLanguage(elLabel);
362
			String label = elLabel.getText();
363
			List<String> labDet = new ArrayList<String>(3);
364
			labDet.add(label);
365
			langLabDet.put(language, labDet);
366
		}
367
	}
368

    
369
	/**
370
	 *
371
	 * @param media
372
	 * @param langLabDet
373
	 */
374
	private void makeRepresentationForMedia(Media media, Map<Language, List<String>> langLabDet) {
375
		for (Language lang : langLabDet.keySet()){
376
			List<String> labDet = langLabDet.get(lang);
377
			if (labDet.get(0) != null){
378
				media.putTitle(LanguageString.NewInstance(labDet.get(0), lang));
379
			}
380
			if (labDet.size()>1) {
381
				media.putDescription(lang, labDet.get(1));
382
			}
383
		}
384
	}
385

    
386
	/**
387
	 * Handles representations for terms. Adds one representation per language in langLabDet.
388
	 *
389
	 * @param ve
390
	 * @param langLabDet
391
	 */
392
	private void makeRepresentationForTerms(TermBase tb, Map<Language, List<String>> langLabDet) {
393
			for (Language lang : langLabDet.keySet()){
394
				List<String> labDet = langLabDet.get(lang);
395
				if (labDet.size()>0){
396
					if (labDet.size()>1) {
397
						tb.addRepresentation(Representation.NewInstance(labDet.get(1), labDet.get(0), labDet.get(0), lang));
398
					} else {
399
						tb.addRepresentation(Representation.NewInstance(labDet.get(0), labDet.get(0), labDet.get(0), lang));
400
					}
401
				}
402
			}
403
	}
404

    
405

    
406
	/**
407
	 * Handles the "MediaObject" children of representations.
408
	 * @param sddNamespace
409
	 * @param ve
410
	 * @param elRepresentation
411
	 */
412
	private void makeRepresentationMediaObjects(Namespace sddNamespace,	VersionableEntity ve, Element elRepresentation) {
413
		List <Element> listMediaObjects = elRepresentation.getChildren("MediaObject", sddNamespace);
414
		for (Element elMediaObject : listMediaObjects) {
415
			String ref = null;
416
			//TODO
417
			String role = null;
418
			if (elMediaObject != null) {
419
				ref = elMediaObject.getAttributeValue("ref");
420
				role = elMediaObject.getAttributeValue("role");
421
			}
422
			if (StringUtils.isNotBlank(ref)) {
423
				if (ve instanceof TaxonDescription) {
424
					TaxonDescription td = (TaxonDescription) ve;
425
					if (td.getSources().size() > 0) {
426
						this.associateImageWithCdmBase(ref, td.getSources().iterator().next().getCitation());
427
					} else {
428
						Reference descriptionSource = ReferenceFactory.newGeneric();
429
						sources.add(descriptionSource);
430
						//TODO type
431
						td.addSource(OriginalSourceType.Unknown, null, null, descriptionSource, null);
432
						this.associateImageWithCdmBase(ref,descriptionSource);
433
					}
434
				} else {
435
					this.associateImageWithCdmBase(ref,ve);
436
				}
437
			}
438
		}
439
	}
440

    
441
	/**
442
	 * Handles the "Links" element
443
	 * @param parent
444
	 * @param sddNamespace
445
	 * @param ve
446
	 */
447
	private void makeRepresentationForIdentifiableMediaEntity(Element parent,
448
			Namespace sddNamespace, IdentifiableMediaEntity ime) {
449
		Element elLinks = parent.getChild("Links",sddNamespace);
450

    
451
		if (elLinks != null) {
452

    
453
			//  <Link rel="Alternate" href="http://www.diversitycampus.net/people/hagedorn"/>
454
			List<Element> listLinks = elLinks.getChildren("Link", sddNamespace);
455
			Media link = Media.NewInstance();
456
			MediaRepresentation mr = MediaRepresentation.NewInstance();
457
			int k = 0;
458
			//for each Link
459
			for (Element elLink : listLinks){
460

    
461
				try {
462
					//TODO
463
					String rel = elLink.getAttributeValue("rel");
464
					String href = elLink.getAttributeValue("href");
465
					URI uri = new URI(href);
466
					mr.addRepresentationPart(MediaRepresentationPart.NewInstance(uri, null));
467
					link.addRepresentation(mr);
468
					ime.addMedia(link);
469

    
470
				} catch (Exception e) {
471
					//FIXME
472
					logger.warn("Import of Link " + k + " failed.");
473
				}
474

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

    
477
			}
478
		}
479
	}
480

    
481
	/**
482
	 * @param sddNamespace
483
	 * @param ve
484
	 * @param elRepresentation
485
	 * @param langLabDet
486
	 * @return
487
	 */
488
	private void makeRepresentationForIdentifiableEntity(Namespace sddNamespace, IdentifiableEntity<?> ie,
489
					Element elRepresentation, Map<Language, List<String>> langLabDet) {
490
		List<String> labDet = null;
491

    
492
		if (ie instanceof TaxonName) {
493
			if (langLabDet.keySet().contains(getTermService().getLanguageByIso("la"))) {
494
				labDet = langLabDet.get(getTermService().getLanguageByIso("la"));
495
			} else if (langLabDet.keySet().contains(datasetLanguage)) {
496
				labDet = langLabDet.get(datasetLanguage);
497
				logger.info("TaxonName " + (String)ImportHelper.getXmlInputValue(elRepresentation, "Label",sddNamespace) + " is not specified as a latin name.");
498
			} else {
499
				labDet = langLabDet.get(langLabDet.keySet().iterator().next());
500
				logger.info("TaxonName " + (String)ImportHelper.getXmlInputValue(elRepresentation, "Label",sddNamespace) + " is not specified as a latin name.");
501
			}
502
		} else {
503
			labDet = langLabDet.get(langLabDet.keySet().iterator().next());
504
		}
505

    
506
		//FIXME labDet is != null only for TaxonName
507
		ie.setTitleCache(labDet.get(0), true);
508

    
509
		if (labDet.size()>1) {
510
			Annotation annotation = null;
511
			if (labDet.get(1) != null) {
512
				if (labDet.get(2) != null) {
513
					annotation = Annotation.NewInstance(labDet.get(2) + " - " + labDet.get(1), datasetLanguage);
514
				} else {
515
					annotation = Annotation.NewInstance(labDet.get(1), datasetLanguage);
516
				}
517
			}
518
			ie.addAnnotation(annotation);
519
		}
520
		return;
521
	}
522

    
523
	/**
524
	 * @param elLabel
525
	 * @return
526
	 */
527
	private Language getLanguage(Element elLanguage) {
528
		String lang = elLanguage.getAttributeValue("lang",xmlNamespace);
529
		Language language = null;
530
		if (StringUtils.isNotBlank(lang)) {
531
			language = getTermService().getLanguageByIso(lang.substring(0, 2));
532
		} else {
533
			language = datasetLanguage;
534
		}
535
		return language;
536
	}
537

    
538

    
539
	// imports the representation (label, detail, lang) of a particular SDD element
540
	protected void importTechnicalMetadata(Element root, Namespace sddNamespace, SDDImportConfigurator sddConfig){
541
		Element elTechnicalMetadata = root.getChild("TechnicalMetadata", sddNamespace);
542
		String nameCreated = elTechnicalMetadata.getAttributeValue("created");
543
		sourceReference = sddConfig.getSourceReference();
544

    
545
		if (nameCreated != null) {
546
			if (!nameCreated.equals("")) {
547
				int year = Integer.parseInt(nameCreated.substring(0,4));
548
				int monthOfYear = Integer.parseInt(nameCreated.substring(5,7));
549
				int dayOfMonth = Integer.parseInt(nameCreated.substring(8,10));
550
				int hourOfDay = Integer.parseInt(nameCreated.substring(11,13));
551
				int minuteOfHour = Integer.parseInt(nameCreated.substring(14,16));
552
				int secondOfMinute = Integer.parseInt(nameCreated.substring(17,19));
553
				DateTime created = new DateTime(year,monthOfYear,dayOfMonth,hourOfDay,minuteOfHour,secondOfMinute,0);
554
				sourceReference.setCreated(created);
555
				sec.setCreated(created);
556
			}
557
		}
558

    
559
		// <Generator name="n/a, handcrafted instance document" version="n/a"/>
560
		Element elGenerator = elTechnicalMetadata.getChild("Generator", sddNamespace);
561
		generatorName = elGenerator.getAttributeValue("name");
562
		generatorVersion = elGenerator.getAttributeValue("version");
563

    
564
		sec.addAnnotation(Annotation.NewDefaultLanguageInstance(generatorName + " - " + generatorVersion));
565
		sourceReference.addAnnotation(Annotation.NewDefaultLanguageInstance(generatorName + " - " + generatorVersion));
566

    
567
	}
568

    
569
	// imports the complete dataset information
570
	protected void importDataset(Element elDataset, Namespace sddNamespace, SDDImportState state){			// <Dataset xml:lang="en-us">
571

    
572
	    descriptiveDataSet = DescriptiveDataSet.NewInstance();
573
		importDatasetLanguage(elDataset,state);
574
		importDatasetRepresentation(elDataset, sddNamespace);
575
		importRevisionData(elDataset, sddNamespace);
576
		importIPRStatements(elDataset, sddNamespace, state);
577
		importTaxonNames(elDataset, sddNamespace, state);
578

    
579
		importDescriptiveConcepts(elDataset, sddNamespace, state);
580
		importCharacters(elDataset, sddNamespace, state);
581
		importCharacterTrees(elDataset, sddNamespace, state);
582

    
583
		MarkerType editorMarkerType = getMarkerType(state, SDDTransformer.uuidMarkerEditor, "editor", "Editor", "edt");
584
		MarkerType geographicAreaMarkerType = getMarkerType(state, SDDTransformer.uuidMarkerSDDGeographicArea, "SDDGeographicArea", "SDDGeographicArea", "ga");
585
		MarkerType descriptiveConceptMarkerType = getMarkerType(state, SDDTransformer.uuidMarkerDescriptiveConcept, "DescriptiveConcept", "Descriptive Concept", "DC");
586
		markerTypes.add(editorMarkerType);
587
		markerTypes.add(geographicAreaMarkerType);
588
		markerTypes.add(descriptiveConceptMarkerType);
589

    
590
		//saving of all imported data into the CDM db
591
		saveVocabularies();
592
		saveFeatures();
593
		saveModifiers();
594
		saveStates();
595
		saveMarkerType();
596
		saveAreas(geographicAreaMarkerType);
597
		saveUnits();
598
		saveStatisticalMeasure();
599
		saveAnnotationType();
600

    
601
		importCodedDescriptions(elDataset, sddNamespace, state);
602
		importAgents(elDataset, sddNamespace, state);
603
		importPublications(elDataset, sddNamespace, state);
604
		importMediaObjects(elDataset, sddNamespace, state);
605
		importTaxonHierarchies(elDataset, sddNamespace, state);
606
		importGeographicAreas(elDataset, sddNamespace, state);
607
		importSpecimens(elDataset,sddNamespace, state);
608

    
609

    
610
		if ((authors != null)||(editors != null)) {
611
			Team team = Team.NewInstance();
612
			if (authors != null) {
613
				for (Person author : authors.values()){
614
					team.addTeamMember(author);
615
				}
616
			}
617
			if (editors != null) {
618
				Marker marker = Marker.NewInstance();
619
				marker.setMarkerType(editorMarkerType);
620
				for (Person editor : editors.values()){
621
					Person edit = editor;
622
					edit.addMarker(marker);
623
					team.addTeamMember(edit);
624
				}
625
			}
626
			sec.setAuthorship(team);
627
			sourceReference.setAuthorship(team);
628
		}
629

    
630
		if (copyright != null) {
631
			sourceReference.addRights(copyright);
632
			sec.addRights(copyright);
633
		}
634

    
635
		// Returns a CdmApplicationController created by the values of this configuration.
636
		IDescriptionService descriptionService = getDescriptionService();
637

    
638
		for (TaxonDescription taxonDescription : taxonDescriptions.values()){
639
			// Persists a Description
640
			descriptionService.save(taxonDescription);
641
		}
642

    
643
		for (String ref : taxonDescriptions.keySet()){
644
			TaxonDescription td = taxonDescriptions.get(ref);
645
			if (citations.containsKey(ref)) {
646
				Reference publication = publications.get(citations.get(ref));
647
				if (locations.containsKey(ref)) {
648
					Annotation location = Annotation.NewInstance(locations.get(ref), datasetLanguage);
649
					//TODO move to a generic place (implemented in hurry therefore dirty)
650
					AnnotationType annotationType = getAnnotationType(state, uuidAnnotationTypeLocation, "location", "location", "location", null);
651
//					annotationTypes.add(annotationType);  TODO necessary??
652
					location.setAnnotationType(annotationType);
653
					(publication).addAnnotation(location);
654
				}
655
				//TODO type
656
				td.addSource(OriginalSourceType.Unknown, null, null, publication, null);
657
			}
658
		}
659
		logger.info("end makeTaxonDescriptions ...");
660

    
661
		if (descriptiveConcepts != null) {
662
			for (Feature feature : descriptiveConcepts) {
663
				Marker marker = Marker.NewInstance();
664
				marker.setMarkerType(descriptiveConceptMarkerType);
665
				feature.addMarker(marker);
666
			}
667
		}
668
		saveFeatures();
669

    
670
		for (Reference publication : publications.values()){
671
			getReferenceService().save(publication);
672
		}
673

    
674
		for (Reference source : sources){
675
			getReferenceService().save(source);
676
		}
677

    
678
		for (FeatureTree featureTree : featureTrees) {
679
			getFeatureTreeService().save(featureTree);
680
		}
681
		getDescriptiveDataSetService().save(descriptiveDataSet);
682
		for (Classification classification : classifications) {
683
			getClassificationService().save(classification);
684
		}
685
		for (DerivedUnit specimen : specimens.values()) {
686
			getOccurrenceService().save(specimen);
687
		}
688
		logger.info("end of persistence ...");
689

    
690
		return;
691
	}
692

    
693
	/**
694
	 *
695
	 */
696
	private void saveVocabularies() {
697
		for (TermVocabulary<?> vocabulary : vocabularies ){
698
			getVocabularyService().save(vocabulary);
699
		}
700

    
701
	}
702

    
703
	private void saveAnnotationType() {
704
		for (AnnotationType annotationType: annotationTypes){
705
		    getTermService().saveOrUpdate(annotationType);
706
		}
707
	}
708

    
709
	private void saveStatisticalMeasure() {
710
		for (StatisticalMeasure sm : statisticalMeasures){
711
			getTermService().save(sm);
712
		}
713
	}
714

    
715
	private void saveUnits() {
716
		if (units != null) {
717
			for (MeasurementUnit unit : units.values()){
718
				if (unit != null) {
719
					getTermService().save(unit);
720
				}
721
			}
722
		}
723
	}
724

    
725
	private void saveAreas(MarkerType geographicAreaMarkerType) {
726
		for (NamedArea area : namedAreas.values() ){
727
			Marker marker = Marker.NewInstance();
728
			marker.setMarkerType(geographicAreaMarkerType);
729
			area.addMarker(marker);
730
			getTermService().save(area);
731
		}
732
	}
733

    
734
	private void saveStates() {
735
		for (State state : states.values() ){
736
			getTermService().save(state);
737
		}
738
	}
739

    
740
	private void saveMarkerType() {
741
		for (MarkerType markerType : markerTypes){
742
			getTermService().save(markerType);
743
		}
744
	}
745

    
746
	private void saveModifiers() {
747
		for (DefinedTerm modifier : modifiers.values() ){
748
			getTermService().save(modifier);
749
		}
750
	}
751

    
752
	private void saveFeatures() {
753
		for (Feature feature : features.values() ){
754
			getTermService().save(feature);
755
		}
756
	}
757

    
758
	// imports the default language of the dataset
759
	protected void importDatasetLanguage(Element elDataset, SDDImportState state){
760
		String nameLang = elDataset.getAttributeValue("lang",xmlNamespace);
761

    
762
		if (StringUtils.isNotBlank(nameLang)) {
763
			String iso = nameLang.substring(0, 2);
764
			datasetLanguage = getTermService().getLanguageByIso(iso);
765
		} else {
766
			datasetLanguage = Language.DEFAULT();
767
		}
768
		if (datasetLanguage == null) {
769
			datasetLanguage = Language.DEFAULT();
770
		}
771
	}
772

    
773
	// imports the specimens
774
	protected void importSpecimens(Element elDataset, Namespace sddNamespace, SDDImportState cdmState) {
775
		logger.info("start Specimens ...");
776
		/*	<Specimens>
777
        		<Specimen id="sp1">
778
           			<Representation>
779
              			<Label>TJM45337</Label>
780
           			</Representation>
781
        		</Specimen>
782
     		</Specimens>
783
		 */
784
		Element elSpecimens = elDataset.getChild("Specimens",sddNamespace);
785
		if (elSpecimens != null){
786
			List<Element> listSpecimens = elSpecimens.getChildren("Specimen", sddNamespace);
787
			for (Element elSpecimen : listSpecimens) {
788
				String id = elSpecimen.getAttributeValue("id");
789
				DerivedUnit specimen = null;
790
				if (!id.equals("")) {
791
					specimen = DerivedUnit.NewPreservedSpecimenInstance();
792
					specimens.put(id,specimen);
793
					importRepresentation(elSpecimen, sddNamespace, specimen, id, cdmState);
794
				}
795
			}
796

    
797
		}
798
	}
799

    
800
	// imports the revision data associated with the Dataset (authors, modifications)
801
	protected void importRevisionData(Element elDataset, Namespace sddNamespace){
802
		// <RevisionData>
803
		logger.info("start RevisionData ...");
804
		Element elRevisionData = elDataset.getChild("RevisionData",sddNamespace);
805
		if (elRevisionData != null){
806
			// <Creators>
807
			Element elCreators = elRevisionData.getChild("Creators",sddNamespace);
808

    
809
			// <Agent role="aut" ref="a1"/>
810
			List<Element> listAgents = elCreators.getChildren("Agent", sddNamespace);
811

    
812
			int j = 0;
813
			//for each Agent
814
			for (Element elAgent : listAgents){
815

    
816
				String role = elAgent.getAttributeValue("role");
817
				String ref = elAgent.getAttributeValue("ref");
818
				if (role.equals("aut")) {
819
					if(!ref.equals("")) {
820
						authors.put(ref, null);
821
					}
822
				}
823
				if (role.equals("edt")) {
824
					if(!ref.equals("")) {
825
						editors.put(ref, null);
826
					}
827
				}
828
				if ((++j % modCount) == 0){ logger.info("Agents handled: " + j);}
829

    
830
			}
831

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

    
835
			if (stringDateModified != null) {
836
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
837
				Date d = null;
838
				try {
839
					d = sdf.parse(stringDateModified);
840
				} catch(Exception e) {
841
					System.err.println("Exception :");
842
					e.printStackTrace();
843
				}
844

    
845
				DateTime updated = null;
846
				if (d != null) {
847
					updated = new DateTime(d);
848
					sourceReference.setUpdated(updated);
849
					sec.setUpdated(updated);
850
				}
851
			}
852
		}
853
	}
854

    
855
	// imports ipr statements associated with a dataset
856
	protected void importIPRStatements(Element elDataset, Namespace sddNamespace, SDDImportState state){
857
		// <IPRStatements>
858
		logger.info("start IPRStatements ...");
859
		Element elIPRStatements = elDataset.getChild("IPRStatements",sddNamespace);
860
		// <IPRStatement role="Copyright">
861
		if (elIPRStatements != null) {
862
			List<Element> listIPRStatements = elIPRStatements.getChildren("IPRStatement", sddNamespace);
863
			int j = 0;
864
			//for each IPRStatement
865

    
866
			for (Element elIPRStatement : listIPRStatements){
867

    
868
				String role = elIPRStatement.getAttributeValue("role");
869
				// <Label xml:lang="en-au">(c) 2003-2006 Centre for Occasional Botany.</Label>
870
				Element elLabel = elIPRStatement.getChild("Label",sddNamespace);
871
				String lang = "";
872
				if (elLabel != null) {
873
					lang = elLabel.getAttributeValue("lang",xmlNamespace);
874
				}
875
				String label = (String)ImportHelper.getXmlInputValue(elIPRStatement, "Label",sddNamespace);
876

    
877
				if (role.equals("Copyright")) {
878
					Language iprLanguage = null;
879
					if (lang != null) {
880
						if (!lang.equals("")) {
881
							iprLanguage = getTermService().getLanguageByIso(lang.substring(0, 2));
882
						} else {
883
							iprLanguage = datasetLanguage;
884
						}
885
					}
886
					if (iprLanguage == null) {
887
						iprLanguage = datasetLanguage;
888
					}
889
					copyright = Rights.NewInstance(label, iprLanguage);
890
				}
891

    
892
				if (copyright != null) {
893
					sourceReference.addRights(copyright);
894
					sec.addRights(copyright);
895
				}
896

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

    
899
			}
900
		}
901
	}
902

    
903
	// imports the taxon names
904
	protected void importTaxonNames(Element elDataset, Namespace sddNamespace, SDDImportState state){
905
		// <TaxonNames>
906
		logger.info("start TaxonNames ...");
907
		Element elTaxonNames = elDataset.getChild("TaxonNames",sddNamespace);
908
		// <TaxonName id="t1" uri="urn:lsid:authority:namespace:my-own-id">
909
		if (elTaxonNames != null) {
910
			List<Element> listTaxonNames = elTaxonNames.getChildren("TaxonName", sddNamespace);
911
			int j = 0;
912
			//for each TaxonName
913
			for (Element elTaxonName : listTaxonNames){
914

    
915
				String id = elTaxonName.getAttributeValue("id");
916
				String uri = elTaxonName.getAttributeValue("uri");
917

    
918
				TaxonName tnb = null;
919
				if (!id.equals("")) {
920
					tnb = TaxonNameFactory.NewNonViralInstance(defaultRank);
921
					IdentifiableSource source = null;
922
					if (isNotBlank(uri)) {
923
						//TODO type
924
						source = IdentifiableSource.NewInstance(OriginalSourceType.Unknown, id, "TaxonName", ReferenceFactory.newGeneric(), uri);
925
					} else {
926
						source = IdentifiableSource.NewDataImportInstance(id, "TaxonName");
927
					}
928
					tnb.addSource(source);
929
					taxonNames.put(id,tnb);
930
				}
931

    
932
				// <Representation>
933
				// <Label xml:lang="la">Viola hederacea Labill.</Label>
934
				importRepresentation(elTaxonName, sddNamespace, tnb, id, state);
935

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

    
938
			}
939
		}
940
	}
941

    
942
	// imports the characters (categorical, quantitative and text ; sequence characters not supported) which correspond to CDM Features
943
	protected void importCharacters(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
944
		// <Characters>
945
		logger.info("start Characters ...");
946
		Element elCharacters = elDataset.getChild("Characters", sddNamespace);
947

    
948
		// <CategoricalCharacter id="c1">
949
		if (elCharacters != null) {
950
			handleCategoricalData(sddNamespace, cdmState, elCharacters);
951
			handleQuantitativeData(sddNamespace, cdmState, elCharacters);
952
			handleTextCharacters(sddNamespace, cdmState, elCharacters);
953
		}
954

    
955
		/*for (Iterator<Feature> f = features.values().iterator() ; f.hasNext() ;){
956
			featureSet.add(f.next()); //XIM Why this line ?
957
		}*/
958

    
959
		return;
960

    
961
	}
962

    
963
	/**
964
	 * @param sddNamespace
965
	 * @param cdmState
966
	 * @param elCharacters
967
	 * @return
968
	 */
969
	private void handleCategoricalData(Namespace sddNamespace, SDDImportState cdmState, Element elCharacters) {
970
		List<Element> elCategoricalCharacters = elCharacters.getChildren("CategoricalCharacter", sddNamespace);
971
		int j = 0;
972
		for (Element elCategoricalCharacter : elCategoricalCharacters){
973
			try {
974

    
975
				String idCC = elCategoricalCharacter.getAttributeValue("id");
976
				Feature categoricalCharacter = Feature.NewInstance();
977
				categoricalCharacter.setKindOf(Feature.DESCRIPTION());
978
				importRepresentation(elCategoricalCharacter, sddNamespace, categoricalCharacter, idCC, cdmState);
979
				categoricalCharacter.setSupportsCategoricalData(true);
980

    
981
				// <States>
982
				Element elStates = elCategoricalCharacter.getChild("States",sddNamespace);
983

    
984
				// <StateDefinition id="s1">
985
				List<Element> elStateDefinitions = elStates.getChildren("StateDefinition",sddNamespace);
986
				TermVocabulary<State> termVocabularyState = TermVocabulary.NewInstance(TermType.State, null, null, null, null);
987

    
988
				vocabularies.add(termVocabularyState);
989

    
990
				int k = 0;
991
				//for each StateDefinition
992
				for (Element elStateDefinition : elStateDefinitions){
993

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

    
996
					String idS = elStateDefinition.getAttributeValue("id");
997
					State state = states.get(idS);
998
					if (state == null){
999
						state = State.NewInstance();
1000
					}else{
1001
						logger.debug("State duplicate found");
1002
					}
1003
					importRepresentation(elStateDefinition, sddNamespace, state, idS, cdmState);
1004

    
1005
					termVocabularyState.addTerm(state);
1006
					states.put(idS,state);
1007
				}
1008
				categoricalCharacter.addSupportedCategoricalEnumeration(termVocabularyState);
1009
				features.put(idCC, categoricalCharacter);
1010

    
1011
			} catch (Exception e) {
1012
				logger.warn("Import of CategoricalCharacter " + j + " failed.");
1013
				cdmState.setUnsuccessfull();
1014
			}
1015

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

    
1018
		}
1019
		return;
1020
	}
1021

    
1022
	/**
1023
	 * @param sddNamespace
1024
	 * @param sddConfig
1025
	 * @param elCharacters
1026
	 */
1027
	private void handleQuantitativeData(Namespace sddNamespace,	SDDImportState cdmState, Element elCharacters) {
1028
		int j;
1029
		// <QuantitativeCharacter id="c2">
1030
		List<Element> elQuantitativeCharacters = elCharacters.getChildren("QuantitativeCharacter", sddNamespace);
1031
		j = 0;
1032
		//for each QuantitativeCharacter
1033
		for (Element elQuantitativeCharacter : elQuantitativeCharacters){
1034

    
1035
			try {
1036

    
1037
				String idQC = elQuantitativeCharacter.getAttributeValue("id");
1038

    
1039
				// <Representation>
1040
				//  <Label>Leaf length</Label>
1041
				// </Representation>
1042
				Feature quantitativeCharacter = Feature.NewInstance();
1043
				quantitativeCharacter.setKindOf(Feature.DESCRIPTION());
1044
				importRepresentation(elQuantitativeCharacter, sddNamespace, quantitativeCharacter, idQC, cdmState);
1045

    
1046
				quantitativeCharacter.setSupportsQuantitativeData(true);
1047

    
1048
				// <MeasurementUnit>
1049
				//  <Label role="Abbrev">m</Label>
1050
				// </MeasurementUnit>
1051
				Element elMeasurementUnit = elQuantitativeCharacter.getChild("MeasurementUnit",sddNamespace);
1052
				String label = "";
1053
				String role = "";
1054
				if (elMeasurementUnit != null) {
1055
					Element elLabel = elMeasurementUnit.getChild("Label",sddNamespace);
1056
					role = elLabel.getAttributeValue("role");
1057
					label = (String)ImportHelper.getXmlInputValue(elMeasurementUnit, "Label",sddNamespace);
1058
				}
1059

    
1060
				MeasurementUnit unit = null;
1061
				if (!label.equals("")){
1062
					if (role != null) {
1063
						if (role.equals("Abbrev")){
1064
							unit = MeasurementUnit.NewInstance(label,label,label);
1065
						}
1066
					} else {
1067
						unit = MeasurementUnit.NewInstance(label,label,label);
1068
					}
1069
				}
1070

    
1071
				if (unit != null) {
1072
					units.put(idQC, unit);
1073
				}
1074

    
1075
				//<Default>
1076
				//  <MeasurementUnitPrefix>milli</MeasurementUnitPrefix>
1077
				//</Default>
1078
				Element elDefault = elQuantitativeCharacter.getChild("Default",sddNamespace);
1079
				if (elDefault != null) {
1080
					String measurementUnitPrefix = (String)ImportHelper.getXmlInputValue(elDefault, "MeasurementUnitPrefix",sddNamespace);
1081
					if (! measurementUnitPrefix.equals("")){
1082
						defaultUnitPrefixes.put(idQC, measurementUnitPrefix);
1083
					}
1084
				}
1085

    
1086
				features.put(idQC, quantitativeCharacter);
1087

    
1088
			} catch (Exception e) {
1089
				//FIXME
1090
				logger.warn("Import of QuantitativeCharacter " + j + " failed.");
1091
				cdmState.setUnsuccessfull();
1092
			}
1093

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

    
1096
		}
1097
		return;
1098
	}
1099

    
1100
	private void handleTextCharacters(Namespace sddNamespace, SDDImportState cdmState, Element elCharacters) {
1101
		int j;
1102
		// <TextCharacter id="c3">
1103
		List<Element> elTextCharacters = elCharacters.getChildren("TextCharacter", sddNamespace);
1104
		j = 0;
1105
		//for each TextCharacter
1106
		for (Element elTextCharacter : elTextCharacters){
1107

    
1108
			try {
1109

    
1110
				String idTC = elTextCharacter.getAttributeValue("id");
1111

    
1112
				// <Representation>
1113
				//  <Label xml:lang="en">Leaf features not covered by other characters</Label>
1114
				// </Representation>
1115
				Feature textCharacter = Feature.NewInstance();
1116
				textCharacter.setKindOf(Feature.DESCRIPTION());
1117
				importRepresentation(elTextCharacter, sddNamespace, textCharacter, idTC, cdmState);
1118

    
1119
				textCharacter.setSupportsTextData(true);
1120

    
1121
				features.put(idTC, textCharacter);
1122

    
1123
			} catch (Exception e) {
1124
				//FIXME
1125
				logger.warn("Import of TextCharacter " + j + " failed.");
1126
				cdmState.setUnsuccessfull();
1127
			}
1128

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

    
1131
		}
1132
		return;
1133
	}
1134

    
1135
	// imports the descriptions of taxa
1136
	protected void importCodedDescriptions(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1137

    
1138
		// <CodedDescriptions>
1139
		logger.info("start CodedDescriptions ...");
1140
		Element elCodedDescriptions = elDataset.getChild("CodedDescriptions",sddNamespace);
1141

    
1142
		// <CodedDescription id="D101">
1143
		if (elCodedDescriptions != null) {
1144
			List<Element> listCodedDescriptions = elCodedDescriptions.getChildren("CodedDescription", sddNamespace);
1145
			int j = 0;
1146
			//for each CodedDescription
1147
			for (Element elCodedDescription : listCodedDescriptions){
1148
				handleCodedDescription(sddNamespace, cdmState, elCodedDescription, j);
1149
				if ((++j % modCount) == 0){ logger.info("CodedDescriptions handled: " + j);}
1150
			}
1151
		}
1152
		return;
1153
	}
1154

    
1155
	/**
1156
	 * @param sddNamespace
1157
	 * @param sddConfig
1158
	 * @param j
1159
	 * @param elCodedDescription
1160
	 * @return
1161
	 */
1162
	private void handleCodedDescription(Namespace sddNamespace, SDDImportState cdmState, Element elCodedDescription, int j) {
1163
		try {
1164

    
1165
			String idCD = elCodedDescription.getAttributeValue("id");
1166

    
1167
			// <Representation>
1168
			//  <Label>&lt;i&gt;Viola hederacea&lt;/i&gt; Labill. as revised by R. Morris April 8, 2006</Label>
1169
			// </Representation>
1170
			TaxonDescription taxonDescription = TaxonDescription.NewInstance();
1171
			if (!generatorName.isEmpty()){
1172
				Annotation annotation = Annotation.NewInstance(generatorName, AnnotationType.TECHNICAL(),Language.DEFAULT());
1173
				taxonDescription.addAnnotation(annotation);
1174
			}
1175
			importRepresentation(elCodedDescription, sddNamespace, taxonDescription, idCD, cdmState);
1176

    
1177
			// <Scope>
1178
			//  <TaxonName ref="t1"/>
1179
			//  <Citation ref="p1" location="p. 30"/>
1180
			// </Scope>
1181
			Element elScope = elCodedDescription.getChild("Scope", sddNamespace);
1182
			Taxon taxon;
1183
			if (elScope != null) {
1184
				taxon = handleCDScope(sddNamespace, cdmState, idCD, elScope);
1185
			} else {//in case no taxon is linked to the description, a new one is created
1186
				taxon = handleCDNoScope(sddNamespace, cdmState, elCodedDescription);
1187
			}
1188

    
1189
			// <SummaryData>
1190
			Element elSummaryData = elCodedDescription.getChild("SummaryData",sddNamespace);
1191
			if (elSummaryData != null) {
1192
				handleSummaryCategoricalData(sddNamespace, taxonDescription, elSummaryData);
1193
				handleSummaryQuantitativeData(sddNamespace, taxonDescription, elSummaryData);
1194
				handleSummaryTextData(sddNamespace, taxonDescription, elSummaryData);
1195
			}
1196

    
1197
			if (taxon != null) {
1198
				taxon.addDescription(taxonDescription);
1199
			}
1200
//
1201
			descriptiveDataSet.addDescription(taxonDescription);
1202

    
1203
//OLD			taxonDescription.setDescriptiveSystem(featureSet);
1204

    
1205
			taxonDescriptions.put(idCD, taxonDescription);//FIXME
1206

    
1207
		} catch (Exception e) {
1208
			//FIXME
1209
			logger.warn("Import of CodedDescription " + j + " failed.", e);
1210
			cdmState.setUnsuccessfull();
1211
		}
1212
		return;
1213
	}
1214

    
1215
	/**
1216
	 * @param sddNamespace
1217
	 * @param sddConfig
1218
	 * @param elCodedDescription
1219
	 * @param taxon
1220
	 * @return
1221
	 */
1222
	private Taxon handleCDNoScope(Namespace sddNamespace,
1223
	        SDDImportState cdmState, Element elCodedDescription	) {
1224
		Taxon taxon = null;
1225
		TaxonName nonViralName = TaxonNameFactory.NewNonViralInstance(defaultRank);
1226
		String id = new String("" + taxonNamesCount);
1227
		IdentifiableSource source = IdentifiableSource.NewDataImportInstance(id, "TaxonName");
1228
		importRepresentation(elCodedDescription, sddNamespace, nonViralName, id, cdmState);
1229

    
1230
		if(cdmState.getConfig().isReuseExistingTaxaWhenPossible()){
1231
			taxon = getTaxonService().findBestMatchingTaxon(nonViralName.getTitleCache());
1232
		}
1233

    
1234
		if(taxon != null){
1235
			nonViralName = CdmBase.deproxy(taxon.getName());
1236
//							taxonNames.put(id ,tnb);
1237
//							taxonNamesCount++;
1238
			logger.info("using existing Taxon " + taxon.getTitleCache());
1239
		} else {
1240
			nonViralName.addSource(source);
1241
			taxonNames.put(id, nonViralName);
1242
			taxonNamesCount++;
1243
			logger.info("creating new Taxon from TaxonName " + nonViralName.getTitleCache());
1244
			taxon = Taxon.NewInstance(nonViralName, sec);
1245
		}
1246
		return taxon;
1247
	}
1248

    
1249
	/**
1250
	 * @param sddNamespace
1251
	 * @param sddConfig
1252
	 * @param idCD
1253
	 * @param elScope
1254
	 * @param taxon
1255
	 * @return
1256
	 */
1257
	private Taxon handleCDScope(Namespace sddNamespace, SDDImportState cdmState,
1258
			String idCD, Element elScope) {
1259
		Taxon taxon = null;
1260
		Element elTaxonName = elScope.getChild("TaxonName", sddNamespace);
1261
		String ref = elTaxonName.getAttributeValue("ref");
1262
		INonViralName nonViralName = taxonNames.get(ref);
1263

    
1264
		if(cdmState.getConfig().isReuseExistingTaxaWhenPossible()){
1265
			taxon = getTaxonService().findBestMatchingTaxon(nonViralName.getTitleCache());
1266
		}
1267

    
1268
		if(taxon != null){
1269
			logger.info("using existing Taxon" + taxon.getTitleCache());
1270
			if(!nonViralName.getUuid().equals(taxon.getName().getUuid())){
1271
				logger.warn("TaxonName entity of existing taxon does not match Name in list -> replacing Name in list");
1272
				nonViralName = taxon.getName();
1273
			}
1274
		} else {
1275
			logger.info("creating new Taxon from TaxonName '" + nonViralName.getTitleCache()+"'");
1276
			taxon = Taxon.NewInstance(nonViralName, sec);
1277
		}
1278

    
1279
		//citation
1280
		Element elCitation = elScope.getChild("Citation",sddNamespace);
1281
		if (elCitation != null) {
1282
			String refCitation = elCitation.getAttributeValue("ref");
1283
			if (! refCitation.equals("")){
1284
				citations.put(idCD, refCitation);
1285
			}
1286
			String location = elCitation.getAttributeValue("location");
1287
			if (! location.equals("")){
1288
				locations.put(idCD, location);
1289
			}
1290
		}
1291
		return taxon;
1292
	}
1293

    
1294
	/**
1295
	 * @param sddNamespace
1296
	 * @param taxonDescription
1297
	 * @param elSummaryData
1298
	 */
1299
	private void handleSummaryTextData(Namespace sddNamespace,
1300
			TaxonDescription taxonDescription, Element elSummaryData) {
1301
		String ref;
1302
		int k;
1303
		// <TextChar ref="c3">
1304
		List<Element> elTextChars = elSummaryData.getChildren("TextChar", sddNamespace);
1305
		k = 0;
1306
		//for each TextChar
1307
		for (Element elTextChar : elTextChars){
1308
			if ((++k % modCount) == 0){ logger.info("TextChar handled: " + (k-1));}
1309
			ref = elTextChar.getAttributeValue("ref");
1310
			Feature feature = features.get(ref);
1311
			TextData textData = TextData.NewInstance();
1312
			textData.setFeature(feature);
1313

    
1314
			// <Content>Free form text</Content>
1315
			String content = (String)ImportHelper.getXmlInputValue(elTextChar, "Content",sddNamespace);
1316
			textData.putText(datasetLanguage, content);
1317
			taxonDescription.addElement(textData);
1318
		}
1319
	}
1320

    
1321
	/**
1322
	 * @param sddNamespace
1323
	 * @param taxonDescription
1324
	 * @param elSummaryData
1325
	 */
1326
	private void handleSummaryQuantitativeData(Namespace sddNamespace,
1327
			TaxonDescription taxonDescription, Element elSummaryData) {
1328
		String ref;
1329
		int k;
1330
		// <Quantitative ref="c2">
1331
		List<Element> elQuantitatives = elSummaryData.getChildren("Quantitative", sddNamespace);
1332
		k = 0;
1333
		//for each Quantitative
1334
		for (Element elQuantitative : elQuantitatives){
1335
			if ((++k % modCount) == 0){ logger.warn("Quantitative handled: " + (k-1));}
1336
			ref = elQuantitative.getAttributeValue("ref");
1337
			Feature feature = features.get(ref);
1338
			QuantitativeData quantitativeData = QuantitativeData.NewInstance();
1339
			quantitativeData.setFeature(feature);
1340

    
1341
			MeasurementUnit unit = units.get(ref);
1342
			String prefix = defaultUnitPrefixes.get(ref);
1343
			if (unit != null) {
1344
				String u = unit.getLabel();
1345
				if (prefix != null) {
1346
					u = prefix + u;
1347
				}
1348
				unit.setLabel(u);
1349
				quantitativeData.setUnit(unit);
1350
			}
1351

    
1352
			// <Measure type="Min" value="2.3"/>
1353
			List<Element> elMeasures = elQuantitative.getChildren("Measure", sddNamespace);
1354
			int l = 0;
1355

    
1356
			//for each State
1357
			for (Element elMeasure : elMeasures){
1358
				if ((++l % modCount) == 0){ logger.info("States handled: " + (l-1));}
1359
				String type = elMeasure.getAttributeValue("type");
1360
				String value = elMeasure.getAttributeValue("value");
1361
				if (value.contains(",")) {
1362
					value = value.replace(',', '.');
1363
				}
1364
				Float v = Float.parseFloat(value);
1365
				//Float v = new Float(0);
1366
				StatisticalMeasure t = null;
1367
				if (type.equals("Min")) {
1368
					t = StatisticalMeasure.MIN();
1369
				} else if (type.equals("Mean")) {
1370
					t = StatisticalMeasure.AVERAGE();
1371
				} else if (type.equals("Max")) {
1372
					t = StatisticalMeasure.MAX();
1373
				} else if (type.equals("SD")) {
1374
					t = StatisticalMeasure.STANDARD_DEVIATION();
1375
				} else if (type.equals("N")) {
1376
					t = StatisticalMeasure.SAMPLE_SIZE();
1377
				} else if (type.equals("UMethLower")) {
1378
					t = StatisticalMeasure.TYPICAL_LOWER_BOUNDARY();
1379
				} else if (type.equals("UMethUpper")) {
1380
					t = StatisticalMeasure.TYPICAL_UPPER_BOUNDARY();
1381
				} else if (type.equals("Var")) {
1382
					t = StatisticalMeasure.VARIANCE();
1383
				} else {
1384
					t = StatisticalMeasure.NewInstance(type,type,type);
1385
					statisticalMeasures.add(t);
1386
				}
1387

    
1388
				StatisticalMeasurementValue statisticalValue = StatisticalMeasurementValue.NewInstance();
1389
				statisticalValue.setValue(v);
1390
				statisticalValue.setType(t);
1391
				quantitativeData.addStatisticalValue(statisticalValue);
1392
				featureData.add(statisticalValue);
1393
			}
1394
			taxonDescription.addElement(quantitativeData);
1395
		}
1396
	}
1397

    
1398
	/**
1399
	 * @param sddNamespace
1400
	 * @param taxonDescription
1401
	 * @param elSummaryData
1402
	 */
1403
	private void handleSummaryCategoricalData(Namespace sddNamespace,
1404
			TaxonDescription taxonDescription, Element elSummaryData) {
1405
		String ref;
1406
		// <Categorical ref="c4">
1407
		List<Element> elCategoricals = elSummaryData.getChildren("Categorical", sddNamespace);
1408
		int k = 0;
1409
		//for each Categorical
1410
		for (Element elCategorical : elCategoricals){
1411
			if ((++k % modCount) == 0){ logger.warn("Categorical handled: " + (k-1));}
1412
			ref = elCategorical.getAttributeValue("ref");
1413
			Feature feature = features.get(ref);
1414
			CategoricalData categoricalData = CategoricalData.NewInstance();
1415
			categoricalData.setFeature(feature);
1416

    
1417
			// <State ref="s3"/>
1418
			List<Element> elStates = elCategorical.getChildren("State", sddNamespace);
1419
			int l = 0;
1420

    
1421
			//for each State
1422
			for (Element elState : elStates){
1423
				if ((++l % modCount) == 0){ logger.info("States handled: " + (l-1));}
1424
				ref = elState.getAttributeValue("ref");
1425
				State state = states.get(ref);
1426
				if (state != null) {
1427
					StateData stateData = StateData.NewInstance();
1428
					stateData.setState(state);
1429
					List<Element> elModifiers = elState.getChildren("Modifier", sddNamespace);
1430
					for (Element elModifier : elModifiers){
1431
						ref = elModifier.getAttributeValue("ref");
1432
						DefinedTerm modifier = modifiers.get(ref);
1433
						if (modifier != null) {
1434
							stateData.addModifier(modifier);
1435
						}
1436
					}
1437
					categoricalData.addStateData(stateData);
1438
				}
1439
				taxonDescription.addElement(categoricalData);
1440
			}
1441
		}
1442
	}
1443

    
1444
	// imports the persons associated with the dataset creation, modification, related publications
1445
	protected void importAgents(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1446
		// <Agents>
1447
		logger.info("start Agents ...");
1448
		Element elAgents = elDataset.getChild("Agents",sddNamespace);
1449
		if (elAgents != null) {
1450
			// <Agent id="a1">
1451
			List <Element> listAgents = elAgents.getChildren("Agent", sddNamespace);
1452
			int j = 0;
1453
			//for each Agent
1454
			for (Element elAgent : listAgents){
1455

    
1456
				try {
1457

    
1458
					String idA = elAgent.getAttributeValue("id");
1459

    
1460
					//  <Representation>
1461
					//   <Label>Kevin Thiele</Label>
1462
					//   <Detail role="Description">Ali Baba is also known as r.a.m.</Detail>
1463
					//  </Representation>
1464
					Person person = Person.NewInstance();
1465
					importRepresentation(elAgent, sddNamespace, person, idA, cdmState);
1466
					person.addSource(IdentifiableSource.NewDataImportInstance(idA, "Agent"));
1467

    
1468
					/*XIM <Links>
1469
					Element elLinks = elAgent.getChild("Links",sddNamespace);
1470

    
1471
					if (elLinks != null) {
1472

    
1473
						//  <Link rel="Alternate" href="http://www.diversitycampus.net/people/hagedorn"/>
1474
						List<Element> listLinks = elLinks.getChildren("Link", sddNamespace);
1475
						int k = 0;
1476
						//for each Link
1477
						for (Element elLink : listLinks){
1478

    
1479
							try {
1480

    
1481
								String rel = elLink.getAttributeValue("rel");
1482
								String href = elLink.getAttributeValue("href");
1483

    
1484
								Media link = Media.NewInstance();
1485
								MediaRepresentation mr = MediaRepresentation.NewInstance();
1486
								mr.addRepresentationPart(MediaRepresentationPart.NewInstance(href, null));
1487
								link.addRepresentation(mr);
1488
								person.addMedia(link);
1489

    
1490
							} catch (Exception e) {
1491
								//FIXME
1492
								logger.warn("Import of Link " + k + " failed.");
1493
								success = false;
1494
							}
1495

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

    
1498
						}
1499
					}
1500
					*/
1501
					if (authors.containsKey(idA)) {
1502
						authors.put(idA,person);
1503
					}
1504

    
1505
					if (editors.containsKey(idA)) {
1506
						editors.put(idA, person);
1507
					}
1508

    
1509
				} catch (Exception e) {
1510
					//FIXME
1511
					logger.warn("Import of Agent " + j + " failed.");
1512
					cdmState.setUnsuccessfull();
1513
				}
1514

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

    
1517
			}
1518
		}
1519
	}
1520

    
1521
	// imports publications related with the data set
1522
	protected void importPublications(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1523
		/* <Publications>
1524
			  <Publication id="p112">
1525
			    <Representation>
1526
			      <Label>Gee, X. & Haa, Y. (2003). How to be happy in five minutes. Instant Gratifications, Palm Beach.</Label>
1527
			    </Representation>
1528
			    <Links>
1529
			    <Link rel="BasedOn" href="doi:10.1992/32311"/>
1530
			    <Link rel="Alternate" href="http://some.service.net/providing/bibliographic.data"/>
1531
			    </Links>
1532
			</Publications>
1533
*/
1534
		logger.info("start Publications ...");
1535
		Element elPublications = elDataset.getChild("Publications",sddNamespace);
1536

    
1537
		if (elPublications != null) {
1538
			List<Element> listPublications = elPublications.getChildren("Publication", sddNamespace);
1539
			int j = 0;
1540
			for (Element elPublication : listPublications){
1541

    
1542
				try {
1543

    
1544
					String idP = elPublication.getAttributeValue("id");
1545
					Reference publication = ReferenceFactory.newArticle();
1546
					importRepresentation(elPublication, sddNamespace, publication, idP, cdmState);
1547

    
1548
					publications.put(idP,publication);
1549

    
1550
				} catch (Exception e) {
1551
					logger.warn("Import of Publication " + j + " failed.");
1552
					cdmState.setUnsuccessfull();
1553
				}
1554

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

    
1557
			}
1558
		}
1559
	}
1560

    
1561
	// imports media objects such as images //FIXME check mediaobj
1562
	protected void importMediaObjects(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1563
		// <MediaObjects>
1564
		logger.info("start MediaObjects ...");
1565
		Element elMediaObjects = elDataset.getChild("MediaObjects",sddNamespace);
1566

    
1567
		if (elMediaObjects != null) {
1568
			// <MediaObject id="m1">
1569
			List<Element> listMediaObjects = elMediaObjects.getChildren("MediaObject", sddNamespace);
1570
			int j = 0;
1571
			for (Element elMO : listMediaObjects){
1572

    
1573
				String id = "";
1574

    
1575
				try {
1576
					String idMO = elMO.getAttributeValue("id");
1577
					id = idMO;
1578

    
1579
					//  <Representation>
1580
					//   <Label>Image description, e.g. to be used for alt-attribute in html.</Label>
1581
					//  </Representation>
1582
					Media media = Media.NewInstance();
1583
					importRepresentation(elMO, sddNamespace, media, idMO, cdmState);
1584

    
1585
					// <Type>Image</Type>
1586
					// <Source href="http://test.edu/test.jpg"/>
1587
					String type = (String)ImportHelper.getXmlInputValue(elMO,"Type",sddNamespace);
1588

    
1589
					if ((type != null) && (type.equals("Image"))) {
1590
						Element elSource = elMO.getChild("Source",sddNamespace);
1591
						String href = elSource.getAttributeValue("href");
1592

    
1593
						ImageInfo imageMetaData = null;
1594
						ImageFile image = null;
1595

    
1596
						if (href.substring(0,7).equals("http://")) {
1597
							try{
1598
								URL url = new URL(href);
1599

    
1600
								imageMetaData = ImageInfo.NewInstance(url.toURI(), 0);
1601
								image = ImageFile.NewInstance(url.toURI(), null, imageMetaData);
1602
							} catch (MalformedURLException e) {
1603
								logger.error("Malformed URL", e);
1604
							} catch (IOException ioe) {
1605
							    logger.error("(IO ex: " + id + "): " + ioe.getMessage());
1606
							}
1607
						} else {
1608
							String sns = cdmState.getConfig().getSourceNameString();
1609
							File f = new File(sns);
1610
							File parent = f.getParentFile();
1611
							String fi = parent.toString() + File.separator + href;
1612
							File file = new File(fi);
1613
							imageMetaData = ImageInfo.NewInstance(new URI(fi), 0); //file
1614
							image = ImageFile.NewInstance(file.toURI(), null, imageMetaData);
1615
						}
1616
						MediaRepresentation representation = MediaRepresentation.NewInstance(imageMetaData.getMimeType(), null);
1617
						representation.addRepresentationPart(image);
1618

    
1619
						media.addRepresentation(representation);
1620

    
1621
						ArrayList<CdmBase> lcb = (ArrayList<CdmBase>) mediaObject_ListCdmBase.get(idMO);
1622
						if (lcb != null) {
1623
							for (int k = 0; k < lcb.size(); k++) {
1624
								if (lcb.get(k) instanceof DefinedTermBase) {
1625
									DefinedTermBase<?> dtb = (DefinedTermBase<?>) lcb.get(k);
1626
									// if (lcb.get(0) instanceof DefinedTermBase) {
1627
									// DefinedTermBase dtb = (DefinedTermBase) lcb.get(0);
1628
									//									if (dtb!=null) {
1629
									//										if (k == 0) {
1630
									dtb.addMedia(media);
1631
									//System.out.println(dtb.getLabel());
1632
									//										} else {
1633
									//											Media me = (Media) media.clone();
1634
									//											dtb.addMedia(me);
1635
									//										}
1636
									//									}
1637
								} else if (lcb.get(k) instanceof Reference) {
1638
									Reference rb = (Reference) lcb.get(k);
1639
									//} else if (lcb.get(0) instanceof Reference) {
1640
									//Reference rb = (Reference) lcb.get(0);
1641
									// rb.setTitleCache(label);
1642
									//									if (rb!=null) {
1643
									//										if (k == 0) {
1644
									rb.addMedia(media);
1645
									//System.out.println(rb.getTitle());
1646
									//										} else {
1647
									//											Media me = (Media) media.clone();
1648
									//											rb.addMedia(me);
1649
									//										}
1650
									//									}
1651
//								 else if (lcb.get(k) instanceof TaxonName){
1652
//									TaxonName tb = (TaxonName) lcb.get(k);
1653
//									tb.addMedia(media);
1654
								} else {
1655
									logger.warn("Can't handle associated media for " + lcb.get(k).getId() + "(" +  lcb.get(k).getClass().getSimpleName()+")"  );
1656
								}
1657
							}
1658
						}
1659
					}
1660

    
1661
				} catch (Exception e) {
1662
					//FIXME
1663
				    logger.warn("Could not attach MediaObject " + j + "(SDD: " + id + ") to several objects: " + e.getMessage());
1664
				    cdmState.setUnsuccessfull();
1665
				}
1666

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

    
1669
				}
1670
			}
1671
		}
1672
	}
1673

    
1674
	// imports the <DescriptiveConcepts> block ; DescriptiveConcepts are used as nodes in CharacterTrees and Characters as leaves
1675
	// but since Modifiers can be linked to DescriptiveConcepts they are stored as features with a particular Marker
1676
	protected void importDescriptiveConcepts(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1677
		/* <DescriptiveConcepts>
1678
		      <DescriptiveConcept id="dc0">
1679
			        <Representation>
1680
			          <Label>Fixed set of modifiers supported in Lucid3</Label>
1681
			        </Representation>
1682
			        <Modifiers>
1683
			          <Modifier id="mod1">
1684
			            <Representation>
1685
			              <Label>rarely</Label>
1686
			            </Representation>
1687
			            <ModifierClass>Frequency</ModifierClass>
1688
			            <ProportionRange lowerestimate="0.0" upperestimate="0.25"/>
1689
			          </Modifier>
1690
		          </Modifiers>
1691
		        </DescriptiveConcept>
1692
	         </DescriptiveConcepts>
1693
		 */
1694
		logger.info("start DescriptiveConcepts ...");
1695
		Element elDescriptiveConcepts = elDataset.getChild("DescriptiveConcepts",sddNamespace);
1696
		if (elDescriptiveConcepts != null) {
1697
			List<Element> listDescriptiveConcepts = elDescriptiveConcepts.getChildren("DescriptiveConcept", sddNamespace);
1698
			int j = 0;
1699

    
1700
			for (Element elDescriptiveConcept : listDescriptiveConcepts){
1701
				try {
1702
				String id = elDescriptiveConcept.getAttributeValue("id");
1703
					Feature feature = Feature.NewInstance();
1704
					feature.setKindOf(Feature.DESCRIPTION());
1705
					if (!id.equals("")) {
1706
					    //	 <Representation>
1707
    					//       <Label>Body</Label>
1708
    					importRepresentation(elDescriptiveConcept, sddNamespace, feature, id, cdmState);
1709
    						features.put(id, feature);
1710
    						getTermService().save(feature);//XIM
1711
    						descriptiveConcepts.add(feature);
1712
    						// imports the modifiers
1713
    						Element elModifiers = elDescriptiveConcept.getChild("Modifiers", sddNamespace);
1714
    					if (elModifiers !=null){
1715
    						List<Element> listModifiers = elModifiers.getChildren("Modifier", sddNamespace);
1716
    							TermVocabulary<DefinedTerm> termVocabularyState = TermVocabulary.NewInstance(TermType.Modifier, null, null, null, null);
1717
    						for (Element elModifier : listModifiers) {
1718
    							DefinedTerm modif = DefinedTerm.NewModifierInstance(null, null, null);
1719
    							String idmod = elModifier.getAttributeValue("id");
1720
    							importRepresentation(elModifier, sddNamespace, modif, idmod, cdmState);
1721
    							termVocabularyState.addTerm(modif);
1722
    							//termVocabularyStates.add(termVocabularyState);
1723
    							getVocabularyService().save(termVocabularyState);//XIM
1724
    							modifiers.put(idmod, modif);
1725
    						}
1726
    						feature.addRecommendedModifierEnumeration(termVocabularyState);
1727
    					}
1728
					}
1729
				}
1730
				catch (Exception e) {
1731
					logger.warn("Import of DescriptiveConcept " + j + " failed: " + e.getMessage());
1732
				}
1733
				if ((++j % modCount) == 0){ logger.info("DescriptiveConcepts handled: " + j);}
1734

    
1735
			}
1736
		}
1737
	}
1738

    
1739
	// imports the <CharacterTrees> block
1740
	protected void importCharacterTrees(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1741
		// <CharacterTrees>
1742
		logger.info("start CharacterTrees ...");
1743
		Element elCharacterTrees = elDataset.getChild("CharacterTrees",sddNamespace);
1744

    
1745
		if (elCharacterTrees != null) {
1746
			List<Element> listCharacterTrees = elCharacterTrees.getChildren("CharacterTree", sddNamespace);
1747
			int j = 0;
1748
			for (Element elCharacterTree : listCharacterTrees){
1749
				try {
1750
					Element elRepresentation = elCharacterTree.getChild("Representation",sddNamespace);
1751
					String label = (String)ImportHelper.getXmlInputValue(elRepresentation,"Label",sddNamespace);
1752
					//Element elDesignedFor = elCharacterTree.getChild("DesignedFor",sddNamespace);//TODO ?
1753

    
1754
					FeatureTree featureTree =  FeatureTree.NewInstance();
1755
					importRepresentation(elCharacterTree, sddNamespace, featureTree, "", cdmState);
1756
					FeatureNode<Feature> root = featureTree.getRoot();
1757
					List<Element> listeOfNodes = elCharacterTree.getChildren("Nodes", sddNamespace);
1758

    
1759
					//Nodes of CharacterTrees in SDD always refer to DescriptiveConcepts
1760
					for (Element elNodes : listeOfNodes) {
1761
						handleCharacterNodes(sddNamespace, root, elNodes);
1762
					}
1763
					featureTrees.add(featureTree);
1764
					if (descriptiveDataSet.getDescriptiveSystem() != null){
1765
						//TODO how to handle multiple
1766
						logger.warn("Multiple feature trees not yet supported");
1767
					}else{
1768
					    descriptiveDataSet.setDescriptiveSystem(featureTree);
1769
					}
1770
				}
1771

    
1772
				catch (Exception e) {
1773
					logger.warn("Import of Character tree " + j + " failed.");
1774
					cdmState.setUnsuccessfull();
1775
				}
1776
				if ((++j % modCount) == 0){ logger.info("CharacterTrees handled: " + j);}
1777

    
1778
			}
1779

    
1780
		}
1781
	}
1782

    
1783
	/**
1784
	 * @param sddNamespace
1785
	 * @param root
1786
	 * @param elNodes
1787
	 */
1788
	private void handleCharacterNodes(Namespace sddNamespace, FeatureNode<Feature> root, Element elNodes) {
1789
		List<Element> listNodes = elNodes.getChildren("Node", sddNamespace);
1790
		if (listNodes != null) {
1791
			for (Element elNode : listNodes){
1792
				String idN = elNode.getAttributeValue("id");
1793
				FeatureNode<Feature> fn = null;
1794
				Feature dc = null;
1795
				if (idN!=null) {
1796
					// DescriptiveConcepts are used as nodes in CharacterTrees
1797
					Element elDescriptiveConcept = elNode.getChild("DescriptiveConcept", sddNamespace);
1798
					if (elDescriptiveConcept != null){
1799
						String refDC = elDescriptiveConcept.getAttributeValue("ref");
1800
						dc = features.get(refDC);
1801
						fn = FeatureNode.NewInstance(dc);
1802
					}
1803
					if (fn==null){
1804
						fn = FeatureNode.NewInstance();
1805
					}
1806
					Element elParent = elNode.getChild("Parent", sddNamespace);
1807
					// in SDD links between Nodes are referenced by the <Parent> tag
1808
					if (elParent!=null){
1809
						String refP = elParent.getAttributeValue("ref");
1810
						if (refP!=null) {
1811
							FeatureNode<Feature> parent = featureNodes.get(refP);
1812
							if (parent==null){
1813
								root.addChild(fn); // if no parent found or the reference is broken, add the node to the root of the tree
1814
							}
1815
							else {
1816
								parent.addChild(fn);
1817
							}
1818
						}
1819
					}
1820
					else {
1821
						root.addChild(fn); // if no parent found or the reference is broken, add the node to the root of the tree
1822
					}
1823
				}
1824
				featureNodes.put(idN, fn);
1825
			}
1826
		}
1827

    
1828
		// Leaves of CharacterTrees in SDD are always CharNodes (referring to Characters)
1829
		List<Element> listCharNodes = elNodes.getChildren("CharNode", sddNamespace);
1830
		if (listCharNodes != null) {
1831
			for (Element elCharNode : listCharNodes){
1832
				Element elParent = elCharNode.getChild("Parent", sddNamespace);
1833
				Element elCharacter = elCharNode.getChild("Character", sddNamespace);
1834
				Element elDependencyRules = elCharNode.getChild("DependencyRules", sddNamespace);
1835
				FeatureNode<Feature> fn = FeatureNode.NewInstance();
1836

    
1837
				if (elDependencyRules!=null){
1838
					Element elInapplicableIf = elCharNode.getChild("InapplicableIf", sddNamespace);
1839
					if (elInapplicableIf!=null){
1840
						List<Element> listStates = elInapplicableIf.getChildren("State", sddNamespace);
1841
						for (Element stateElement : listStates) {
1842
							String refState = stateElement.getAttributeValue("ref");
1843
							if ((refState!=null)&&(!refState.equals(""))) {
1844
								State state = states.get(refState);
1845
								fn.addInapplicableState(state);
1846
							}
1847
						}
1848
					}
1849
					Element elOnlyapplicableIf = elCharNode.getChild("OnlyApplicableIf", sddNamespace);
1850
					if (elOnlyapplicableIf!=null){
1851
						List<Element> listStates = elInapplicableIf.getChildren("State", sddNamespace);
1852
						for (Element stateElement : listStates) {
1853
							String refState = stateElement.getAttributeValue("ref");
1854
							if ((refState!=null)&&(!refState.equals(""))) {
1855
								State state = states.get(refState);
1856
								fn.addApplicableState(state);
1857
							}
1858
						}
1859
					}
1860
				}
1861

    
1862
				if (elParent!=null){
1863
					String refP = elParent.getAttributeValue("ref");
1864
					if ((refP!=null)&&(!refP.equals(""))) {
1865
					FeatureNode<Feature> parent = featureNodes.get(refP);
1866
						if (parent==null){
1867
						parent = root; // if no parent found or the reference is broken, add the node to the root of the tree
1868
						}
1869
						parent.addChild(fn);
1870
					}
1871
				}
1872
				String refC = elCharacter.getAttributeValue("ref");
1873
				if ((refC!=null)&&(!refC.equals(""))){
1874
					Feature character = features.get(refC);
1875
					fn.setTerm(character);
1876
					featureNodes.put(refC, fn);
1877
				}
1878
			}
1879
		}
1880
	}
1881

    
1882
	// imports the <TaxonHierarchies> block
1883
	protected void importTaxonHierarchies(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1884

    
1885
		logger.info("start TaxonHierarchies ...");
1886
		Element elTaxonHierarchies = elDataset.getChild("TaxonHierarchies",sddNamespace);
1887

    
1888
		if (elTaxonHierarchies != null) {
1889
			List<Element> listTaxonHierarchies = elTaxonHierarchies.getChildren("TaxonHierarchy", sddNamespace);
1890
			int j = 0;
1891
			for (Element elTaxonHierarchy : listTaxonHierarchies){
1892
				try {
1893
					Element elRepresentation = elTaxonHierarchy.getChild("Representation",sddNamespace);
1894
					String label = (String)ImportHelper.getXmlInputValue(elRepresentation,"Label",sddNamespace);
1895
						Classification classification =  Classification.NewInstance(label);
1896
						importRepresentation(elTaxonHierarchy, sddNamespace, classification, "", cdmState);
1897

    
1898
						Element elNodes = elTaxonHierarchy.getChild("Nodes", sddNamespace); // There can be only one <Nodes> block for TaxonHierarchies
1899
						List<Element> listNodes = elNodes.getChildren("Node", sddNamespace);
1900

    
1901
						for (Element elNode : listNodes){
1902
							String idN = elNode.getAttributeValue("id");
1903
							TaxonName tnb = null;
1904
							if (!idN.equals("")) {
1905
								Element elTaxonName = elNode.getChild("TaxonName", sddNamespace);
1906
								String refTN = elTaxonName.getAttributeValue("ref");
1907
								tnb = taxonNames.get(refTN);
1908
								Taxon taxon = tnb.getTaxa().iterator().next() ;
1909
								Element elParent = elNode.getChild("Parent", sddNamespace);
1910
								if (elParent!=null){
1911
									String refP = elParent.getAttributeValue("ref");
1912
									if (!refP.equals("")) {
1913
										TaxonNode parent = taxonNodes.get(refP);
1914
										TaxonNode child = parent.addChildTaxon(taxon, sec, null);
1915
										child.setSynonymToBeUsed( Synonym.NewInstance(tnb, sec)); //TODO is this required??
1916
										taxonNodes.put(idN,child);
1917
									}
1918
								}
1919
								else {
1920
									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
1921
									tn.setSynonymToBeUsed( Synonym.NewInstance(tnb, sec));  //TODO is this required??
1922
									taxonNodes.put(idN,tn);
1923
								}
1924
							}
1925
						}
1926

    
1927
						classifications.add(classification);
1928
					}
1929

    
1930
				catch (Exception e) {
1931
					//FIXME
1932
					logger.warn("Import of Taxon Hierarchy " + j + " failed.");
1933
					cdmState.setUnsuccessfull();
1934
				}
1935

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

    
1938
			}
1939

    
1940
		}
1941
	}
1942

    
1943
	// imports the <GeographicAreas> block
1944
	protected void importGeographicAreas(Element elDataset, Namespace sddNamespace, SDDImportState cdmState) {
1945
		Element elGeographicAreas = elDataset.getChild("GeographicAreas",sddNamespace);
1946
		if (elGeographicAreas != null) {
1947
			List<Element> listGeographicAreas = elGeographicAreas.getChildren("GeographicArea", sddNamespace);
1948
			int j = 0;
1949

    
1950
			for (Element elGeographicArea : listGeographicAreas){
1951

    
1952
				String id = elGeographicArea.getAttributeValue("id");
1953
				NamedArea na = NamedArea.NewInstance();
1954
				importRepresentation(elGeographicArea, sddNamespace, na, id, cdmState);
1955
				namedAreas.put(id,na);
1956
								}
1957
			if ((++j % modCount) == 0){ logger.info("GeographicAreas handled: " + j);}
1958
		}
1959
	}
1960
}
(1-1/3)