Project

General

Profile

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

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

    
12
import java.io.File;
13
import java.io.IOException;
14
import java.math.BigDecimal;
15
import java.net.MalformedURLException;
16
import java.net.URI;
17
import java.net.URL;
18
import java.text.SimpleDateFormat;
19
import java.util.ArrayList;
20
import java.util.Date;
21
import java.util.HashMap;
22
import java.util.HashSet;
23
import java.util.List;
24
import java.util.Map;
25
import java.util.Set;
26
import java.util.UUID;
27

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

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

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

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

    
104
	private static int modCount = 1000;
105

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

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

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

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

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

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

    
143

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

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

    
152
	private Rights copyright = null;
153

    
154
	private int taxonNamesCount = 0;
155

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

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

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

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

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

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

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

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

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

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

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

    
238

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

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

    
265

    
266

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

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

    
275

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

    
285

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

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

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

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

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

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

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

    
328
	}
329

    
330

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

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

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

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

    
406

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

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

    
452
		if (elLinks != null) {
453

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

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

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

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

    
478
			}
479
		}
480
	}
481

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

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

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

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

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

    
539

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

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

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

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

    
568
	}
569

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

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

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

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

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

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

    
610

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

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

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

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

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

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

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

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

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

    
691
		return;
692
	}
693

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

    
702
	}
703

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

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

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

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

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

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

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

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

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

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

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

    
798
		}
799
	}
800

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

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

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

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

    
831
			}
832

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

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

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

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

    
867
			for (Element elIPRStatement : listIPRStatements){
868

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

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

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

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

    
900
			}
901
		}
902
	}
903

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

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

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

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

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

    
939
			}
940
		}
941
	}
942

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

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

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

    
960
		return;
961

    
962
	}
963

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

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

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

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

    
990
				vocabularies.add(termVocabularyState);
991

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

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

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

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

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

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

    
1020
		}
1021
		return;
1022
	}
1023

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

    
1037
			try {
1038

    
1039
				String idQC = elQuantitativeCharacter.getAttributeValue("id");
1040

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

    
1048
				quantitativeCharacter.setSupportsQuantitativeData(true);
1049

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

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

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

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

    
1088
				features.put(idQC, quantitativeCharacter);
1089

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

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

    
1098
		}
1099
		return;
1100
	}
1101

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

    
1110
			try {
1111

    
1112
				String idTC = elTextCharacter.getAttributeValue("id");
1113

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

    
1121
				textCharacter.setSupportsTextData(true);
1122

    
1123
				features.put(idTC, textCharacter);
1124

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

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

    
1133
		}
1134
		return;
1135
	}
1136

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

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

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

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

    
1167
			String idCD = elCodedDescription.getAttributeValue("id");
1168

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

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

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

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

    
1205
//OLD			taxonDescription.setDescriptiveSystem(featureSet);
1206

    
1207
			taxonDescriptions.put(idCD, taxonDescription);//FIXME
1208

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1458
				try {
1459

    
1460
					String idA = elAgent.getAttributeValue("id");
1461

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

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

    
1473
					if (elLinks != null) {
1474

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

    
1481
							try {
1482

    
1483
								String rel = elLink.getAttributeValue("rel");
1484
								String href = elLink.getAttributeValue("href");
1485

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

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

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

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

    
1507
					if (editors.containsKey(idA)) {
1508
						editors.put(idA, person);
1509
					}
1510

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

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

    
1519
			}
1520
		}
1521
	}
1522

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

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

    
1544
				try {
1545

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

    
1550
					publications.put(idP,publication);
1551

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

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

    
1559
			}
1560
		}
1561
	}
1562

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

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

    
1575
				String id = "";
1576

    
1577
				try {
1578
					String idMO = elMO.getAttributeValue("id");
1579
					id = idMO;
1580

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

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

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

    
1595
						CdmImageInfo imageMetaData = null;
1596
						ImageFile image = null;
1597

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

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

    
1621
						media.addRepresentation(representation);
1622

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

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

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

    
1671
				}
1672
			}
1673
		}
1674
	}
1675

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

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

    
1738
			}
1739
		}
1740
	}
1741

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

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

    
1757
					TermTree featureTree =  TermTree.NewFeatureInstance();
1758
					importRepresentation(elCharacterTree, sddNamespace, featureTree, "", cdmState);
1759
					TermNode<Feature> root = featureTree.getRoot();
1760
					List<Element> listeOfNodes = elCharacterTree.getChildren("Nodes", sddNamespace);
1761

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

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

    
1781
			}
1782
		}
1783
	}
