Project

General

Profile

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

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

    
12
import java.io.File;
13
import java.io.FileOutputStream;
14
import java.io.IOException;
15
import java.io.OutputStreamWriter;
16
import java.io.Writer;
17
import java.util.ArrayList;
18
import java.util.HashMap;
19
import java.util.HashSet;
20
import java.util.Iterator;
21
import java.util.List;
22
import java.util.Map;
23
import java.util.Set;
24

    
25
import javax.xml.bind.Marshaller;
26

    
27
import org.apache.log4j.Logger;
28
import org.apache.xerces.dom.DocumentImpl;
29
import org.apache.xerces.dom.ElementImpl;
30
import org.apache.xerces.impl.xpath.regex.ParseException;
31
import org.apache.xml.serialize.DOMSerializer;
32
import org.apache.xml.serialize.OutputFormat;
33
import org.apache.xml.serialize.XMLSerializer;
34
import org.joda.time.DateTime;
35
import org.joda.time.format.DateTimeFormatter;
36
import org.joda.time.format.ISODateTimeFormat;
37
import org.xml.sax.SAXException;
38

    
39
import eu.etaxonomy.cdm.api.service.IdentificationKeyGenerator;
40
import eu.etaxonomy.cdm.api.service.NaturalLanguageGenerator;
41
import eu.etaxonomy.cdm.io.jaxb.CdmMarshallerListener;
42
import eu.etaxonomy.cdm.model.agent.AgentBase;
43
import eu.etaxonomy.cdm.model.agent.Person;
44
import eu.etaxonomy.cdm.model.agent.Team;
45
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
46
import eu.etaxonomy.cdm.model.common.Annotation;
47
import eu.etaxonomy.cdm.model.common.AnnotationType;
48
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
49
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
50
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
51
import eu.etaxonomy.cdm.model.common.Language;
52
import eu.etaxonomy.cdm.model.common.LanguageString;
53
import eu.etaxonomy.cdm.model.common.Marker;
54
import eu.etaxonomy.cdm.model.common.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.DescriptionElementBase;
60
import eu.etaxonomy.cdm.model.description.Feature;
61
import eu.etaxonomy.cdm.model.description.FeatureNode;
62
import eu.etaxonomy.cdm.model.description.FeatureTree;
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.location.NamedArea;
72
import eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity;
73
import eu.etaxonomy.cdm.model.media.Media;
74
import eu.etaxonomy.cdm.model.media.MediaRepresentation;
75
import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
76
import eu.etaxonomy.cdm.model.media.Rights;
77
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
78
import eu.etaxonomy.cdm.model.occurrence.Specimen;
79
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
80
import eu.etaxonomy.cdm.model.reference.IDatabase;
81
import eu.etaxonomy.cdm.model.reference.ReferenceBase;
82
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
83
import eu.etaxonomy.cdm.model.reference.ReferenceType;
84
import eu.etaxonomy.cdm.model.taxon.Taxon;
85
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
86
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
87

    
88
/**
89
 * Writes the SDD XML file. 
90
 * 
91
 * @author h.fradin
92
 * @created 10.12.2008
93
 * @version 1.0
94
 */
