Project

General

Profile

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

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

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

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

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

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

    
97
	private static int modCount = 1000;
98

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

    
121
	private Set<Feature> descriptiveConcepts = new HashSet<Feature>();
122
	private Set<AnnotationType> annotationTypes = new HashSet<AnnotationType>();
123
//	private Set<Feature> featureSet = new HashSet<Feature>();
124
	private Set<Reference> sources = new HashSet<Reference>();
125
	private Reference sec = ReferenceFactory.newDatabase();
126
	private Reference sourceReference = null;
127

    
128
	private Language datasetLanguage = null;
129
	private WorkingSet workingSet = null;
130

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

    
133
	private String generatorName = "";
134
	private String generatorVersion = "";
135
	
136

    
137
	private Set<StatisticalMeasure> statisticalMeasures = new HashSet<StatisticalMeasure>();
138
	private Set<VersionableEntity> featureData = new HashSet<VersionableEntity>();
139
	private Set<FeatureTree> featureTrees = new HashSet<FeatureTree>();
140
	private Set<Classification> classifications = new HashSet<Classification>();
141

    
142
	private Rights copyright = null;
143

    
144
	private int taxonNamesCount = 0;
145
	
146
	public SDDImport(){
147
		super();
148
	}
149

    
150
	@Override
151
	public boolean doCheck(SDDImportState state){
152
		boolean result = true;
153
		logger.warn("No check implemented for SDD");
154
		return result;
155
	}
156

    
157
	//	@Override
158
	//	public boolean doInvoke(IImportConfigurator config, Map<String, MapWrapper<? extends CdmBase>> stores){
159
	@Override
160
	public void doInvoke(SDDImportState state){
161
		
162
		TransactionStatus ts = startTransaction();
163
		SDDImportConfigurator sddConfig = state.getConfig();
164
		IProgressMonitor progressMonitor = sddConfig.getProgressMonitor();
165
				
166
		logger.info("start Datasets ...");
167
		
168
		// <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">
169
		Element root = sddConfig.getSourceRoot();
170
		Namespace sddNamespace = sddConfig.getSddNamespace();
171

    
172
		logger.info("start TechnicalMetadata ...");
173
		// <TechnicalMetadata created="2006-04-20T10:00:00">
174
		importTechnicalMetadata(root, sddNamespace, sddConfig);
175
		List<Element> elDatasets = root.getChildren("Dataset",sddNamespace);
176
		int i = 0;
177

    
178
		//for each Dataset
179
		logger.info("start Dataset ...");
180
		progressMonitor.beginTask("Importing SDD data", elDatasets.size());
181
		for (Element elDataset : elDatasets){
182
			importDataset(elDataset, sddNamespace, state);			
183
//			if ((++i % modCount) == 0){ logger.info("dataset(s) handled: " + i);}
184
//			logger.info(i + " dataset(s) handled");
185
			progressMonitor.worked(1);
186
		}
187
		commitTransaction(ts);
188
		progressMonitor.done();
189
		logger.info("End of transaction");
190
		return;
191
	}
192

    
193
	/* (non-Javadoc)
194
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
195
	 */
196
	protected boolean isIgnore(SDDImportState state){
197
		return false;
198
	}
199

    
200

    
201
	// associates the reference of a media object in SDD with a CdmBase Object
202
	protected void associateImageWithCdmBase(String refMO, CdmBase cb){
203
		if ((refMO != null) && (cb!=null)) {
204
			if (! refMO.equals("")) {
205
				if (! mediaObject_ListCdmBase.containsKey(refMO)) {
206
					List<CdmBase> lcb = new ArrayList<CdmBase>();
207
					lcb.add(cb);
208
					mediaObject_ListCdmBase.put(refMO,lcb);
209
				} else {
210
					List<CdmBase> lcb = mediaObject_ListCdmBase.get(refMO);
211
					lcb.add(cb);
212
					mediaObject_ListCdmBase.put(refMO,lcb);
213
				}
214
			}
215
		}
216
	}
217

    
218
	// imports information about the Dataset
219
	protected void importDatasetRepresentation(Element parent, Namespace sddNamespace){
220
		logger.info("start Representation ...");
221
		/* <Representation>
222
			<Label>The Genus Viola</Label>
223
			<Detail>This is an example for a very simple SDD file, representing a single description with categorical, quantitative, and text character. Compare also the "Fragment*" examples, which contain more complex examples in the form of document fragments. Intended for version="SDD 1.1".</Detail>
224
	       </Representation>
225
		 */
226

    
227
		
228
		
229
		Element elRepresentation = parent.getChild("Representation",sddNamespace);
230
		String label = (String)ImportHelper.getXmlInputValue(elRepresentation, "Label",sddNamespace);
231
		String detail = (String)ImportHelper.getXmlInputValue(elRepresentation, "Detail",sddNamespace);
232
		
233
		//new
234
		Representation representation = Representation.NewInstance(detail, label, null, datasetLanguage);
235
		workingSet.addRepresentation(representation);
236
		
237

    
238
		//old
239
//		sec.setTitleCache(label, true);
240
//
241
//		if (detail != null) {
242
//			Annotation annotation = Annotation.NewInstance(detail, datasetLanguage);
243
//			annotation.setAnnotationType(AnnotationType.EDITORIAL());
244
//			sec.addAnnotation(annotation);
245
//		}
246
		
247

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

    
250
		for (Element elMediaObject : listMediaObjects) {
251
			String ref = null;
252
			String role = null;
253
			if (elMediaObject != null) {
254
				ref = elMediaObject.getAttributeValue("ref");
255
				role = elMediaObject.getAttributeValue("role");
256
			}
257
			if (ref != null) {
258
				if (!ref.equals("")) {
259
					this.associateImageWithCdmBase(ref,sourceReference);
260
					this.associateImageWithCdmBase(ref,sec);
261
					mediaObject_Role.put(ref,role);
262
				}
263
			}
264
		}
265
	}
266

    
267
	// imports the representation (label, detail, lang) of a particular SDD element
268
	protected void importRepresentation(Element parent, Namespace sddNamespace, VersionableEntity ve, String id, SDDImportState state){
269
		Element elRepresentation = parent.getChild("Representation",sddNamespace);
270
		
271
		Map<Language,List<String>> langLabDet = new HashMap<Language,List<String>>();
272

    
273
		handleRepresentationLabels(sddNamespace, elRepresentation, langLabDet);
274
		handleRepresentationDetails(sddNamespace, elRepresentation, langLabDet);
275

    
276
		if (ve instanceof TermBase) {
277
			makeRepresentationForTerms((TermBase)ve, langLabDet);
278
		}else if (ve instanceof Media) {
279
			makeRepresentationForMedia((Media)ve, langLabDet);
280
		}else if (ve instanceof IdentifiableEntity<?>) {
281
			IdentifiableEntity<?> ie = (IdentifiableEntity<?>)ve;
282
			makeRepresentationForIdentifiableEntity(sddNamespace, ie, elRepresentation, langLabDet);
283
			if (ve instanceof IdentifiableMediaEntity<?>){
284
				makeRepresentationForIdentifiableMediaEntity(parent, sddNamespace, (IdentifiableMediaEntity<?>)ve);
285
			}
286
		}
287

    
288
		makeRepresentationMediaObjects(sddNamespace, ve, elRepresentation);//FIXME
289

    
290
	}
291

    
292

    
293
	/**
294
	 * Handles the "Detail" children of representations. Adds the result to the langLabDet.
295
	 * @param sddNamespace
296
	 * @param elRepresentation
297
	 * @param langLabDet
298
	 */
299
	private void handleRepresentationDetails(Namespace sddNamespace,
300
			Element elRepresentation, Map<Language, List<String>> langLabDet) {
301
		List<Element> listDetails = elRepresentation.getChildren("Detail",sddNamespace);
302
		for (Element elDetail : listDetails){
303
			Language language = getLanguage(elDetail);
304
			String role = elDetail.getAttributeValue("role");
305
			String detail = elDetail.getText();
306
			List<String> labDet = langLabDet.get(language);
307
			labDet.add(detail);
308
			labDet.add(role);
309
			langLabDet.put(language, labDet);
310
		}
311
	}
312

    
313
	/**
314
	 * Handles the "Label" children of representations. Adds the result to the langLabDet.
315
	 * @param sddNamespace
316
	 * @param elRepresentation
317
	 * @param langLabDet
318
	 */
