Project

General

Profile

Download (70.2 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
package eu.etaxonomy.cdm.io.sdd.in;
10

    
11
import java.io.File;
12
import java.io.IOException;
13
import java.math.BigDecimal;
14
import java.net.MalformedURLException;
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
import java.util.UUID;
25

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

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

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

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

    
103
	private static int modCount = 1000;
104

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

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

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

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

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

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

    
142

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

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

    
151
	private Rights copyright = null;
152

    
153
	private int taxonNamesCount = 0;
154

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

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

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

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

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

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

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

    
207
		// <Datasets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://rs.tdwg.org/UBIF/2006/" xsi:schemaLocation="http://rs.tdwg.org/UBIF/2006/ ../SDD.xsd">
208
		Element root = sddConfig.getSourceRoot();
209
		Namespace sddNamespace = sddConfig.getSddNamespace();
210

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

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

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

    
237

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

    
255
	// imports information about the Dataset
256
	protected void importDatasetRepresentation(Element parent, Namespace sddNamespace){
257
		logger.info("start Representation ...");
258
		/* <Representation>
259
			<Label>The Genus Viola</Label>
260
			<Detail>This is an example for a very simple SDD file, representing a single description with categorical, quantitative, and text character. Compare also the "Fragment*" examples, which contain more complex examples in the form of document fragments. Intended for version="SDD 1.1".</Detail>
261
	       </Representation>
262
		 */
263

    
264

    
265

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

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

    
274

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

    
284

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

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

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

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

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

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

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

    
327
	}
328

    
329

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

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

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

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

    
405

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

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

    
451
		if (elLinks != null) {
452

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

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

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

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

    
477
			}
478
		}
479
	}
480

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

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

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

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

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

    
538

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

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

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

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

    
567
	}
568

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

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

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

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

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

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

    
609

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

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

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

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

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

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

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

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

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

    
690
		return;
691
	}
692

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

    
701
	}
702

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

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

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

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

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

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

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

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

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

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

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

    
797
		}
798
	}
799

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

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

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

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

    
830
			}
831

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

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

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

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

    
866
			for (Element elIPRStatement : listIPRStatements){
867

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

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

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

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

    
899
			}
900
		}
901
	}
902

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

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

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

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

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

    
938
			}
939
		}
940
	}
941

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

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

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

    
959
		return;
960

    
961
	}
962

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

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

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

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

    
989
				vocabularies.add(termVocabularyState);
990

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

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

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

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

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

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

    
1019
		}
1020
		return;
1021
	}
1022

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

    
1036
			try {
1037

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

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

    
1047
				quantitativeCharacter.setSupportsQuantitativeData(true);
1048

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

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

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

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

    
1087
				features.put(idQC, quantitativeCharacter);
1088

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

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

    
1097
		}
1098
		return;
1099
	}
1100

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

    
1109
			try {
1110

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

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

    
1120
				textCharacter.setSupportsTextData(true);
1121

    
1122
				features.put(idTC, textCharacter);
1123

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

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

    
1132
		}
1133
		return;
1134
	}
1135

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1457
				try {
1458

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

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

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

    
1472
					if (elLinks != null) {
1473

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

    
1480
							try {
1481

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

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

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

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

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

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

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

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

    
1518
			}
1519
		}
1520
	}
1521

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

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

    
1543
				try {
1544

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

    
1549
					publications.put(idP,publication);
1550

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

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

    
1558
			}
1559
		}
1560
	}
1561

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

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

    
1575
				String id = "";
1576

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

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

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

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

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

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

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

    
1621
						media.addRepresentation(representation);
1622

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

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

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

    
1671
				}
1672
			}
1673
		}
1674
	}
1675

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

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

    
1738
			}
1739
		}
1740
	}
1741

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

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

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

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

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

    
1781
			}
1782
		}
1783
	}
1784

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

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

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

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

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

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

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

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

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

    
1908
						for (Element elNode : listNodes){
1909
							String idN = elNode.getAttributeValue("id");
1910
							TaxonName tnb = null;
1911
							if (!idN.equals("")) {
1912
								Element elTaxonName = elNode.getChild("TaxonName", sddNamespace);
1913
								String refTN = elTaxonName.getAttributeValue("ref");
1914
								tnb = taxonNames.get(refTN);
1915
								Taxon taxon = tnb.getTaxa().iterator().next() ;
1916
								Element elParent = elNode.getChild("Parent", sddNamespace);
1917
								if (elParent!=null){
1918
									String refP = elParent.getAttributeValue("ref");
1919
									if (!refP.equals("")) {
1920
										TaxonNode parent = taxonNodes.get(refP);
1921
										TaxonNode child = parent.addChildTaxon(taxon, sec, null);
1922
										child.setSynonymToBeUsed( Synonym.NewInstance(tnb, sec)); //TODO is this required??
1923
										taxonNodes.put(idN,child);
1924
									}
1925
								}
1926
								else {
1927
									TaxonNode tn = classification.addChildTaxon(taxon, sec, null); // if no parent found or the reference is broken, add the node to the root of the tree
1928
									tn.setSynonymToBeUsed( Synonym.NewInstance(tnb, sec));  //TODO is this required??
1929
									taxonNodes.put(idN,tn);
1930
								}
1931
							}
1932
						}
1933

    
1934
						classifications.add(classification);
1935
					}
1936

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

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

    
1945
			}
1946

    
1947
		}
1948
	}
1949

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

    
1957
			for (Element elGeographicArea : listGeographicAreas){
1958

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