Project

General

Profile

Download (68.8 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.mediaMetaData.ImageMetaData;
36
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
37
import eu.etaxonomy.cdm.io.common.CdmImportBase;
38
import eu.etaxonomy.cdm.io.common.ICdmImport;
39
import eu.etaxonomy.cdm.io.common.IImportConfigurator;
40
import eu.etaxonomy.cdm.io.common.ImportHelper;
41
import eu.etaxonomy.cdm.io.sdd.SDDTransformer;
42
import eu.etaxonomy.cdm.model.agent.Person;
43
import eu.etaxonomy.cdm.model.agent.Team;
44
import eu.etaxonomy.cdm.model.common.Annotation;
45
import eu.etaxonomy.cdm.model.common.AnnotationType;
46
import eu.etaxonomy.cdm.model.common.CdmBase;
47
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
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.Representation;
55
import eu.etaxonomy.cdm.model.common.TermBase;
56
import eu.etaxonomy.cdm.model.common.TermVocabulary;
57
import eu.etaxonomy.cdm.model.common.VersionableEntity;
58
import eu.etaxonomy.cdm.model.description.CategoricalData;
59
import eu.etaxonomy.cdm.model.description.Feature;
60
import eu.etaxonomy.cdm.model.description.FeatureNode;
61
import eu.etaxonomy.cdm.model.description.FeatureTree;
62
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
63
import eu.etaxonomy.cdm.model.description.Modifier;
64
import eu.etaxonomy.cdm.model.description.QuantitativeData;
65
import eu.etaxonomy.cdm.model.description.State;
66
import eu.etaxonomy.cdm.model.description.StateData;
67
import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
68
import eu.etaxonomy.cdm.model.description.StatisticalMeasurementValue;
69
import eu.etaxonomy.cdm.model.description.TaxonDescription;
70
import eu.etaxonomy.cdm.model.description.TextData;
71
import eu.etaxonomy.cdm.model.description.WorkingSet;
72
import eu.etaxonomy.cdm.model.location.NamedArea;
73
import eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity;
74
import eu.etaxonomy.cdm.model.media.ImageFile;
75
import eu.etaxonomy.cdm.model.media.Media;
76
import eu.etaxonomy.cdm.model.media.MediaRepresentation;
77
import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
78
import eu.etaxonomy.cdm.model.media.Rights;
79
import eu.etaxonomy.cdm.model.name.NonViralName;
80
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
81
import eu.etaxonomy.cdm.model.occurrence.Specimen;
82
import eu.etaxonomy.cdm.model.reference.Reference;
83
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
84
import eu.etaxonomy.cdm.model.taxon.Classification;
85
import eu.etaxonomy.cdm.model.taxon.Synonym;
86
import eu.etaxonomy.cdm.model.taxon.Taxon;
87
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
88

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

    
98
	private static int modCount = 1000;
99

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

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

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

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

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

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

    
143
	private Rights copyright = null;
144

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

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

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

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

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

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

    
202

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

    
220
	// imports information about the Dataset
221
	protected void importDatasetRepresentation(Element parent, Namespace sddNamespace){
222
		logger.info("start Representation ...");
223
		/* <Representation>
224
			<Label>The Genus Viola</Label>
225
			<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>
226
	       </Representation>
227
		 */
228

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

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

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

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

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

    
275
		handleRepresentationLabels(sddNamespace, elRepresentation, langLabDet);
276
		handleRepresentationDetails(sddNamespace, elRepresentation, langLabDet);
277

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

    
290
		makeRepresentationMediaObjects(sddNamespace, ve, elRepresentation);//FIXME
291

    
292
	}
293

    
294

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

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

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

    
370

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

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

    
415
		if (elLinks != null) {
416

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

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

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

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

    
441
			}
442
		}
443
	}
444

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

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

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

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

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

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

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

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

    
528
		sec.addAnnotation(Annotation.NewDefaultLanguageInstance(generatorName + " - " + generatorVersion));
529
		sourceReference.addAnnotation(Annotation.NewDefaultLanguageInstance(generatorName + " - " + generatorVersion));
530

    
531
	}
532

    
533
	// imports the complete dataset information
534
	protected boolean importDataset(Element elDataset, Namespace sddNamespace, SDDImportState state){			// <Dataset xml:lang="en-us">
535
		boolean success = true;
536
		SDDImportConfigurator sddConfig = state.getConfig();
537

    
538
		workingSet = WorkingSet.NewInstance();
539
		importDatasetLanguage(elDataset,sddConfig);
540
		importDatasetRepresentation(elDataset, sddNamespace);
541
		importRevisionData(elDataset, sddNamespace);
542
		importIPRStatements(elDataset, sddNamespace, sddConfig);
543
		importTaxonNames(elDataset, sddNamespace, sddConfig);
544

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

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

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

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

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

    
657
	/**
658
	 * 
659
	 */
660
	private void saveVocabularies() {
661
		for (TermVocabulary vocabulary : vocabularies ){
662
			getVocabularyService().save(vocabulary);
663
		}
664
		
665
	}
666

    
667
	private void saveAnnotationType() {
668
		for (AnnotationType annotationType: annotationTypes){
669
			getTermService().save(annotationType); 
670
		}
671
	}
672

    
673
	private void saveStatisticalMeasure() {
674
		for (StatisticalMeasure sm : statisticalMeasures){
675
			getTermService().save(sm); 
676
		}
677
	}
678

    
679
	private void saveUnits() {
680
		if (units != null) {
681
			for (MeasurementUnit unit : units.values()){
682
				if (unit != null) {
683
					getTermService().save(unit); 
684
				}
685
			}
686
		}
687
	}
688

    
689
	private void saveAreas(MarkerType geographicAreaMarkerType) {
690
		for (NamedArea area : namedAreas.values() ){
691
			Marker marker = Marker.NewInstance();
692
			marker.setMarkerType(geographicAreaMarkerType);
693
			area.addMarker(marker);
694
			getTermService().save(area);
695
		}
696
	}
697

    
698
	private void saveStates() {
699
		for (State state : states.values() ){
700
			getTermService().save(state);
701
		}
702
	}
703

    
704
	private void saveMarkerType() {
705
		for (MarkerType markerType : markerTypes){
706
			getTermService().save(markerType);
707
		}
708
	}
709

    
710
	private void saveModifiers() {
711
		for (Modifier modifier : modifiers.values() ){
712
			getTermService().save(modifier);
713
		}
714
	}
715

    
716
	private void saveFeatures() {
717
		for (Feature feature : features.values() ){
718
			getTermService().save(feature);
719
		}
720
	}
721

    
722
	// imports the default language of the dataset
723
	protected void importDatasetLanguage(Element elDataset, SDDImportConfigurator sddConfig){
724
		String nameLang = elDataset.getAttributeValue("lang",xmlNamespace);
725

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

    
762
		}
763
	}
764

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

    
774
			// <Agent role="aut" ref="a1"/>
775
			List<Element> listAgents = elCreators.getChildren("Agent", sddNamespace);
776

    
777
			int j = 0;
778
			//for each Agent
779
			for (Element elAgent : listAgents){
780

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

    
795
			}
796

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

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

    
810
				DateTime updated = null;
811
				if (d != null) {
812
					updated = new DateTime(d);
813
					sourceReference.setUpdated(updated);
814
					sec.setUpdated(updated);
815
				}
816
			}
817
		}
818
	}
819

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

    
831
			for (Element elIPRStatement : listIPRStatements){
832

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

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

    
857
				if (copyright != null) {
858
					sourceReference.addRights(copyright);
859
					sec.addRights(copyright);
860
				}
861

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

    
864
			}
865
		}
866
	}
867

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

    
880
				String id = elTaxonName.getAttributeValue("id");
881
				String uri = elTaxonName.getAttributeValue("uri");
882

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

    
898
				// <Representation>
899
				// <Label xml:lang="la">Viola hederacea Labill.</Label>
900
				importRepresentation(elTaxonName, sddNamespace, tnb, id, sddConfig);
901

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

    
904
			}
905
		}
906
	}
907

    
908
	// imports the characters (categorical, quantitative and text ; sequence characters not supported) which correspond to CDM Features
909
	protected boolean importCharacters(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig){
910
		boolean success = true;
911
		// <Characters>
912
		logger.info("start Characters ...");
913
		Element elCharacters = elDataset.getChild("Characters", sddNamespace);
914

    
915
		// <CategoricalCharacter id="c1">
916
		if (elCharacters != null) {
917
			success &= handleCategoricalData(sddNamespace, sddConfig, elCharacters);
918
			success &= handleQuantitativeData(sddNamespace, sddConfig, elCharacters);
919
			success &= handleTextCharacters(sddNamespace, sddConfig, elCharacters);
920
		}
921

    
922
		/*for (Iterator<Feature> f = features.values().iterator() ; f.hasNext() ;){
923
			featureSet.add(f.next()); //XIM Why this line ?
924
		}*/
925
		
926
		return success;
927

    
928
	}
929

    
930
	/**
931
	 * @param sddNamespace
932
	 * @param sddConfig
933
	 * @param success
934
	 * @param elCharacters
935
	 * @return
936
	 */
937
	private boolean handleCategoricalData(Namespace sddNamespace, SDDImportConfigurator sddConfig, Element elCharacters) {
938
		boolean success = true;
939
		List<Element> elCategoricalCharacters = elCharacters.getChildren("CategoricalCharacter", sddNamespace);
940
		int j = 0;
941
		for (Element elCategoricalCharacter : elCategoricalCharacters){
942
			try {
943

    
944
				String idCC = elCategoricalCharacter.getAttributeValue("id");
945
				Feature categoricalCharacter = Feature.NewInstance();
946
				categoricalCharacter.setKindOf(Feature.DESCRIPTION());
947
				importRepresentation(elCategoricalCharacter, sddNamespace, categoricalCharacter, idCC, sddConfig);
948
				categoricalCharacter.setSupportsCategoricalData(true);
949

    
950
				// <States>
951
				Element elStates = elCategoricalCharacter.getChild("States",sddNamespace);
952

    
953
				// <StateDefinition id="s1">
954
				List<Element> elStateDefinitions = elStates.getChildren("StateDefinition",sddNamespace);
955
				TermVocabulary<State> termVocabularyState = new TermVocabulary<State>();
956
				
957
				vocabularies.add(termVocabularyState);
958
				
959
				int k = 0;
960
				//for each StateDefinition
961
				for (Element elStateDefinition : elStateDefinitions){
962

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

    
965
					String idS = elStateDefinition.getAttributeValue("id");
966
					State state = states.get(idS);
967
					if (state == null){
968
						state = State.NewInstance();
969
					}else{
970
						logger.debug("State duplicate found");
971
					}
972
					importRepresentation(elStateDefinition, sddNamespace, state, idS, sddConfig);
973

    
974
					termVocabularyState.addTerm(state);
975
					states.put(idS,state);
976
				}
977
				categoricalCharacter.addSupportedCategoricalEnumeration(termVocabularyState);
978
				features.put(idCC, categoricalCharacter);
979

    
980
			} catch (Exception e) {
981
				logger.warn("Import of CategoricalCharacter " + j + " failed.");
982
				success = false; 
983
			}
984

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

    
987
		}
988
		return success;
989
	}
990

    
991
	/**
992
	 * @param sddNamespace
993
	 * @param sddConfig
994
	 * @param elCharacters
995
	 */
996
	private boolean handleQuantitativeData(Namespace sddNamespace,	SDDImportConfigurator sddConfig, Element elCharacters) {
997
		boolean success = true;
998
		int j;
999
		// <QuantitativeCharacter id="c2">
1000
		List<Element> elQuantitativeCharacters = elCharacters.getChildren("QuantitativeCharacter", sddNamespace);
1001
		j = 0;
1002
		//for each QuantitativeCharacter
1003
		for (Element elQuantitativeCharacter : elQuantitativeCharacters){
1004

    
1005
			try {
1006

    
1007
				String idQC = elQuantitativeCharacter.getAttributeValue("id");
1008

    
1009
				// <Representation>
1010
				//  <Label>Leaf length</Label>
1011
				// </Representation>
1012
				Feature quantitativeCharacter = Feature.NewInstance();
1013
				quantitativeCharacter.setKindOf(Feature.DESCRIPTION());
1014
				importRepresentation(elQuantitativeCharacter, sddNamespace, quantitativeCharacter, idQC, sddConfig);
1015

    
1016
				quantitativeCharacter.setSupportsQuantitativeData(true);
1017

    
1018
				// <MeasurementUnit>
1019
				//  <Label role="Abbrev">m</Label>
1020
				// </MeasurementUnit>
1021
				Element elMeasurementUnit = elQuantitativeCharacter.getChild("MeasurementUnit",sddNamespace);
1022
				String label = "";
1023
				String role = "";
1024
				if (elMeasurementUnit != null) {
1025
					Element elLabel = elMeasurementUnit.getChild("Label",sddNamespace);
1026
					role = elLabel.getAttributeValue("role");
1027
					label = (String)ImportHelper.getXmlInputValue(elMeasurementUnit, "Label",sddNamespace);
1028
				}
1029

    
1030
				MeasurementUnit unit = null;
1031
				if (!label.equals("")){
1032
					if (role != null) {
1033
						if (role.equals("Abbrev")){
1034
							unit = MeasurementUnit.NewInstance(label,label,label);
1035
						}
1036
					} else {
1037
						unit = MeasurementUnit.NewInstance(label,label,label);
1038
					}
1039
				}
1040

    
1041
				if (unit != null) {
1042
					units.put(idQC, unit);
1043
				}
1044

    
1045
				//<Default>
1046
				//  <MeasurementUnitPrefix>milli</MeasurementUnitPrefix>
1047
				//</Default>
1048
				Element elDefault = elQuantitativeCharacter.getChild("Default",sddNamespace);
1049
				if (elDefault != null) {
1050
					String measurementUnitPrefix = (String)ImportHelper.getXmlInputValue(elDefault, "MeasurementUnitPrefix",sddNamespace);
1051
					if (! measurementUnitPrefix.equals("")){
1052
						defaultUnitPrefixes.put(idQC, measurementUnitPrefix);
1053
					}
1054
				}
1055

    
1056
				features.put(idQC, quantitativeCharacter);
1057

    
1058
			} catch (Exception e) {
1059
				//FIXME
1060
				logger.warn("Import of QuantitativeCharacter " + j + " failed.");
1061
				success = false; 
1062
			}
1063

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

    
1066
		}
1067
		return success;
1068
	}
1069

    
1070
	private boolean handleTextCharacters(Namespace sddNamespace, SDDImportConfigurator sddConfig, Element elCharacters) {
1071
		boolean success = true;
1072
		int j;
1073
		// <TextCharacter id="c3">
1074
		List<Element> elTextCharacters = elCharacters.getChildren("TextCharacter", sddNamespace);
1075
		j = 0;
1076
		//for each TextCharacter
1077
		for (Element elTextCharacter : elTextCharacters){
1078

    
1079
			try {
1080

    
1081
				String idTC = elTextCharacter.getAttributeValue("id");
1082

    
1083
				// <Representation>
1084
				//  <Label xml:lang="en">Leaf features not covered by other characters</Label>
1085
				// </Representation>
1086
				Feature textCharacter = Feature.NewInstance();
1087
				textCharacter.setKindOf(Feature.DESCRIPTION());
1088
				importRepresentation(elTextCharacter, sddNamespace, textCharacter, idTC, sddConfig);
1089

    
1090
				textCharacter.setSupportsTextData(true);
1091

    
1092
				features.put(idTC, textCharacter);
1093

    
1094
			} catch (Exception e) {
1095
				//FIXME
1096
				logger.warn("Import of TextCharacter " + j + " failed.");
1097
				success = false; 
1098
			}
1099

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

    
1102
		}
1103
		return success;
1104
	}
1105

    
1106
	// imports the descriptions of taxa
1107
	protected boolean importCodedDescriptions(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig){
1108
		boolean success = true;
1109
		
1110
		// <CodedDescriptions>
1111
		logger.info("start CodedDescriptions ...");
1112
		Element elCodedDescriptions = elDataset.getChild("CodedDescriptions",sddNamespace);
1113
		
1114
		// <CodedDescription id="D101">
1115
		if (elCodedDescriptions != null) {
1116
			List<Element> listCodedDescriptions = elCodedDescriptions.getChildren("CodedDescription", sddNamespace);
1117
			int j = 0;
1118
			//for each CodedDescription
1119
			for (Element elCodedDescription : listCodedDescriptions){
1120
				success &= handleCodedDescription(sddNamespace, sddConfig, elCodedDescription, j);
1121
				if ((++j % modCount) == 0){ logger.info("CodedDescriptions handled: " + j);}
1122
			}
1123
		}
1124
		return success;
1125
	}
1126

    
1127
	/**
1128
	 * @param sddNamespace
1129
	 * @param sddConfig
1130
	 * @param j
1131
	 * @param elCodedDescription
1132
	 * @return
1133
	 */