319
	private void handleRepresentationLabels(Namespace sddNamespace,
320
				Element elRepresentation, Map<Language, List<String>> langLabDet) {
321
		// <Label xml:lang="la">Viola hederacea Labill.</Label>
322
		List<Element> listLabels = elRepresentation.getChildren("Label",sddNamespace);
323
		for (Element elLabel : listLabels){
324
			Language language = getLanguage(elLabel);
325
			String label = elLabel.getText();
326
			List<String> labDet = new ArrayList<String>(3);
327
			labDet.add(label);
328
			langLabDet.put(language, labDet);
329
		}
330
	}
331
	
332
	/**
333
	 * 
334
	 * @param ve
335
	 * @param langLabDet
336
	 */
337
	private void makeRepresentationForMedia(Media m, Map<Language, List<String>> langLabDet) {
338
		for (Language lang : langLabDet.keySet()){
339
			List<String> labDet = langLabDet.get(lang);
340
			if (labDet.get(0) != null){
341
				m.putTitle(LanguageString.NewInstance(labDet.get(0), lang));
342
			}
343
			if (labDet.size()>1) {
344
				m.addDescription(labDet.get(1), lang);
345
			}
346
		}
347
	}
348

    
349
	/**
350
	 * Handles representations for terms. Adds one representation per language in langLabDet.
351
	 * 
352
	 * @param ve
353
	 * @param langLabDet
354
	 */
355
	private void makeRepresentationForTerms(TermBase tb, Map<Language, List<String>> langLabDet) {
356
			for (Language lang : langLabDet.keySet()){
357
				List<String> labDet = langLabDet.get(lang);
358
				if (labDet.size()>0){
359
					if (labDet.size()>1) {
360
						tb.addRepresentation(Representation.NewInstance(labDet.get(1), labDet.get(0), labDet.get(0), lang));
361
					} else {
362
						tb.addRepresentation(Representation.NewInstance(labDet.get(0), labDet.get(0), labDet.get(0), lang));
363
					}
364
				}
365
			}
366
	}
367

    
368

    
369
	/**
370
	 * Handles the "MediaObject" children of representations.
371
	 * @param sddNamespace
372
	 * @param ve
373
	 * @param elRepresentation
374
	 */
375
	private void makeRepresentationMediaObjects(Namespace sddNamespace,	VersionableEntity ve, Element elRepresentation) {
376
		List <Element> listMediaObjects = elRepresentation.getChildren("MediaObject", sddNamespace);
377
		for (Element elMediaObject : listMediaObjects) {
378
			String ref = null;
379
			//TODO
380
			String role = null;
381
			if (elMediaObject != null) {
382
				ref = elMediaObject.getAttributeValue("ref");
383
				role = elMediaObject.getAttributeValue("role");
384
			}
385
			if (StringUtils.isNotBlank(ref)) {
386
				if (ve instanceof TaxonDescription) {
387
					TaxonDescription td = (TaxonDescription) ve;
388
					if (td.getDescriptionSources().size() > 0) {
389
						this.associateImageWithCdmBase(ref,(Reference) td.getDescriptionSources().toArray()[0]);
390
					} else {
391
						Reference descriptionSource = ReferenceFactory.newGeneric();
392
						sources.add(descriptionSource);
393
						td.addDescriptionSource(descriptionSource);
394
						this.associateImageWithCdmBase(ref,descriptionSource);
395
					}
396
				} else {
397
					this.associateImageWithCdmBase(ref,ve);
398
				}
399
			}
400
		}
401
	}
402

    
403
	/**
404
	 * Handles the "Links" element
405
	 * @param parent
406
	 * @param sddNamespace
407
	 * @param ve
408
	 */
409
	private void makeRepresentationForIdentifiableMediaEntity(Element parent,
410
			Namespace sddNamespace, IdentifiableMediaEntity ime) {
411
		Element elLinks = parent.getChild("Links",sddNamespace);
412

    
413
		if (elLinks != null) {
414

    
415
			//  <Link rel="Alternate" href="http://www.diversitycampus.net/people/hagedorn"/>
416
			List<Element> listLinks = elLinks.getChildren("Link", sddNamespace);
417
			Media link = Media.NewInstance();
418
			MediaRepresentation mr = MediaRepresentation.NewInstance();
419
			int k = 0;
420
			//for each Link
421
			for (Element elLink : listLinks){
422

    
423
				try {
424
					//TODO
425
					String rel = elLink.getAttributeValue("rel");
426
					String href = elLink.getAttributeValue("href");
427
					URI uri = new URI(href);
428
					mr.addRepresentationPart(MediaRepresentationPart.NewInstance(uri, null));
429
					link.addRepresentation(mr);
430
					ime.addMedia(link);
431

    
432
				} catch (Exception e) {
433
					//FIXME
434
					logger.warn("Import of Link " + k + " failed.");
435
				}
436

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

    
439
			}
440
		}
441
	}
442

    
443
	/**
444
	 * @param sddNamespace
445
	 * @param ve
446
	 * @param elRepresentation
447
	 * @param langLabDet
448
	 * @return
449
	 */
450
	private void makeRepresentationForIdentifiableEntity(Namespace sddNamespace, IdentifiableEntity<?> ie, 
451
					Element elRepresentation, Map<Language, List<String>> langLabDet) {
452
		List<String> labDet = null;
453

    
454
		if (ie instanceof TaxonNameBase) {
455
			if (langLabDet.keySet().contains(getTermService().getLanguageByIso("la"))) {
456
				labDet = langLabDet.get(getTermService().getLanguageByIso("la"));
457
			} else if (langLabDet.keySet().contains(datasetLanguage)) {
458
				labDet = langLabDet.get(datasetLanguage);
459
				logger.info("TaxonName " + (String)ImportHelper.getXmlInputValue(elRepresentation, "Label",sddNamespace) + " is not specified as a latin name.");
460
			} else {
461
				labDet = langLabDet.get(langLabDet.keySet().iterator().next());
462
				logger.info("TaxonName " + (String)ImportHelper.getXmlInputValue(elRepresentation, "Label",sddNamespace) + " is not specified as a latin name.");
463
			}
464
		} else {
465
			labDet = langLabDet.get(langLabDet.keySet().iterator().next());
466
		}
467

    
468
		//FIXME labDet is != null only for TaxonNameBase
469
		ie.setTitleCache(labDet.get(0), true);
470

    
471
		if (labDet.size()>1) {
472
			Annotation annotation = null;
473
			if (labDet.get(1) != null) {
474
				if (labDet.get(2) != null) {
475
					annotation = Annotation.NewInstance(labDet.get(2) + " - " + labDet.get(1), datasetLanguage);
476
				} else {
477
					annotation = Annotation.NewInstance(labDet.get(1), datasetLanguage);
478
				}
479
			}
480
			ie.addAnnotation(annotation);
481
		}
482
		return;
483
	}
484

    
485
	/**
486
	 * @param elLabel
487
	 * @return
488
	 */
489
	private Language getLanguage(Element elLanguage) {
490
		String lang = elLanguage.getAttributeValue("lang",xmlNamespace);
491
		Language language = null;
492
		if (StringUtils.isNotBlank(lang)) {
493
			language = getTermService().getLanguageByIso(lang.substring(0, 2));
494
		} else {
495
			language = datasetLanguage;
496
		}
497
		return language;
498
	}
499
	
500

    
501
	// imports the representation (label, detail, lang) of a particular SDD element
502
	protected void importTechnicalMetadata(Element root, Namespace sddNamespace, SDDImportConfigurator sddConfig){
503
		Element elTechnicalMetadata = root.getChild("TechnicalMetadata", sddNamespace);
504
		String nameCreated = elTechnicalMetadata.getAttributeValue("created");
505
		sourceReference = sddConfig.getSourceReference();
506

    
507
		if (nameCreated != null) {
508
			if (!nameCreated.equals("")) {
509
				int year = Integer.parseInt(nameCreated.substring(0,4));
510
				int monthOfYear = Integer.parseInt(nameCreated.substring(5,7));
511
				int dayOfMonth = Integer.parseInt(nameCreated.substring(8,10));
512
				int hourOfDay = Integer.parseInt(nameCreated.substring(11,13));
513
				int minuteOfHour = Integer.parseInt(nameCreated.substring(14,16));
514
				int secondOfMinute = Integer.parseInt(nameCreated.substring(17,19));
515
				DateTime created = new DateTime(year,monthOfYear,dayOfMonth,hourOfDay,minuteOfHour,secondOfMinute,0);
516
				sourceReference.setCreated(created);
517
				sec.setCreated(created);
518
			}
519
		}
520

    
521
		// <Generator name="n/a, handcrafted instance document" version="n/a"/>
522
		Element elGenerator = elTechnicalMetadata.getChild("Generator", sddNamespace);
523
		generatorName = elGenerator.getAttributeValue("name");
524
		generatorVersion = elGenerator.getAttributeValue("version");
525

    
526
		sec.addAnnotation(Annotation.NewDefaultLanguageInstance(generatorName + " - " + generatorVersion));
527
		sourceReference.addAnnotation(Annotation.NewDefaultLanguageInstance(generatorName + " - " + generatorVersion));
528

    
529
	}
