Properly deserialize bound codes
This commit is contained in:
parent
232afee955
commit
ce253bed70
|
@ -1,5 +1,9 @@
|
|||
package ca.uhn.fhir.model.primitive;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -42,7 +46,7 @@ public class BoundCodeDt<T extends Enum<?>> extends CodeDt {
|
|||
Validate.notNull(theBinder, "theBinder must not be null");
|
||||
myBinder = theBinder;
|
||||
}
|
||||
|
||||
|
||||
public BoundCodeDt(IValueSetEnumBinder<T> theBinder, T theValue) {
|
||||
Validate.notNull(theBinder, "theBinder must not be null");
|
||||
myBinder = theBinder;
|
||||
|
@ -52,7 +56,7 @@ public class BoundCodeDt<T extends Enum<?>> extends CodeDt {
|
|||
public IValueSetEnumBinder<T> getBinder() {
|
||||
return myBinder;
|
||||
}
|
||||
|
||||
|
||||
public T getValueAsEnum() {
|
||||
Validate.notNull(myBinder, "This object does not have a binder. Constructor BoundCodeDt() should not be called!");
|
||||
T retVal = myBinder.fromCodeString(getValue());
|
||||
|
@ -62,6 +66,13 @@ public class BoundCodeDt<T extends Enum<?>> extends CodeDt {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void readExternal(ObjectInput theIn) throws IOException, ClassNotFoundException {
|
||||
super.readExternal(theIn);
|
||||
myBinder = (IValueSetEnumBinder<T>) theIn.readObject();
|
||||
}
|
||||
|
||||
public void setValueAsEnum(T theValue) {
|
||||
Validate.notNull(myBinder, "This object does not have a binder. Constructor BoundCodeDt() should not be called!");
|
||||
if (theValue==null) {
|
||||
|
@ -70,4 +81,10 @@ public class BoundCodeDt<T extends Enum<?>> extends CodeDt {
|
|||
setValue(myBinder.toCodeString(theValue));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExternal(ObjectOutput theOut) throws IOException {
|
||||
super.writeExternal(theOut);
|
||||
theOut.writeObject(myBinder);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package org.hl7.fhir.instance.model.api;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -20,7 +22,7 @@ package org.hl7.fhir.instance.model.api;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
public interface IBaseEnumFactory<T extends Enum<?>> {
|
||||
public interface IBaseEnumFactory<T extends Enum<?>> extends Serializable {
|
||||
|
||||
/**
|
||||
* Read an enumeration value from the string that represents it on the XML or JSON
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
package ca.uhn.fhir.jpa.config;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.ServerValidationModeEnum;
|
||||
|
||||
public class Tmp {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
ctx.getRestfulClientFactory().setSocketTimeout(200000);
|
||||
ctx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://localhost:8080/hapi-fhir-jpaserver-example/baseDstu2");
|
||||
|
||||
Bundle b = new Bundle();
|
||||
b.setType(BundleTypeEnum.TRANSACTION);
|
||||
int resCount = 20;
|
||||
for (int i = 0; i < (resCount / 2); i++) {
|
||||
Organization org = new Organization();
|
||||
org.setId(IdDt.newRandomUuid());
|
||||
org.setName("Random Org " + i);
|
||||
org.addAddress().addLine("Random Org Line 1");
|
||||
org.addIdentifier().setSystem("urn:foo").setValue("some_system" + i);
|
||||
b.addEntry().setResource(org).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Organization");
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.setId(IdDt.newRandomUuid());
|
||||
patient.addName().addFamily("Family" + i).addGiven("Gigven " + i);
|
||||
patient.addAddress().addLine("Random Patient Line 1");
|
||||
patient.addIdentifier().setSystem("urn:bar").setValue("some_system" + i);
|
||||
b.addEntry().setResource(patient).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Patient");
|
||||
}
|
||||
|
||||
int total = 0;
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < 300; i++) {
|
||||
client.transaction().withBundle(b).execute();
|
||||
ourLog.info("" + i);
|
||||
total += resCount;
|
||||
}
|
||||
|
||||
long delay = System.currentTimeMillis() - start;
|
||||
ourLog.info("Wrote {} resources at {}ms / res", total, delay / total);
|
||||
|
||||
//sync 13:57:14.683 [main] INFO ca.uhn.fhir.jpa.config.Tmp - Wrote 6000 resources at 7ms / res
|
||||
}
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(Tmp.class);
|
||||
|
||||
}
|
|
@ -31,8 +31,6 @@ import org.apache.commons.lang3.Validate;
|
|||
import ca.uhn.fhir.model.api.IBoundCodeableConcept;
|
||||
import ca.uhn.fhir.model.api.IValueSetEnumBinder;
|
||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
||||
|
||||
@DatatypeDef(name = "CodeableConcept", isSpecialization = true)
|
||||
public class BoundCodeableConceptDt<T extends Enum<?>> extends CodeableConceptDt implements IBoundCodeableConcept {
|
||||
|
|
|
@ -3,7 +3,6 @@ package ca.uhn.fhir.model.dstu2;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
@ -15,18 +14,71 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
import ca.uhn.fhir.model.dstu2.composite.AddressDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.IdentifierTypeCodesEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.MaritalStatusCodesEnum;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
|
||||
public class ModelSerializationTest {
|
||||
public class ModelSerializationDstu2Test {
|
||||
|
||||
private static final FhirContext ourCtx = FhirContext.forDstu2();
|
||||
|
||||
/**
|
||||
* Verify that MaritalStatusCodeEnum (and, by extension, BoundCodeableConcepts in general) are serializable. Author: Nick Peterson (nrpeterson@gmail.com)
|
||||
*/
|
||||
@Test
|
||||
public void testBoundCodeableConceptSerialization() {
|
||||
MaritalStatusCodesEnum maritalStatus = MaritalStatusCodesEnum.M;
|
||||
byte[] bytes = SerializationUtils.serialize(maritalStatus);
|
||||
assertTrue(bytes.length > 0);
|
||||
|
||||
MaritalStatusCodesEnum deserialized = SerializationUtils.deserialize(bytes);
|
||||
assertEquals(maritalStatus.getCode(), deserialized.getCode());
|
||||
assertEquals(maritalStatus.getSystem(), deserialized.getSystem());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBoundCodeSerialization() {
|
||||
Patient p = new Patient();
|
||||
p.setGender(AdministrativeGenderEnum.MALE);
|
||||
IdentifierDt identifier = p.addIdentifier();
|
||||
identifier.setType(IdentifierTypeCodesEnum.DL);
|
||||
|
||||
Patient out = testIsSerializable(p);
|
||||
|
||||
/*
|
||||
* Make sure the binder still works for Code
|
||||
*/
|
||||
assertEquals(AdministrativeGenderEnum.MALE, out.getGenderElement().getValueAsEnum());
|
||||
out.getGenderElement().setValue("female");
|
||||
assertEquals(AdministrativeGenderEnum.FEMALE, out.getGenderElement().getValueAsEnum());
|
||||
|
||||
assertEquals(IdentifierTypeCodesEnum.DL, out.getIdentifier().get(0).getType().getValueAsEnum().iterator().next());
|
||||
out.getIdentifier().get(0).getType().setValueAsEnum(IdentifierTypeCodesEnum.MR);
|
||||
assertEquals("MR", out.getIdentifier().get(0).getType().getCoding().get(0).getCode());
|
||||
assertEquals("http://hl7.org/fhir/v2/0203", out.getIdentifier().get(0).getType().getCoding().get(0).getSystem());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends IBaseResource> T testIsSerializable(T theObject) {
|
||||
byte[] bytes = SerializationUtils.serialize(theObject);
|
||||
assertTrue(bytes.length > 0);
|
||||
|
||||
IBaseResource obj = SerializationUtils.deserialize(bytes);
|
||||
assertTrue(obj != null);
|
||||
|
||||
IParser p = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||
assertEquals(p.encodeResourceToString(theObject), p.encodeResourceToString(obj));
|
||||
|
||||
return (T) obj;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialization() throws Exception {
|
||||
String input = IOUtils.toString(ModelSerializationTest.class.getResourceAsStream("/diagnosticreport-examples-lab-text(72ac8493-52ac-41bd-8d5d-7258c289b5ea).xml"));
|
||||
String input = IOUtils.toString(ModelSerializationDstu2Test.class.getResourceAsStream("/diagnosticreport-examples-lab-text(72ac8493-52ac-41bd-8d5d-7258c289b5ea).xml"));
|
||||
|
||||
Bundle parsed = ourCtx.newXmlParser().parseResource(Bundle.class, input);
|
||||
testIsSerializable(parsed);
|
||||
|
@ -44,31 +96,4 @@ public class ModelSerializationTest {
|
|||
testIsSerializable(patient);
|
||||
}
|
||||
|
||||
private void testIsSerializable(IBaseResource theObject) {
|
||||
byte[] bytes = SerializationUtils.serialize(theObject);
|
||||
assertTrue(bytes.length > 0);
|
||||
|
||||
IBaseResource obj = SerializationUtils.deserialize(bytes);
|
||||
assertTrue(obj != null);
|
||||
|
||||
IParser p = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||
assertEquals(p.encodeResourceToString(theObject), p.encodeResourceToString(obj));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that MaritalStatusCodeEnum (and, by extension, BoundCodeableConcepts in general) are serializable.
|
||||
* Author: Nick Peterson (nrpeterson@gmail.com)
|
||||
*/
|
||||
@Test
|
||||
public void testBoundCodeableConceptSerialization() {
|
||||
MaritalStatusCodesEnum maritalStatus = MaritalStatusCodesEnum.M;
|
||||
byte[] bytes = SerializationUtils.serialize(maritalStatus);
|
||||
assertTrue(bytes.length > 0);
|
||||
|
||||
MaritalStatusCodesEnum deserialized = SerializationUtils.deserialize(bytes);
|
||||
assertEquals(maritalStatus.getCode(), deserialized.getCode());
|
||||
assertEquals(maritalStatus.getSystem(), deserialized.getSystem());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,10 @@
|
|||
package org.hl7.fhir.dstu3.model;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseEnumeration;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||
|
@ -38,11 +43,20 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
*
|
||||
*/
|
||||
@DatatypeDef(name = "code", isSpecialization = true)
|
||||
public class Enumeration<T extends Enum<?>> extends PrimitiveType<T> implements IBaseEnumeration<T> {
|
||||
public class Enumeration<T extends Enum<?>> extends PrimitiveType<T> implements IBaseEnumeration<T>, Externalizable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final EnumFactory<T> myEnumFactory;
|
||||
private EnumFactory<T> myEnumFactory;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @deprecated This no-arg constructor is provided for serialization only - Do not use
|
||||
*/
|
||||
@Deprecated
|
||||
public Enumeration() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
@ -100,4 +114,18 @@ public class Enumeration<T extends Enum<?>> extends PrimitiveType<T> implements
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void readExternal(ObjectInput theIn) throws IOException, ClassNotFoundException {
|
||||
myEnumFactory = (EnumFactory<T>) theIn.readObject();
|
||||
super.readExternal(theIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExternal(ObjectOutput theOut) throws IOException {
|
||||
theOut.writeObject(myEnumFactory);
|
||||
super.writeExternal(theOut);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
package org.hl7.fhir.dstu3.model;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
|
@ -8,64 +13,18 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
|||
|
||||
import ca.uhn.fhir.model.api.IElement;
|
||||
|
||||
public abstract class PrimitiveType<T> extends Type implements IPrimitiveType<T>, IBaseHasExtensions, IElement {
|
||||
public abstract class PrimitiveType<T> extends Type implements IPrimitiveType<T>, IBaseHasExtensions, IElement, Externalizable {
|
||||
|
||||
private static final long serialVersionUID = 3L;
|
||||
|
||||
private T myCoercedValue;
|
||||
private String myStringValue;
|
||||
|
||||
public T getValue() {
|
||||
return myCoercedValue;
|
||||
}
|
||||
|
||||
public String asStringValue() {
|
||||
return myStringValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return new HashCodeBuilder().append(getValue()).toHashCode();
|
||||
}
|
||||
|
||||
public PrimitiveType<T> setValue(T theValue) {
|
||||
myCoercedValue = theValue;
|
||||
updateStringValue();
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void updateStringValue() {
|
||||
if (myCoercedValue == null) {
|
||||
myStringValue = null;
|
||||
} else {
|
||||
// NB this might be null
|
||||
myStringValue = encode(myCoercedValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && StringUtils.isBlank(getValueAsString());
|
||||
}
|
||||
|
||||
public void fromStringValue(String theValue) {
|
||||
if (theValue == null) {
|
||||
myCoercedValue = null;
|
||||
} else {
|
||||
// NB this might be null
|
||||
myCoercedValue = parse(theValue);
|
||||
}
|
||||
myStringValue = theValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must override to convert an encoded representation of this datatype into a "coerced" one
|
||||
*
|
||||
* @param theValue
|
||||
* Will not be null
|
||||
* @return May return null if the value does not correspond to anything
|
||||
*/
|
||||
protected abstract T parse(String theValue);
|
||||
public abstract Type copy();
|
||||
|
||||
/**
|
||||
* Subclasses must override to convert a "coerced" value into an encoded one.
|
||||
|
@ -76,37 +35,6 @@ public abstract class PrimitiveType<T> extends Type implements IPrimitiveType<T>
|
|||
*/
|
||||
protected abstract String encode(T theValue);
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String primitiveValue() {
|
||||
return asStringValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + "[" + asStringValue() + "]";
|
||||
}
|
||||
|
||||
public boolean hasValue() {
|
||||
return !StringUtils.isBlank(getValueAsString());
|
||||
}
|
||||
|
||||
public String getValueAsString() {
|
||||
return asStringValue();
|
||||
}
|
||||
|
||||
public void setValueAsString(String theValue) {
|
||||
fromStringValue(theValue);
|
||||
}
|
||||
|
||||
protected Type typedCopy() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
public abstract Type copy();
|
||||
|
||||
@Override
|
||||
public boolean equalsDeep(Base obj) {
|
||||
if (!super.equalsDeep(obj))
|
||||
|
@ -141,4 +69,92 @@ public abstract class PrimitiveType<T> extends Type implements IPrimitiveType<T>
|
|||
return b.isEquals();
|
||||
}
|
||||
|
||||
public void fromStringValue(String theValue) {
|
||||
if (theValue == null) {
|
||||
myCoercedValue = null;
|
||||
} else {
|
||||
// NB this might be null
|
||||
myCoercedValue = parse(theValue);
|
||||
}
|
||||
myStringValue = theValue;
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return myCoercedValue;
|
||||
}
|
||||
|
||||
public String getValueAsString() {
|
||||
return asStringValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return new HashCodeBuilder().append(getValue()).toHashCode();
|
||||
}
|
||||
|
||||
public boolean hasValue() {
|
||||
return !StringUtils.isBlank(getValueAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && StringUtils.isBlank(getValueAsString());
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must override to convert an encoded representation of this datatype into a "coerced" one
|
||||
*
|
||||
* @param theValue
|
||||
* Will not be null
|
||||
* @return May return null if the value does not correspond to anything
|
||||
*/
|
||||
protected abstract T parse(String theValue);
|
||||
|
||||
public String primitiveValue() {
|
||||
return asStringValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readExternal(ObjectInput theIn) throws IOException, ClassNotFoundException {
|
||||
String object = (String) theIn.readObject();
|
||||
setValueAsString(object);
|
||||
}
|
||||
|
||||
public PrimitiveType<T> setValue(T theValue) {
|
||||
myCoercedValue = theValue;
|
||||
updateStringValue();
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setValueAsString(String theValue) {
|
||||
fromStringValue(theValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + "[" + asStringValue() + "]";
|
||||
}
|
||||
|
||||
protected Type typedCopy() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
protected void updateStringValue() {
|
||||
if (myCoercedValue == null) {
|
||||
myStringValue = null;
|
||||
} else {
|
||||
// NB this might be null
|
||||
myStringValue = encode(myCoercedValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExternal(ObjectOutput theOut) throws IOException {
|
||||
theOut.writeObject(getValueAsString());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
package ca.uhn.fhir.model;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.lang3.SerializationUtils;
|
||||
import org.hl7.fhir.dstu3.model.Address;
|
||||
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
|
||||
import org.hl7.fhir.dstu3.model.HumanName;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
|
||||
public class ModelSerializationDstu3Test {
|
||||
|
||||
private static final FhirContext ourCtx = FhirContext.forDstu3();
|
||||
|
||||
/**
|
||||
* Verify that MaritalStatusCodeEnum (and, by extension, BoundCodeableConcepts in general) are serializable. Author: Nick Peterson (nrpeterson@gmail.com)
|
||||
*/
|
||||
@Test
|
||||
public void testBoundCodeableConceptSerialization() {
|
||||
AdministrativeGender maritalStatus = AdministrativeGender.MALE;
|
||||
byte[] bytes = SerializationUtils.serialize(maritalStatus);
|
||||
assertTrue(bytes.length > 0);
|
||||
|
||||
AdministrativeGender deserialized = SerializationUtils.deserialize(bytes);
|
||||
assertEquals(AdministrativeGender.MALE, deserialized);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBoundCodeSerialization() {
|
||||
Patient p = new Patient();
|
||||
p.setGender(AdministrativeGender.MALE);
|
||||
|
||||
Patient out = testIsSerializable(p);
|
||||
|
||||
/*
|
||||
* Make sure the binder still works for Code
|
||||
*/
|
||||
assertEquals(AdministrativeGender.MALE, out.getGender());
|
||||
out.getGenderElement().setValueAsString("female");
|
||||
assertEquals(AdministrativeGender.FEMALE, out.getGender());
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends IBaseResource> T testIsSerializable(T theObject) {
|
||||
byte[] bytes = SerializationUtils.serialize(theObject);
|
||||
assertTrue(bytes.length > 0);
|
||||
|
||||
IBaseResource obj = SerializationUtils.deserialize(bytes);
|
||||
assertTrue(obj != null);
|
||||
|
||||
IParser p = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||
assertEquals(p.encodeResourceToString(theObject), p.encodeResourceToString(obj));
|
||||
|
||||
return (T) obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Contributed by Travis from iSalus
|
||||
*/
|
||||
@Test
|
||||
public void testSerialization2() {
|
||||
Patient patient = new Patient();
|
||||
patient.addName(new HumanName().addGiven("George").addFamily("Washington"));
|
||||
patient.addName(new HumanName().addGiven("George2").addFamily("Washington2"));
|
||||
patient.addAddress(new Address().addLine("line 1").addLine("line 2").setCity("city").setState("UT"));
|
||||
patient.addAddress(new Address().addLine("line 1b").addLine("line 2b").setCity("cityb").setState("UT"));
|
||||
patient.setBirthDate(new Date());
|
||||
|
||||
testIsSerializable(patient);
|
||||
}
|
||||
|
||||
}
|
|
@ -216,6 +216,14 @@
|
|||
requests where the URL does not contain an ID but needs to (e.g. for
|
||||
an update) or contains an ID but shouldn't (e.g. for a create)
|
||||
</action>
|
||||
<action type="fix">
|
||||
When fields of type BoundCodeDt (e.g. Patient.gender)
|
||||
are serialized and deserialized using Java's native
|
||||
object serialization, the enum binder was not
|
||||
serialized too. This meant that values for the
|
||||
field in the deserialized object could not be
|
||||
modified. Thanks to Thomas Andersen for reporting!
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.4" date="2016-02-04">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue