Handles dependency rules.
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / sdd / out / SDDDocumentBuilder.java
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 buildIdentificationKey(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 = deb.getFeature();
330 if (feat!=null && feat.getLabel()!=null && !featureList.contains(feat)){
331 featureList.add(feat);
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 boolean dependencies = false;
1230 ElementImpl elDependecyRules = new ElementImpl(document, "DependecyRules");
1231 if (parent.getInapplicableIf()!=null){
1232 Set<State> innaplicableIf = parent.getInapplicableIf();
1233 ElementImpl elInnaplicableIf = new ElementImpl(document, "InapplicableIf");
1234 for (State state : innaplicableIf) {
1235 ElementImpl elState = new ElementImpl(document, STATE);
1236 buildReference(state, states, REF, elState, "State", statesCount);
1237 elInnaplicableIf.appendChild(elState);
1238 }
1239 elDependecyRules.appendChild(elInnaplicableIf);
1240 dependencies = true;
1241 }
1242 if (parent.getOnlyApplicableIf()!=null){
1243 Set<State> onlyApplicableIf = parent.getOnlyApplicableIf();
1244 ElementImpl elOnlyApplicableIf = new ElementImpl(document, "OnlyApplicableIf");
1245 for (State state : onlyApplicableIf) {
1246 ElementImpl elState = new ElementImpl(document, STATE);
1247 buildReference(state, states, REF, elState, "State", statesCount);
1248 elOnlyApplicableIf.appendChild(elState);
1249 }
1250 elDependecyRules.appendChild(elOnlyApplicableIf);
1251 dependencies = true;
1252 }
1253 if (dependencies == true) elCharNode.appendChild(elDependecyRules);
1254 charactersCount = buildReference(fref, characters, REF, elCharacter, "c", charactersCount);
1255 elCharNode.appendChild(elCharacter);
1256 elCharNode.appendChild(elParent);
1257 element.appendChild(elCharNode);
1258 }
1259 }
1260
1261 public void buildMediaObjects(ElementImpl dataset) throws ParseException {
1262
1263 if (cdmSource.getMedia() != null) {
1264 ElementImpl elMediaObjects = new ElementImpl(document, MEDIA_OBJECTS);
1265
1266 for (int i = 0; i < cdmSource.getMedia().size(); i++) {
1267 ElementImpl elMediaObject = new ElementImpl(document, MEDIA_OBJECT);
1268 Media mediobj = (Media) cdmSource.getMedia().get(i);
1269 mediasCount = buildReference(mediobj, medias, ID, elMediaObject, "t", mediasCount);
1270 buildRepresentation(elMediaObject, mediobj);
1271 Set<MediaRepresentation> smr = mediobj.getRepresentations();
1272 for (Iterator<MediaRepresentation> mr = smr.iterator() ; mr.hasNext();){
1273 MediaRepresentation mediarep = mr.next();
1274 ElementImpl elType = new ElementImpl(document, "Type");
1275 elType.appendChild(document.createTextNode(mediarep.getMimeType()));
1276 elMediaObject.appendChild(elType);
1277 List<MediaRepresentationPart> lmrp = mediarep.getParts();
1278 for (Iterator<MediaRepresentationPart> mrp = lmrp.iterator();mrp.hasNext();){
1279 MediaRepresentationPart mediareppart = mrp.next();
1280 ElementImpl elSource = new ElementImpl(document, "Source");
1281 elSource.setAttribute("href",mediareppart.getUri());
1282 elMediaObject.appendChild(elSource);
1283 }
1284 }
1285 elMediaObjects.appendChild(elMediaObject);
1286 }
1287 dataset.appendChild(elMediaObjects);
1288 }
1289 }
1290
1291 public void buildPublications(ElementImpl dataset) throws ParseException {
1292
1293 if (cdmSource.getReferences() != null) {
1294 ElementImpl elPublications = new ElementImpl(document, PUBLICATIONS);
1295 boolean editorial = false;
1296 for (int i = 0; i < cdmSource.getReferences().size(); i++) {
1297 ElementImpl elPublication = new ElementImpl(document, "Publication");
1298 ReferenceBase publication = cdmSource.getReferences().get(i);
1299 Set<Annotation> annotations = publication.getAnnotations();
1300 for (Iterator<Annotation> a = annotations.iterator() ; a.hasNext() ;){
1301 Annotation annotation = a.next();
1302 AnnotationType annotationType = annotation.getAnnotationType();
1303 if (annotationType.equals(AnnotationType.EDITORIAL())) {
1304 editorial = true;
1305 }
1306 else {
1307 editorial = false;
1308 }
1309 }
1310 if (!editorial){
1311 articlesCount = buildReference(publication, articles, ID, elPublication, "p", articlesCount);
1312 buildRepresentation(elPublication, (IDatabase) publication);
1313 elPublications.appendChild(elPublication);
1314 }
1315 }
1316 dataset.appendChild(elPublications);
1317 }
1318 }
1319
1320 public int buildReference(VersionableEntity ve, Map references, String refOrId, ElementImpl element, String prefix, int count) throws ParseException {
1321 if (references.containsKey(ve)) {
1322 element.setAttribute(refOrId,(String) references.get(ve));
1323 } else {
1324 if (ve instanceof IdentifiableEntity) {
1325 IdentifiableEntity ie = (IdentifiableEntity) ve;
1326 if (ie.getSources().size() > 0) {
1327 IdentifiableSource os = (IdentifiableSource) ie.getSources().toArray()[0];
1328 String id = os.getIdInSource();
1329 String uri = os.getCitationMicroReference();
1330 if (uri != null) {element.setAttribute(URI, uri);}
1331 if (id != null) {
1332 if (!id.equals("")) {
1333 if (!references.containsValue(id)) {
1334 element.setAttribute(refOrId, id);
1335 } else while (element.getAttribute(refOrId).equals("")) {
1336 if (!references.containsValue(prefix + (count+1))) {
1337 element.setAttribute(refOrId, prefix + (count+1));
1338 }
1339 count++;
1340 }
1341 } else while (element.getAttribute(refOrId).equals("")) {
1342 if (!references.containsValue(prefix + (count+1))) {
1343 element.setAttribute(refOrId, prefix + (count+1));
1344 }
1345 count++;
1346 }
1347 } else while (element.getAttribute(refOrId).equals("")) {
1348 if (!references.containsValue(prefix + (count+1))) {
1349 element.setAttribute(refOrId, prefix + (count+1));
1350 }
1351 count++;
1352 }
1353 } else while (element.getAttribute(refOrId).equals("")) {
1354 if (!references.containsValue(prefix + (count+1))) {
1355 element.setAttribute(refOrId, prefix + (count+1));
1356 }
1357 count++;
1358 }
1359 } else while (element.getAttribute(refOrId).equals("")) {
1360 if (!references.containsValue(prefix + (count+1))) {
1361 element.setAttribute(refOrId, prefix + (count+1));
1362 }
1363 count++;
1364 }
1365 references.put(ve, element.getAttribute(refOrId));
1366 }
1367 return count;
1368 }
1369
1370 public void buildGeographicAreas(ElementImpl dataset) {
1371 if (cdmSource.getTerms() != null) {
1372 ElementImpl elGeographicAreas = new ElementImpl(document, "GeographicAreas");
1373
1374 int f = cdmSource.getTerms().size();
1375 for (int i = 0; i < f; i++) {
1376 if (cdmSource.getTerms().get(i) instanceof NamedArea) {
1377 NamedArea na = (NamedArea) cdmSource.getTerms().get(i);
1378 for (Iterator<Marker> mark = na.getMarkers().iterator() ; mark.hasNext();) {
1379 Marker marker = mark.next();
1380 if (marker.getMarkerType().getLabel().equals("SDDGeographicArea")) {
1381 ElementImpl elGeographicArea = new ElementImpl(document, "GeographicArea");
1382 namedAreasCount = buildReference(na, namedAreas, ID, elGeographicArea, "a", namedAreasCount);
1383 buildRepresentation(elGeographicArea,na);
1384 elGeographicAreas.appendChild(elGeographicArea);
1385 }
1386 }
1387
1388 }
1389 }
1390 dataset.appendChild(elGeographicAreas);
1391 }
1392 }
1393
1394 public void buildSpecimens(ElementImpl dataset) throws ParseException {
1395
1396 if (cdmSource.getOccurrences() != null) {
1397 ElementImpl elSpecimens = new ElementImpl(document, "Specimens");
1398
1399 for (int i = 0; i < cdmSource.getOccurrences().size(); i++) {
1400 ElementImpl elSpecimen = new ElementImpl(document, "Specimen");
1401 SpecimenOrObservationBase sob = cdmSource.getOccurrences().get(i);
1402 if (sob instanceof Specimen){
1403 specimenCount = buildReference(sob, specimens, ID, elSpecimen, "s", specimenCount);
1404 buildRepresentation(elSpecimen, sob);
1405 elSpecimens.appendChild(elSpecimen);
1406 }
1407 }
1408 dataset.appendChild(elSpecimens);
1409 }
1410
1411 }
1412
1413
1414 }