530

    
531
	// imports the complete dataset information
532
	protected void importDataset(Element elDataset, Namespace sddNamespace, SDDImportState state){			// <Dataset xml:lang="en-us">
533
		
534
		workingSet = WorkingSet.NewInstance();
535
		importDatasetLanguage(elDataset,state);
536
		importDatasetRepresentation(elDataset, sddNamespace);
537
		importRevisionData(elDataset, sddNamespace);
538
		importIPRStatements(elDataset, sddNamespace, state);
539
		importTaxonNames(elDataset, sddNamespace, state);
540

    
541
		importDescriptiveConcepts(elDataset, sddNamespace, state);
542
		importCharacters(elDataset, sddNamespace, state);
543
		importCharacterTrees(elDataset, sddNamespace, state);
544
		
545
		MarkerType editorMarkerType = getMarkerType(state, SDDTransformer.uuidMarkerEditor, "editor", "Editor", "edt");
546
		MarkerType geographicAreaMarkerType = getMarkerType(state, SDDTransformer.uuidMarkerSDDGeographicArea, "SDDGeographicArea", "SDDGeographicArea", "ga"); 
547
		MarkerType descriptiveConceptMarkerType = getMarkerType(state, SDDTransformer.uuidMarkerDescriptiveConcept, "DescriptiveConcept", "Descriptive Concept", "DC");
548
		markerTypes.add(editorMarkerType);
549
		markerTypes.add(geographicAreaMarkerType);
550
		markerTypes.add(descriptiveConceptMarkerType);
551
		
552
		//saving of all imported data into the CDM db
553
		saveVocabularies();
554
		saveFeatures();
555
		saveModifiers();
556
		saveStates();
557
		saveMarkerType();
558
		saveAreas(geographicAreaMarkerType);		
559
		saveUnits();
560
		saveStatisticalMeasure();		
561
		saveAnnotationType();
562

    
563
		importCodedDescriptions(elDataset, sddNamespace, state);
564
		importAgents(elDataset, sddNamespace, state);
565
		importPublications(elDataset, sddNamespace, state);
566
		importMediaObjects(elDataset, sddNamespace, state);
567
		importTaxonHierarchies(elDataset, sddNamespace, state);
568
		importGeographicAreas(elDataset, sddNamespace, state);
569
		importSpecimens(elDataset,sddNamespace, state);
570
		
571
		
572
		if ((authors != null)||(editors != null)) {
573
			Team team = Team.NewInstance();
574
			if (authors != null) {
575
				for (Person author : authors.values()){
576
					team.addTeamMember(author);
577
				}
578
			}
579
			if (editors != null) {
580
				Marker marker = Marker.NewInstance();
581
				marker.setMarkerType(editorMarkerType);
582
				for (Person editor : editors.values()){
583
					Person edit = editor;
584
					edit.addMarker(marker);
585
					team.addTeamMember(edit);
586
				}
587
			}
588
			sec.setAuthorTeam(team);
589
			sourceReference.setAuthorTeam(team);
590
		}
591

    
592
		if (copyright != null) {
593
			sourceReference.addRights(copyright);
594
			sec.addRights(copyright);
595
		}
596
		
597
		// Returns a CdmApplicationController created by the values of this configuration.
598
		IDescriptionService descriptionService = getDescriptionService();
599
		
600
		for (TaxonDescription taxonDescription : taxonDescriptions.values()){
601
			// Persists a Description
602
			descriptionService.save(taxonDescription);
603
		}
604
		
605
		for (String ref : taxonDescriptions.keySet()){
606
			TaxonDescription td = taxonDescriptions.get(ref);
607
			if (citations.containsKey(ref)) {
608
				Reference publication = publications.get(citations.get(ref));
609
				if (locations.containsKey(ref)) {
610
					Annotation location = Annotation.NewInstance(locations.get(ref), datasetLanguage);
611
					AnnotationType annotationType = AnnotationType.NewInstance("", "location", "");
612
					annotationTypes.add(annotationType);
613
					location.setAnnotationType(annotationType);
614
					(publication).addAnnotation(location);
615
				}
616
				td.addDescriptionSource(publication);
617
			}
618
		}
619
		logger.info("end makeTaxonDescriptions ...");
620

    
621
		if (descriptiveConcepts != null) {
622
			for (Feature feature : descriptiveConcepts) {
623
				Marker marker = Marker.NewInstance();
624
				marker.setMarkerType(descriptiveConceptMarkerType);
625
				feature.addMarker(marker);
626
			}
627
		}
628
		saveFeatures();
629
		
630
		for (Reference publication : publications.values()){
631
			getReferenceService().save(publication); 
632
		}
633
		
634
		for (Reference source : sources){
635
			getReferenceService().save(source); 
636
		}
637

    
638
		for (FeatureTree featureTree : featureTrees) {
639
			getFeatureTreeService().save(featureTree);
640
		}
641
		getWorkingSetService().save(workingSet);
642
		for (Classification classification : classifications) {
643
			getClassificationService().save(classification);
644
		}
645
		for (Specimen specimen : specimens.values()) {
646
			getOccurrenceService().save(specimen);
647
		}
648
		logger.info("end of persistence ...");
649
		
650
		return;
651
	}
652

    
653
	/**
654
	 * 
655
	 */
656
	private void saveVocabularies() {
657
		for (TermVocabulary vocabulary : vocabularies ){
658
			getVocabularyService().save(vocabulary);
659
		}
660
		
661
	}
662

    
663
	private void saveAnnotationType() {
664
		for (AnnotationType annotationType: annotationTypes){
665
			getTermService().save(annotationType); 
666
		}
667
	}
668

    
669
	private void saveStatisticalMeasure() {
670
		for (StatisticalMeasure sm : statisticalMeasures){
671
			getTermService().save(sm); 
672
		}
673
	}
674

    
675
	private void saveUnits() {
676
		if (units != null) {
677
			for (MeasurementUnit unit : units.values()){
678
				if (unit != null) {
679
					getTermService().save(unit); 
680
				}
681
			}
682
		}
683
	}
684

    
685
	private void saveAreas(MarkerType geographicAreaMarkerType) {
686
		for (NamedArea area : namedAreas.values() ){
687
			Marker marker = Marker.NewInstance();
688
			marker.setMarkerType(geographicAreaMarkerType);
689
			area.addMarker(marker);
690
			getTermService().save(area);
691
		}
692
	}
693

    
694
	private void saveStates() {
695
		for (State state : states.values() ){
696
			getTermService().save(state);
697
		}
698
	}
699

    
700
	private void saveMarkerType() {
701
		for (MarkerType markerType : markerTypes){
702
			getTermService().save(markerType);
703
		}
704
	}
705

    
706
	private void saveModifiers() {
707
		for (Modifier modifier : modifiers.values() ){
708
			getTermService().save(modifier);
709
		}
710
	}
711

    
712
	private void saveFeatures() {
713
		for (Feature feature : features.values() ){
714
			getTermService().save(feature);
715
		}
716
	}
717

    
718
	// imports the default language of the dataset
719
	protected void importDatasetLanguage(Element elDataset, SDDImportState state){
720
		String nameLang = elDataset.getAttributeValue("lang",xmlNamespace);
721

    
722
		if (StringUtils.isNotBlank(nameLang)) {
723
			String iso = nameLang.substring(0, 2);
724
			datasetLanguage = getTermService().getLanguageByIso(iso);
725
		} else {
726
			datasetLanguage = Language.DEFAULT();
727
		}
728
		if (datasetLanguage == null) {
729
			datasetLanguage = Language.DEFAULT();
730
		}
731
	}
732
	
733
	// imports the specimens