1134
	private boolean handleCodedDescription(Namespace sddNamespace, SDDImportConfigurator sddConfig, Element elCodedDescription, int j) {
1135
		boolean success = true ;
1136
		try {
1137

    
1138
			String idCD = elCodedDescription.getAttributeValue("id");
1139

    
1140
			// <Representation>
1141
			//  <Label>&lt;i&gt;Viola hederacea&lt;/i&gt; Labill. as revised by R. Morris April 8, 2006</Label>
1142
			// </Representation>
1143
			TaxonDescription taxonDescription = TaxonDescription.NewInstance();
1144
			if (!generatorName.isEmpty()){
1145
				Annotation annotation = Annotation.NewInstance(generatorName, AnnotationType.TECHNICAL(),Language.DEFAULT());
1146
				taxonDescription.addAnnotation(annotation);
1147
			}
1148
			importRepresentation(elCodedDescription, sddNamespace, taxonDescription, idCD, sddConfig);
1149

    
1150
			// <Scope>
1151
			//  <TaxonName ref="t1"/>
1152
			//  <Citation ref="p1" location="p. 30"/>
1153
			// </Scope>
1154
			Element elScope = elCodedDescription.getChild("Scope", sddNamespace);
1155
			Taxon taxon;
1156
			if (elScope != null) {
1157
				taxon = handleCDScope(sddNamespace, sddConfig, idCD, elScope);
1158
			} else {//in case no taxon is linked to the description, a new one is created
1159
				taxon = handleCDNoScope(sddNamespace, sddConfig, elCodedDescription);
1160
			}
1161

    
1162
			// <SummaryData>
1163
			Element elSummaryData = elCodedDescription.getChild("SummaryData",sddNamespace);
1164
			if (elSummaryData != null) {
1165
				handleSummaryCategoricalData(sddNamespace, taxonDescription, elSummaryData);
1166
				handleSummaryQuantitativeData(sddNamespace, taxonDescription, elSummaryData);
1167
				handleSummaryTextData(sddNamespace, taxonDescription, elSummaryData);
1168
			}
1169

    
1170
			if (taxon != null) {
1171
				taxon.addDescription(taxonDescription);
1172
			}
1173
//			
1174
			workingSet.addDescription(taxonDescription);
1175
			
1176
//OLD			taxonDescription.setDescriptiveSystem(featureSet);
1177

    
1178
			taxonDescriptions.put(idCD, taxonDescription);//FIXME
1179

    
1180
		} catch (Exception e) {
1181
			//FIXME
1182
			logger.warn("Import of CodedDescription " + j + " failed.", e);
1183
			success = false;
1184
		}
1185
		return success;
1186
	}
1187

    
1188
	/**
1189
	 * @param sddNamespace
1190
	 * @param sddConfig
1191
	 * @param elCodedDescription
1192
	 * @param taxon
1193
	 * @return
1194
	 */
1195
	private Taxon handleCDNoScope(Namespace sddNamespace,
1196
			SDDImportConfigurator sddConfig, Element elCodedDescription	) {
1197
		Taxon taxon = null;
1198
		NonViralName nonViralName = NonViralName.NewInstance(null);
1199
		String id = new String("" + taxonNamesCount);
1200
		IdentifiableSource source = IdentifiableSource.NewInstance(id, "TaxonName");
1201
		importRepresentation(elCodedDescription, sddNamespace, nonViralName, id, sddConfig);
1202
		
1203
		if(sddConfig.isDoMatchTaxa()){
1204
			taxon = getTaxonService().findBestMatchingTaxon(nonViralName.getTitleCache());
1205
		}
1206
		
1207
		if(taxon != null){
1208
			nonViralName = HibernateProxyHelper.deproxy(taxon.getName(), NonViralName.class);
1209
//							taxonNameBases.put(id ,tnb);
1210
//							taxonNamesCount++;
1211
			logger.info("using existing Taxon " + taxon.getTitleCache());
1212
		} else {
1213
			nonViralName.addSource(source);
1214
			taxonNameBases.put(id ,nonViralName);
1215
			taxonNamesCount++;						
1216
			logger.info("creating new Taxon from TaxonName " + nonViralName.getTitleCache());
1217
			taxon = Taxon.NewInstance(nonViralName, sec);
1218
		}
1219
		return taxon;
1220
	}
1221

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

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

    
1287
			// <Content>Free form text</Content>
1288
			String content = (String)ImportHelper.getXmlInputValue(elTextChar, "Content",sddNamespace);
1289
			textData.putText(datasetLanguage, content);
1290
			taxonDescription.addElement(textData);
1291
		}
1292
	}
1293

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

    
1314
			MeasurementUnit unit = units.get(ref);
1315
			String prefix = defaultUnitPrefixes.get(ref);
1316
			if (unit != null) {
1317
				String u = unit.getLabel();
1318
				if (prefix != null) {
1319
					u = prefix + u;
1320
				}
1321
				unit.setLabel(u);
1322
				quantitativeData.setUnit(unit);
1323
			}
1324

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

    
1361
				StatisticalMeasurementValue statisticalValue = StatisticalMeasurementValue.NewInstance();
1362
				statisticalValue.setValue(v);
1363
				statisticalValue.setType(t);
1364
				quantitativeData.addStatisticalValue(statisticalValue);
1365
				featureData.add(statisticalValue);
1366
			}
1367
			taxonDescription.addElement(quantitativeData);
1368
		}
1369
	}
1370

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

    
1390
			// <State ref="s3"/>
1391
			List<Element> elStates = elCategorical.getChildren("State", sddNamespace);
1392
			int l = 0;
1393
			
1394
			//for each State
