![JAR search and dependency download from the Maven repository](/logo.png)
org.openehr.am.serialize.XMLSerializer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xml-serializer Show documentation
Show all versions of xml-serializer Show documentation
Java XML Serializer of the Archetype Object Model
The newest version!
package org.openehr.am.serialize;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.openehr.am.archetype.Archetype;
import org.openehr.am.archetype.assertion.Assertion;
import org.openehr.am.archetype.assertion.AssertionVariable;
import org.openehr.am.archetype.assertion.ExpressionBinaryOperator;
import org.openehr.am.archetype.assertion.ExpressionItem;
import org.openehr.am.archetype.assertion.ExpressionLeaf;
import org.openehr.am.archetype.assertion.ExpressionOperator;
import org.openehr.am.archetype.assertion.ExpressionUnaryOperator;
import org.openehr.am.archetype.constraintmodel.ArchetypeInternalRef;
import org.openehr.am.archetype.constraintmodel.ArchetypeSlot;
import org.openehr.am.archetype.constraintmodel.CAttribute;
import org.openehr.am.archetype.constraintmodel.CComplexObject;
import org.openehr.am.archetype.constraintmodel.CDomainType;
import org.openehr.am.archetype.constraintmodel.CMultipleAttribute;
import org.openehr.am.archetype.constraintmodel.CObject;
import org.openehr.am.archetype.constraintmodel.CPrimitiveObject;
import org.openehr.am.archetype.constraintmodel.Cardinality;
import org.openehr.am.archetype.constraintmodel.ConstraintRef;
import org.openehr.am.archetype.constraintmodel.primitive.CBoolean;
import org.openehr.am.archetype.constraintmodel.primitive.CDate;
import org.openehr.am.archetype.constraintmodel.primitive.CDateTime;
import org.openehr.am.archetype.constraintmodel.primitive.CDuration;
import org.openehr.am.archetype.constraintmodel.primitive.CInteger;
import org.openehr.am.archetype.constraintmodel.primitive.CPrimitive;
import org.openehr.am.archetype.constraintmodel.primitive.CReal;
import org.openehr.am.archetype.constraintmodel.primitive.CString;
import org.openehr.am.archetype.constraintmodel.primitive.CTime;
import org.openehr.am.archetype.ontology.ArchetypeOntology;
import org.openehr.am.archetype.ontology.ArchetypeTerm;
import org.openehr.am.archetype.ontology.OntologyBinding;
import org.openehr.am.archetype.ontology.OntologyBindingItem;
import org.openehr.am.archetype.ontology.OntologyDefinitions;
import org.openehr.am.archetype.ontology.QueryBindingItem;
import org.openehr.am.archetype.ontology.TermBindingItem;
import org.openehr.am.openehrprofile.datatypes.quantity.CDvOrdinal;
import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantity;
import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantityItem;
import org.openehr.am.openehrprofile.datatypes.quantity.Ordinal;
import org.openehr.am.openehrprofile.datatypes.text.CCodePhrase;
import org.openehr.rm.common.resource.ResourceDescription;
import org.openehr.rm.common.resource.ResourceDescriptionItem;
import org.openehr.rm.common.resource.TranslationDetails;
import org.openehr.rm.datatypes.quantity.DvQuantity;
import org.openehr.rm.datatypes.text.CodePhrase;
import org.openehr.rm.support.basic.Interval;
import org.openehr.rm.support.identification.ArchetypeID;
/**
* XML serializer of the openEHR Archetype Object Model.
*
* @author Mattias Forss
*/
public class XMLSerializer {
/**
* Create an outputter with default encoding, indent and lineSeparator
*/
public XMLSerializer() {
this.encoding = UTF8;
outputter = new XMLOutputter();
outputter.setFormat(Format.getPrettyFormat().setEncoding(encoding.name()));
}
/**
* Create an outputter which can use a JDOM formatter of choice, e.g.
* Format.getPrettyFormat().setEncoding(encoding.name()).setTextMode(TextMode.PRESERVE)
*/
public XMLSerializer(Format format) {
this.encoding = UTF8;
outputter = new XMLOutputter();
outputter.setFormat(format);
}
/**
* Output given archetype as string in XML format
*
* @param archetype
* @return a string in XML format
* @throws IOException
*/
public String output(Archetype archetype) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
output(archetype, baos);
return baos.toString(encoding.name());
}
/**
* Output given archetype to outputStream
*
* @param archetype
* @param out
* @throws IOException
*/
public void output(Archetype archetype, OutputStream out) throws IOException {
Document document = new Document();
output(archetype, document);
outputter.output(document, out);
}
/**
* Output given archetype to Document
*
* @param archetype
* @param out
* @throws IOException
*/
public void output(Archetype archetype, Document out) {
Element rootElement = new Element("archetype", defaultNamespace);
rootElement.addNamespaceDeclaration(xsiNamespace);
rootElement.addNamespaceDeclaration(xsdNamespace);
out.setRootElement(rootElement);
output(archetype, rootElement);
}
/**
* Output given archetype to writer
*
* @param archetype
* @param out
* @throws IOException
*/
public void output(Archetype archetype, Element out) {
printHeader(archetype, out);
printDefinition(archetype.getDefinition(), out);
printOntology(archetype.getOntology(), archetype.getConcept(), out);
}
protected void printHeader(Archetype archetype, Element out) {
Element originalLanguage = new Element("original_language", defaultNamespace);
out.getChildren().add(originalLanguage);
printCodePhrase(archetype.getOriginalLanguage(), originalLanguage);
printString("is_controlled", archetype.isControlled() ? "true" : "false", out);
printDescription(archetype.getDescription(), out);
printTranslations(archetype.getTranslations(), out);
if (archetype.getUid() != null) {
Element uid = new Element("uid", defaultNamespace);
out.getChildren().add(uid);
printString("value", archetype.getUid().toString(), uid);
}
Element archetypeId = new Element("archetype_id", defaultNamespace);
out.getChildren().add(archetypeId);
printString("value", archetype.getArchetypeId().toString(), archetypeId);
printString("adl_version", archetype.getAdlVersion(), out);
printString("concept", archetype.getConcept(), out);
final ArchetypeID parentID = archetype.getParentArchetypeId();
if(parentID != null) {
Element parentArchetypeId = new Element("parent_archetype_id", defaultNamespace);
out.getChildren().add(parentArchetypeId);
printString("value", parentID.toString(), parentArchetypeId);
}
}
private void printTranslations(Map translations, Element out) {
if (translations == null) {
return;
}
for (Entry translation : translations.entrySet()) {
// Note that each translation is serialised to one translations (note the plural!) element
Element translationsElement = new Element("translations", defaultNamespace);
out.getChildren().add(translationsElement);
Element languageElement = new Element("language", defaultNamespace);
translationsElement.getChildren().add(languageElement);
printCodePhrase(translation.getValue().getLanguage(), languageElement);
TranslationDetails transDetails = translation.getValue();
printStringMap("author", transDetails.getAuthor(), translationsElement);
if (transDetails.getAccreditation() != null) {
printString("accreditation", transDetails.getAccreditation(), translationsElement);
}
printStringMap("other_details", transDetails.getOtherDetails(), translationsElement);
}
}
protected void printDescription(ResourceDescription description, Element out) {
if (description == null) {
return;
}
Element des = new Element("description", defaultNamespace);
out.getChildren().add(des);
printStringMap("original_author", description.getOriginalAuthor(), des);
printStringList("other_contributors", description.getOtherContributors(), des);
printString("lifecycle_state", description.getLifecycleState(), des);
if (description.getResourcePackageUri() != null && description.getResourcePackageUri().length() >0) { // only add this tag if non-empty
printString("resource_package_uri", description.getResourcePackageUri(), des);
}
printStringMap("other_details", description.getOtherDetails(), des);
for (ResourceDescriptionItem item : description.getDetails().values()) {
Element details = new Element("details", defaultNamespace);
des.getChildren().add(details);
printDescriptionItem(item, details);
}
}
protected void printDescriptionItem(ResourceDescriptionItem item, Element out) {
Element language = new Element("language", defaultNamespace);
out.getChildren().add(language);
printCodePhrase(item.getLanguage(), language);
printString("purpose", item.getPurpose(), out); // Mandatory
printStringList("keywords", item.getKeywords(), out);
printString("use", item.getUse(), out); // Mandatory
printString("misuse", item.getMisuse(), out); // Mandatory
printString("copyright", item.getCopyright(), out);
printStringMap("original_resource_uri",
item.getOriginalResourceUri(), out);
printStringMap("other_details", item.getOtherDetails(), out);
}
private void printCodePhrase(CodePhrase cp, Element out) {
if (cp == null) {
return;
}
Element terminologyId = new Element("terminology_id", defaultNamespace);
out.getChildren().add(terminologyId);
printString("value", cp.getTerminologyId().getValue(), terminologyId);
printString("code_string", cp.getCodeString(), out);
}
private void printStringMap(String label, Map map, Element out) {
if(map != null && !map.isEmpty()) {
for(Map.Entry entry : map.entrySet()) {
Element elm = new Element(label, defaultNamespace);
out.getChildren().add(elm);
elm.setAttribute("id", entry.getKey());
if (entry.getValue() != null) {
elm.setText(map.get(entry.getValue()));
}
}
}
}
private void printString(String label, String value, Element out) {
printString(label, value, out, false);
}
private void printString(String label, String value, Element out, boolean addXSDStringType) {
Element elm = new Element(label, defaultNamespace);
if (addXSDStringType) {
elm.setAttribute("type", "xsd:string", xsiNamespace); // the type is expected here.
}
out.getChildren().add(elm);
if (value != null) {
elm.setText(value);
}
}
private void printStringList(String label, List list, Element out) {
if (list == null || list.isEmpty()) {
return;
}
for(int i = 0, j = list.size(); i < j; i++) {
Element elm = new Element(label, defaultNamespace);
out.getChildren().add(elm);
elm.setText(list.get(i));
}
}
protected void printDefinition(CComplexObject definition, Element out) {
if (definition == null) {
return;
}
Element def = new Element("definition", defaultNamespace);
out.getChildren().add(def);
printCComplexObjectTop(definition, def);
}
protected void printCComplexObjectTop(CComplexObject ccobj, Element out) {
printCObjectElements(ccobj, out);
// print all attributes
if(!ccobj.isAnyAllowed()) {
for (CAttribute cattribute : ccobj.getAttributes()) {
printCAttribute(cattribute, out);
}
}
}
protected void printCComplexObject(CComplexObject ccobj, Element out) {
Element children = new Element("children", defaultNamespace);
out.getChildren().add(children);
children.setAttribute("type", "C_COMPLEX_OBJECT", xsiNamespace);
printCObjectElements(ccobj, children);
// print all attributes
if(!ccobj.isAnyAllowed()) {
for (CAttribute cattribute : ccobj.getAttributes()) {
printCAttribute(cattribute, children);
}
}
}
protected void printConstraintRef(ConstraintRef ref, Element out) {
Element children = new Element("children", defaultNamespace);
out.getChildren().add(children);
children.setAttribute("type", "CONSTRAINT_REF", xsiNamespace);
printCObjectElements(ref, children);
printString("reference", ref.getReference(), children);
}
protected void printArchetypeInternalRef(ArchetypeInternalRef ref, Element out) {
Element children = new Element("children", defaultNamespace);
out.getChildren().add(children);
children.setAttribute("type", "ARCHETYPE_INTERNAL_REF", xsiNamespace);
printCObjectElements(ref, children);
printString("target_path", ref.getTargetPath(), children);
}
protected void printArchetypeSlot(ArchetypeSlot slot, Element out) {
Element children = new Element("children", defaultNamespace);
out.getChildren().add(children);
children.setAttribute("type", "ARCHETYPE_SLOT", xsiNamespace);
printCObjectElements(slot, children);
// print all attributes
if (!slot.isAnyAllowed()) {
if (slot.getIncludes() != null) {
for (Assertion include : slot.getIncludes()) {
Element includes = new Element("includes", defaultNamespace);
children.getChildren().add(includes);
printAssertion(include, includes);
}
}
if (slot.getExcludes() != null) {
for (Assertion exclude : slot.getExcludes()) {
Element excludes = new Element("excludes", defaultNamespace);
children.getChildren().add(excludes);
printAssertion(exclude, excludes);
}
}
}
}
protected void printAssertion(Assertion assertion, Element out) {
if (assertion.getTag() != null) { // must not be displayed at all if null according to spec.
printString("tag", assertion.getTag(), out);
}
printString("string_expression", assertion.getStringExpression(), out);
printExpressionItem("expression", assertion.getExpression(), out);
if(assertion.getVariables() != null) {
List variables = assertion.getVariables();
for(AssertionVariable var : variables) {
Element vars = new Element("variables", defaultNamespace);
out.getChildren().add(vars);
printString("name", var.getName(), vars);
printString("definition", var.getDefinition(), vars);
}
}
}
protected void printExpressionItem(String label, ExpressionItem expItem, Element out) {
if(expItem instanceof ExpressionLeaf) {
printExpressionLeaf(label, (ExpressionLeaf) expItem, out);
} else if(expItem instanceof ExpressionOperator) {
printExpressionOperator(label, (ExpressionOperator) expItem, out);
} else {
// unknown ExpressionItem
Element elm = new Element(label, defaultNamespace);
out.getChildren().add(elm);
elm.setAttribute("type", "EXPR_ITEM", xsiNamespace);
printString("type", expItem.getType(), elm);
}
}
protected void printExpressionLeaf(String label, ExpressionLeaf expLeaf, Element out) {
Element elm = new Element(label, defaultNamespace);
out.getChildren().add(elm);
elm.setAttribute("type", "EXPR_LEAF", xsiNamespace);
printString("type", expLeaf.getType(), elm);
if (expLeaf.getItem() instanceof CPrimitive) {
Element item = new Element("item", defaultNamespace);
elm.getChildren().add(item);
printCPrimitive((CPrimitive) expLeaf.getItem(), item);
} else {
//EXPR_LEAF.item is defined as xs:any in the AM schema (the reason for which is unclear)
//and consequently of type object in C# land.
// That's why having the XSD type explicitly set to string fixes the problem when deserialising to a C# string instead of XmlText.
printString("item", expLeaf.getItem().toString(), elm, true);
}
printString("reference_type", expLeaf.getReferenceType().name().toLowerCase(), elm); // the Reference type is expected in lower case here as per spec examples
}
protected void printExpressionOperator(String label, ExpressionOperator expOperator, Element out) {
Element elm = new Element(label, defaultNamespace);
out.getChildren().add(elm);
if(expOperator instanceof ExpressionUnaryOperator) {
elm.setAttribute("type", "EXPR_UNARY_OPERATOR", xsiNamespace);
printExpressionOperatorElements(expOperator, elm);
printExpressionItem("operand", ((ExpressionUnaryOperator)expOperator).getOperand(), elm);
} else if(expOperator instanceof ExpressionBinaryOperator) {
final ExpressionBinaryOperator expBinaryOperator = (ExpressionBinaryOperator)expOperator;
elm.setAttribute("type", "EXPR_BINARY_OPERATOR", xsiNamespace);
printExpressionOperatorElements(expOperator, elm);
printExpressionItem("left_operand", expBinaryOperator.getLeftOperand(), elm);
printExpressionItem("right_operand", expBinaryOperator.getRightOperand(), elm);
} else {
// unknown ExpressionOperator
elm.setAttribute("type", "EXPR_OPERATOR", xsiNamespace);
printExpressionOperatorElements(expOperator, elm);
}
}
protected void printExpressionOperatorElements(ExpressionOperator expOperator, Element out) {
printString("type", expOperator.getType(), out);
printString("operator", String.valueOf(expOperator.getOperator().getValue()), out);
printString("precedence_overridden",
expOperator.isPrecedenceOverridden() == true ? "true" : "false", out);
}
protected void printCAttribute(CAttribute cattribute, Element out) {
final boolean isMultipleAttribute;
if (cattribute instanceof CMultipleAttribute) {
isMultipleAttribute = true;
} else {
isMultipleAttribute = false;
}
Element attributes = new Element("attributes", defaultNamespace);
out.getChildren().add(attributes);
if(isMultipleAttribute) {
attributes.setAttribute("type", "C_MULTIPLE_ATTRIBUTE", xsiNamespace);
} else {
attributes.setAttribute("type", "C_SINGLE_ATTRIBUTE", xsiNamespace);
}
// FIXME: AOM XML schema spec is wrong. Has 'unbounded' attribute for C_ATTRIBUTE and element with name
// 'rm_type_name' instead of 'rm_attribute_name'.
printString("rm_attribute_name", cattribute.getRmAttributeName(), attributes);
Element existence = new Element("existence", defaultNamespace);
attributes.getChildren().add(existence);
printString("lower_included", "true", existence);
printString("upper_included", "true", existence);
printString("lower_unbounded", "false", existence);
printString("upper_unbounded", "false", existence);
int lower = 0, upper = 0;
if(cattribute.getExistence().equals(CAttribute.Existence.REQUIRED)) {
lower = 1;
upper = 1;
} else if(cattribute.getExistence().equals(CAttribute.Existence.OPTIONAL)) {
lower = 0;
upper = 1;
}
printString("lower", Integer.toString(lower), existence);
printString("upper", Integer.toString(upper), existence);
if(!cattribute.isAnyAllowed()) {
List children = cattribute.getChildren();
if (children.size() > 1
|| !(children.get(0) instanceof CPrimitiveObject)) {
for (CObject cobject : cattribute.getChildren()) {
printCObject(cobject, attributes);
}
} else {
CObject child = children.get(0);
printCPrimitiveObject((CPrimitiveObject) child, attributes);
}
}
if(isMultipleAttribute) {
Element cardinality = new Element("cardinality", defaultNamespace);
attributes.getChildren().add(cardinality);
printCardinality(
((CMultipleAttribute) cattribute).getCardinality(), cardinality);
}
}
protected void printCObject(CObject cobj, Element out) {
// print specialised types
if (cobj instanceof CDomainType) {
printCDomainType((CDomainType) cobj, out);
} else if (cobj instanceof CPrimitiveObject) {
printCPrimitiveObject((CPrimitiveObject) cobj, out);
} else if (cobj instanceof CComplexObject) {
printCComplexObject((CComplexObject) cobj, out);
} else if (cobj instanceof ArchetypeInternalRef) {
printArchetypeInternalRef((ArchetypeInternalRef) cobj, out);
} else if (cobj instanceof ConstraintRef) { // FIXME: Add in ADLSerializer as well
printConstraintRef((ConstraintRef) cobj, out);
} else if (cobj instanceof ArchetypeSlot) {
printArchetypeSlot((ArchetypeSlot) cobj, out);
}
}
protected void printCObjectElements(CObject cobj, Element out) {
// we always need the upper case with underscore notation for the rm type name
printString("rm_type_name", getUpperCaseWithUnderscoreFromCamelCase(cobj.getRmTypeName()), out);
printOccurrences(cobj.getOccurrences(), out);
printString("node_id", cobj.getNodeId(), out);
}
protected void printOccurrences(Interval occurrences, Element out) {
if (occurrences == null) {
return;
}
Element occurs = new Element("occurrences", defaultNamespace);
out.getChildren().add(occurs);
printInterval(occurrences, occurs);
}
protected void printCardinality(Cardinality cardinality, Element out) {
if (cardinality.isOrdered()) {
printString("is_ordered", "true", out);
} else {
printString("is_ordered", "false", out);
}
if (cardinality.isUnique()) {
printString("is_unique", "true", out);
} else {
printString("is_unique", "false", out);
}
Element interval = new Element("interval", defaultNamespace);
out.getChildren().add(interval);
printInterval(cardinality.getInterval(), interval);
}
protected void printCDomainType(CDomainType cdomain, Element out) {
if (cdomain instanceof CCodePhrase) {
printCCodePhrase((CCodePhrase) cdomain, out);
} else if (cdomain instanceof CDvOrdinal) {
printCDvOrdinal((CDvOrdinal) cdomain, out);
} else if (cdomain instanceof CDvQuantity) {
printCDvQuantity((CDvQuantity) cdomain, out);
} else {
// unknown CDomainType
System.err.println("Cannot serialize CDomainType of type '" + cdomain.getClass().getName() + "'!");
}
}
protected void printCCodePhrase(CCodePhrase ccp, Element out) {
Element children = new Element("children", defaultNamespace);
out.getChildren().add(children);
children.setAttribute("type", "C_CODE_PHRASE", xsiNamespace);
printCObjectElements(ccp, children);
if (ccp.hasAssumedValue()) {
CodePhrase assumedValue= ccp.getAssumedValue();
Element assumedValueEl = new Element("assumed_value", defaultNamespace);
children.getChildren().add(assumedValueEl);
printCodePhrase(assumedValue, assumedValueEl);
}
if(ccp.getTerminologyId() != null) {
Element terminologyId = new Element("terminology_id", defaultNamespace);
children.getChildren().add(terminologyId);
printString("value", ccp.getTerminologyId().getValue(), terminologyId);
}
if (ccp.getCodeList() != null) {
final List codeList = ccp.getCodeList();
for (int i = 0, j = codeList.size(); i < j; i++) {
printString("code_list", codeList.get(i), children);
}
}
}
protected void printCDvOrdinal(CDvOrdinal cordinal, Element out) {
Element children = new Element("children", defaultNamespace);
out.getChildren().add(children);
children.setAttribute("type", "C_DV_ORDINAL", xsiNamespace);
printCObjectElements(cordinal, children);
if (cordinal.hasAssumedValue()) {
Ordinal assumedValue = cordinal.getAssumedValue();
Element assumedValueEl = new Element("assumed_value", defaultNamespace);
children.getChildren().add(assumedValueEl);
printString("value", String.valueOf(assumedValue.getValue()), assumedValueEl);
printSymbolOfOrdinal(assumedValue, assumedValueEl);
}
if(cordinal.getList() != null) {
final List ordinals = cordinal.getList();
Ordinal ordinal;
for (Iterator it = ordinals.iterator(); it.hasNext();) {
ordinal = it.next();
Element list = new Element("list", defaultNamespace);
children.getChildren().add(list);
printString("value", String.valueOf(ordinal.getValue()), list);
printSymbolOfOrdinal(ordinal, list);
}
}
}
private void printSymbolOfOrdinal(Ordinal ordinal, Element list) {
Element symbol = new Element("symbol", defaultNamespace);
list.getChildren().add(symbol);
printString("value", null, symbol); // this is the mandatory(!) value of a DV_CODED_TEXT symbol.
Element definingCode = new Element("defining_code", defaultNamespace);
symbol.getChildren().add(definingCode);
printCodePhrase(ordinal.getSymbol(), definingCode);
}
protected void printCDvQuantity(CDvQuantity cquantity, Element out) {
Element children = new Element("children", defaultNamespace);
out.getChildren().add(children);
children.setAttribute("type", "C_DV_QUANTITY", xsiNamespace);
printCObjectElements(cquantity, children);
if (cquantity.hasAssumedValue()) {
Element assumedValueEl = new Element("assumed_value", defaultNamespace);
children.getChildren().add(assumedValueEl);
DvQuantity assumedValue = cquantity.getAssumedValue();
if(assumedValue.getMagnitude() != null) {
printString("magnitude", ""+assumedValue.getMagnitude(), assumedValueEl);
}
if(assumedValue.getUnits() != null) {
printString("units", assumedValue.getUnits(), assumedValueEl);
}
printString("precision", ""+assumedValue.getPrecision(), assumedValueEl);
}
CodePhrase property = cquantity.getProperty();
if (property != null) {
Element prop = new Element("property", defaultNamespace);
children.getChildren().add(prop);
printCodePhrase(property, prop);
}
if (cquantity.getList() != null) {
final List list = cquantity.getList();
for (CDvQuantityItem item : list) {
Element lst = new Element("list", defaultNamespace);
children.getChildren().add(lst);
printMagnitudePrecisionUnitsOfCDVQuantityItem(item, lst);
}
}
}
private void printMagnitudePrecisionUnitsOfCDVQuantityItem(CDvQuantityItem item, Element lst) {
if(item.getMagnitude() != null) {
Element magnitude = new Element("magnitude", defaultNamespace);
lst.getChildren().add(magnitude);
printInterval(item.getMagnitude(), magnitude);
}
if(item.getPrecision() != null) {
Element precision = new Element("precision", defaultNamespace);
lst.getChildren().add(precision);
printInterval(item.getPrecision(), precision);
}
printString("units", item.getUnits(), lst);
}
protected void printOntology(ArchetypeOntology ontology, String concept, Element out) {
if(ontology == null) {
return;
}
Element onto = new Element("ontology", defaultNamespace);
out.getChildren().add(onto);
// TODO: Check why this is not in the XML schema specification of the AOM.
//printString("primary_language", ontology.getPrimaryLanguage(), 2, out);
// TODO: Check why this is not in the XML schema specification of the AOM.
//printStringList("languages_available", ontology.getLanguages(), 2, out);
//printStringList("terminologies_available", ontology.getTerminologies(), 2, out);
//final int specDepth = StringUtils.countMatches(".", concept);
//printString("specialisation_depth", String.valueOf(specDepth), 2, out);
if(ontology.getTermDefinitionsList() != null) {
final List termDefinitions = ontology.getTermDefinitionsList();
for (OntologyDefinitions defs : termDefinitions) {
Element trmDefinitions = new Element("term_definitions", defaultNamespace);
onto.getChildren().add(trmDefinitions);
trmDefinitions.setAttribute("language", defs.getLanguage());
for (ArchetypeTerm term : defs.getDefinitions()) {
Element items = new Element("items", defaultNamespace);
trmDefinitions.getChildren().add(items);
items.setAttribute("code", term.getCode());
printStringMap("items", term.getItems(), items);
}
}
}
if(ontology.getConstraintDefinitionsList() != null) {
final List constraintDefinitions = ontology.getConstraintDefinitionsList();
for (OntologyDefinitions defs : constraintDefinitions) {
Element consDefinitions = new Element("constraint_definitions", defaultNamespace);
onto.getChildren().add(consDefinitions);
consDefinitions.setAttribute("language", defs.getLanguage());
for (ArchetypeTerm term : defs.getDefinitions()) {
Element items = new Element("items", defaultNamespace);
consDefinitions.getChildren().add(items);
items.setAttribute("code", term.getCode());
printStringMap("items", term.getItems(), items);
}
}
}
if (ontology.getTermBindingList() != null) {
final List termBindings = ontology.getTermBindingList();
TermBindingItem item;
for (OntologyBinding bind : termBindings) {
Element trmBindings = new Element("term_bindings", defaultNamespace);
onto.getChildren().add(trmBindings);
trmBindings.setAttribute("terminology", bind.getTerminology());
for (OntologyBindingItem bindItem : bind.getBindingList()) {
item = (TermBindingItem) bindItem;
for(String value : item.getTerms()) {
Element items = new Element("items", defaultNamespace);
trmBindings.getChildren().add(items);
items.setAttribute("code", item.getCode());
Element vl = new Element("value", defaultNamespace);
items.getChildren().add(vl);
String terminologyId = value.substring(1, value.lastIndexOf("::"));
String codeString = value.substring(value.lastIndexOf("::") + 2, value.length() - 1);
Element termId = new Element("terminology_id", defaultNamespace);
vl.getChildren().add(termId);
printString("value", terminologyId, termId);
printString("code_string", codeString, vl);
}
}
}
}
if (ontology.getConstraintBindingList() != null) {
final List constraintBindings = ontology.getConstraintBindingList();
QueryBindingItem item;
for (OntologyBinding bind : constraintBindings) {
Element consBindings = new Element("constraint_bindings", defaultNamespace);
onto.getChildren().add(consBindings);
consBindings.setAttribute("terminology", bind.getTerminology());
for (OntologyBindingItem bindItem : bind.getBindingList()) {
item = (QueryBindingItem) bindItem;
Element items = new Element("items", defaultNamespace);
consBindings.getChildren().add(items);
items.setAttribute("code", item.getCode());
printString("value", item.getQuery().getUrl(), items);
}
}
}
}
protected void printCPrimitiveObject(CPrimitiveObject cpo, Element out) {
CPrimitive cp = cpo.getItem();
if (cp == null) {
return;
}
Element children = new Element("children", defaultNamespace);
out.getChildren().add(children);
children.setAttribute("type", "C_PRIMITIVE_OBJECT", xsiNamespace);
printCObjectElements(cpo, children);
Element item = new Element("item", defaultNamespace);
children.getChildren().add(item);
printCPrimitive(cp, item);
}
protected void printCPrimitive(CPrimitive cp, Element out) {
if (cp instanceof CBoolean) {
out.setAttribute("type", "C_BOOLEAN", xsiNamespace);
printCBoolean((CBoolean) cp, out);
} else if (cp instanceof CDate) {
out.setAttribute("type", "C_DATE", xsiNamespace);
printCDate((CDate) cp, out);
} else if (cp instanceof CDateTime) {
out.setAttribute("type", "C_DATE_TIME", xsiNamespace);
printCDateTime((CDateTime) cp, out);
} else if (cp instanceof CTime) {
out.setAttribute("type", "C_TIME", xsiNamespace);
printCTime((CTime) cp, out);
} else if (cp instanceof CDuration) {
out.setAttribute("type", "C_DURATION", xsiNamespace);
printCDuration((CDuration) cp, out);
} else if (cp instanceof CInteger) {
out.setAttribute("type", "C_INTEGER", xsiNamespace);
printCInteger((CInteger) cp, out);
} else if (cp instanceof CReal) {
out.setAttribute("type", "C_REAL", xsiNamespace);
printCReal((CReal) cp, out);
} else if (cp instanceof CString) {
out.setAttribute("type", "C_STRING", xsiNamespace);
printCString((CString) cp, out);
} else {
out.setAttribute("type", "C_PRIMITIVE", xsiNamespace);
System.err.println("Cannot serialize CPrimitive of type '" + cp.getClass().getName() + "'!");
}
}
protected void printCBoolean(CBoolean cboolean, Element out) {
printString("true_valid", cboolean.isTrueValid() == true ?
"true" : "false", out);
printString("false_valid", cboolean.isFalseValid() == true ?
"true" : "false", out);
if(cboolean.hasAssumedValue()) {
printString("assumed_value", cboolean.assumedValue().booleanValue() == true ?
"true" : "false", out);
}
}
protected void printCDate(CDate cdate, Element out) {
if (cdate.getPattern() != null) {
printString("pattern", cdate.getPattern(), out);
}
if(cdate.getInterval() != null) {
Element range = new Element("range", defaultNamespace);
out.getChildren().add(range);
printInterval(cdate.getInterval(), range);
}
if(cdate.hasAssumedValue()) {
printString("assumed_value", cdate.assumedValue().toString(), out);
}
}
protected void printCDateTime(CDateTime cdatetime, Element out) {
if (cdatetime.getPattern() != null) {
printString("pattern", cdatetime.getPattern(), out);
}
// FIXME: Output timezone_validity. CDateTime seem to be missing this function.
if(cdatetime.getInterval() != null) {
Element range = new Element("range", defaultNamespace);
out.getChildren().add(range);
printInterval(cdatetime.getInterval(), range);
}
if(cdatetime.hasAssumedValue()) {
printString("assumed_value", cdatetime.assumedValue().toString(), out);
}
}
protected void printCTime(CTime ctime, Element out) {
if (ctime.getPattern() != null) {
printString("pattern", ctime.getPattern(), out);
}
// FIXME: Output timezone_validity. CTime seem to be missing this function.
if(ctime.getInterval() != null) {
Element range = new Element("range", defaultNamespace);
out.getChildren().add(range);
printInterval(ctime.getInterval(), range);
}
if(ctime.hasAssumedValue()) {
printString("assumed_value", ctime.assumedValue().toString(), out);
}
}
protected void printCDuration(CDuration cduration, Element out) {
if (cduration.getPattern() != null) {
printString("pattern", cduration.getPattern().toString(), out);
}
Element range = new Element("range", defaultNamespace);
out.getChildren().add(range);
if(cduration.getInterval() != null) {
printInterval(cduration.getInterval(), range);
} else {
// these should be supplied even for a null range
printString("lower_unbounded", "true", range);
printString("upper_unbounded", "true", range);
}
if(cduration.hasAssumedValue()) {
printString("assumed_value", cduration.assumedValue().toString(), out);
}
}
protected void printCInteger(CInteger cinteger, Element out) {
if(cinteger.getList() != null) {
printList(cinteger.getList(), out);
}
if(cinteger.getInterval() != null) {
Element range = new Element("range", defaultNamespace);
out.getChildren().add(range);
printInterval(cinteger.getInterval(), range);
}
// TODO: Write 'list_open' element... xs:boolean [0..1]
if(cinteger.hasAssumedValue()) {
printString("assumed_value", cinteger.assumedValue().toString(), out);
}
}
protected void printCReal(CReal creal, Element out) {
if (creal.getList() != null) {
printList(creal.getList(), out);
}
if(creal.getInterval() != null) {
Element range = new Element("range", defaultNamespace);
out.getChildren().add(range);
printInterval(creal.getInterval(), range);
}
if(creal.hasAssumedValue()) {
printString("assumed_value", creal.assumedValue().toString(), out);
}
}
protected void printCString(CString cstring, Element out) {
if(cstring.getPattern() != null) {
printString("pattern", cstring.getPattern(), out);
}
if(cstring.getList() != null){
printList(cstring.getList(), out);
}
// TODO: Write 'list_open' element... xs:boolean [0..1]
if(cstring.hasAssumedValue()) {
printString("assumed_value", cstring.assumedValue().toString(), out);
}
}
protected void printList(List list, Element out) {
if(list == null) {
return;
}
for(int i = 0, j = list.size(); i < j; i++) {
printString("list", list.get(i).toString(), out);
}
}
@SuppressWarnings("unchecked")
protected void printInterval(Interval interval, Element out) {
if(interval == null) {
return;
}
final Comparable lower = interval.getLower();
final Comparable upper = interval.getUpper();
if (! interval.isLowerUnbounded()) { // not included is implied if unbounded
printString("lower_included",
interval.isLowerIncluded() == true ? "true" : "false",
out);
}
if (! interval.isUpperUnbounded()) { // not included is implied if unbounded
printString("upper_included",
interval.isUpperIncluded() == true ? "true" : "false",
out);
}
printString("lower_unbounded",
interval.isLowerUnbounded() ? "true" : "false", out);
printString("upper_unbounded",
interval.isUpperUnbounded() ? "true" : "false", out);
if(lower != null) {
printString("lower", lower.toString(), out);
}
if(upper != null) {
printString("upper", upper.toString(), out);
}
}
private String getUpperCaseWithUnderscoreFromCamelCase(String str) {
if( str == null || str.length() == 0 ) {
return str;
}
StringBuffer result = new StringBuffer();
char prevChar = 'A'; // init with an upper case letter
/*
* Change underscore to space, insert space before capitals
*/
for( int i = 0; i < str.length(); i++ ) {
char c = str.charAt( i );
if(! Character.isUpperCase(prevChar) &&
!(prevChar=='<') && // without this DV_INTERVAL --> DV_INTERVAL<_DV_QUANTITY>
!(prevChar=='_') &&
Character.isLetter(c) &&
Character.isUpperCase(c))
{
result.append("_");
result.append( Character.toUpperCase( c ) );
}
else {
result.append( Character.toUpperCase( c ) );
}
prevChar = c;
}
return result.toString();
}
/* charset encodings */
public static final Charset UTF8 = Charset.forName("UTF-8");
public static final Charset LATIN1 = Charset.forName("ISO-8859-1");
public static final Namespace defaultNamespace = Namespace.getNamespace("http://schemas.openehr.org/v1");
public static final Namespace xsiNamespace = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
public static final Namespace xsdNamespace = Namespace.getNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
/* fields */
private Charset encoding;
private XMLOutputter outputter;
}
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is XMLSerializer.
*
* The Initial Developer of the Original Code is
* Link�pings universitet, Sweden.
* Portions created by the Initial Developer are Copyright (C) 2005-2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): Mattias Forss
* Rong Chen
* Erik Sundvall
* Humberto Naves
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
© 2015 - 2025 Weber Informatics LLC | Privacy Policy