734
	protected void importSpecimens(Element elDataset, Namespace sddNamespace, SDDImportState cdmState) {
735
		logger.info("start Specimens ...");
736
		/*	<Specimens>
737
        		<Specimen id="sp1">
738
           			<Representation>
739
              			<Label>TJM45337</Label>
740
           			</Representation>
741
        		</Specimen>
742
     		</Specimens>
743
		 */
744
		Element elSpecimens = elDataset.getChild("Specimens",sddNamespace);
745
		if (elSpecimens != null){
746
			List<Element> listSpecimens = elSpecimens.getChildren("Specimen", sddNamespace);
747
			int j = 0;
748
			for (Element elSpecimen : listSpecimens) {
749
				String id = elSpecimen.getAttributeValue("id");
750
				Specimen specimen = null;
751
				if (!id.equals("")) {
752
					specimen = Specimen.NewInstance();
753
					specimens.put(id,specimen);
754
					importRepresentation(elSpecimen, sddNamespace, specimen, id, cdmState);
755
				}
756
			}
757

    
758
		}
759
	}
760

    
761
	// imports the revision data associated with the Dataset (authors, modifications)
762
	protected void importRevisionData(Element elDataset, Namespace sddNamespace){
763
		// <RevisionData>
764
		logger.info("start RevisionData ...");
765
		Element elRevisionData = elDataset.getChild("RevisionData",sddNamespace);
766
		if (elRevisionData != null){
767
			// <Creators>
768
			Element elCreators = elRevisionData.getChild("Creators",sddNamespace);
769

    
770
			// <Agent role="aut" ref="a1"/>
771
			List<Element> listAgents = elCreators.getChildren("Agent", sddNamespace);
772

    
773
			int j = 0;
774
			//for each Agent
775
			for (Element elAgent : listAgents){
776

    
777
				String role = elAgent.getAttributeValue("role");
778
				String ref = elAgent.getAttributeValue("ref");
779
				if (role.equals("aut")) {
780
					if(!ref.equals("")) {
781
						authors.put(ref, null);
782
					}
783
				}
784
				if (role.equals("edt")) {
785
					if(!ref.equals("")) {
786
						editors.put(ref, null);
787
					}
788
				}
789
				if ((++j % modCount) == 0){ logger.info("Agents handled: " + j);}
790

    
791
			}
792

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

    
796
			if (stringDateModified != null) {
797
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
798
				Date d = null;
799
				try {
800
					d = sdf.parse(stringDateModified);
801
				} catch(Exception e) {
802
					System.err.println("Exception :");
803
					e.printStackTrace();
804
				}
805

    
806
				DateTime updated = null;
807
				if (d != null) {
808
					updated = new DateTime(d);
809
					sourceReference.setUpdated(updated);
810
					sec.setUpdated(updated);
811
				}
812
			}
813
		}
814
	}
815

    
816
	// imports ipr statements associated with a dataset
817
	protected void importIPRStatements(Element elDataset, Namespace sddNamespace, SDDImportState state){
818
		// <IPRStatements>
819
		logger.info("start IPRStatements ...");
820
		Element elIPRStatements = elDataset.getChild("IPRStatements",sddNamespace);
821
		// <IPRStatement role="Copyright">
822
		if (elIPRStatements != null) {
823
			List<Element> listIPRStatements = elIPRStatements.getChildren("IPRStatement", sddNamespace);
824
			int j = 0;
825
			//for each IPRStatement
826

    
827
			for (Element elIPRStatement : listIPRStatements){
828

    
829
				String role = elIPRStatement.getAttributeValue("role");
830
				// <Label xml:lang="en-au">(c) 2003-2006 Centre for Occasional Botany.</Label>
831
				Element elLabel = elIPRStatement.getChild("Label",sddNamespace);
832
				String lang = "";
833
				if (elLabel != null) {
834
					lang = elLabel.getAttributeValue("lang",xmlNamespace);
835
				}
836
				String label = (String)ImportHelper.getXmlInputValue(elIPRStatement, "Label",sddNamespace);
837

    
838
				if (role.equals("Copyright")) {
839
					Language iprLanguage = null;
840
					if (lang != null) {
841
						if (!lang.equals("")) {
842
							iprLanguage = getTermService().getLanguageByIso(lang.substring(0, 2));
843
						} else {
844
							iprLanguage = datasetLanguage;
845
						}
846
					}
847
					if (iprLanguage == null) {
848
						iprLanguage = datasetLanguage;
849
					}
850
					copyright = Rights.NewInstance(label, iprLanguage);
851
				}
852

    
853
				if (copyright != null) {
854
					sourceReference.addRights(copyright);
855
					sec.addRights(copyright);
856
				}
857

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

    
860
			}
861
		}
862
	}
863

    
864
	// imports the taxon names
865
	protected void importTaxonNames(Element elDataset, Namespace sddNamespace, SDDImportState state){
866
		// <TaxonNames>
867
		logger.info("start TaxonNames ...");
868
		Element elTaxonNames = elDataset.getChild("TaxonNames",sddNamespace);
869
		// <TaxonName id="t1" uri="urn:lsid:authority:namespace:my-own-id">
870
		if (elTaxonNames != null) {
871
			List<Element> listTaxonNames = elTaxonNames.getChildren("TaxonName", sddNamespace);
872
			int j = 0;
873
			//for each TaxonName
874
			for (Element elTaxonName : listTaxonNames){
875

    
876
				String id = elTaxonName.getAttributeValue("id");
877
				String uri = elTaxonName.getAttributeValue("uri");
878

    
879
				NonViralName tnb = null;
880
				if (!id.equals("")) {
881
					tnb = NonViralName.NewInstance(null);
882
					IdentifiableSource source = null;
883
					if (uri != null) {
884
						if (!uri.equals("")) {
885
							source = IdentifiableSource.NewInstance(id, "TaxonName", ReferenceFactory.newGeneric(), uri);
886
						}
887
					} else {
888
						source = IdentifiableSource.NewInstance(id, "TaxonName");
889
					}
890
					tnb.addSource(source);
891
					taxonNameBases.put(id,tnb);
892
				}
893

    
894
				// <Representation>
895
				// <Label xml:lang="la">Viola hederacea Labill.</Label>
896
				importRepresentation(elTaxonName, sddNamespace, tnb, id, state);
897

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

    
900
			}
901
		}
902
	}
903

    
904
	// imports the characters (categorical, quantitative and text ; sequence characters not supported) which correspond to CDM Features
905
	protected void importCharacters(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
906
		// <Characters>
907
		logger.info("start Characters ...");
908
		Element elCharacters = elDataset.getChild("Characters", sddNamespace);
909

    
910
		// <CategoricalCharacter id="c1">
911
		if (elCharacters != null) {
912
			handleCategoricalData(sddNamespace, cdmState, elCharacters);
913
			handleQuantitativeData(sddNamespace, cdmState, elCharacters);
914
			handleTextCharacters(sddNamespace, cdmState, elCharacters);
915
		}
916

    
917
		/*for (Iterator<Feature> f = features.values().iterator() ; f.hasNext() ;){
918
			featureSet.add(f.next()); //XIM Why this line ?
919
		}*/
920
		
921
		return;
922

    
923
	}
924

    
925
	/**
926
	 * @param sddNamespace
927
	 * @param sddConfig
928
	 * @param elCharacters
929
	 * @return
930
	 */
931
	private void handleCategoricalData(Namespace sddNamespace, SDDImportState cdmState, Element elCharacters) {
932
		List<Element> elCategoricalCharacters = elCharacters.getChildren("CategoricalCharacter", sddNamespace);
933
		int j = 0;
934
		for (Element elCategoricalCharacter : elCategoricalCharacters){
935
			try {
936

    
937
				String idCC = elCategoricalCharacter.getAttributeValue("id");
938
				Feature categoricalCharacter = Feature.NewInstance();
939
				categoricalCharacter.setKindOf(Feature.DESCRIPTION());
940
				importRepresentation(elCategoricalCharacter, sddNamespace, categoricalCharacter, idCC, cdmState);
941
				categoricalCharacter.setSupportsCategoricalData(true);
942

    
943
				// <States>
944
				Element elStates = elCategoricalCharacter.getChild("States",sddNamespace);
945

    
946
				// <StateDefinition id="s1">
947
				List<Element> elStateDefinitions = elStates.getChildren("StateDefinition",sddNamespace);
948
				TermVocabulary<State> termVocabularyState = TermVocabulary.NewInstance(null, null, null, null);
949
				
950
				vocabularies.add(termVocabularyState);
951
				
952
				int k = 0;
953
				//for each StateDefinition
954
				for (Element elStateDefinition : elStateDefinitions){
955

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

    
958
					String idS = elStateDefinition.getAttributeValue("id");
959
					State state = states.get(idS);
960
					if (state == null){
961
						state = State.NewInstance();
962
					}else{
963
						logger.debug("State duplicate found");
964
					}
965
					importRepresentation(elStateDefinition, sddNamespace, state, idS, cdmState);
966

    
967
					termVocabularyState.addTerm(state);
968
					states.put(idS,state);
969
				}
970
				categoricalCharacter.addSupportedCategoricalEnumeration(termVocabularyState);
971
				features.put(idCC, categoricalCharacter);
972

    
973
			} catch (Exception e) {
974
				logger.warn("Import of CategoricalCharacter " + j + " failed.");
975
				cdmState.setUnsuccessfull(); 
976
			}
977

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

    
980
		}
981
		return;
982
	}