1395
			for (Element elState : elStates){
1396
				if ((++l % modCount) == 0){ logger.info("States handled: " + (l-1));}
1397
				ref = elState.getAttributeValue("ref");
1398
				State state = states.get(ref);
1399
				if (state != null) {
1400
					StateData stateData = StateData.NewInstance();
1401
					stateData.setState(state);
1402
					List<Element> elModifiers = elState.getChildren("Modifier", sddNamespace);
1403
					for (Element elModifier : elModifiers){
1404
						ref = elModifier.getAttributeValue("ref");
1405
						Modifier modifier = modifiers.get(ref);
1406
						if (modifier != null) {
1407
							stateData.addModifier(modifier);
1408
						}
1409
					}
1410
					categoricalData.addState(stateData);
1411
				}
1412
				taxonDescription.addElement(categoricalData);
1413
			}
1414
		}
1415
	}
1416

    
1417
	// imports the persons associated with the dataset creation, modification, related publications
1418
	protected void importAgents(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig, boolean success){
1419
		// <Agents>
1420
		logger.info("start Agents ...");
1421
		Element elAgents = elDataset.getChild("Agents",sddNamespace);
1422
		if (elAgents != null) {
1423
			// <Agent id="a1">
1424
			List <Element> listAgents = elAgents.getChildren("Agent", sddNamespace);
1425
			int j = 0;
1426
			//for each Agent
1427
			for (Element elAgent : listAgents){
1428

    
1429
				try {
1430

    
1431
					String idA = elAgent.getAttributeValue("id");
1432

    
1433
					//  <Representation>
1434
					//   <Label>Kevin Thiele</Label>
1435
					//   <Detail role="Description">Ali Baba is also known as r.a.m.</Detail>
1436
					//  </Representation>
1437
					Person person = Person.NewInstance();
1438
					importRepresentation(elAgent, sddNamespace, person, idA, sddConfig);
1439
					person.addSource(IdentifiableSource.NewInstance(idA, "Agent"));
1440

    
1441
					/*XIM <Links>
1442
					Element elLinks = elAgent.getChild("Links",sddNamespace);
1443

    
1444
					if (elLinks != null) {
1445

    
1446
						//  <Link rel="Alternate" href="http://www.diversitycampus.net/people/hagedorn"/>
1447
						List<Element> listLinks = elLinks.getChildren("Link", sddNamespace);
1448
						int k = 0;
1449
						//for each Link
1450
						for (Element elLink : listLinks){
1451

    
1452
							try {
1453

    
1454
								String rel = elLink.getAttributeValue("rel");
1455
								String href = elLink.getAttributeValue("href");
1456

    
1457
								Media link = Media.NewInstance();
1458
								MediaRepresentation mr = MediaRepresentation.NewInstance();
1459
								mr.addRepresentationPart(MediaRepresentationPart.NewInstance(href, null));
1460
								link.addRepresentation(mr);
1461
								person.addMedia(link);
1462

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

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

    
1471
						}
1472
					}
1473
					*/
1474
					if (authors.containsKey(idA)) {
1475
						authors.put(idA,person);
1476
					}
1477

    
1478
					if (editors.containsKey(idA)) {
1479
						editors.put(idA, person);
1480
					}
1481

    
1482
				} catch (Exception e) {
1483
					//FIXME
1484
					logger.warn("Import of Agent " + j + " failed.");
1485
					success = false; 
1486
				}
1487

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

    
1490
			}
1491
		}
1492
	}
1493

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

    
1510
		if (elPublications != null) {
1511
			List<Element> listPublications = elPublications.getChildren("Publication", sddNamespace);
1512
			int j = 0;
1513
			for (Element elPublication : listPublications){
1514

    
1515
				try {
1516

    
1517
					String idP = elPublication.getAttributeValue("id");
1518
					Reference publication = ReferenceFactory.newArticle();
1519
					importRepresentation(elPublication, sddNamespace, publication, idP, sddConfig);
1520

    
1521
					publications.put(idP,publication);
1522

    
1523
				} catch (Exception e) {
1524
					logger.warn("Import of Publication " + j + " failed.");
1525
					success = false; 
1526
				}
1527

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

    
1530
			}
1531
		}
1532
	}
1533

    
1534
	// imports media objects such as images //FIXME check mediaobj
1535
	protected void importMediaObjects(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig, boolean success){
1536
		// <MediaObjects>
1537
		logger.info("start MediaObjects ...");
1538
		Element elMediaObjects = elDataset.getChild("MediaObjects",sddNamespace);
1539

    
1540
		if (elMediaObjects != null) {
1541
			// <MediaObject id="m1">
1542
			List<Element> listMediaObjects = elMediaObjects.getChildren("MediaObject", sddNamespace);
1543
			int j = 0;
1544
			for (Element elMO : listMediaObjects){
1545

    
1546
				String id = "";
1547

    
1548
				try {
1549
					String idMO = elMO.getAttributeValue("id");
1550
					id = idMO;
1551

    
1552
					//  <Representation>
1553
					//   <Label>Image description, e.g. to be used for alt-attribute in html.</Label>
1554
					//  </Representation>
1555
					Media media = Media.NewInstance();
1556
					importRepresentation(elMO, sddNamespace, media, idMO, sddConfig);
1557

    
1558
					// <Type>Image</Type>
1559
					// <Source href="http://test.edu/test.jpg"/>
1560
					String type = (String)ImportHelper.getXmlInputValue(elMO,"Type",sddNamespace);
1561

    
1562
					if ((type != null) && (type.equals("Image"))) {
1563
						Element elSource = elMO.getChild("Source",sddNamespace);
1564
						String href = elSource.getAttributeValue("href");
1565

    
1566
						ImageMetaData imageMetaData = ImageMetaData.newInstance();
1567
						ImageFile image = null;
1568
						if (href.substring(0,7).equals("http://")) {
1569
							try{
1570
								URL url = new URL(href);
1571
								
1572
								imageMetaData.readMetaData(url.toURI(), 0);
1573
								image = ImageFile.NewInstance(url.toURI(), null, imageMetaData);
1574
							} catch (MalformedURLException e) {
1575
								logger.error("Malformed URL", e);
1576
							}
1577
						} else {
1578
							String sns = sddConfig.getSourceNameString();
1579
							File f = new File(sns);
1580
							File parent = f.getParentFile();
1581
							String fi = parent.toString() + File.separator + href;
1582
							File file = new File(fi);
1583
							imageMetaData.readMetaData(new URI(fi), 0); //file
1584
							image = ImageFile.NewInstance(file.toURI(), null, imageMetaData);
1585
						}
1586
						MediaRepresentation representation = MediaRepresentation.NewInstance(imageMetaData.getMimeType(), null);
1587
						representation.addRepresentationPart(image);
1588

    
1589
						media.addRepresentation(representation);
1590

    
1591
						ArrayList<CdmBase> lcb = (ArrayList<CdmBase>) mediaObject_ListCdmBase.get(idMO);
1592
						if (lcb != null) {
1593
							for (int k = 0; k < lcb.size(); k++) {
1594
								if (lcb.get(k) instanceof DefinedTermBase) {
1595
									DefinedTermBase dtb = (DefinedTermBase) lcb.get(k);
1596
									// if (lcb.get(0) instanceof DefinedTermBase) {
1597
									// DefinedTermBase dtb = (DefinedTermBase) lcb.get(0);
1598
									//									if (dtb!=null) {
1599
									//										if (k == 0) {
1600
									dtb.addMedia(media);
1601
									//System.out.println(dtb.getLabel());
1602
									//										} else {
1603
									//											Media me = (Media) media.clone();
1604
									//											dtb.addMedia(me);
1605
									//										}
1606
									//									}
1607
								} else if (lcb.get(k) instanceof Reference) {
1608
									Reference rb = (Reference) lcb.get(k);
1609
									//} else if (lcb.get(0) instanceof Reference) {
1610
									//Reference rb = (Reference) lcb.get(0);
1611
									// rb.setTitleCache(label);
1612
									//									if (rb!=null) {
1613
									//										if (k == 0) {
1614
									rb.addMedia(media);
1615
									//System.out.println(rb.getTitle());
1616
									//										} else {
1617
									//											Media me = (Media) media.clone();
1618
									//											rb.addMedia(me);
1619
									//										}
1620
									//									}
1621
//								 else if (lcb.get(k) instanceof TaxonNameBase){
1622
//									TaxonNameBase tb = (TaxonNameBase) lcb.get(k);
1623
//									tb.addMedia(media);
1624
								} else {
1625
									logger.warn("Can't handle associated media for " + lcb.get(k).getId() + "(" +  lcb.get(k).getClass().getSimpleName()+")"  );
1626
								}
1627
							}
1628
						}
1629
					}
1630

    
1631
				} catch (Exception e) {
1632
					//FIXME
1633
					logger.warn("Could not attach MediaObject " + j + "(SDD: " + id + ") to several objects.");
1634
					success = false; 
1635
				}
1636

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

    
1639
				}
1640
			}
1641
		}
1642
	}
1643

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

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

    
1699
					}
1700
				}
1701
				catch (Exception e) {
1702
					logger.warn("Import of DescriptiveConcept " + j + " failed: " + e.getMessage());
1703
				}
1704
				if ((++j % modCount) == 0){ logger.info("DescriptiveConcepts handled: " + j);}
1705

    
1706
			}
1707
		}
1708
	}
1709

    
1710
	// imports the <CharacterTrees> block