1784

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

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

    
1838
                if (elParent!=null){
1839
                    String refP = elParent.getAttributeValue("ref");
1840
                    if ((refP!=null)&&(!refP.equals(""))) {
1841
                        TermNode<Feature> parent = termNodes.get(refP);
1842
                        if (parent==null){
1843
                            parent = root; // if no parent found or the reference is broken, add the node to the root of the tree
1844
                        }
1845
                        fn = parent.addChild();
1846
                    }
1847
                }
1848
                if (fn == null){  //TODO check if correct, added when solving #8257
1849
                    fn = root.addChild();
1850
                }
1851

    
1852
				if (elDependencyRules!=null){
1853
					Element elInapplicableIf = elCharNode.getChild("InapplicableIf", sddNamespace);
1854
					if (elInapplicableIf!=null){
1855
						List<Element> listStates = elInapplicableIf.getChildren("State", sddNamespace);
1856
						for (Element stateElement : listStates) {
1857
							String refState = stateElement.getAttributeValue("ref");
1858
							if (StringUtils.isNotBlank(refState)) {
1859
	                            State state = states.get(refState);
1860
								//FIXME handle feature
1861
								fn.addInapplicableState(null, state);
1862
							}
1863
						}
1864
					}
1865
					Element elOnlyapplicableIf = elCharNode.getChild("OnlyApplicableIf", sddNamespace);
1866
					if (elOnlyapplicableIf!=null){
1867
						List<Element> listStates = elInapplicableIf.getChildren("State", sddNamespace);
1868
						for (Element stateElement : listStates) {
1869
							String refState = stateElement.getAttributeValue("ref");
1870
							if (StringUtils.isNotBlank(refState)) {
1871
								State state = states.get(refState);
1872
								//FIXME handle feature
1873
								fn.addApplicableState(null, state);
1874
							}
1875
						}
1876
					}
1877
				}
1878

    
1879
				String refC = elCharacter.getAttributeValue("ref");
1880
				if ((refC!=null)&&(!refC.equals(""))){
1881
					Feature character = features.get(refC);
1882
					fn.setTerm(character);
1883
					termNodes.put(refC, fn);
1884
				}
1885
			}
1886
		}
1887
	}
1888

    
1889
	// imports the <TaxonHierarchies> block
1890
	protected void importTaxonHierarchies(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1891

    
1892
		logger.info("start TaxonHierarchies ...");
1893
		Element elTaxonHierarchies = elDataset.getChild("TaxonHierarchies",sddNamespace);
1894

    
1895
		if (elTaxonHierarchies != null) {
1896
			List<Element> listTaxonHierarchies = elTaxonHierarchies.getChildren("TaxonHierarchy", sddNamespace);
1897
			int j = 0;
1898
			for (Element elTaxonHierarchy : listTaxonHierarchies){
1899
				try {
1900
					Element elRepresentation = elTaxonHierarchy.getChild("Representation",sddNamespace);
1901
					String label = (String)ImportHelper.getXmlInputValue(elRepresentation,"Label",sddNamespace);
1902
						Classification classification =  Classification.NewInstance(label);
1903
						importRepresentation(elTaxonHierarchy, sddNamespace, classification, "", cdmState);
1904

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

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

    
1934
						classifications.add(classification);
1935
					}
1936

    
1937
				catch (Exception e) {
1938
					//FIXME
1939
					logger.warn("Import of Taxon Hierarchy " + j + " failed.");
1940
					cdmState.setUnsuccessfull();
1941
				}
1942

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

    
1945
			}
1946

    
1947
		}
1948
	}
1949

    
1950
	// imports the <GeographicAreas> block
1951
	protected void importGeographicAreas(Element elDataset, Namespace sddNamespace, SDDImportState cdmState) {
1952
		Element elGeographicAreas = elDataset.getChild("GeographicAreas",sddNamespace);
1953
		if (elGeographicAreas != null) {
1954
			List<Element> listGeographicAreas = elGeographicAreas.getChildren("GeographicArea", sddNamespace);
1955
			int j = 0;
1956

    
1957
			for (Element elGeographicArea : listGeographicAreas){
1958

    
1959
				String id = elGeographicArea.getAttributeValue("id");
1960
				NamedArea na = NamedArea.NewInstance();
1961
				importRepresentation(elGeographicArea, sddNamespace, na, id, cdmState);
1962
				namedAreas.put(id,na);
1963
								}
1964
			if ((++j % modCount) == 0){ logger.info("GeographicAreas handled: " + j);}
1965
		}
1966
	}
1967
}
(1-1/3)