983

    
984
	/**
985
	 * @param sddNamespace
986
	 * @param sddConfig
987
	 * @param elCharacters
988
	 */
989
	private void handleQuantitativeData(Namespace sddNamespace,	SDDImportState cdmState, Element elCharacters) {
990
		int j;
991
		// <QuantitativeCharacter id="c2">
992
		List<Element> elQuantitativeCharacters = elCharacters.getChildren("QuantitativeCharacter", sddNamespace);
993
		j = 0;
994
		//for each QuantitativeCharacter
995
		for (Element elQuantitativeCharacter : elQuantitativeCharacters){
996

    
997
			try {
998

    
999
				String idQC = elQuantitativeCharacter.getAttributeValue("id");
1000

    
1001
				// <Representation>
1002
				//  <Label>Leaf length</Label>
1003
				// </Representation>
1004
				Feature quantitativeCharacter = Feature.NewInstance();
1005
				quantitativeCharacter.setKindOf(Feature.DESCRIPTION());
1006
				importRepresentation(elQuantitativeCharacter, sddNamespace, quantitativeCharacter, idQC, cdmState);
1007

    
1008
				quantitativeCharacter.setSupportsQuantitativeData(true);
1009

    
1010
				// <MeasurementUnit>
1011
				//  <Label role="Abbrev">m</Label>
1012
				// </MeasurementUnit>
1013
				Element elMeasurementUnit = elQuantitativeCharacter.getChild("MeasurementUnit",sddNamespace);
1014
				String label = "";
1015
				String role = "";
1016
				if (elMeasurementUnit != null) {
1017
					Element elLabel = elMeasurementUnit.getChild("Label",sddNamespace);
1018
					role = elLabel.getAttributeValue("role");
1019
					label = (String)ImportHelper.getXmlInputValue(elMeasurementUnit, "Label",sddNamespace);
1020
				}
1021

    
1022
				MeasurementUnit unit = null;
1023
				if (!label.equals("")){
1024
					if (role != null) {
1025
						if (role.equals("Abbrev")){
1026
							unit = MeasurementUnit.NewInstance(label,label,label);
1027
						}
1028
					} else {
1029
						unit = MeasurementUnit.NewInstance(label,label,label);
1030
					}
1031
				}
1032

    
1033
				if (unit != null) {
1034
					units.put(idQC, unit);
1035
				}
1036

    
1037
				//<Default>
1038
				//  <MeasurementUnitPrefix>milli</MeasurementUnitPrefix>
1039
				//</Default>
1040
				Element elDefault = elQuantitativeCharacter.getChild("Default",sddNamespace);
1041
				if (elDefault != null) {
1042
					String measurementUnitPrefix = (String)ImportHelper.getXmlInputValue(elDefault, "MeasurementUnitPrefix",sddNamespace);
1043
					if (! measurementUnitPrefix.equals("")){
1044
						defaultUnitPrefixes.put(idQC, measurementUnitPrefix);
1045
					}
1046
				}
1047

    
1048
				features.put(idQC, quantitativeCharacter);
1049

    
1050
			} catch (Exception e) {
1051
				//FIXME
1052
				logger.warn("Import of QuantitativeCharacter " + j + " failed.");
1053
				cdmState.setUnsuccessfull();
1054
			}
1055

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

    
1058
		}
1059
		return;
1060
	}
1061

    
1062
	private void handleTextCharacters(Namespace sddNamespace, SDDImportState cdmState, Element elCharacters) {
1063
		int j;
1064
		// <TextCharacter id="c3">
1065
		List<Element> elTextCharacters = elCharacters.getChildren("TextCharacter", sddNamespace);
1066
		j = 0;
1067
		//for each TextCharacter
1068
		for (Element elTextCharacter : elTextCharacters){
1069

    
1070
			try {
1071

    
1072
				String idTC = elTextCharacter.getAttributeValue("id");
1073

    
1074
				// <Representation>
1075
				//  <Label xml:lang="en">Leaf features not covered by other characters</Label>
1076
				// </Representation>
1077
				Feature textCharacter = Feature.NewInstance();
1078
				textCharacter.setKindOf(Feature.DESCRIPTION());
1079
				importRepresentation(elTextCharacter, sddNamespace, textCharacter, idTC, cdmState);
1080

    
1081
				textCharacter.setSupportsTextData(true);
1082

    
1083
				features.put(idTC, textCharacter);
1084

    
1085
			} catch (Exception e) {
1086
				//FIXME
1087
				logger.warn("Import of TextCharacter " + j + " failed.");
1088
				cdmState.setUnsuccessfull();
1089
			}
1090

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

    
1093
		}
1094
		return;
1095
	}
1096

    
1097
	// imports the descriptions of taxa
1098
	protected void importCodedDescriptions(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1099
				
1100
		// <CodedDescriptions>
1101
		logger.info("start CodedDescriptions ...");
1102
		Element elCodedDescriptions = elDataset.getChild("CodedDescriptions",sddNamespace);
1103
		
1104
		// <CodedDescription id="D101">
1105
		if (elCodedDescriptions != null) {
1106
			List<Element> listCodedDescriptions = elCodedDescriptions.getChildren("CodedDescription", sddNamespace);
1107
			int j = 0;
1108
			//for each CodedDescription
1109
			for (Element elCodedDescription : listCodedDescriptions){
1110
				handleCodedDescription(sddNamespace, cdmState, elCodedDescription, j);
1111
				if ((++j % modCount) == 0){ logger.info("CodedDescriptions handled: " + j);}
1112
			}
1113
		}
1114
		return;
1115
	}
1116

    
1117
	/**
1118
	 * @param sddNamespace
1119
	 * @param sddConfig
1120
	 * @param j
1121
	 * @param elCodedDescription
1122
	 * @return
1123
	 */
1124
	private void handleCodedDescription(Namespace sddNamespace, SDDImportState cdmState, Element elCodedDescription, int j) {
1125
		try {
1126

    
1127
			String idCD = elCodedDescription.getAttributeValue("id");
1128

    
1129
			// <Representation>
1130
			//  <Label>&lt;i&gt;Viola hederacea&lt;/i&gt; Labill. as revised by R. Morris April 8, 2006</Label>
1131
			// </Representation>
1132
			TaxonDescription taxonDescription = TaxonDescription.NewInstance();
1133
			if (!generatorName.isEmpty()){
1134
				Annotation annotation = Annotation.NewInstance(generatorName, AnnotationType.TECHNICAL(),Language.DEFAULT());
1135
				taxonDescription.addAnnotation(annotation);
1136
			}
1137
			importRepresentation(elCodedDescription, sddNamespace, taxonDescription, idCD, cdmState);
1138

    
1139
			// <Scope>
1140
			//  <TaxonName ref="t1"/>
1141
			//  <Citation ref="p1" location="p. 30"/>
1142
			// </Scope>
1143
			Element elScope = elCodedDescription.getChild("Scope", sddNamespace);
1144
			Taxon taxon;
1145
			if (elScope != null) {
1146
				taxon = handleCDScope(sddNamespace, cdmState, idCD, elScope);
1147
			} else {//in case no taxon is linked to the description, a new one is created
1148
				taxon = handleCDNoScope(sddNamespace, cdmState, elCodedDescription);
1149
			}
1150

    
1151
			// <SummaryData>
1152
			Element elSummaryData = elCodedDescription.getChild("SummaryData",sddNamespace);
1153
			if (elSummaryData != null) {
1154
				handleSummaryCategoricalData(sddNamespace, taxonDescription, elSummaryData);
1155
				handleSummaryQuantitativeData(sddNamespace, taxonDescription, elSummaryData);
1156
				handleSummaryTextData(sddNamespace, taxonDescription, elSummaryData);
1157
			}
1158

    
1159
			if (taxon != null) {
1160
				taxon.addDescription(taxonDescription);
1161
			}
1162
//			
1163
			workingSet.addDescription(taxonDescription);
1164
			
1165
//OLD			taxonDescription.setDescriptiveSystem(featureSet);
1166

    
1167
			taxonDescriptions.put(idCD, taxonDescription);//FIXME
1168

    
1169
		} catch (Exception e) {
1170
			//FIXME
1171
			logger.warn("Import of CodedDescription " + j + " failed.", e);
1172
			cdmState.setUnsuccessfull();
1173
		}
1174
		return;
1175
	}