1711
	protected void importCharacterTrees(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig, boolean success){
1712
		// <CharacterTrees>
1713
		logger.info("start CharacterTrees ...");
1714
		Element elCharacterTrees = elDataset.getChild("CharacterTrees",sddNamespace);
1715

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

    
1725
					FeatureTree featureTree =  FeatureTree.NewInstance();
1726
					importRepresentation(elCharacterTree, sddNamespace, featureTree, "", sddConfig);
1727
					FeatureNode root = featureTree.getRoot();
1728
					List<Element> listeOfNodes = elCharacterTree.getChildren("Nodes", sddNamespace);
1729

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

    
1743
				catch (Exception e) {
1744
					logger.warn("Import of Character tree " + j + " failed.");
1745
					success = false; 
1746
				}
1747
				if ((++j % modCount) == 0){ logger.info("CharacterTrees handled: " + j);}
1748

    
1749
			}
1750

    
1751
		}
1752
	}
1753

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

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

    
1853
	// imports the <TaxonHierarchies> block
1854
	protected void importTaxonHierarchies(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig, boolean success){
1855

    
1856
		logger.info("start TaxonHierarchies ...");
1857
		Element elTaxonHierarchies = elDataset.getChild("TaxonHierarchies",sddNamespace);
1858

    
1859
		if (elTaxonHierarchies != null) {
1860
			List<Element> listTaxonHierarchies = elTaxonHierarchies.getChildren("TaxonHierarchy", sddNamespace);
1861
			int j = 0;
1862
			for (Element elTaxonHierarchy : listTaxonHierarchies){
1863
				try {
1864
					Element elRepresentation = elTaxonHierarchy.getChild("Representation",sddNamespace);
1865
					String label = (String)ImportHelper.getXmlInputValue(elRepresentation,"Label",sddNamespace);
1866
						Classification classification =  Classification.NewInstance(label);
1867
						importRepresentation(elTaxonHierarchy, sddNamespace, classification, "", sddConfig);
1868
					
1869
						Set<TaxonNode> root = classification.getChildNodes();
1870
						Element elNodes = elTaxonHierarchy.getChild("Nodes", sddNamespace); // There can be only one <Nodes> block for TaxonHierarchies
1871
						List<Element> listNodes = elNodes.getChildren("Node", sddNamespace);
1872
						
1873
						for (Element elNode : listNodes){
1874
							String idN = elNode.getAttributeValue("id");
1875
							TaxonNameBase tnb = null;
1876
							if (!idN.equals("")) {
1877
								Element elTaxonName = elNode.getChild("TaxonName", sddNamespace);
1878
								String refTN = elTaxonName.getAttributeValue("ref");
1879
								tnb = taxonNameBases.get(refTN);
1880
								Taxon taxon = (Taxon) tnb.getTaxa().iterator().next() ;
1881
								Element elParent = elNode.getChild("Parent", sddNamespace);
1882
								if (elParent!=null){
1883
									String refP = elParent.getAttributeValue("ref");
1884
									if (!refP.equals("")) {
1885
										TaxonNode parent = taxonNodes.get(refP);
1886
										TaxonNode child = parent.addChildTaxon(taxon, sec, "", Synonym.NewInstance(tnb, sec));
1887
										taxonNodes.put(idN,child);
1888
									}
1889
								}
1890
								else {
1891
									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
1892
									taxonNodes.put(idN,tn);
1893
								}
1894
							}
1895
						}
1896

    
1897
						classifications.add(classification);
1898
					}
1899

    
1900
				catch (Exception e) {
1901
					//FIXME
1902
					logger.warn("Import of Taxon Hierarchy " + j + " failed.");
1903
					success = false; 
1904
				}
1905

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

    
1908
			}
1909

    
1910
		}
1911
	}
1912
	
1913
	
1914
	// imports the <GeographicAreas> block 
1915
	protected void importGeographicAreas(Element elDataset, Namespace sddNamespace, SDDImportConfigurator sddConfig) {
1916
		Element elGeographicAreas = elDataset.getChild("GeographicAreas",sddNamespace);
1917
		if (elGeographicAreas != null) {
1918
			List<Element> listGeographicAreas = elGeographicAreas.getChildren("GeographicArea", sddNamespace);
1919
			int j = 0;
1920
						
1921
			for (Element elGeographicArea : listGeographicAreas){
1922

    
1923
				String id = elGeographicArea.getAttributeValue("id");
1924
				NamedArea na = new NamedArea();
1925
				importRepresentation(elGeographicArea, sddNamespace, na, id, sddConfig);
1926
				namedAreas.put(id,na);
1927
								}
1928
			if ((++j % modCount) == 0){ logger.info("GeographicAreas handled: " + j);}
1929
							}
1930
							}
1931
}
(2-2/4)