rightsterm -> rightstype ticket #1306
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / sdd / 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;
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.HashMap;
18 import java.util.Iterator;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Set;
22
23 import javax.xml.bind.Marshaller;
24
25 import org.apache.log4j.Logger;
26 import org.apache.xerces.dom.DocumentImpl;
27 import org.apache.xerces.dom.ElementImpl;
28 import org.joda.time.DateTime;
29 import org.joda.time.format.DateTimeFormatter;
30 import org.joda.time.format.ISODateTimeFormat;
31 import org.xml.sax.SAXException;
32
33 import org.apache.xerces.impl.xpath.regex.ParseException;
34 import org.apache.xml.serialize.DOMSerializer;
35 import org.apache.xml.serialize.OutputFormat;
36 import org.apache.xml.serialize.XMLSerializer;
37
38 import eu.etaxonomy.cdm.io.jaxb.CdmMarshallerListener;
39 import eu.etaxonomy.cdm.model.agent.Person;
40 import eu.etaxonomy.cdm.model.agent.Team;
41 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
42 import eu.etaxonomy.cdm.model.common.Annotation;
43 import eu.etaxonomy.cdm.model.common.AnnotationType;
44 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
45 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
46 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
47 import eu.etaxonomy.cdm.model.common.Language;
48 import eu.etaxonomy.cdm.model.common.LanguageString;
49 import eu.etaxonomy.cdm.model.common.Representation;
50 import eu.etaxonomy.cdm.model.common.TermBase;
51 import eu.etaxonomy.cdm.model.common.TermVocabulary;
52 import eu.etaxonomy.cdm.model.common.VersionableEntity;
53 import eu.etaxonomy.cdm.model.description.CategoricalData;
54 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
55 import eu.etaxonomy.cdm.model.description.Feature;
56 import eu.etaxonomy.cdm.model.description.QuantitativeData;
57 import eu.etaxonomy.cdm.model.description.State;
58 import eu.etaxonomy.cdm.model.description.StateData;
59 import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
60 import eu.etaxonomy.cdm.model.description.StatisticalMeasurementValue;
61 import eu.etaxonomy.cdm.model.description.TaxonDescription;
62 import eu.etaxonomy.cdm.model.description.TextData;
63 import eu.etaxonomy.cdm.model.media.Media;
64 import eu.etaxonomy.cdm.model.media.Rights;
65 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
66 import eu.etaxonomy.cdm.model.reference.IArticle;
67 import eu.etaxonomy.cdm.model.reference.IDatabase;
68 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
69 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
70 import eu.etaxonomy.cdm.model.reference.ReferenceType;
71 import eu.etaxonomy.cdm.model.taxon.Taxon;
72 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
73
74 /**
75 * Writes the SDD XML file.
76 *
77 * @author h.fradin
78 * @created 10.12.2008
79 * @version 1.0
80 */
81
82 public class SDDDocumentBuilder {
83
84 private DocumentImpl document;
85 private XMLSerializer xmlserializer;
86 private Writer writer;
87 private DOMSerializer domi;
88 private SDDDataSet cdmSource;
89
90 private Map<Person,String> agents = new HashMap<Person,String>();
91 private Map<TaxonNameBase,String> taxonNames = new HashMap<TaxonNameBase,String>();
92 private Map<Feature,String> characters = new HashMap<Feature,String>();
93 private Map<TaxonDescription,String> codedDescriptions = new HashMap<TaxonDescription,String>();
94 private Map<Media,String> medias = new HashMap<Media,String>();
95 private Map<State,String> states = new HashMap<State,String>();
96 private Map<ReferenceBase, String> articles = new HashMap<ReferenceBase, String>();
97 private ReferenceFactory refFactory = ReferenceFactory.newInstance();
98
99 private int agentsCount = 0;
100 private int articlesCount = 0;
101 private int codedDescriptionsCount = 0;
102 private int taxonNamesCount = 0;
103 private int charactersCount = 0;
104 private int mediasCount = 0;
105 private int statesCount = 0;
106
107 private String AGENT = "Agent";
108 private String AGENTS = "Agents";
109 private String CATEGORICAL = "Categorical";
110 private String CATEGORICAL_CHARACTER = "CategoricalCharacter";
111 private String CHARACTER = "Character";
112 private String CHARACTERS = "Characters";
113 private String CHARACTER_TREE = "CharacterTree";
114 private String CHARACTER_TREES = "CharacterTrees";
115 private String CHAR_NODE = "CharNode";
116 private String CITATION = "Citation";
117 private String CODED_DESCRIPTION = "CodedDescription";
118 private String CODED_DESCRIPTIONS = "CodedDescriptions";
119 private String CONTENT = "Content";
120 private String CREATORS = "Creators";
121 private String DATASET = "Dataset";
122 private String DATASETS = "Datasets";
123 private String DATE_CREATED = "DateCreated";
124 private String DATE_MODIFIED = "DateModified";
125 private String DEPENDENCY_RULES = "DependencyRules";
126 private String DESCRIPTIVE_CONCEPT = "DescriptiveConcept";
127 private String DESCRIPTIVE_CONCEPTS = "DescriptiveConcepts";
128 private String DETAIL = "Detail";
129 private String GENERATOR = "Generator";
130 private String ID = "id";
131 private String IMAGE = "Image";
132 private String INAPPLICABLE_IF = "InapplicableIf";
133 private String IPR_STATEMENT = "IPRStatement";
134 private String IPR_STATEMENTS = "IPRStatements";
135 private String LABEL = "Label";
136 private String MEASURE = "Measure";
137 private String MEDIA_OBJECT = "MediaObject";
138 private String MEDIA_OBJECTS = "MediaObjects";
139 private String NODE = "Node";
140 private String NODES = "Nodes";
141 private String NOTE = "Note";
142 private String PARENT = "Parent";
143 private String QUANTITATIVE = "Quantitative";
144 private String QUANTITATIVE_CHARACTER = "QuantitativeCharacter";
145 private String REF = "ref";
146 private String REPRESENTATION = "Representation";
147 private String REVISION_DATA = "RevisionData";
148 private String ROLE = "role";
149 private String SCOPE = "Scope";
150 private String SHOULD_CONTAIN_ALL_CHARACTERS = "ShouldContainAllCharacters";
151 private String SOURCE = "Source";
152 private String STATE = "State";
153 private String STATE_DEFINITION = "StateDefinition";
154 private String STATES = "States";
155 private String STATUS = "Status";
156 private String SUMMARY_DATA = "SummaryData";
157 private String TAXON_NAME = "TaxonName";
158 private String TAXON_NAMES = "TaxonNames";
159 private String TECHNICAL_METADATA = "TechnicalMetadata";
160 private String TEXT = "Text";
161 private String TEXT_CHAR = "TextChar";
162 private String TEXT_CHARACTER = "TextCharacter";
163 private String TYPE = "Type";
164 private String URI = "uri";
165
166 private Language defaultLanguage = Language.DEFAULT();
167
168 private static final Logger logger = Logger.getLogger(SDDDocumentBuilder.class);
169
170 // private SDDContext sddContext;
171
172 public SDDDocumentBuilder() throws SAXException, IOException {
173
174 document = new DocumentImpl();
175
176 // sddContext = SDDContext.newInstance(new Class[] {SDDDataSet.class});
177 // logger.debug(sddContext.toString());
178
179 }
180
181 public void marshal(SDDDataSet cdmSource, File sddDestination) throws IOException {
182
183 this.cdmSource = cdmSource;
184 Marshaller marshaller;
185 CdmMarshallerListener marshallerListener = new CdmMarshallerListener();
186 logger.info("Start marshalling");
187 writeCDMtoSDD(sddDestination);
188
189 }
190
191 /**Write the DOM document.
192 * @param base
193 * @throws IOException
194 */
195 public void writeCDMtoSDD(File sddDestination) throws IOException {
196
197 try {
198 buildDocument();
199 } catch (ParseException e) {
200 System.out.println("Problem with SDD export located in the buildDocument() method ...");
201 e.printStackTrace();
202 }
203
204 OutputFormat format = new OutputFormat(document, "UTF-8", true);
205
206 FileOutputStream fos = new FileOutputStream(sddDestination);
207
208 writer = new OutputStreamWriter(fos, "UTF-8");
209
210 xmlserializer = new XMLSerializer(writer, format);
211 domi = xmlserializer.asDOMSerializer(); // As a DOM Serializer
212
213 domi.serialize(document.getDocumentElement());
214
215 writer.close();
216 }
217
218 // #############
219 // # BUILD DOM #
220 // #############
221
222 /**
223 * Builds the whole document.
224 * @param base the Base
225 * @throws ParseException
226 */
227 public void buildDocument() throws ParseException {
228
229 //create <Datasets> = root node
230 ElementImpl baselement = new ElementImpl(document, DATASETS);
231
232 baselement.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
233 baselement.setAttribute("xmlns", "http://rs.tdwg.org/UBIF/2006/");
234 baselement.setAttribute("xsi:schemaLocation", "http://rs.tdwg.org/UBIF/2006 http://rs.tdwg.org/UBIF/2006/Schema/1.1/SDD.xsd");
235
236 buildTechnicalMetadata(baselement);
237
238 List<ReferenceBase> references = cdmSource.getReferences();
239 Iterator<ReferenceBase> iterator = references.iterator();
240 IDatabase d = refFactory.newDatabase();
241 while (iterator.hasNext()) {
242 ReferenceBase reference = (ReferenceBase) iterator.next();
243 if (reference.getType().equals(ReferenceType.Database)) {
244 buildDataset(baselement, reference);
245 }
246 }
247
248 // for datasets with no Database ReferenceBase
249 // buildDataset(baselement, cdmSource, null);
250
251 //append the root element to the DOM document
252 document.appendChild(baselement);
253 }
254
255 // #############
256 // # BUILD DOM #
257 // #############
258
259 /**
260 * Builds TechnicalMetadata associated with the SDD file
261 */
262 public void buildTechnicalMetadata(ElementImpl baselement) throws ParseException {
263 //create TechnicalMetadata
264 ElementImpl technicalMetadata = new ElementImpl(document, TECHNICAL_METADATA);
265 //select different databases associated to different descriptions TODO
266 List<ReferenceBase> references = cdmSource.getReferences();
267 Iterator<ReferenceBase> iterator = references.iterator();
268 boolean database = false;
269 IDatabase d = refFactory.newDatabase();
270 while ((iterator.hasNext()) && (!database)) {
271 ReferenceBase reference = (ReferenceBase) iterator.next();
272 if (reference.getType().equals(ReferenceType.Database)) {
273 d = reference;
274 }
275 }
276 DateTime dt = d.getCreated();
277 String date = dt.toString().substring(0, 19);
278 technicalMetadata.setAttribute("created", date);
279
280 ElementImpl generator = new ElementImpl(document, GENERATOR);
281 generator.setAttribute("name", "EDIT CDM");
282 generator.setAttribute("version", "v1");
283 generator.setAttribute("notes","This SDD file has been generated by the SDD export functionality of the EDIT platform for Cybertaxonomy - Copyright (c) 2008");
284 technicalMetadata.appendChild(generator);
285
286 baselement.appendChild(technicalMetadata);
287 }
288
289 // Builds the information associated with a dataset
290 public void buildDataset(ElementImpl baselement,IDatabase reference) throws ParseException {
291 // create Dataset and language
292 ElementImpl dataset = new ElementImpl(document, DATASET);
293 // no default language associated with a dataset in the CDM
294 dataset.setAttribute("xml:lang", Language.DEFAULT().getIso639_1());
295 baselement.appendChild(dataset);
296 buildRepresentation(dataset, reference);
297 buildRevisionData(dataset, reference);
298 buildIPRStatements(dataset, reference);
299 buildTaxonNames(dataset);
300 buildCharacters(dataset);
301 buildCodedDescriptions(dataset);
302
303 }
304
305 /**
306 * Builds a Representation element using a ReferenceBase
307 */
308 public void buildRepresentation(ElementImpl element, IDatabase reference) throws ParseException {
309
310 // create <Representation> element
311 ElementImpl representation = new ElementImpl(document, REPRESENTATION);
312 element.appendChild(representation);
313 buildLabel(representation, reference.getTitleCache());
314
315 Set<Annotation> annotations = ((ReferenceBase)reference).getAnnotations();
316 Iterator iterator = annotations.iterator();
317 String detailText = null;
318 if (iterator.hasNext()) {
319 Annotation annotation = (Annotation) iterator.next();
320 detailText = annotation.getText();
321 }
322
323 if (detailText != null && !detailText.equals("")) {
324 ElementImpl detail = new ElementImpl(document, DETAIL);
325 detail.appendChild(document.createTextNode(detailText));
326 representation.appendChild(detail);
327 }
328
329 Set<Media> rm = ((ReferenceBase)reference).getMedia();
330
331 if (rm != null && rm.size() > 0) {
332 ElementImpl mediaObject;
333
334 for (int i = 0; i < rm.size(); i++) {
335 mediaObject = new ElementImpl(document, MEDIA_OBJECT);
336 //mediaObject = org.apache.xerces.dom.ElementImpl(document, MEDIA_OBJECT);
337 mediasCount = buildReference((Media) rm.toArray()[i], medias, REF, mediaObject, "m", mediasCount);
338 representation.appendChild(mediaObject);
339 }
340 }
341
342 }
343
344 // ################
345 // # GENERIC BRICKS #
346 // ################
347
348 /**
349 * Creates a Label element
350 * @param base
351 * @param element
352 */
353 public void buildLabel(ElementImpl element, String text) {
354 // create <Label> element
355 ElementImpl label = new ElementImpl(document, LABEL);
356
357 // if language different from language dataset, indicate it TODO, but need to deal with a database language
358 label.appendChild(document.createTextNode(text));
359 element.appendChild(label);
360 }
361
362
363 /**
364 * Builds TaxonNames associated with the Dataset
365 */
366 public void buildTaxonNames(ElementImpl dataset) throws ParseException {
367
368 // <TaxonNames>
369 // <TaxonName id="t1" uri="urn:lsid:authority:namespace:my-own-id">
370 // <Representation>
371 // <Label xml:lang="la">Viola hederacea Labill.</Label>
372 // </Representation>
373 // </TaxonName>
374 // </TaxonNames>
375
376 if (cdmSource.getTaxonomicNames() != null) {
377 ElementImpl elTaxonNames = new ElementImpl(document, TAXON_NAMES);
378
379 for (int i = 0; i < cdmSource.getTaxonomicNames().size(); i++) {
380 ElementImpl elTaxonName = new ElementImpl(document, TAXON_NAME);
381 TaxonNameBase tnb = cdmSource.getTaxonomicNames().get(i);
382
383 taxonNamesCount = buildReference(tnb, taxonNames, REF, elTaxonName, "t", taxonNamesCount);
384
385 buildRepresentation(elTaxonName, tnb);
386
387 elTaxonNames.appendChild(elTaxonName);
388 }
389
390 dataset.appendChild(elTaxonNames);
391 }
392
393 }
394
395 /**
396 * Builds an element Agent referring to Agent defined later in the SDD file
397 */
398 public void buildRefAgent(ElementImpl element, TeamOrPersonBase ag, String role) throws ParseException {
399 if (ag instanceof Person) {
400 Person p = (Person) ag;
401 ElementImpl agent = new ElementImpl(document, AGENT);
402 agent.setAttribute(ROLE, role);
403 agentsCount = buildReference(p, agents, REF, agent, "a", agentsCount);
404 element.appendChild(agent);
405 }
406
407 if (ag instanceof Team) {
408 Team team = (Team) ag;
409 for (int i = 0; i < team.getTeamMembers().size(); i++) {
410 ElementImpl agent = new ElementImpl(document, AGENT);
411 agent.setAttribute(ROLE, role);
412 Person author = team.getTeamMembers().get(i);
413 if (author.getSources() != null) {
414 IdentifiableSource os = (IdentifiableSource) author.getSources().toArray()[0];
415 String id = os.getIdInSource();
416 if (id != null) {
417 if (!id.equals("")) {
418 if (!agents.containsValue(id)) {
419 agent.setAttribute(REF, id);
420 } else if (!agents.containsValue("a" + (agentsCount+1))) {
421 agent.setAttribute(REF, "a" + (agentsCount+1));
422 agentsCount++;
423 } else {
424 agent.setAttribute(REF, id + (agentsCount+1));
425 agentsCount++;
426 }
427 } else {
428 agent.setAttribute(REF, "a" + (agentsCount+1));
429 agentsCount++;
430 }
431 } else {
432 agent.setAttribute(REF, "a" + (agentsCount+1));
433 agentsCount++;
434 }
435 } else {
436 agent.setAttribute(REF, "a" + (agentsCount+1));
437 agentsCount++;
438 }
439 agents.put(author, agent.getAttribute(REF));
440 element.appendChild(agent);
441 }
442 }
443 }
444
445 /**
446 * Builds ModifiedDate associated with RevisionData
447 */
448 public void buildDateModified(ElementImpl revisionData, IDatabase database) throws ParseException {
449
450 // <DateModified>2006-04-08T00:00:00</DateModified>
451
452 if (((ReferenceBase)database).getUpdated() != null) {
453 ElementImpl dateModified = new ElementImpl(document, DATE_MODIFIED);
454
455 DateTime c = ((ReferenceBase)database).getUpdated();
456 DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
457
458 String date = fmt.print(c);
459 dateModified.appendChild(document.createTextNode(date));
460
461 revisionData.appendChild(dateModified);
462 }
463
464 }
465
466 /**
467 * Builds IPRStatements associated with the Dataset
468 */
469 public void buildIPRStatements(ElementImpl dataset, IDatabase database) throws ParseException {
470
471 // <IPRStatements>
472 // <IPRStatement role="Copyright">
473 // <Label xml:lang="en-au">(c) 2003-2006 Centre for Occasional Botany.</Label>
474 // </IPRStatement>
475 // </IPRStatements>
476
477 if (database.getRights() != null) {
478 // create IPRStatements
479 ElementImpl iprStatements = new ElementImpl(document, IPR_STATEMENTS);
480 dataset.appendChild(iprStatements);
481
482 //mapping between IPRStatement Copyright (SDD) and first Right in the list of Rights
483 ElementImpl iprStatement = new ElementImpl(document, IPR_STATEMENT);
484 iprStatement.setAttribute("role", "Copyright");
485 iprStatements.appendChild(iprStatement);
486 buildLabel(iprStatement, ((Rights) database.getRights().toArray()[0]).getText());
487 }
488
489 }
490
491 /**
492 * Builds RevisionData associated with the Dataset
493 */
494 public void buildRevisionData(ElementImpl dataset, IDatabase database) throws ParseException {
495
496 // <RevisionData>
497 // <Creators>
498 // <Agent role="aut" ref="a1"/>
499 // <Agent role="aut" ref="a2"/>
500 // <Agent role="edt" ref="a3"/>
501 // </Creators>
502 // <DateModified>2006-04-08T00:00:00</DateModified>
503 // </RevisionData>
504
505 ElementImpl revisionData = new ElementImpl(document, REVISION_DATA);
506
507 // authors
508 TeamOrPersonBase authors = database.getAuthorTeam();
509 // TeamOrPersonBase editors = database.getUpdatedBy();
510
511 if ((authors != null)) { // || (editors != null)) {
512 ElementImpl creators = new ElementImpl(document, CREATORS);
513 if (authors != null) {
514 buildRefAgent(creators, authors, "aut");
515 }
516 // if (editors != null) {
517 // buildRefAgent(creators, editors, "edt");
518 // }
519 revisionData.appendChild(creators);
520 }
521
522 buildDateModified(revisionData, database);
523
524 dataset.appendChild(revisionData);
525 }
526
527 /**
528 * Builds a Representation element using an IdentifiableEntity
529 */
530 public void buildRepresentation(ElementImpl element, IdentifiableEntity ie) throws ParseException {
531
532 // create <Representation> element
533 ElementImpl representation = new ElementImpl(document, REPRESENTATION);
534 element.appendChild(representation);
535 buildLabel(representation, ie.getTitleCache());
536
537 Set<Annotation> annotations = ie.getAnnotations();
538 Iterator iterator = annotations.iterator();
539 String detailText = null;
540 if (iterator.hasNext()) {
541 Annotation annotation = (Annotation) iterator.next();
542 detailText = annotation.getText();
543 }
544
545 if (detailText != null && !detailText.equals("")) {
546 ElementImpl detail = new ElementImpl(document, DETAIL);
547 detail.appendChild(document.createTextNode(detailText));
548 representation.appendChild(detail);
549 }
550
551 }
552
553 /**
554 * Builds Characters associated with the Dataset
555 */
556 public void buildCharacters(ElementImpl dataset) throws ParseException {
557
558 if (cdmSource.getTerms() != null) {
559 ElementImpl elCharacters = new ElementImpl(document, CHARACTERS);
560
561 //TODO Boucle infinie
562 int f = cdmSource.getTerms().size();
563 for (int i = 0; i < f; i++) {
564 if (cdmSource.getTerms().get(i) instanceof Feature) {
565 Feature character = (Feature) cdmSource.getTerms().get(i);
566 if (character.isSupportsQuantitativeData()) {
567 ElementImpl elQuantitativeCharacter = new ElementImpl(document, QUANTITATIVE_CHARACTER);
568 charactersCount = buildReference(character, characters, ID, elQuantitativeCharacter, "c", charactersCount);
569 // TODO if the character also supports text, add to the label a short tag to distinguish
570 // it as the quantitative version and create a unique label
571 buildRepresentation(elQuantitativeCharacter, character);
572 // TODO <MeasurementUnit> and <Default>
573 elCharacters.appendChild(elQuantitativeCharacter);
574 }
575
576 if (character.isSupportsCategoricalData()) {
577 ElementImpl elCategoricalCharacter = new ElementImpl(document, CATEGORICAL_CHARACTER);
578 charactersCount = buildReference(character, characters, ID, elCategoricalCharacter, "c", charactersCount);
579 buildRepresentation(elCategoricalCharacter, character);
580
581 Set<TermVocabulary<State>> enumerations = character.getSupportedCategoricalEnumerations();
582 if (enumerations != null) {
583 if (enumerations.size()>0) {
584 ElementImpl elStates = new ElementImpl(document, STATES);
585 TermVocabulary tv = (TermVocabulary) enumerations.toArray()[0];
586 Set<State> stateList = tv.getTerms();
587 for (int j = 0; j < stateList.size(); j++) {
588 ElementImpl elStateDefinition = new ElementImpl(document, STATE_DEFINITION);
589 State state = (State) stateList.toArray()[j];
590 statesCount = buildReference(state, states, ID, elStateDefinition, "s", statesCount);
591 buildRepresentation(elStateDefinition, state);
592 elStates.appendChild(elStateDefinition);
593 }
594 elCategoricalCharacter.appendChild(elStates);
595 elCharacters.appendChild(elCategoricalCharacter);
596 }
597 }
598 }
599 if (character.isSupportsTextData()) {
600 ElementImpl elTextCharacter = new ElementImpl(document, TEXT_CHARACTER);
601 charactersCount = buildReference(character, characters, ID, elTextCharacter, "c", charactersCount);
602 buildRepresentation(elTextCharacter, character);
603 // TODO <MeasurementUnit> and <Default>
604 elCharacters.appendChild(elTextCharacter);
605 }
606 }
607 }
608
609 dataset.appendChild(elCharacters);
610 }
611
612 }
613
614 /**
615 * Builds an element Agent referring to Agent defined later in the SDD file
616 */
617 public int buildReference(VersionableEntity ve, Map references, String refOrId, ElementImpl element, String prefix, int count) throws ParseException {
618 if (references.containsKey(ve)) {
619 element.setAttribute(refOrId,(String) references.get(ve));
620 } else {
621 if (ve instanceof IdentifiableEntity) {
622 IdentifiableEntity ie = (IdentifiableEntity) ve;
623 if (ie.getSources().size() > 0) {
624 IdentifiableSource os = (IdentifiableSource) ie.getSources().toArray()[0];
625 String id = os.getIdInSource();
626 if (id != null) {
627 if (!id.equals("")) {
628 if (!references.containsValue(id)) {
629 element.setAttribute(refOrId, id);
630 } else while (element.getAttribute(refOrId).equals("")) {
631 if (!references.containsValue(prefix + (count+1))) {
632 element.setAttribute(refOrId, prefix + (count+1));
633 }
634 count++;
635 }
636 } else while (element.getAttribute(refOrId).equals("")) {
637 if (!references.containsValue(prefix + (count+1))) {
638 element.setAttribute(refOrId, prefix + (count+1));
639 }
640 count++;
641 }
642 } else while (element.getAttribute(refOrId).equals("")) {
643 if (!references.containsValue(prefix + (count+1))) {
644 element.setAttribute(refOrId, prefix + (count+1));
645 }
646 count++;
647 }
648 } else while (element.getAttribute(refOrId).equals("")) {
649 if (!references.containsValue(prefix + (count+1))) {
650 element.setAttribute(refOrId, prefix + (count+1));
651 }
652 count++;
653 }
654 } else while (element.getAttribute(refOrId).equals("")) {
655 if (!references.containsValue(prefix + (count+1))) {
656 element.setAttribute(refOrId, prefix + (count+1));
657 }
658 count++;
659 }
660 references.put(ve, element.getAttribute(refOrId));
661 }
662 return count;
663 }
664
665 /**
666 * Builds a Representation element using a Feature
667 */
668 public void buildRepresentation(ElementImpl element, TermBase tb) throws ParseException {
669
670 // create <Representation> element
671 ElementImpl representation = new ElementImpl(document, REPRESENTATION);
672 element.appendChild(representation);
673
674 Set<Representation> representations = tb.getRepresentations();
675 if (representations != null) {
676 if (!representations.isEmpty()) {
677 String label = ((Representation) representations.toArray()[0]).getLabel();
678 buildLabel(representation, label);
679 String detailText = tb.getDescription();
680
681 if (detailText != null && !detailText.equals("")) {
682 if (!detailText.equals(label)) {
683 ElementImpl detail = new ElementImpl(document, DETAIL);
684 detail.appendChild(document.createTextNode(detailText));
685 representation.appendChild(detail);
686 }
687 }
688
689 }
690 }
691
692 if (tb instanceof DefinedTermBase) {
693 DefinedTermBase dtb = (DefinedTermBase) tb;
694 Set<Media> rm = dtb.getMedia();
695
696 if (rm != null && rm.size() > 0) {
697 ElementImpl mediaObject;
698
699 for (int i = 0; i < rm.size(); i++) {
700 mediaObject = new ElementImpl(document, MEDIA_OBJECT);
701 mediasCount = buildReference((Media) rm.toArray()[i], medias, REF, mediaObject, "m", mediasCount);
702 representation.appendChild(mediaObject);
703 }
704 }
705 }
706
707 }
708
709 // /**
710 // * Builds Coded Descriptions associated with the Dataset
711 // */
712 public void buildCodedDescriptions(ElementImpl dataset) throws ParseException {
713
714 if (cdmSource.getTaxa() != null) {
715 ElementImpl elCodedDescriptions = new ElementImpl(document, CODED_DESCRIPTIONS);
716
717 for (Iterator<? extends TaxonBase> tb = cdmSource.getTaxa().iterator() ; tb.hasNext() ;){
718 Taxon taxon = (Taxon) tb.next();
719 Set<TaxonDescription> descriptions = taxon.getDescriptions();
720 for (Iterator<TaxonDescription> td = descriptions.iterator() ; td.hasNext() ;){
721 TaxonDescription taxonDescription = td.next();
722 ElementImpl elCodedDescription = new ElementImpl(document, CODED_DESCRIPTION);
723 codedDescriptionsCount = buildReference(taxonDescription, codedDescriptions, ID, elCodedDescription, "D", codedDescriptionsCount);
724 buildRepresentation(elCodedDescription, taxonDescription);
725 buildScope(elCodedDescription, taxonDescription);
726 buildSummaryData(elCodedDescription, taxonDescription);
727 elCodedDescriptions.appendChild(elCodedDescription);
728 }
729 }
730
731 dataset.appendChild(elCodedDescriptions);
732 }
733
734 }
735
736 /**
737 * Builds Scope associated with a CodedDescription
738 */
739 public void buildScope(ElementImpl element, TaxonDescription taxonDescription) throws ParseException {
740
741 // <Scope>
742 // <TaxonName ref="t1"/>
743 // <Citation ref="p1" location="p. 30"/>
744 // </Scope>
745
746 ElementImpl scope = new ElementImpl(document, SCOPE);
747
748 Taxon taxon = taxonDescription.getTaxon();
749 if (taxon != null) {
750 TaxonNameBase taxonNameBase = taxon.getName();
751 if (taxonNameBase != null) {
752 String ref = taxonNames.get(taxonNameBase);
753 if (!ref.equals("")) {
754 ElementImpl taxonName = new ElementImpl(document, TAXON_NAME);
755 taxonName.setAttribute(REF, ref);
756 scope.appendChild(taxonName);
757 }
758 }
759 }
760
761 Set<ReferenceBase> descriptionSources = taxonDescription.getDescriptionSources();
762 for (Iterator<ReferenceBase> rb = descriptionSources.iterator() ; rb.hasNext() ;){
763 ReferenceBase descriptionSource = rb.next();
764 if (descriptionSource.getType().equals(ReferenceType.Article)) {
765
766 ElementImpl citation = new ElementImpl(document, CITATION);
767 articlesCount = buildReference(descriptionSource, articles, REF, citation, "p", articlesCount);
768
769 Set<Annotation> annotations = descriptionSource.getAnnotations();
770 for (Iterator<Annotation> a = annotations.iterator() ; a.hasNext() ;){
771 Annotation annotation = a.next();
772 AnnotationType annotationType = annotation.getAnnotationType();
773 if (annotationType != null) {
774 String type = annotationType.getLabel();
775 if (type.equals("location")) {
776 citation.setAttribute("location", annotation.getText());
777 }
778 }
779 }
780
781 scope.appendChild(citation);
782 }
783 }
784
785 element.appendChild(scope);
786 }
787
788 /**
789 * Builds SummaryData associated with a CodedDescription
790 */
791 public void buildSummaryData(ElementImpl element, TaxonDescription taxonDescription) throws ParseException {
792
793 // <SummaryData>
794 // <Categorical ref="c4">
795 // <State ref="s3"/>
796 // <State ref="s4"/>
797 // </Categorical>
798
799 ElementImpl summaryData = new ElementImpl(document, SUMMARY_DATA);
800 Set<DescriptionElementBase> elements = taxonDescription.getElements();
801 for (Iterator<DescriptionElementBase> deb = elements.iterator() ; deb.hasNext() ;){
802 DescriptionElementBase descriptionElement = deb.next();
803 if (descriptionElement instanceof CategoricalData) {
804 CategoricalData categoricalData = (CategoricalData) descriptionElement;
805 buildCategorical(summaryData, categoricalData);
806 }
807 if (descriptionElement instanceof QuantitativeData) {
808 QuantitativeData quantitativeData = (QuantitativeData) descriptionElement;
809 buildQuantitative(summaryData, quantitativeData);
810 }
811 if (descriptionElement instanceof TextData) {
812 TextData textData = (TextData) descriptionElement;
813 buildTextChar(summaryData, textData);
814 }
815 }
816 element.appendChild(summaryData);
817 }
818
819 /**
820 * Builds Categorical associated with a SummaryData
821 */
822 public void buildCategorical(ElementImpl element, CategoricalData categoricalData) throws ParseException {
823
824 // <SummaryData>
825 // <Categorical ref="c4">
826 // <State ref="s3"/>
827 // <State ref="s4"/>
828 // </Categorical>
829
830 ElementImpl categorical = new ElementImpl(document, CATEGORICAL);
831 Feature feature = categoricalData.getFeature();
832 buildReference(feature, characters, REF, categorical, "c", charactersCount);
833 List<StateData> states = categoricalData.getStates();
834 for (Iterator<StateData> sd = states.iterator() ; sd.hasNext() ;){
835 StateData stateData = sd.next();
836 State s = stateData.getState();
837 buildState(categorical, s);
838 }
839 element.appendChild(categorical);
840 }
841
842 /**
843 * Builds State associated with a Categorical
844 */
845 public void buildState(ElementImpl element, State s) throws ParseException {
846
847 // <SummaryData>
848 // <Categorical ref="c4">
849 // <State ref="s3"/>
850 // <State ref="s4"/>
851 // </Categorical>
852
853 ElementImpl state = new ElementImpl(document, STATE);
854 buildReference(s, states, REF, state, "s", statesCount);
855 element.appendChild(state);
856 }
857
858 /**
859 * Builds Quantitative associated with a SummaryData
860 */
861 public void buildQuantitative(ElementImpl element, QuantitativeData quantitativeData) throws ParseException {
862
863 // <Quantitative ref="c2">
864 // <Measure type="Min" value="2.3"></Measure>
865 // <Measure type="Mean" value="5.1"/>
866 // <Measure type="Max" value="7.9"/>
867 // <Measure type="SD" value="1.3"/>
868 // <Measure type="N" value="20"/>
869 // </Quantitative>
870
871 ElementImpl quantitative = new ElementImpl(document, QUANTITATIVE);
872 Feature feature = quantitativeData.getFeature();
873 buildReference(feature, characters, REF, quantitative, "c", charactersCount);
874 Set<StatisticalMeasurementValue> statisticalValues = quantitativeData.getStatisticalValues();
875 for (Iterator<StatisticalMeasurementValue> smv = statisticalValues.iterator() ; smv.hasNext() ;){
876 StatisticalMeasurementValue statisticalValue = smv.next();
877 buildMeasure(quantitative, statisticalValue);
878 }
879 element.appendChild(quantitative);
880 }
881
882 /**
883 * Builds Measure associated with a Quantitative
884 */
885 public void buildMeasure(ElementImpl element, StatisticalMeasurementValue statisticalValue) throws ParseException {
886
887 // <Quantitative ref="c2">
888 // <Measure type="Min" value="2.3"></Measure>
889 // <Measure type="Mean" value="5.1"/>
890 // <Measure type="Max" value="7.9"/>
891 // <Measure type="SD" value="1.3"/>
892 // <Measure type="N" value="20"/>
893 // </Quantitative>
894
895 ElementImpl measure = new ElementImpl(document, MEASURE);
896 StatisticalMeasure type = statisticalValue.getType();
897 String label = type.getLabel();
898 if (label.equals("Average")) {
899 measure.setAttribute("type", "Mean");
900 } else if (label.equals("StandardDeviation")) {
901 measure.setAttribute("type", "SD");
902 } else if (label.equals("SampleSize")) {
903 measure.setAttribute("type", "N");
904 } else {
905 measure.setAttribute("type", label);
906 }
907 float value = statisticalValue.getValue();
908 measure.setAttribute("value", String.valueOf(value));
909 element.appendChild(measure);
910 }
911
912 /**
913 * Builds TextChar associated with a SummaryData
914 */
915 public void buildTextChar(ElementImpl element, TextData textData) throws ParseException {
916
917 // <TextChar ref="c3">
918 // <Content>Free form text</Content>
919 // </TextChar>
920
921 ElementImpl textChar = new ElementImpl(document, TEXT_CHAR);
922 Feature feature = textData.getFeature();
923 buildReference(feature, characters, REF, textChar, "c", charactersCount);
924 Map<Language,LanguageString> multilanguageText = textData.getMultilanguageText();
925 for (Iterator<Language> l = multilanguageText.keySet().iterator() ; l.hasNext() ;){
926 Language language = l.next();
927 LanguageString languageString = multilanguageText.get(language);
928 buildContent(textChar,languageString);
929 }
930 element.appendChild(textChar);
931 }
932
933 /**
934 * Builds Content associated with a TextChar
935 */
936 public void buildContent(ElementImpl element, LanguageString languageString) throws ParseException {
937
938 // <TextChar ref="c3">
939 // <Content>Free form text</Content>
940 // </TextChar>
941
942 ElementImpl content = new ElementImpl(document, CONTENT);
943 Language language = languageString.getLanguage();
944 String text = languageString.getText();
945 if (!language.getIso639_1().equals(defaultLanguage.getIso639_1())) {
946 content.setAttribute("xml:lang", language.getIso639_1());
947 }
948 content.setTextContent(text);
949 element.appendChild(content);
950 }
951
952 // /**
953 // * Build Hashtables with the references for the different elements that build the dataset,
954 // * and that are then used in the different building elements methods
955 // */
956 //
957 // public void buildReferences() {
958 //
959 // // <TaxonNames> references
960 // for (int i = 0; i < cdmSource.getTaxonomicNames().size(); i++) {
961 // OriginalSource os = (OriginalSource) cdmSource.getAgents().get(i).getSources().toArray()[i];
962 // String id = os.getIdNamespace();
963 // if (id != null) {
964 // if (!id.equals("")) {
965 // if (!references.containsValue(id)) {
966 // references.put(cdmSource.getAgents().get(i), id);
967 // } else if (!references.containsValue("a" + (i+1))) {
968 // references.put(cdmSource.getAgents().get(i), "a" + (i+1));
969 // } else {
970 // references.put(cdmSource.getAgents().get(i), id + (i+1));
971 // }
972 // } else {
973 // references.put(cdmSource.getAgents().get(i), "a" + (i+1));
974 // }
975 // } else {
976 // references.put(cdmSource.getAgents().get(i), "a" + (i+1));
977 // }
978 // }
979 //
980 // // <Character> references
981 // for (int i = 0; i < cdmSource.getFeatureData().size(); i++) {
982 // references.put(cdmSource.getFeatureData().get(i), "c" + (i+1));
983 // }
984 //
985 // /* no groups so far in CDM TODO
986 // // <DescriptiveConcept> and <Node> references
987 // for (int i = 0; i < base.getNbGroups(); i++) {
988 // references.put(base.getGroupAt(i), "dc" + (i+1));
989 // }
990 // */
991 //
992 // // <State> references
993 //
994 // for (int i = 0; i < cdmSource.get(); i++) {
995 // variable = base.getVariableAt(i);
996 // for (int j = 0; j < variable.getNbModes(); j++) {
997 // references.put(variable.getModeAt(j), "s" + statesCounter);
998 // statesCounter++;
999 // }
1000 // }
1001 //
1002 // // <CodedDescription> references
1003 // for (int i = 0; i < base.getNbIndividuals(); i++) {
1004 // references.put(base.getIndividualAt(i), "D" + (i+1));
1005 // }
1006 //
1007 // // <MediaObject> references
1008 // // TODO
1009 // ArrayList al = base.getAllResources();
1010 // for (int i = 0; i < al.size(); i++) {
1011 // BaseObjectResource bor = (BaseObjectResource) al.get(i);
1012 //
1013 // if (!referencesMediaObjects.containsKey(bor)) {
1014 // referencesMediaObjects.put(bor, "m" + mediaObjectsCounter);
1015 // mediaObjectsCounter++;
1016 // }
1017 // }
1018 //
1019 // // base.images
1020 // // BaseObjectResource bor = base.getResource();
1021 // //bor.getName();
1022 // //bor.getDescription();
1023 // //bor.getFullFilename();
1024 //
1025 // if (!referencesMediaObjects.containsKey(bor)) {
1026 // referencesMediaObjects.put(bor, "m" + mediaObjectsCounter);
1027 // mediaObjectsCounter++;
1028 // }
1029 //
1030 // // group.images
1031 //
1032 // for (int i = 0; i < base.getNbGroups(); i++) {
1033 // Object[] tab = ((Group) base.getGroupAt(i)).getAllResources();
1034 //
1035 // for (int j = 0; j < tab.length; j++) {
1036 // bor = (BaseObjectResource) tab[j];
1037 //
1038 // if (!referencesMediaObjects.containsKey(bor)) {
1039 // referencesMediaObjects.put(bor, "m" + mediaObjectsCounter);
1040 // mediaObjectsCounter++;
1041 // }
1042 // }
1043 // }
1044 //
1045 // int nbGroups = base.getNbGroups();
1046 // ArrayList mObjArrayList;
1047 // if (nbGroups > 0) {
1048 // for (int i = 0; i < nbGroups; i++) {
1049 // mObjArrayList = ((Group) base.getGroupAt(i)).getImages();
1050 // for (int j = 0; j < mObjArrayList.size(); j++) {
1051 // String temp = (String) mObjArrayList.get(j);
1052 // if (!referencesMediaObjects.containsKey(temp)) {
1053 // referencesMediaObjects.put(temp, "m" + mediaObjectsCounter);
1054 // mediaObjectsCounter++;
1055 // }
1056 // }
1057 // }
1058 // }
1059 //
1060 // // individual.images
1061 // for (int i = 0; i < base.getNbIndividuals(); i++) {
1062 // Object[] tab = ((Individual) base.getIndividualAt(i)).getAllResources();
1063 //
1064 // for (int j = 0; j < tab.length; j++) {
1065 // bor = (BaseObjectResource) tab[j];
1066 //
1067 // if (!referencesMediaObjects.containsKey(bor)) {
1068 // referencesMediaObjects.put(bor, "m" + mediaObjectsCounter);
1069 // mediaObjectsCounter++;
1070 // }
1071 // }
1072 // }
1073 //
1074 // int nbIndividuals = base.getNbIndividuals();
1075 // if (nbIndividuals > 0) {
1076 // for (int i = 0; i < nbIndividuals; i++) {
1077 // mObjArrayList = ((Individual) base.getIndividualAt(i)).getImages();
1078 // for (int j = 0; j < mObjArrayList.size(); j++) {
1079 // String temp = (String) mObjArrayList.get(j);
1080 // if (!referencesMediaObjects.containsKey(temp)) {
1081 // referencesMediaObjects.put(temp, "m" + mediaObjectsCounter);
1082 // mediaObjectsCounter++;
1083 // }
1084 // }
1085 // }
1086 // }
1087 //
1088 // // variable.images
1089 //
1090 // int nbVariables = base.getNbVariables();
1091 // if (nbVariables > 0) {
1092 // for (int i = 0; i < nbVariables; i++) {
1093 // mObjArrayList = ((Variable) base.getVariableAt(i)).getImages();
1094 // for (int j = 0; j < mObjArrayList.size(); j++) {
1095 // String temp = (String) mObjArrayList.get(j);
1096 // if (!referencesMediaObjects.containsKey(temp)) {
1097 // referencesMediaObjects.put(temp, "m" + mediaObjectsCounter);
1098 // mediaObjectsCounter++;
1099 // }
1100 // }
1101 // }
1102 // }
1103 //
1104 // // mode.images
1105 //
1106 // int nbModesTotal = base.getNbModes();
1107 // int nbModes;
1108 // if (nbModesTotal > 0) {
1109 // for (int i = 0; i < nbVariables; i++) {
1110 // variable = (Variable) base.getVariableAt(i);
1111 // nbModes = variable.getNbModes();
1112 // for (int j = 0; j < nbModes; j++) {
1113 // mObjArrayList = variable.getModeAt(j).getImages();
1114 // for (int k = 0; k < mObjArrayList.size(); k++) {
1115 // String temp = (String) mObjArrayList.get(k);
1116 // if (!referencesMediaObjects.containsKey(temp)) {
1117 // referencesMediaObjects.put(temp, "m" + mediaObjectsCounter);
1118 // mediaObjectsCounter++;
1119 // }
1120 // }
1121 // }
1122 // }
1123 // }
1124 //
1125 // for (int i = 0; i < base.getLinks().size(); i++) {
1126 // referencesLinks.put(base.getLinkAt(i), "m" + mediaObjectsCounter);
1127 // mediaObjectsCounter++;
1128 // }
1129 //
1130 // }
1131
1132 }