1176

    
1177
	/**
1178
	 * @param sddNamespace
1179
	 * @param sddConfig
1180
	 * @param elCodedDescription
1181
	 * @param taxon
1182
	 * @return
1183
	 */
1184
	private Taxon handleCDNoScope(Namespace sddNamespace, SDDImportState cdmState, Element elCodedDescription	) {
1185
		Taxon taxon = null;
1186
		NonViralName nonViralName = NonViralName.NewInstance(null);
1187
		String id = new String("" + taxonNamesCount);
1188
		IdentifiableSource source = IdentifiableSource.NewInstance(id, "TaxonName");
1189
		importRepresentation(elCodedDescription, sddNamespace, nonViralName, id, cdmState);
1190
		
1191
		if(cdmState.getConfig().isDoMatchTaxa()){
1192
			taxon = getTaxonService().findBestMatchingTaxon(nonViralName.getTitleCache());
1193
		}
1194
		
1195
		if(taxon != null){
1196
			nonViralName = HibernateProxyHelper.deproxy(taxon.getName(), NonViralName.class);
1197
//							taxonNameBases.put(id ,tnb);
1198
//							taxonNamesCount++;
1199
			logger.info("using existing Taxon " + taxon.getTitleCache());
1200
		} else {
1201
			nonViralName.addSource(source);
1202
			taxonNameBases.put(id ,nonViralName);
1203
			taxonNamesCount++;						
1204
			logger.info("creating new Taxon from TaxonName " + nonViralName.getTitleCache());
1205
			taxon = Taxon.NewInstance(nonViralName, sec);
1206
		}
1207
		return taxon;
1208
	}
1209

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

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

    
1275
			// <Content>Free form text</Content>
1276
			String content = (String)ImportHelper.getXmlInputValue(elTextChar, "Content",sddNamespace);
1277
			textData.putText(datasetLanguage, content);
1278
			taxonDescription.addElement(textData);
1279
		}
1280
	}
1281

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

    
1302
			MeasurementUnit unit = units.get(ref);
1303
			String prefix = defaultUnitPrefixes.get(ref);
1304
			if (unit != null) {
1305
				String u = unit.getLabel();
1306
				if (prefix != null) {
1307
					u = prefix + u;
1308
				}
1309
				unit.setLabel(u);
1310
				quantitativeData.setUnit(unit);
1311
			}
1312

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

    
1349
				StatisticalMeasurementValue statisticalValue = StatisticalMeasurementValue.NewInstance();
1350
				statisticalValue.setValue(v);
1351
				statisticalValue.setType(t);
1352
				quantitativeData.addStatisticalValue(statisticalValue);
1353
				featureData.add(statisticalValue);
1354
			}
1355
			taxonDescription.addElement(quantitativeData);
1356
		}
1357
	}
1358

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

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

    
1405
	// imports the persons associated with the dataset creation, modification, related publications
1406
	protected void importAgents(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1407
		// <Agents>
1408
		logger.info("start Agents ...");
1409
		Element elAgents = elDataset.getChild("Agents",sddNamespace);
1410
		if (elAgents != null) {
1411
			// <Agent id="a1">
1412
			List <Element> listAgents = elAgents.getChildren("Agent", sddNamespace);
1413
			int j = 0;
1414
			//for each Agent
1415
			for (Element elAgent : listAgents){
1416

    
1417
				try {
1418

    
1419
					String idA = elAgent.getAttributeValue("id");
1420

    
1421
					//  <Representation>
1422
					//   <Label>Kevin Thiele</Label>
1423
					//   <Detail role="Description">Ali Baba is also known as r.a.m.</Detail>
1424
					//  </Representation>
1425
					Person person = Person.NewInstance();
1426
					importRepresentation(elAgent, sddNamespace, person, idA, cdmState);
1427
					person.addSource(IdentifiableSource.NewInstance(idA, "Agent"));
1428

    
1429
					/*XIM <Links>
1430
					Element elLinks = elAgent.getChild("Links",sddNamespace);
1431

    
1432
					if (elLinks != null) {
1433

    
1434
						//  <Link rel="Alternate" href="http://www.diversitycampus.net/people/hagedorn"/>
1435
						List<Element> listLinks = elLinks.getChildren("Link", sddNamespace);
1436
						int k = 0;
1437
						//for each Link
1438
						for (Element elLink : listLinks){
1439

    
1440
							try {
1441

    
1442
								String rel = elLink.getAttributeValue("rel");
1443
								String href = elLink.getAttributeValue("href");
1444

    
1445
								Media link = Media.NewInstance();
1446
								MediaRepresentation mr = MediaRepresentation.NewInstance();
1447
								mr.addRepresentationPart(MediaRepresentationPart.NewInstance(href, null));
1448
								link.addRepresentation(mr);
1449
								person.addMedia(link);
1450

    
1451
							} catch (Exception e) {
1452
								//FIXME
1453
								logger.warn("Import of Link " + k + " failed.");
1454
								success = false; 
1455
							}
1456

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

    
1459
						}
1460
					}
1461
					*/
1462
					if (authors.containsKey(idA)) {
1463
						authors.put(idA,person);
1464
					}
1465

    
1466
					if (editors.containsKey(idA)) {
1467
						editors.put(idA, person);
1468
					}
1469

    
1470
				} catch (Exception e) {
1471
					//FIXME
1472
					logger.warn("Import of Agent " + j + " failed.");
1473
					cdmState.setUnsuccessfull(); 
1474
				}
1475

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

    
1478
			}
1479
		}
1480
	}
1481

    
1482
	// imports publications related with the data set