95

    
96
public class SDDDocumentBuilder {
97

    
98
	private DocumentImpl document;
99
	private XMLSerializer xmlserializer;
100
	private Writer writer;
101
	private DOMSerializer domi;
102
	private SDDDataSet cdmSource;
103

    
104
	private Map<Person,String> agents = new HashMap<Person,String>();
105
	private Map<TaxonNameBase,String> taxonNames = new HashMap<TaxonNameBase,String>();
106
	private Map<Feature,String> characters = new HashMap<Feature,String>();
107
	private Map<FeatureNode,String> featureNodes = new HashMap<FeatureNode,String>();
108
	private Map<Feature,String> descriptiveConcepts = new HashMap<Feature,String>();
109
	private Map<TaxonDescription,String> codedDescriptions = new HashMap<TaxonDescription,String>();
110
	private Map<Media,String> medias = new HashMap<Media,String>();
111
	private Map<State,String> states = new HashMap<State,String>();
112
	private Map<ReferenceBase, String> articles = new HashMap<ReferenceBase, String>();
113
	private Map<VersionableEntity, String> featuretrees = new HashMap<VersionableEntity, String>();
114
	private Map<Modifier, String> modifiers = new HashMap<Modifier, String>();
115
	private Map<TaxonNode, String> taxonNodes = new HashMap<TaxonNode,String>();
116
	private Map<NamedArea, String> namedAreas = new HashMap<NamedArea,String>();
117
	private Map<Specimen, String> specimens = new HashMap<Specimen,String>();
118
	private ReferenceFactory refFactory = ReferenceFactory.newInstance();
119
	
120
	private Map<VersionableEntity,String> features = new HashMap<VersionableEntity,String>();
121
	private int agentsCount = 0;
122
	private int articlesCount = 0;
123
	private int codedDescriptionsCount = 0;
124
	private int taxonNamesCount = 0;
125
	private int charactersCount = 0;
126
	private int textcharactersCount = 0;
127
	private int mediasCount = 0;
128
	private int statesCount = 0;
129
	private int featureNodesCount = 0;
130
	private int chartreeCount = 0;
131
	private int charnodeCount = 0;
132
	private int taxonNodesCount = 0;
133
	private int namedAreasCount = 0;
134
	private int specimenCount = 0;
135
	private int descriptiveConceptCount = 0;
136
	private int modifiersCount = 0;
137
	
138
	private String AGENT = "Agent";
139
	private String AGENTS = "Agents";
140
	private String CATEGORICAL = "Categorical";
141
	private String CATEGORICAL_CHARACTER = "CategoricalCharacter";
142
	private String CHARACTER = "Character";
143
	private String CHARACTERS = "Characters";
144
	private String CHARACTER_TREE = "CharacterTree";
145
	private String CHARACTER_TREES = "CharacterTrees";
146
	private String CHAR_NODE = "CharNode";
147
	private String CITATION = "Citation";
148
	private String CODED_DESCRIPTION = "CodedDescription";
149
	private String CODED_DESCRIPTIONS = "CodedDescriptions";
150
	private String CONTENT = "Content";
151
	private String CREATORS = "Creators";
152
	private String DATASET = "Dataset";
153
	private String DATASETS = "Datasets";
154
	private String DATE_CREATED = "DateCreated";
155
	private String DATE_MODIFIED = "DateModified";
156
	private String DEPENDENCY_RULES = "DependencyRules";
157
	private String DESCRIPTIVE_CONCEPT = "DescriptiveConcept";
158
	private String DESCRIPTIVE_CONCEPTS = "DescriptiveConcepts";
159
	private String DETAIL = "Detail";
160
	private String GENERATOR = "Generator";
161
	private String ID = "id";
162
	private String IMAGE = "Image";
163
	private String INAPPLICABLE_IF = "InapplicableIf";
164
	private String IPR_STATEMENT = "IPRStatement";
165
	private String IPR_STATEMENTS = "IPRStatements";
166
	private String LABEL = "Label";
167
	private String MEASURE = "Measure";
168
	private String MEDIA_OBJECT = "MediaObject";
169
	private String MEDIA_OBJECTS = "MediaObjects";
170
	private String NODE = "Node";
171
	private String NODES = "Nodes";
172
	private String NOTE = "Note";
173
	private String PARENT = "Parent";
174
	private String PUBLICATIONS = "Publications";
175
	private String QUANTITATIVE = "Quantitative";
176
	private String QUANTITATIVE_CHARACTER = "QuantitativeCharacter";
177
	private String REF = "ref";
178
	private String REPRESENTATION = "Representation";
179
	private String REVISION_DATA = "RevisionData";
180
	private String ROLE = "role";
181
	private String SCOPE = "Scope";
182
	private String SHOULD_CONTAIN_ALL_CHARACTERS = "ShouldContainAllCharacters";
183
	private String SOURCE = "Source";
184
	private String STATE = "State";
185
	private String STATE_DEFINITION = "StateDefinition";
186
	private String STATES = "States";
187
	private String STATUS = "Status";
188
	private String SUMMARY_DATA = "SummaryData";
189
	private String TAXON_NAME = "TaxonName";
190
	private String TAXON_NAMES = "TaxonNames";
191
	private String TECHNICAL_METADATA = "TechnicalMetadata";
192
	private String TEXT = "text";
193
	private String TEXT_CHAR = "TextChar";
194
	private String TEXT_CHARACTER = "TextCharacter";
195
	private String TYPE = "Type";
196
	private String URI = "uri";
197

    
198
	private Language defaultLanguage = Language.DEFAULT();
199

    
200
	private static final Logger logger = Logger.getLogger(SDDDocumentBuilder.class);
201
	
202
	private boolean natlang = true; // Only for tests on natural language generation ; to be deleted after
203
	private String NEWLINE = System.getProperty("line.separator");
204

    
205
	public SDDDocumentBuilder() throws SAXException, IOException {
206

    
207
		document = new DocumentImpl();
208

    
209
	}
210

    
211
	public void marshal(SDDDataSet cdmSource, File sddDestination) throws IOException {
212

    
213
		this.cdmSource = cdmSource;
214
		Marshaller marshaller;		
215
		CdmMarshallerListener marshallerListener = new CdmMarshallerListener();
216
		logger.info("Start marshalling");
217
		writeCDMtoSDD(sddDestination);
218

    
219
	}
220

    
221
	/**Write the DOM document.
222
	 * @param base
223
	 * @throws IOException
224
	 */
225
	public void writeCDMtoSDD(File sddDestination) throws IOException {
226

    
227
		try {
228
			buildDocument();
229
		} catch (ParseException e) {
230
			e.printStackTrace();
231
		}
232

    
233
		OutputFormat format = new OutputFormat(document, "UTF-8", true);
234

    
235
		FileOutputStream fos = new FileOutputStream(sddDestination);
236

    
237
		writer = new OutputStreamWriter(fos, "UTF-8");
238

    
239
		xmlserializer = new XMLSerializer(writer, format);
240
		domi = xmlserializer.asDOMSerializer(); // As a DOM Serializer
241

    
242
		domi.serialize(document.getDocumentElement());
243

    
244
		writer.close();
245
	}
246

    
247
	//	#############
248
	//	# BUILD DOM	#
249
	//	#############	
250

    
251
	/**
252
	 * Builds the whole document.
253
	 * @param base the Base
254
	 * @throws ParseException 
255
	 */
256
	public void buildDocument() throws ParseException {
257

    
258
		//create <Datasets> = root node
259
		ElementImpl baselement = new ElementImpl(document, DATASETS);
260
		if (natlang) {
261
			buildNaturalLanguageDescription(baselement);
262
		}
263
		else {
264
		baselement.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
265
		baselement.setAttribute("xmlns", "http://rs.tdwg.org/UBIF/2006/");
266
		baselement.setAttribute("xsi:schemaLocation", "http://rs.tdwg.org/UBIF/2006 http://rs.tdwg.org/UBIF/2006/Schema/1.1/SDD.xsd");
267

    
268
		buildTechnicalMetadata(baselement);
269

    
270
		List<ReferenceBase> references = cdmSource.getReferences();
271
		Iterator<ReferenceBase> iterator = references.iterator();
272
		IDatabase d = refFactory.newDatabase();
273
		while (iterator.hasNext()) {
274
			ReferenceBase reference = (ReferenceBase) iterator.next();
275
			if (reference.getType().equals(ReferenceType.Database)) {
276
				buildDataset(baselement, reference);
277
			}
278
		}
279
		}
280
		document.appendChild(baselement);
281
	}
282
	
283
	// Only for tests on natural language generation ; to be deleted after
284
	public void buildNaturalLanguageDescription(ElementImpl dataset) {
285
		List<TextData> listTextData = null;
286
		Set<TaxonDescription> descriptions = null;
287
		TaxonDescription description = null;
288
		FeatureTree featureTree = null;
289
		for (Iterator<? extends TaxonBase> tb = cdmSource.getTaxa().iterator() ; tb.hasNext() ;){
290
			Taxon taxon = (Taxon) tb.next();
291
			if (taxon.generateTitle().contains("pauciflora")) { // write the name (or part of the name) of the taxon you want to import the descriptions
292
				descriptions = taxon.getDescriptions();
293
				description = descriptions.iterator().next();
294
			}
295
		}
296
		for (int i = 0; i < cdmSource.getFeatureData().size(); i++) {
297
			VersionableEntity featu = cdmSource.getFeatureData().get(i);
298
			if (featu instanceof FeatureTree){
299
				FeatureTree ft = (FeatureTree) featu;
300
				if (ft.getLabel().contains("Main")) {
301
					featureTree = ft;
302
				}
303
			}
304
		}
305
		NaturalLanguageGenerator natlgen = new NaturalLanguageGenerator();
306
//		MicroFormatQuantitativeDescriptionBuilder micro = new MicroFormatQuantitativeDescriptionBuilder();
307
//		natlgen.setQuantitativeDescriptionBuilder(micro);
308
//		listTextData = natlgen.generateNaturalLanguageDescription(featureTree, description);
309
//		for (Iterator<TextData> td = listTextData.iterator() ; td.hasNext();) {
310
//			TextData textD = td.next();
311
//			System.out.println(textD.getText(Language.DEFAULT()));
312
//		}
313
		String descriptionString = natlgen.generateStringNaturalLanguageDescription(featureTree, description, Language.DEFAULT());
314
		System.out.println(descriptionString);
315
	}
316

    
317
	// TO BE DELETED SOON
318
	public void buildIdentificationKey(ElementImpl dataset) {
319
		IdentificationKeyGenerator idkgen = new IdentificationKeyGenerator();
320
		Set<TaxonDescription> descriptions = new HashSet<TaxonDescription>();
321
		List<Feature> featureList = new ArrayList<Feature>();
322
		for (Iterator<? extends TaxonBase> tb = cdmSource.getTaxa().iterator() ; tb.hasNext() ;){
323
			Taxon taxon = (Taxon) tb.next();
324
			for (TaxonDescription td : taxon.getDescriptions()){
325
				descriptions.add(td);
326
				for(DescriptionElementBase deb : td.getElements()){
327
				if (deb.isInstanceOf(CategoricalData.class)){
328
					CategoricalData catdat = (CategoricalData)deb;
329
					Feature feat = catdat.getFeature();
330
					if (feat!=null && feat.getLabel()!=null && !featureList.contains(feat)){
331
						featureList.add(catdat.getFeature());
332
					}
333
				}
334
				}
335
			}
336
		}
337
		idkgen.setFeatures(featureList);
338
		idkgen.setTaxa(descriptions);
339
		logger.error("Start keys");
340
		
341
		idkgen.makeandprint();
342
	}
343
	//	#############
344
	//	# BUILD DOM	#
345
	//	#############	
346

    
347
	/**
348
	 * Builds TechnicalMetadata associated with the SDD file
349
	 */
350
	public void buildTechnicalMetadata(ElementImpl baselement) throws ParseException {
351
		//create TechnicalMetadata
352
		ElementImpl technicalMetadata = new ElementImpl(document, TECHNICAL_METADATA);
353
		//select different databases associated to different descriptions TODO
354
		List<ReferenceBase> references = cdmSource.getReferences();
355
		Iterator<ReferenceBase> iterator = references.iterator();
356
		boolean database = false;
357
		IDatabase d = refFactory.newDatabase();
358
		while ((iterator.hasNext()) && (!database)) {
359
			ReferenceBase reference = (ReferenceBase) iterator.next();
360
			if (reference.getType().equals(ReferenceType.Database)) {
361
				d = reference;
362
			}
363
		}
364
		DateTime dt = d.getCreated();
365
		String date = dt.toString().substring(0, 19);
366
		technicalMetadata.setAttribute("created", date);
367

    
368
		ElementImpl generator = new ElementImpl(document, GENERATOR);
369
		generator.setAttribute("name", "EDIT CDM");
370
		generator.setAttribute("version", "v1");
371
		generator.setAttribute("notes","This SDD file has been generated by the SDD export functionality of the EDIT platform for Cybertaxonomy - Copyright (c) 2008");
372
		technicalMetadata.appendChild(generator);
373

    
374
		baselement.appendChild(technicalMetadata);
375
	}
376

    
377
	// Builds the information associated with a dataset
378
	public void buildDataset(ElementImpl baselement,IDatabase reference) throws ParseException {
379
		// create Dataset and language
380
		ElementImpl dataset = new ElementImpl(document, DATASET);
381
		// no default language associated with a dataset in the CDM
382
		dataset.setAttribute("xml:lang", Language.DEFAULT().getIso639_1());
383
		baselement.appendChild(dataset);
384
		buildRepresentation(dataset, reference);
385
		buildRevisionData(dataset, reference);
386
		buildIPRStatements(dataset, reference);
387
		buildTaxonNames(dataset);
388
		buildDescriptiveConcepts(dataset);
389
		buildCharacters(dataset);
390
		buildCodedDescriptions(dataset);
391
		buildAgents(dataset);
392
		buildPublications(dataset);
393
		buildMediaObjects(dataset);
394
		buildCharacterTrees(dataset);
395
		buildTaxonomicTrees(dataset);
396
		buildGeographicAreas(dataset);
397
		buildSpecimens(dataset);
398
	}
399

    
400
	/**
401
	 * Builds a Representation element using a ReferenceBase
402
	 */
403
	public void buildRepresentation(ElementImpl element, IDatabase reference) throws ParseException {
404

    
405
		//			create <Representation> element
406
		ElementImpl representation = new ElementImpl(document, REPRESENTATION);
407
		element.appendChild(representation);
408
		buildLabel(representation, reference.getTitleCache());
409

    
410
		Set<Annotation> annotations = ((ReferenceBase)reference).getAnnotations();
411
		Iterator iterator = annotations.iterator();
412
		String detailText = null;
413
		if (iterator.hasNext()) {
414
			Annotation annotation = (Annotation) iterator.next();
415
			detailText = annotation.getText();
416
		}
417

    
418
		if (detailText != null && !detailText.equals("")) {
419
			ElementImpl detail = new ElementImpl(document, DETAIL);
420
			detail.appendChild(document.createTextNode(detailText));
421
			representation.appendChild(detail);
422
		}
423

    
424
		Set<Media> rm = ((ReferenceBase)reference).getMedia();
425

    
426
		if (rm != null && rm.size() > 0) {
427
			ElementImpl mediaObject;
428

    
429
			for (int i = 0; i < rm.size(); i++) {
430
				mediaObject = new ElementImpl(document, MEDIA_OBJECT);
431
				mediasCount = buildReference((Media) rm.toArray()[i], medias, REF, mediaObject, "m", mediasCount);
432
				representation.appendChild(mediaObject);
433
			}
434
		}
435

    
436
	}
437
	
438
	
439
	/**
440
	 * Builds a Representation element using a Feature
441
	 */
442
	public void buildRepresentation(ElementImpl element, TermBase tb) throws ParseException {
443

    
444
		//			create <Representation> element
445
		ElementImpl representation = new ElementImpl(document, REPRESENTATION);
446
		element.appendChild(representation);
447

    
448
		Set<Representation> representations = tb.getRepresentations();
449
		if (representations != null) {
450
			if (!representations.isEmpty()) {
451
				String label = ((Representation) representations.toArray()[0]).getLabel();
452
				buildLabel(representation, label);
453
				String detailText = tb.getDescription();
454

    
455
				if (detailText != null && !detailText.equals("")) {
456
					if (!detailText.equals(label)) {
457
						ElementImpl detail = new ElementImpl(document, DETAIL);
458
						detail.appendChild(document.createTextNode(detailText));
459
						representation.appendChild(detail);
460
					}
461
				}
462

    
463
			}
464
		}		
465

    
466
		if (tb instanceof DefinedTermBase) {
467
			DefinedTermBase dtb = (DefinedTermBase) tb;
468
			Set<Media> rm = dtb.getMedia();
469

    
470
			if (rm != null && rm.size() > 0) {
471
				ElementImpl mediaObject;
472

    
473
				for (int i = 0; i < rm.size(); i++) {
474
					mediaObject = new ElementImpl(document, MEDIA_OBJECT);
475
					mediasCount = buildReference((Media) rm.toArray()[i], medias, REF, mediaObject, "m", mediasCount);
476
					representation.appendChild(mediaObject);
477
				}
478
			}
479
		}
480
	}
481
	
482
	/**
483
	 * Builds a Representation element using an IdentifiableEntity 
484
	 */
485
	public void buildRepresentation(ElementImpl element, IdentifiableEntity ie) throws ParseException {
486

    
487
		//			create <Representation> element
488
		ElementImpl representation = new ElementImpl(document, REPRESENTATION);
489
		element.appendChild(representation);
490
		buildLabel(representation, ie.getTitleCache());
491

    
492
		Set<Annotation> annotations = ie.getAnnotations();
493
		Iterator iterator = annotations.iterator();
494
		String detailText = null;
495
		if (iterator.hasNext()) {
496
			Annotation annotation = (Annotation) iterator.next();
497
			detailText = annotation.getText();
498
		}
499

    
500
		if (detailText != null && !detailText.equals("")) {
501
			ElementImpl detail = new ElementImpl(document, DETAIL);
502
			detail.appendChild(document.createTextNode(detailText));
503
			representation.appendChild(detail);
504
		}
505

    
506
		if (ie instanceof DefinedTermBase) {
507
			DefinedTermBase dtb = (DefinedTermBase) ie;
508
			Set<Media> rm = dtb.getMedia();
509

    
510
			if (rm != null && rm.size() > 0) {
511
				ElementImpl mediaObject;
512

    
513
				for (int i = 0; i < rm.size(); i++) {
514
					mediaObject = new ElementImpl(document, MEDIA_OBJECT);
515
					mediasCount = buildReference((Media) rm.toArray()[i], medias, REF, mediaObject, "m", mediasCount);
516
					representation.appendChild(mediaObject);
517
				}
518
			}
519
		}
520
		if (ie instanceof IdentifiableMediaEntity) {
521
			IdentifiableMediaEntity ime = (IdentifiableMediaEntity) ie;
522
			Set<Media> medias = ime.getMedia();
523
			if (medias != null){
524
				ElementImpl elLinks = new ElementImpl(document, "Links");
525
				for (Iterator<Media> m = medias.iterator() ; m.hasNext() ;){
526
					Media media = m.next();
527
					Set<MediaRepresentation> smr = media.getRepresentations();
528
					for (Iterator<MediaRepresentation> mr = smr.iterator() ; mr.hasNext();){
529
						MediaRepresentation mediarep = mr.next();
530
						List<MediaRepresentationPart> lmrp = mediarep.getParts();
531
						for (Iterator<MediaRepresentationPart> mrp = lmrp.iterator();mrp.hasNext();){
532
							MediaRepresentationPart mediareppart = mrp.next();
533
							ElementImpl elLink = new ElementImpl(document, "Link");
534
							elLink.setAttribute("href",mediareppart.getUri());
535
							elLinks.appendChild(elLink);
536
						}
537
					}
538
				}
539
				element.appendChild(elLinks);
540
			}
541
		}
542

    
543
	}
544

    
545
	/**
546
	 * Builds RevisionData associated with the Dataset
547
	 */
548
	public void buildRevisionData(ElementImpl dataset, IDatabase database) throws ParseException {
549

    
550
		// <RevisionData>
551
		//  <Creators>
552
		//    <Agent role="aut" ref="a1"/>
553
		//    <Agent role="aut" ref="a2"/>
554
		//    <Agent role="edt" ref="a3"/>
555
		//  </Creators>
556
		//  <DateModified>2006-04-08T00:00:00</DateModified>
557
		// </RevisionData>
558

    
559
		ElementImpl revisionData = new ElementImpl(document, REVISION_DATA);
560

    
561
		// authors
562
		TeamOrPersonBase authors = database.getAuthorTeam();
563
		//TeamOrPersonBase editors = database.getUpdatedBy();
564

    
565
		if ((authors != null)) { // || (editors != null)) {
566
			ElementImpl creators = new ElementImpl(document, CREATORS);
567
			if (authors != null) {
568
				buildRefAgent(creators, authors, "aut");
569
			}
570
			//			if (editors != null) {
571
			//						buildRefAgent(creators, editors, "edt");
572
			//			}
573
			revisionData.appendChild(creators);
574
		}
575

    
576
		buildDateModified(revisionData, database);
577

    
578
		dataset.appendChild(revisionData);
579
	}
580

    
581
	/**
582
	 * Builds ModifiedDate associated with RevisionData
583
	 */
584
	public void buildDateModified(ElementImpl revisionData, IDatabase database) throws ParseException {
585

    
586
		//  <DateModified>2006-04-08T00:00:00</DateModified>
587

    
588
		if (((ReferenceBase)database).getUpdated() != null) {
589
			ElementImpl dateModified = new ElementImpl(document, DATE_MODIFIED);
590

    
591
			DateTime c = ((ReferenceBase)database).getUpdated();
592
			DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
593

    
594
			String date = fmt.print(c);
595
			dateModified.appendChild(document.createTextNode(date));
596

    
597
			revisionData.appendChild(dateModified);
598
		}
599

    
600
	}
601

    
602
	/**
603
	 * Builds IPRStatements associated with the Dataset
604
	 */
605
	public void buildIPRStatements(ElementImpl dataset, IDatabase database) throws ParseException {
606

    
607
		// <IPRStatements>
608
		//  <IPRStatement role="Copyright">
609
		//    <Label xml:lang="en-au">(c) 2003-2006 Centre for Occasional Botany.</Label>
610
		//  </IPRStatement>
611
		// </IPRStatements>
612

    
613
		if (database.getRights() != null) {
614
			//create IPRStatements
615
			ElementImpl iprStatements = new ElementImpl(document, IPR_STATEMENTS);
616
			dataset.appendChild(iprStatements);
617

    
618
			//mapping between IPRStatement Copyright (SDD) and first Right in the list of Rights
619
			ElementImpl iprStatement = new ElementImpl(document, IPR_STATEMENT);
620
			iprStatement.setAttribute("role", "Copyright");
621
			iprStatements.appendChild(iprStatement);
622
			if (!database.getRights().isEmpty()) {
623
				buildLabel(iprStatement, ((Rights) database.getRights().toArray()[0]).getText());
624
			}
625
		}
626

    
627
	}
628
	
629
	/**
630
	 * Creates a Label element 
631
	 * @param base
632
	 * @param element
633
	 */
634
	public void buildLabel(ElementImpl element, String text) {
635
		ElementImpl label = new ElementImpl(document, LABEL);
636
		label.appendChild(document.createTextNode(text));
637
		element.appendChild(label);
638
	}
639
	
640
	//	################
641
	//	# GENERIC BRICKS       #
642
	//	################
643

    
644
	/**
645
	 * Builds TaxonNames associated with the Dataset
646
	 */
647
	public void buildTaxonNames(ElementImpl dataset) throws ParseException {
648

    
649
		// <TaxonNames>
650
		//  <TaxonName id="t1" uri="urn:lsid:authority:namespace:my-own-id">
651
		//    <Representation>
652
		//      <Label xml:lang="la">Viola hederacea Labill.</Label>
653
		//    </Representation>
654
		//  </TaxonName>
655
		// </TaxonNames>
656

    
657
		if (cdmSource.getTaxonomicNames() != null) {
658
			ElementImpl elTaxonNames = new ElementImpl(document, TAXON_NAMES);
659

    
660
			for (int i = 0; i < cdmSource.getTaxonomicNames().size(); i++) {
661
				ElementImpl elTaxonName = new ElementImpl(document, TAXON_NAME);
662
				TaxonNameBase tnb = cdmSource.getTaxonomicNames().get(i);
663

    
664
				taxonNamesCount = buildReference(tnb, taxonNames, ID, elTaxonName, "t", taxonNamesCount);
665

    
666
				buildRepresentation(elTaxonName, tnb);
667

    
668
				elTaxonNames.appendChild(elTaxonName);
669
			}
670

    
671
			dataset.appendChild(elTaxonNames);
672
		}
673

    
674
	}
675
	
676

    
677
	public void buildDescriptiveConcepts(ElementImpl dataset) throws ParseException {
678

    
679
		if (cdmSource.getFeatureData() != null) {
680
			ElementImpl elFeatures = new ElementImpl(document, DESCRIPTIVE_CONCEPTS);
681
			int f = cdmSource.getTerms().size();
682
			for (int i = 0; i < f; i++) {
683
				DefinedTermBase dtb = cdmSource.getTerms().get(i);
684
				if (dtb instanceof Feature) {
685
					ElementImpl elFeat = new ElementImpl(document, DESCRIPTIVE_CONCEPT);
686
					Feature feature = (Feature) dtb;
687
					if (feature.getMarkers()!= null){
688
						Set<Marker> markers = feature.getMarkers();
689
						for(Iterator<Marker> m = markers.iterator() ; m.hasNext();){
690
							Marker marker = m.next();
691
							if (marker.getMarkerType().getLabel().equals("DescriptiveConcept")){
692
								descriptiveConceptCount = buildReference(dtb, descriptiveConcepts, ID, elFeat, "dc", descriptiveConceptCount);
693
								buildRepresentation(elFeat, feature);
694
								if (!feature.getRecommendedModifierEnumeration().isEmpty()){
695
									ElementImpl elModifiers = new ElementImpl(document, "Modifiers");
696
									for(Iterator<TermVocabulary<Modifier>> menum = feature.getRecommendedModifierEnumeration().iterator() ; menum.hasNext() ;) {
697
										TermVocabulary<Modifier> termVoc = menum.next();
698
										Set<Modifier> sm = termVoc.getTerms() ;
699
										for (Iterator<Modifier> modif = sm.iterator() ; modif.hasNext() ;) {
700
											Modifier modifier = modif.next();
701
											ElementImpl elModifier = new ElementImpl(document, "Modifier");
702
											modifiersCount = buildReference(modifier, modifiers, ID, elModifier, "mod", modifiersCount);
703
											buildRepresentation(elModifier,modifier);
704
											elModifiers.appendChild(elModifier);
705
										}
706
									}
707
									elFeat.appendChild(elModifiers);
708
								}
709
								elFeatures.appendChild(elFeat);
710
							}
711
						}
712
					}
713
				}
714
			}
715
			dataset.appendChild(elFeatures);
716
		}
717
	}
718

    
719

    
720
	/**
721
	 * Builds Characters associated with the Dataset
722
	 */
723
	public void buildCharacters(ElementImpl dataset) throws ParseException {
724

    
725
		if (cdmSource.getTerms() != null) {
726
			ElementImpl elCharacters = new ElementImpl(document, CHARACTERS);
727

    
728
			int f = cdmSource.getTerms().size();
729
			for (int i = 0; i < f; i++) {
730
				if (cdmSource.getTerms().get(i) instanceof Feature) {
731
					Feature character = (Feature) cdmSource.getTerms().get(i);
732
					if (character.isSupportsQuantitativeData()) {
733
						ElementImpl elQuantitativeCharacter = new ElementImpl(document, QUANTITATIVE_CHARACTER);
734
						charactersCount = buildReference(character, characters, ID, elQuantitativeCharacter, "c", charactersCount);
735
						buildRepresentation(elQuantitativeCharacter, character);
736
						elCharacters.appendChild(elQuantitativeCharacter);
737
				}
738

    
739
					if (character.isSupportsCategoricalData()) {
740
						ElementImpl elCategoricalCharacter = new ElementImpl(document, CATEGORICAL_CHARACTER);
741
						charactersCount = buildReference(character, characters, ID, elCategoricalCharacter, "c", charactersCount);
742
						buildRepresentation(elCategoricalCharacter, character);
743

    
744
						Set<TermVocabulary<State>> enumerations = character.getSupportedCategoricalEnumerations();
745
						if (enumerations != null) {
746
							if (enumerations.size()>0) {
747
								ElementImpl elStates = new ElementImpl(document, STATES);
748
								TermVocabulary tv = (TermVocabulary) enumerations.toArray()[0];
749
								Set<State> stateList = tv.getTerms();
750
								for (int j = 0; j < stateList.size(); j++) {
751
									ElementImpl elStateDefinition = new ElementImpl(document, STATE_DEFINITION);
752
									State state = (State) stateList.toArray()[j];
753
									statesCount = buildReference(state, states, ID, elStateDefinition, "s", statesCount);
754
									buildRepresentation(elStateDefinition, state);
755
									elStates.appendChild(elStateDefinition);
756
			}
757
								elCategoricalCharacter.appendChild(elStates);
758
								elCharacters.appendChild(elCategoricalCharacter);
759
							}
760
						}
761
					}
762
					if (character.isSupportsTextData()) {
763
						ElementImpl elTextCharacter = new ElementImpl(document, TEXT_CHARACTER);
764
						textcharactersCount = buildReference(character, characters, ID, elTextCharacter, TEXT, textcharactersCount);
765
						buildRepresentation(elTextCharacter, character);
766
						elCharacters.appendChild(elTextCharacter);
767
					}
768
				}
769
			}
770

    
771
			dataset.appendChild(elCharacters);
772
		}
773

    
774
	}
775

    
776
	public void buildCodedDescriptions(ElementImpl dataset) throws ParseException {
777

    
778
		if (cdmSource.getTaxa() != null) {
779
			ElementImpl elCodedDescriptions = new ElementImpl(document, CODED_DESCRIPTIONS);
780

    
781
			for (Iterator<? extends TaxonBase> tb = cdmSource.getTaxa().iterator() ; tb.hasNext() ;){
782
				Taxon taxon = (Taxon) tb.next();
783
				Set<TaxonDescription> descriptions = taxon.getDescriptions();
784
				for (Iterator<TaxonDescription> td = descriptions.iterator() ; td.hasNext() ;){
785
					TaxonDescription taxonDescription = td.next();
786
					ElementImpl elCodedDescription = new ElementImpl(document, CODED_DESCRIPTION);
787
					codedDescriptionsCount = buildReference(taxonDescription, codedDescriptions, ID, elCodedDescription, "D", codedDescriptionsCount);
788
					buildRepresentation(elCodedDescription, taxonDescription);
789
					buildScope(elCodedDescription, taxonDescription);
790
					buildSummaryData(elCodedDescription, taxonDescription);
791
					elCodedDescriptions.appendChild(elCodedDescription);
792
								}
793
							}
794

    
795
			dataset.appendChild(elCodedDescriptions);
796
		}
797

    
798
	}
799
							
800
	/**
801
	 * Builds Scope associated with a CodedDescription
802
	 */
803
	public void buildScope(ElementImpl element, TaxonDescription taxonDescription) throws ParseException {
804

    
805
		//		  <Scope>
806
		//         <TaxonName ref="t1"/>
807
		//         <Citation ref="p1" location="p. 30"/>
808
		//        </Scope>
809

    
810
		ElementImpl scope = new ElementImpl(document, SCOPE);
811

    
812
		Taxon taxon = taxonDescription.getTaxon();
813
		if (taxon != null) {
814
			TaxonNameBase taxonNameBase = taxon.getName();
815
			if (taxonNameBase != null) {
816
				String ref = taxonNames.get(taxonNameBase);
817
				if (!ref.equals("")) {
818
					ElementImpl taxonName = new ElementImpl(document, TAXON_NAME);
819
					taxonName.setAttribute(REF, ref);
820
					scope.appendChild(taxonName);
821
					}
822
				}
823
		}
824

    
825
		Set<ReferenceBase> descriptionSources = taxonDescription.getDescriptionSources();
826
		for (Iterator<ReferenceBase> rb = descriptionSources.iterator() ; rb.hasNext() ;){
827
			ReferenceBase descriptionSource = rb.next();
828
			if (descriptionSource.getType().equals(ReferenceType.Article)) {
829

    
830
				ElementImpl citation = new ElementImpl(document, CITATION);
831
				articlesCount = buildReference(descriptionSource, articles, REF, citation, "p", articlesCount);
832

    
833
				Set<Annotation> annotations = descriptionSource.getAnnotations();
834
				for (Iterator<Annotation> a = annotations.iterator() ; a.hasNext() ;){
835
					Annotation annotation = a.next();
836
					AnnotationType annotationType = annotation.getAnnotationType();
837
					if (annotationType != null) {
838
						String type = annotationType.getLabel();
839
						if (type.equals("location")) {
840
							citation.setAttribute("location", annotation.getText());
841
	}
842
					}
843
				}
844

    
845
				scope.appendChild(citation);
846
			}
847
		}
848

    
849
		element.appendChild(scope);
850
	}
851

    
852
	/**
853
	 * Builds SummaryData associated with a CodedDescription
854
	 */
855
	public void buildSummaryData(ElementImpl element, TaxonDescription taxonDescription) throws ParseException {
856

    
857
		//			<SummaryData>
858
		//	          <Categorical ref="c4">
859
		//	            <State ref="s3"/>
860
		//	            <State ref="s4"/>
861
		//	          </Categorical>
862

    
863
		ElementImpl summaryData = new ElementImpl(document, SUMMARY_DATA);
864
		Set<DescriptionElementBase> elements = taxonDescription.getElements();
865
		for (Iterator<DescriptionElementBase> deb = elements.iterator() ; deb.hasNext() ;){
866
			DescriptionElementBase descriptionElement = deb.next();
867
			if (descriptionElement instanceof CategoricalData) {
868
				CategoricalData categoricalData = (CategoricalData) descriptionElement;
869
				buildCategorical(summaryData, categoricalData);
870
			}
871
			if (descriptionElement instanceof QuantitativeData) {
872
				QuantitativeData quantitativeData = (QuantitativeData) descriptionElement;
873
				buildQuantitative(summaryData, quantitativeData);
874
			}
875
			if (descriptionElement instanceof TextData) {
876
				TextData textData = (TextData) descriptionElement;
877
				buildTextChar(summaryData, textData);
878
			}
879
		}
880
		element.appendChild(summaryData);
881
	}
882

    
883
	/**
884
	 * Builds Categorical associated with a SummaryData
885
	 */
886
	public void buildCategorical(ElementImpl element, CategoricalData categoricalData) throws ParseException {
887

    
888
		//			<SummaryData>
889
		//	          <Categorical ref="c4">
890
		//	            <State ref="s3"/>
891
		//	            <State ref="s4"/>
892
		//	          </Categorical>
893

    
894
		ElementImpl categorical = new ElementImpl(document, CATEGORICAL);
895
		Feature feature = categoricalData.getFeature();
896
		buildReference(feature, characters, REF, categorical, "c", charactersCount);
897
		List<StateData> states = categoricalData.getStates();
898
		for (Iterator<StateData> sd = states.iterator() ; sd.hasNext() ;){
899
			StateData stateData = sd.next();
900
			State s = stateData.getState();
901
			buildState(categorical, s);
902
		}
903
		element.appendChild(categorical);
904
	}
905

    
906
	/**
907
	 * Builds State associated with a Categorical
908
	 */
909
	public void buildState(ElementImpl element, State s) throws ParseException {
910

    
911
		//			<SummaryData>
912
		//	          <Categorical ref="c4">
913
		//	            <State ref="s3"/>
914
		//	            <State ref="s4"/>
915
		//	          </Categorical>
916

    
917
		ElementImpl state = new ElementImpl(document, STATE);
918
		buildReference(s, states, REF, state, "s", statesCount);
919
		element.appendChild(state);
920
	}
921

    
922
	/**
923
	 * Builds Quantitative associated with a SummaryData
924
	 */
925
	public void buildQuantitative(ElementImpl element, QuantitativeData quantitativeData) throws ParseException {
926

    
927
		//		<Quantitative ref="c2">
928
		//        <Measure type="Min" value="2.3"></Measure>
929
		//        <Measure type="Mean" value="5.1"/>
930
		//        <Measure type="Max" value="7.9"/>
931
		//        <Measure type="SD" value="1.3"/>
932
		//        <Measure type="N" value="20"/>
933
		//      </Quantitative>
934

    
935
		ElementImpl quantitative = new ElementImpl(document, QUANTITATIVE);
936
		Feature feature = quantitativeData.getFeature();
937
		buildReference(feature, characters, REF, quantitative, "c", charactersCount);
938
		Set<StatisticalMeasurementValue> statisticalValues = quantitativeData.getStatisticalValues();
939
		for (Iterator<StatisticalMeasurementValue> smv = statisticalValues.iterator() ; smv.hasNext() ;){
940
			StatisticalMeasurementValue statisticalValue = smv.next();
941
			buildMeasure(quantitative, statisticalValue);
942
		}
943
		element.appendChild(quantitative);
944
	}
945

    
946
	/**
947
	 * Builds Measure associated with a Quantitative XIMCHECK
948
	 */
949
	public void buildMeasure(ElementImpl element, StatisticalMeasurementValue statisticalValue) throws ParseException {
950

    
951
		//		<Quantitative ref="c2">
952
		//        <Measure type="Min" value="2.3"></Measure>
953
		//        <Measure type="Mean" value="5.1"/>
954
		//        <Measure type="Max" value="7.9"/>
955
		//        <Measure type="SD" value="1.3"/>
956
		//        <Measure type="N" value="20"/>
957
		//      </Quantitative>
958

    
959
		ElementImpl measure = new ElementImpl(document, MEASURE);
960
		StatisticalMeasure type = statisticalValue.getType();
961
		String label = type.getLabel();
962
		if (label.equals("Average")) {
963
			measure.setAttribute("type", "Mean");
964
		} else if (label.equals("StandardDeviation")) {
965
			measure.setAttribute("type", "SD");
966
		} else if (label.equals("SampleSize")) {
967
			measure.setAttribute("type", "N");
968
		} else {
969
			measure.setAttribute("type", label);
970
		}
971
		float value = statisticalValue.getValue();
972
		measure.setAttribute("value", String.valueOf(value));
973
		element.appendChild(measure);
974
	}
975

    
976
	/**
977
	 * Builds TextChar associated with a SummaryData
978
	 */
979
	public void buildTextChar(ElementImpl element, TextData textData) throws ParseException {
980

    
981
		//			<TextChar ref="c3">
982
		//            <Content>Free form text</Content>
983
		//          </TextChar>
984

    
985
		ElementImpl textChar = new ElementImpl(document, TEXT_CHAR);
986
		Feature feature = textData.getFeature();
987
		buildReference(feature, characters, REF, textChar, "c", charactersCount);
988
		Map<Language,LanguageString> multilanguageText = textData.getMultilanguageText();
989
		for (Iterator<Language> l = multilanguageText.keySet().iterator() ; l.hasNext() ;){
990
			Language language = l.next();
991
			LanguageString languageString = multilanguageText.get(language);
992
			buildContent(textChar,languageString);
993
		}
994
		element.appendChild(textChar);
995
	}
996

    
997
	/**
998
	 * Builds Content associated with a TextChar
999
	 */
1000
	public void buildContent(ElementImpl element, LanguageString languageString) throws ParseException {
1001

    
1002
		//			<TextChar ref="c3">
1003
		//            <Content>Free form text</Content>
1004
		//          </TextChar>
1005

    
1006
		ElementImpl content = new ElementImpl(document, CONTENT);
1007
		Language language = languageString.getLanguage();
1008
		String text = languageString.getText();
1009
		if (!language.getIso639_1().equals(defaultLanguage.getIso639_1())) {
1010
			content.setAttribute("xml:lang", language.getIso639_1());
1011
		}
1012
		content.setTextContent(text);
1013
		element.appendChild(content);
1014
	}
1015

    
1016
	/**
1017
	 * Builds an element Agent referring to Agent defined later in the SDD file
1018
	 */
1019
	public void buildRefAgent(ElementImpl element, TeamOrPersonBase ag, String role) throws ParseException {
1020
		if (ag instanceof Person) {
1021
			Person p = (Person) ag;
1022
			ElementImpl agent = new ElementImpl(document, AGENT);
1023
			if (ag.getMarkers()!= null){
1024
				Set<Marker> markers = ag.getMarkers();
1025
				for(Iterator<Marker> m = markers.iterator() ; m.hasNext();){
1026
					Marker marker = m.next();
1027
					if (marker.getMarkerType().getLabel().equals("editor")){
1028
						agent.setAttribute(ROLE, "edt");
1029
					}
1030
				}
1031
			}
1032
			else {
1033
				agent.setAttribute(ROLE, role);
1034
			}
1035
			agentsCount = buildReference(p, agents, REF, agent, "a", agentsCount);
1036
			element.appendChild(agent);
1037
		}
1038

    
1039
		if (ag instanceof Team) {
1040
			Team team = (Team) ag;
1041
			for (int i = 0; i < team.getTeamMembers().size(); i++) {
1042
				Person author = team.getTeamMembers().get(i);
1043
				ElementImpl agent = new ElementImpl(document, AGENT);
1044
				if (author.getMarkers()!= null){
1045
					Set<Marker> markers = author.getMarkers();
1046
					if (!markers.isEmpty()){
1047
						for(Iterator<Marker> m = markers.iterator() ; m.hasNext();){
1048
							Marker marker = m.next();
1049
							if (marker.getMarkerType().getLabel().equals("editor")){
1050
								agent.setAttribute(ROLE, "edt");
1051
							}
1052
						}
1053
					}
1054
						else {
1055
							agent.setAttribute(ROLE, role);
1056
						}
1057
				}
1058
				else {
1059
					agent.setAttribute(ROLE, role);
1060
				}
1061
				if (author.getSources() != null) {
1062
					IdentifiableSource os = (IdentifiableSource) author.getSources().toArray()[0];
1063
					String id = os.getIdInSource();
1064
					if (id != null) {
1065
						if (!id.equals("")) {
1066
							if (!agents.containsValue(id)) {
1067
								agent.setAttribute(REF, id);
1068
							} else if (!agents.containsValue("a" + (agentsCount+1))) {
1069
								agent.setAttribute(REF, "a" + (agentsCount+1));
1070
								agentsCount++;
1071
							} else {
1072
								agent.setAttribute(REF, id + (agentsCount+1));
1073
								agentsCount++;
1074
							}
1075
						} else {
1076
							agent.setAttribute(REF, "a" + (agentsCount+1));
1077
							agentsCount++;
1078
						}
1079
					} else {
1080
						agent.setAttribute(REF, "a" + (agentsCount+1));
1081
						agentsCount++;
1082
					}
1083
				} else {
1084
					agent.setAttribute(REF, "a" + (agentsCount+1));
1085
					agentsCount++;
1086
				}
1087
				agents.put(author, agent.getAttribute(REF));
1088
				element.appendChild(agent);
1089
			}
1090
		}
1091
	}
1092

    
1093

    
1094
	/**
1095
	 * Builds Agents associated with the Dataset
1096
	 */
1097
	public void buildAgents(ElementImpl dataset) throws ParseException {
1098

    
1099
		if (cdmSource.getAgents() != null) {
1100
			ElementImpl elAgents = new ElementImpl(document, AGENTS);
1101

    
1102
			for (int i = 0; i < cdmSource.getAgents().size(); i++) {
1103
				ElementImpl elAgent = new ElementImpl(document, AGENT);
1104
				AgentBase personagent = (AgentBase)cdmSource.getAgents().get(i);
1105
				if (personagent  instanceof Person){
1106
					if (personagent.getMarkers()!= null){
1107
						Set<Marker> markers = personagent.getMarkers();
1108
						for(Iterator<Marker> m = markers.iterator() ; m.hasNext();){
1109
							Marker marker = m.next();
1110
							if (marker.getMarkerType().getLabel().equals("editor")){
1111
								agentsCount = buildReference(personagent, agents, ID, elAgent, "a", agentsCount);
1112
							}
1113
						}
1114
					}
1115
				agentsCount = buildReference(personagent, agents, ID, elAgent, "a", agentsCount);
1116
				buildRepresentation(elAgent, personagent);
1117
				elAgents.appendChild(elAgent);
1118
				}
1119
			}
1120

    
1121
			dataset.appendChild(elAgents);
1122
		}
1123
	}
1124
	
1125
	public void buildCharacterTrees(ElementImpl dataset) throws ParseException {
1126

    
1127
		if (cdmSource.getFeatureData() != null) {
1128
			ElementImpl elChartrees = new ElementImpl(document, CHARACTER_TREES);
1129

    
1130
			for (int i = 0; i < cdmSource.getFeatureData().size(); i++) {
1131
				VersionableEntity featu = cdmSource.getFeatureData().get(i);
1132
				if (featu instanceof FeatureTree){
1133
					FeatureTree ft = (FeatureTree) featu;
1134
					ElementImpl elChartree = new ElementImpl(document, CHARACTER_TREE);
1135
					chartreeCount = buildReference(featu, featuretrees, ID, elChartree, "ct", chartreeCount);
1136
					buildRepresentation(elChartree, ft);
1137
					elChartrees.appendChild(elChartree);
1138
					ElementImpl elNodes = new ElementImpl(document, NODES);
1139
					elChartree.appendChild(elNodes);
1140
					List<FeatureNode> roots = ft.getRootChildren();
1141
					for (Iterator<FeatureNode> fn = roots.iterator(); fn.hasNext();) {
1142
						FeatureNode featureNode = fn.next();
1143
						buildBranches(featureNode,elNodes,true);				
1144
				}
1145
			}
1146
			}
1147
			dataset.appendChild(elChartrees);
1148
		}
1149
	}
1150
	
1151
	public void buildTaxonomicTrees(ElementImpl dataset) throws ParseException {
1152

    
1153
		if (cdmSource.getTaxa() != null) {
1154
			ElementImpl elTaxonHierarchies = new ElementImpl(document, "TaxonHierarchies");
1155
			ElementImpl elTaxonHierarchy = new ElementImpl(document, "TaxonHierarchy");
1156
			for (Iterator<? extends TaxonBase> tb = cdmSource.getTaxa().iterator() ; tb.hasNext() ;){
1157
				Taxon taxon = (Taxon) tb.next();
1158
				if (taxon.getTaxonNodes()!=null){
1159
					for (Iterator<TaxonNode> tn = taxon.getTaxonNodes().iterator() ; tn.hasNext() ;){
1160
						TaxonNode taxonnode = tn.next();
1161
							if (taxonnode.isTopmostNode()) {
1162
								ElementImpl elNode = new ElementImpl(document, "Node");
1163
								taxonNodesCount = buildReference(taxonnode, taxonNodes, ID, elNode, "tn", taxonNodesCount);
1164
								ElementImpl elTaxonName = new ElementImpl(document, TAXON_NAME);
1165
								taxonNamesCount = buildReference(taxonnode.getTaxon().getName(), taxonNames, REF, elTaxonName, "t", taxonNamesCount);
1166
								elNode.appendChild(elTaxonName);
1167
								elTaxonHierarchy.appendChild(elNode);
1168
								if (taxonnode.hasChildNodes()){
1169
									buildTaxonBranches(taxonnode.getChildNodes(),taxonnode, elTaxonHierarchy);
1170
								}
1171
							}
1172
					}
1173
				}
1174
			}
1175
			elTaxonHierarchies.appendChild(elTaxonHierarchy);
1176
			dataset.appendChild(elTaxonHierarchies);
1177
		}
1178
	}
1179

    
1180
	private void buildTaxonBranches(Set<TaxonNode> children, TaxonNode parent, ElementImpl elTaxonHierarchy){
1181
		if (children != null){
1182
			for (Iterator<TaxonNode> tn = children.iterator() ; tn.hasNext();){
1183
				TaxonNode taxonnode = tn.next();
1184
				ElementImpl elNode = new ElementImpl(document, "Node");
1185
				ElementImpl elParent = new ElementImpl(document, PARENT);
1186
				ElementImpl elTaxonName = new ElementImpl(document, TAXON_NAME);
1187
				if (taxonnode.hasChildNodes()){
1188
					buildTaxonBranches(taxonnode.getChildNodes(),taxonnode, elTaxonHierarchy);
1189
				}
1190
				taxonNodesCount = buildReference(taxonnode, taxonNodes, ID, elNode, "tn", taxonNodesCount);
1191
				taxonNodesCount = buildReference(parent, taxonNodes, REF, elParent, "tn", taxonNodesCount);
1192
				taxonNamesCount = buildReference(taxonnode.getTaxon().getName(), taxonNames, REF, elTaxonName, "t", taxonNamesCount);
1193
				elNode.appendChild(elParent);
1194
				elNode.appendChild(elTaxonName);
1195
				elTaxonHierarchy.appendChild(elNode);
1196
			}
1197
		}
1198
	}
1199
	
1200
	public void buildBranches(FeatureNode parent, ElementImpl element, boolean isRoot) {
1201
		List<FeatureNode> children = parent.getChildren();
1202
		if (!parent.isLeaf()){
1203
			ElementImpl elCharNode = new ElementImpl(document, NODE);
1204
			charnodeCount = buildReference(parent, featuretrees, ID, elCharNode, "cn", charnodeCount);
1205
			FeatureNode grandparent = parent.getParent();
1206
			if ((grandparent !=null)&&(!isRoot))	{
1207
				ElementImpl elParent = new ElementImpl(document, PARENT);
1208
				charnodeCount = buildReference(grandparent, featuretrees, REF, elParent, "cn", charnodeCount);
1209
				elCharNode.appendChild(elParent);
1210
			}
1211
			ElementImpl elDescriptiveConcept = new ElementImpl(document, DESCRIPTIVE_CONCEPT);
1212
			Feature fref = parent.getFeature();
1213
			descriptiveConceptCount = buildReference(fref, descriptiveConcepts, REF, elDescriptiveConcept, "dc", descriptiveConceptCount);
1214
			elCharNode.appendChild(elDescriptiveConcept);
1215
			element.appendChild(elCharNode);
1216
			for (Iterator<FeatureNode> ifn = children.iterator() ; ifn.hasNext() ;){
1217
				FeatureNode fn = ifn.next();
1218
				buildBranches(fn,element,false);
1219
			}
1220
		}
1221
		else {
1222
			ElementImpl elCharNode = new ElementImpl(document, CHAR_NODE);
1223
			ElementImpl elParent = new ElementImpl(document, PARENT);
1224
			FeatureNode grandparent = parent.getParent();
1225
			charnodeCount = buildReference(grandparent, featuretrees, REF, elParent, "cn", charnodeCount);
1226
			charnodeCount = buildReference(parent, featuretrees, ID, elCharNode, "cn", charnodeCount);
1227
			ElementImpl elCharacter = new ElementImpl(document, CHARACTER);
1228
			Feature fref = parent.getFeature();
1229
			charactersCount = buildReference(fref, characters, REF, elCharacter, "c", charactersCount);
1230
			elCharNode.appendChild(elCharacter);
1231
			elCharNode.appendChild(elParent);
1232
			element.appendChild(elCharNode);
1233
			}
1234
	}
1235

    
1236
	public void buildMediaObjects(ElementImpl dataset) throws ParseException {
1237

    
1238
		if (cdmSource.getMedia() != null) {
1239
			ElementImpl elMediaObjects = new ElementImpl(document, MEDIA_OBJECTS);
1240

    
1241
			for (int i = 0; i < cdmSource.getMedia().size(); i++) {
1242
				ElementImpl elMediaObject = new ElementImpl(document, MEDIA_OBJECT);
1243
				Media mediobj = (Media) cdmSource.getMedia().get(i);
1244
				mediasCount = buildReference(mediobj, medias, ID, elMediaObject, "t", mediasCount);
1245
				buildRepresentation(elMediaObject, mediobj);
1246
				Set<MediaRepresentation> smr = mediobj.getRepresentations();
1247
					for (Iterator<MediaRepresentation> mr = smr.iterator() ; mr.hasNext();){
1248
						MediaRepresentation mediarep = mr.next();
1249
						ElementImpl elType = new ElementImpl(document, "Type");
1250
						elType.appendChild(document.createTextNode(mediarep.getMimeType()));
1251
						elMediaObject.appendChild(elType);
1252
						List<MediaRepresentationPart> lmrp = mediarep.getParts();
1253
						for (Iterator<MediaRepresentationPart> mrp = lmrp.iterator();mrp.hasNext();){
1254
								MediaRepresentationPart mediareppart = mrp.next();
1255
								ElementImpl elSource = new ElementImpl(document, "Source");
1256
								elSource.setAttribute("href",mediareppart.getUri());
1257
								elMediaObject.appendChild(elSource);
1258
							}
1259
					}
1260
				elMediaObjects.appendChild(elMediaObject);
1261
			}
1262
			dataset.appendChild(elMediaObjects);
1263
		}
1264
	}
1265

    
1266
	public void buildPublications(ElementImpl dataset) throws ParseException {
1267

    
1268
		if (cdmSource.getReferences() != null) {
1269
			ElementImpl elPublications = new ElementImpl(document, PUBLICATIONS);
1270
			boolean editorial = false;
1271
			for (int i = 0; i < cdmSource.getReferences().size(); i++) {
1272
				ElementImpl elPublication = new ElementImpl(document, "Publication");
1273
				ReferenceBase publication = cdmSource.getReferences().get(i);
1274
					Set<Annotation> annotations = publication.getAnnotations();
1275
					for (Iterator<Annotation> a = annotations.iterator() ; a.hasNext() ;){
1276
						Annotation annotation = a.next();
1277
						AnnotationType annotationType = annotation.getAnnotationType();
1278
					if (annotationType.equals(AnnotationType.EDITORIAL())) {
1279
							editorial = true;
1280
						}
1281
						else {
1282
							editorial = false;
1283
						}
1284
					}
1285
					if (!editorial){
1286
				articlesCount = buildReference(publication, articles, ID, elPublication, "p", articlesCount);
1287
					buildRepresentation(elPublication, (IDatabase) publication);
1288
				elPublications.appendChild(elPublication);
1289
					}
1290
			}
1291
			dataset.appendChild(elPublications);
1292
		}
1293
	}
1294

    
1295
	public int buildReference(VersionableEntity ve, Map references, String refOrId, ElementImpl element, String prefix, int count) throws ParseException {
1296
		if (references.containsKey(ve)) {
1297
			element.setAttribute(refOrId,(String) references.get(ve));
1298
		} else {
1299
			if (ve instanceof IdentifiableEntity) {
1300
				IdentifiableEntity ie = (IdentifiableEntity) ve;
1301
				if (ie.getSources().size() > 0) {
1302
					IdentifiableSource os = (IdentifiableSource) ie.getSources().toArray()[0];
1303
					String id = os.getIdInSource();
1304
					String uri = os.getCitationMicroReference();
1305
					if (uri != null) {element.setAttribute(URI, uri);}
1306
					if (id != null) {
1307
						if (!id.equals("")) {
1308
							if (!references.containsValue(id)) {
1309
								element.setAttribute(refOrId, id);
1310
							} else while (element.getAttribute(refOrId).equals("")) {
1311
								if (!references.containsValue(prefix + (count+1))) {
1312
									element.setAttribute(refOrId, prefix + (count+1));
1313
								}
1314
								count++;
1315
							}
1316
						} else while (element.getAttribute(refOrId).equals("")) {
1317
							if (!references.containsValue(prefix + (count+1))) {
1318
								element.setAttribute(refOrId, prefix + (count+1));
1319
							}
1320
							count++;
1321
						}
1322
					} else while (element.getAttribute(refOrId).equals("")) {
1323
						if (!references.containsValue(prefix + (count+1))) {
1324
							element.setAttribute(refOrId, prefix + (count+1));
1325
						}
1326
						count++;
1327
					}
1328
				} else while (element.getAttribute(refOrId).equals("")) {
1329
					if (!references.containsValue(prefix + (count+1))) {
1330
						element.setAttribute(refOrId, prefix + (count+1));
1331
					}
1332
					count++;
1333
				}
1334
			} else while (element.getAttribute(refOrId).equals("")) {
1335
				if (!references.containsValue(prefix + (count+1))) {
1336
					element.setAttribute(refOrId, prefix + (count+1));
1337
				}
1338
				count++;
1339
			}
1340
			references.put(ve, element.getAttribute(refOrId));
1341
		}
1342
		return count;
1343
	}
1344

    
1345
	public void buildGeographicAreas(ElementImpl dataset) {
1346
		if (cdmSource.getTerms() != null) {
1347
			ElementImpl elGeographicAreas = new ElementImpl(document, "GeographicAreas");
1348

    
1349
			int f = cdmSource.getTerms().size();
1350
			for (int i = 0; i < f; i++) {
1351
				if (cdmSource.getTerms().get(i) instanceof NamedArea) {
1352
					NamedArea na = (NamedArea) cdmSource.getTerms().get(i);
1353
					for (Iterator<Marker> mark = na.getMarkers().iterator() ; mark.hasNext();) {
1354
						Marker marker = mark.next();
1355
						if (marker.getMarkerType().getLabel().equals("SDDGeographicArea")) {
1356
							ElementImpl elGeographicArea = new ElementImpl(document, "GeographicArea");
1357
							namedAreasCount = buildReference(na, namedAreas, ID, elGeographicArea, "a", namedAreasCount);
1358
							buildRepresentation(elGeographicArea,na);
1359
							elGeographicAreas.appendChild(elGeographicArea);
1360
				}
1361
			}
1362

    
1363
		}
1364
	}
1365
			dataset.appendChild(elGeographicAreas);
1366
				}
1367
			}
1368
				
1369
	public void buildSpecimens(ElementImpl dataset) throws ParseException {
1370

    
1371
		if (cdmSource.getOccurrences() != null) {
1372
			ElementImpl elSpecimens = new ElementImpl(document, "Specimens");
1373

    
1374
			for (int i = 0; i < cdmSource.getOccurrences().size(); i++) {
1375
				ElementImpl elSpecimen = new ElementImpl(document, "Specimen");
1376
				SpecimenOrObservationBase sob = cdmSource.getOccurrences().get(i);
1377
				if (sob instanceof Specimen){
1378
					specimenCount = buildReference(sob, specimens, ID, elSpecimen, "s", specimenCount);
1379
					buildRepresentation(elSpecimen, sob);
1380
					elSpecimens.appendChild(elSpecimen);
1381
			}
1382
		}
1383
			dataset.appendChild(elSpecimens);
1384
	}
1385

    
1386
			}
1387

    
1388
	
1389
}
(3-3/5)