Description About How to Serialize-Deserialize

Introduction

There are two strategies about serialization and deserialization: "long" and "short" versions.

Long serialization is supported with xstream in OpenMRS 1.5.

Short serialization is supported with xstream starting in OpenMRS 1.6.

Long Serialization and Long Deserialization

(requires OpenMRS 1.5)

In Long serialization we serialize all attributes of the object. All domain objects in package “org.openmrs” are optionally mapped into a short name, such as “org.openmrs.User” -> “user”. There are only three attributes of domain objects will be serialized as an attribute of the element in the xml output: “BaseOpenmrsObject.uuid”, “BaseOpenmrsData.voided” and “BaseOpenmrsMetaData.retired”. If one domain object inherits from any of these three abstract classes, then relative attribute such as “uuid” will be serialized as an attribute of element in xml output, not as a child element.

In Long deserialization we deserialize an xml string to get a domain object. The form of this xml string is just like the xml output generated by Long serialization.

Short Serialization and Short Deserialization

(requires OpenMRS 1.6)

In Short serialization, the only difference comparing with Long Serialization is that there are some special domain objects: User/Person/Patient and any class whose name ends with “Type”. When any one of these special domain objects exists as an attribute of another object, we only serialize its "uuid" property in xml output. However if it is the sole object and not an attribute of another object, it serializes like Long serialization.

In Short deserialization, when xstream meets an element which only has “uuid” attribute, then we will deserialize this element to a object through such a manner: "Context.getXXXService().getXXXByUUID(uuid)".

Note: In both long and short serialization, we use "id" attribute in xml output to deal with cyclic reference.

Example Code

(1) Long Serialization

Privilege p = Context.getUserService().getPrivilege("Delete Cohorts");
String xmlOutput = Context.getSerializationService().serialize(p,XStreamSerializer.class);

xml Output:

<privilege id="1" uuid="afc993ec-8b43-4af2-9974-54c7f98214ce" retired="false">
   <description>Able to add a cohort to the system</description>
   <privilege>Delete Cohorts</privilege>
</privilege>

(2) Long Deserialization

StringBuilder xmlBuilder = new StringBuilder();
xmlBuider.append("<privilege id=\"1\" uuid=\"afc993ec-8b43-4af2-9974-54c7f98214ce\" retired=\"false\">\n");
xmlBuilder.append(" <description>Able to add a cohort to the system</description>\n");
xmlBuilder.append(" <privilege>Delete Cohorts</privilege>\n");
xmlBuilder.append("</privilege>\n");

Privilege p = Context.getSerializationService().deserialize(xmlBuilder.toString(), Privilege.class, XStreamSerializer.class);

(3) Short Serialization

/* PatientIdentifierType has a attribute "creator" and it will be shortly serialized. You can see it in next segment "Short Deserialization" */
PatientIdentifierType pit = Context.getPatientService().getPatientIdentifierTypeByUuid( "1a339fe9-38bc-4ab3-b180-320988c0b968");
String xmlOutput = Context.getSerializationService().serialize(pit, XStreamShortSerializer.class);

xml Output:

<patientIdentifierType id="1" uuid="1a339fe9-38bc-4ab3-b180-320988c0b968" retired="false">
  <name>OpenMRS Identification Number</name>
  <description>Unique number used in OpenMRS</description>
  <creator id=\"2\" uuid=\"6adb7c42-cfd2-4301-b53b-ff17c5654ff7\"/>
  <dateCreated class=\"sql-timestamp\" id=\"3\">2005-09-22 00:00:00 CST</dateCreated>
  <patientIdentifierTypeId>1</patientIdentifierTypeId>
  <required>false</required>
  <checkDigit>true</checkDigit>
  <validator>org.openmrs.patient.impl.LuhnIdentifierValidator</validator
</patientIdentifierType>

(4) Short Deserialization

/* You can see that the "creator" element only has "uuid" attribute and it will be short deserialized */
StringBuilder xmlBuilder = new StringBuilder();
xmlBuilder.append("<patientIdentifierType id=\"1\" uuid=\"1a339fe9-38bc-4ab3-b180-320988c0b968\" retired=\"false\">\n");
xmlBuilder.append(" <name>OpenMRS Identification Number</name>\n");
xmlBuilder.append(" <description>Unique number used in OpenMRS</description>\n");
xmlBuilder.append(" <creator id=\"2\" uuid=\"6adb7c42-cfd2-4301-b53b-ff17c5654ff7\"/>\n");
xmlBuilder.append(" <dateCreated class=\"sql-timestamp\" id=\"3\">2005-09-22 00:00:00 CST</dateCreated>\n");
xmlBuilder.append("<patientIdentifierTypeId>1</patientIdentifierTypeId>\n");
xmlBuilder.append(" <required>false</required>\n");
xmlBuilder.append(" <checkDigit>true</checkDigit>\n");
xmlBuilder.append("<validator>org.openmrs.patient.impl.LuhnIdentifierValidator</validator>\n"); xmlBuilder.append("</patientIdentifierType>\n");

PatientIdentifierType pit = Context.getSerializationService().deserialize(xmlBuilder.toString(), PatientIdentifierType.class, XStreamShortSerializer.class);