1483
	protected void importPublications(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1484
		/* <Publications>
1485
			  <Publication id="p112">
1486
			    <Representation>
1487
			      <Label>Gee, X. & Haa, Y. (2003). How to be happy in five minutes. Instant Gratifications, Palm Beach.</Label>
1488
			    </Representation>
1489
			    <Links>
1490
			    <Link rel="BasedOn" href="doi:10.1992/32311"/>
1491
			    <Link rel="Alternate" href="http://some.service.net/providing/bibliographic.data"/>
1492
			    </Links>
1493
			</Publications>
1494
*/
1495
		logger.info("start Publications ...");
1496
		Element elPublications = elDataset.getChild("Publications",sddNamespace);
1497

    
1498
		if (elPublications != null) {
1499
			List<Element> listPublications = elPublications.getChildren("Publication", sddNamespace);
1500
			int j = 0;
1501
			for (Element elPublication : listPublications){
1502

    
1503
				try {
1504

    
1505
					String idP = elPublication.getAttributeValue("id");
1506
					Reference publication = ReferenceFactory.newArticle();
1507
					importRepresentation(elPublication, sddNamespace, publication, idP, cdmState);
1508

    
1509
					publications.put(idP,publication);
1510

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

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

    
1518
			}
1519
		}
1520
	}
1521

    
1522
	// imports media objects such as images //FIXME check mediaobj
1523
	protected void importMediaObjects(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1524
		// <MediaObjects>
1525
		logger.info("start MediaObjects ...");
1526
		Element elMediaObjects = elDataset.getChild("MediaObjects",sddNamespace);
1527

    
1528
		if (elMediaObjects != null) {
1529
			// <MediaObject id="m1">
1530
			List<Element> listMediaObjects = elMediaObjects.getChildren("MediaObject", sddNamespace);
1531
			int j = 0;
1532
			for (Element elMO : listMediaObjects){
1533

    
1534
				String id = "";
1535

    
1536
				try {
1537
					String idMO = elMO.getAttributeValue("id");
1538
					id = idMO;
1539

    
1540
					//  <Representation>
1541
					//   <Label>Image description, e.g. to be used for alt-attribute in html.</Label>
1542
					//  </Representation>
1543
					Media media = Media.NewInstance();
1544
					importRepresentation(elMO, sddNamespace, media, idMO, cdmState);
1545

    
1546
					// <Type>Image</Type>
1547
					// <Source href="http://test.edu/test.jpg"/>
1548
					String type = (String)ImportHelper.getXmlInputValue(elMO,"Type",sddNamespace);
1549

    
1550
					if ((type != null) && (type.equals("Image"))) {
1551
						Element elSource = elMO.getChild("Source",sddNamespace);
1552
						String href = elSource.getAttributeValue("href");
1553

    
1554
						ImageInfo imageMetaData = null;
1555
						ImageFile image = null;
1556
						if (href.substring(0,7).equals("http://")) {
1557
							try{
1558
								URL url = new URL(href);
1559
								
1560
								imageMetaData = ImageInfo.NewInstance(url.toURI(), 0);
1561
								image = ImageFile.NewInstance(url.toURI(), null, imageMetaData);
1562
							} catch (MalformedURLException e) {
1563
								logger.error("Malformed URL", e);
1564
							}
1565
						} else {
1566
							String sns = cdmState.getConfig().getSourceNameString();
1567
							File f = new File(sns);
1568
							File parent = f.getParentFile();
1569
							String fi = parent.toString() + File.separator + href;
1570
							File file = new File(fi);
1571
							imageMetaData  = ImageInfo.NewInstance(new URI(fi), 0); //file
1572
							image = ImageFile.NewInstance(file.toURI(), null, imageMetaData);
1573
						}
1574
						MediaRepresentation representation = MediaRepresentation.NewInstance(imageMetaData.getMimeType(), null);
1575
						representation.addRepresentationPart(image);
1576

    
1577
						media.addRepresentation(representation);
1578

    
1579
						ArrayList<CdmBase> lcb = (ArrayList<CdmBase>) mediaObject_ListCdmBase.get(idMO);
1580
						if (lcb != null) {
1581
							for (int k = 0; k < lcb.size(); k++) {
1582
								if (lcb.get(k) instanceof DefinedTermBase) {
1583
									DefinedTermBase dtb = (DefinedTermBase) lcb.get(k);
1584
									// if (lcb.get(0) instanceof DefinedTermBase) {
1585
									// DefinedTermBase dtb = (DefinedTermBase) lcb.get(0);
1586
									//									if (dtb!=null) {
1587
									//										if (k == 0) {
1588
									dtb.addMedia(media);
1589
									//System.out.println(dtb.getLabel());
1590
									//										} else {
1591
									//											Media me = (Media) media.clone();
1592
									//											dtb.addMedia(me);
1593
									//										}
1594
									//									}
1595
								} else if (lcb.get(k) instanceof Reference) {
1596
									Reference rb = (Reference) lcb.get(k);
1597
									//} else if (lcb.get(0) instanceof Reference) {
1598
									//Reference rb = (Reference) lcb.get(0);
1599
									// rb.setTitleCache(label);
1600
									//									if (rb!=null) {
1601
									//										if (k == 0) {
1602
									rb.addMedia(media);
1603
									//System.out.println(rb.getTitle());
1604
									//										} else {
1605
									//											Media me = (Media) media.clone();
1606
									//											rb.addMedia(me);
1607
									//										}
1608
									//									}
1609
//								 else if (lcb.get(k) instanceof TaxonNameBase){
1610
//									TaxonNameBase tb = (TaxonNameBase) lcb.get(k);
1611
//									tb.addMedia(media);
1612
								} else {
1613
									logger.warn("Can't handle associated media for " + lcb.get(k).getId() + "(" +  lcb.get(k).getClass().getSimpleName()+")"  );
1614
								}
1615
							}
1616
						}
1617
					}
1618

    
1619
				} catch (Exception e) {
1620
					//FIXME
1621
					logger.warn("Could not attach MediaObject " + j + "(SDD: " + id + ") to several objects.");
1622
					cdmState.setUnsuccessfull();
1623
				}
1624

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

    
1627
				}
1628
			}
1629
		}
1630
	}
1631

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

    
1658
			for (Element elDescriptiveConcept : listDescriptiveConcepts){
1659
				try {
1660
				String id = elDescriptiveConcept.getAttributeValue("id");
1661
					Feature feature = Feature.NewInstance();
1662
					feature.setKindOf(Feature.DESCRIPTION());
1663
					if (!id.equals("")) {
1664
					//	 <Representation>
1665
					//       <Label>Body</Label>
1666
					importRepresentation(elDescriptiveConcept, sddNamespace, feature, id, state);
1667
						features.put(id, feature);
1668
						getTermService().save(feature);//XIM
1669
						descriptiveConcepts.add(feature);
1670
						// imports the modifiers
1671
						Element elModifiers = elDescriptiveConcept.getChild("Modifiers", sddNamespace);
1672
					if (elModifiers !=null){
1673
						List<Element> listModifiers = elModifiers.getChildren("Modifier", sddNamespace);
1674
							TermVocabulary<Modifier> termVocabularyState = TermVocabulary.NewInstance(null, null, null, null);
1675
						for (Element elModifier : listModifiers) {
1676
								Modifier modif = Modifier.NewInstance();
1677
								String idmod = elModifier.getAttributeValue("id");
1678
								importRepresentation(elModifier, sddNamespace, modif, idmod, state);
1679
								termVocabularyState.addTerm(modif);
1680
								//termVocabularyStates.add(termVocabularyState);
1681
								getVocabularyService().save(termVocabularyState);//XIM
1682
								modifiers.put(idmod, modif);
1683
						}
1684
							feature.addRecommendedModifierEnumeration(termVocabularyState);
1685
				}
1686

    
1687
					}
1688
				}
1689
				catch (Exception e) {
1690
					logger.warn("Import of DescriptiveConcept " + j + " failed: " + e.getMessage());
1691
				}
1692
				if ((++j % modCount) == 0){ logger.info("DescriptiveConcepts handled: " + j);}
1693

    
1694
			}
1695
		}
1696
	}
1697

    
1698
	// imports the <CharacterTrees> block
1699
	protected void importCharacterTrees(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1700
		// <CharacterTrees>
1701
		logger.info("start CharacterTrees ...");
1702
		Element elCharacterTrees = elDataset.getChild("CharacterTrees",sddNamespace);
1703

    
1704
		if (elCharacterTrees != null) {
1705
			List<Element> listCharacterTrees = elCharacterTrees.getChildren("CharacterTree", sddNamespace);
1706
			int j = 0;
1707
			for (Element elCharacterTree : listCharacterTrees){
1708
				try {
1709
					Element elRepresentation = elCharacterTree.getChild("Representation",sddNamespace);
1710
					String label = (String)ImportHelper.getXmlInputValue(elRepresentation,"Label",sddNamespace);
1711
					//Element elDesignedFor = elCharacterTree.getChild("DesignedFor",sddNamespace);//TODO ?
1712

    
1713
					FeatureTree featureTree =  FeatureTree.NewInstance();
1714
					importRepresentation(elCharacterTree, sddNamespace, featureTree, "", cdmState);
1715
					FeatureNode root = featureTree.getRoot();
1716
					List<Element> listeOfNodes = elCharacterTree.getChildren("Nodes", sddNamespace);
1717

    
1718
					//Nodes of CharacterTrees in SDD always refer to DescriptiveConcepts
1719
					for (Element elNodes : listeOfNodes) {
1720
						handleCharacterNodes(sddNamespace, root, elNodes);
1721
					}
1722
					featureTrees.add(featureTree);
1723
					if (workingSet.getDescriptiveSystem() != null){
1724
						//TODO how to handle multiple 
1725
						logger.warn("Multiple feature trees not yet supported");
1726
					}else{
1727
						workingSet.setDescriptiveSystem(featureTree);
1728
					}
1729
				}
1730

    
1731
				catch (Exception e) {
1732
					logger.warn("Import of Character tree " + j + " failed.");
1733
					cdmState.setUnsuccessfull();
1734
				}
1735
				if ((++j % modCount) == 0){ logger.info("CharacterTrees handled: " + j);}
1736

    
1737
			}
1738

    
1739
		}
1740
	}
1741

    
1742
	/**
1743
	 * @param sddNamespace
1744
	 * @param root
1745
	 * @param elNodes
1746
	 */
1747
	private void handleCharacterNodes(Namespace sddNamespace, FeatureNode root, Element elNodes) {
1748
		List<Element> listNodes = elNodes.getChildren("Node", sddNamespace);
1749
		if (listNodes != null) {
1750
			for (Element elNode : listNodes){
1751
				String idN = elNode.getAttributeValue("id");
1752
				FeatureNode fn = null;
1753
				Feature dc = null;
1754
				if (idN!=null) {
1755
					// DescriptiveConcepts are used as nodes in CharacterTrees
1756
					Element elDescriptiveConcept = elNode.getChild("DescriptiveConcept", sddNamespace);
1757
					if (elDescriptiveConcept != null){
1758
						String refDC = elDescriptiveConcept.getAttributeValue("ref");
1759
						dc = features.get(refDC);
1760
						fn = FeatureNode.NewInstance(dc);
1761
					}
1762
					if (fn==null){
1763
						fn = FeatureNode.NewInstance();
1764
					}
1765
					Element elParent = elNode.getChild("Parent", sddNamespace);
1766
					// in SDD links between Nodes are referenced by the <Parent> tag
1767
					if (elParent!=null){
1768
						String refP = elParent.getAttributeValue("ref");
1769
						if (refP!=null) {
1770
							FeatureNode parent = featureNodes.get(refP);
1771
							if (parent==null){
1772
								root.addChild(fn); // if no parent found or the reference is broken, add the node to the root of the tree
1773
							}
1774
							else {
1775
								parent.addChild(fn);
1776
							}
1777
						}
1778
					}
1779
					else {
1780
						root.addChild(fn); // if no parent found or the reference is broken, add the node to the root of the tree
1781
					}
1782
				}
1783
				featureNodes.put(idN, fn);
1784
			}
1785
		}
1786

    
1787
		// Leaves of CharacterTrees in SDD are always CharNodes (referring to Characters)
1788
		List<Element> listCharNodes = elNodes.getChildren("CharNode", sddNamespace);
1789
		if (listCharNodes != null) {
1790
			for (Element elCharNode : listCharNodes){
1791
				Element elParent = elCharNode.getChild("Parent", sddNamespace);
1792
				Element elCharacter = elCharNode.getChild("Character", sddNamespace);
1793
				Element elDependencyRules = elCharNode.getChild("DependencyRules", sddNamespace);
1794
				FeatureNode fn = FeatureNode.NewInstance();
1795
				
1796
				if (elDependencyRules!=null){
1797
					Element elInapplicableIf = elCharNode.getChild("InapplicableIf", sddNamespace);
1798
					if (elInapplicableIf!=null){
1799
						List<Element> listStates = elInapplicableIf.getChildren("State", sddNamespace);
1800
						for (Element stateElement : listStates) {
1801
							String refState = stateElement.getAttributeValue("ref");
1802
							if ((refState!=null)&&(!refState.equals(""))) {
1803
								State state = states.get(refState);
1804
								fn.addInapplicableState(state);
1805
							}
1806
						}
1807
					}
1808
					Element elOnlyapplicableIf = elCharNode.getChild("OnlyApplicableIf", sddNamespace);
1809
					if (elOnlyapplicableIf!=null){
1810
						List<Element> listStates = elInapplicableIf.getChildren("State", sddNamespace);
1811
						for (Element stateElement : listStates) {
1812
							String refState = stateElement.getAttributeValue("ref");
1813
							if ((refState!=null)&&(!refState.equals(""))) {
1814
								State state = states.get(refState);
1815
								fn.addApplicableState(state);
1816
							}
1817
						}
1818
					}
1819
				}
1820
				
1821
				if (elParent!=null){
1822
					String refP = elParent.getAttributeValue("ref");
1823
					if ((refP!=null)&&(!refP.equals(""))) {
1824
					FeatureNode parent = featureNodes.get(refP);
1825
						if (parent==null){
1826
						parent = root; // if no parent found or the reference is broken, add the node to the root of the tree
1827
						}
1828
						parent.addChild(fn);
1829
					}
1830
				}
1831
				String refC = elCharacter.getAttributeValue("ref");
1832
				if ((refC!=null)&&(!refC.equals(""))){
1833
					Feature character = features.get(refC);
1834
					fn.setFeature(character);
1835
					featureNodes.put(refC, fn);
1836
				}
1837
			}		
1838
		}
1839
	}
1840

    
1841
	// imports the <TaxonHierarchies> block
1842
	protected void importTaxonHierarchies(Element elDataset, Namespace sddNamespace, SDDImportState cdmState){
1843

    
1844
		logger.info("start TaxonHierarchies ...");
1845
		Element elTaxonHierarchies = elDataset.getChild("TaxonHierarchies",sddNamespace);
1846

    
1847
		if (elTaxonHierarchies != null) {
1848
			List<Element> listTaxonHierarchies = elTaxonHierarchies.getChildren("TaxonHierarchy", sddNamespace);
1849
			int j = 0;
1850
			for (Element elTaxonHierarchy : listTaxonHierarchies){
1851
				try {
1852
					Element elRepresentation = elTaxonHierarchy.getChild("Representation",sddNamespace);
1853
					String label = (String)ImportHelper.getXmlInputValue(elRepresentation,"Label",sddNamespace);
1854
						Classification classification =  Classification.NewInstance(label);
1855
						importRepresentation(elTaxonHierarchy, sddNamespace, classification, "", cdmState);
1856
					
1857
						Set<TaxonNode> root = classification.getChildNodes();
1858
						Element elNodes = elTaxonHierarchy.getChild("Nodes", sddNamespace); // There can be only one <Nodes> block for TaxonHierarchies
1859
						List<Element> listNodes = elNodes.getChildren("Node", sddNamespace);
1860
						
1861
						for (Element elNode : listNodes){
1862
							String idN = elNode.getAttributeValue("id");
1863
							TaxonNameBase tnb = null;
1864
							if (!idN.equals("")) {
1865
								Element elTaxonName = elNode.getChild("TaxonName", sddNamespace);
1866
								String refTN = elTaxonName.getAttributeValue("ref");
1867
								tnb = taxonNameBases.get(refTN);
1868
								Taxon taxon = (Taxon) tnb.getTaxa().iterator().next() ;
1869
								Element elParent = elNode.getChild("Parent", sddNamespace);
1870
								if (elParent!=null){
1871
									String refP = elParent.getAttributeValue("ref");
1872
									if (!refP.equals("")) {
1873
										TaxonNode parent = taxonNodes.get(refP);
1874
										TaxonNode child = parent.addChildTaxon(taxon, sec, "", Synonym.NewInstance(tnb, sec));
1875
										taxonNodes.put(idN,child);
1876
									}
1877
								}
1878
								else {
1879
									TaxonNode tn = classification.addChildTaxon(taxon, sec, "", Synonym.NewInstance(tnb, sec)); // if no parent found or the reference is broken, add the node to the root of the tree
1880
									taxonNodes.put(idN,tn);
1881
								}
1882
							}
1883
						}
1884

    
1885
						classifications.add(classification);
1886
					}
1887

    
1888
				catch (Exception e) {
1889
					//FIXME
1890
					logger.warn("Import of Taxon Hierarchy " + j + " failed.");
1891
					cdmState.setUnsuccessfull();
1892
				}
1893

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

    
1896
			}
1897

    
1898
		}
1899
	}
1900
	
1901
	
1902
	// imports the <GeographicAreas> block 
1903
	protected void importGeographicAreas(Element elDataset, Namespace sddNamespace, SDDImportState cdmState) {
1904
		Element elGeographicAreas = elDataset.getChild("GeographicAreas",sddNamespace);
1905
		if (elGeographicAreas != null) {
1906
			List<Element> listGeographicAreas = elGeographicAreas.getChildren("GeographicArea", sddNamespace);
1907
			int j = 0;
1908
						
1909
			for (Element elGeographicArea : listGeographicAreas){
1910

    
1911
				String id = elGeographicArea.getAttributeValue("id");
1912
				NamedArea na = new NamedArea();
1913
				importRepresentation(elGeographicArea, sddNamespace, na, id, cdmState);
1914
				namedAreas.put(id,na);
1915
								}
1916
			if ((++j % modCount) == 0){ logger.info("GeographicAreas handled: " + j);}
1917
							}
1918
							}
1919
}
(2-2/4)