diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java index 5f402f6fa7f..48cc3962b3e 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java @@ -26,7 +26,6 @@ import java.io.InputStream; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; -import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; @@ -35,33 +34,24 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; import org.apache.commons.io.IOUtils; -import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseBackboneElement; import org.hl7.fhir.instance.model.api.IBaseDatatype; import org.hl7.fhir.instance.model.api.IBaseDatatypeElement; -import org.hl7.fhir.instance.model.api.IBaseEnumeration; -import org.hl7.fhir.instance.model.api.IBaseExtension; -import org.hl7.fhir.instance.model.api.IBaseReference; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseXhtml; import org.hl7.fhir.instance.model.api.ICompositeType; import org.hl7.fhir.instance.model.api.IIdType; -import org.hl7.fhir.instance.model.api.INarrative; import org.hl7.fhir.instance.model.api.IPrimitiveType; import ca.uhn.fhir.model.api.ExtensionDt; -import ca.uhn.fhir.model.api.IBoundCodeableConcept; import ca.uhn.fhir.model.api.IDatatype; import ca.uhn.fhir.model.api.IElement; import ca.uhn.fhir.model.api.IResource; @@ -69,16 +59,10 @@ import ca.uhn.fhir.model.api.IResourceBlock; import ca.uhn.fhir.model.api.IValueSetEnumBinder; import ca.uhn.fhir.model.api.annotation.Block; import ca.uhn.fhir.model.api.annotation.Child; -import ca.uhn.fhir.model.api.annotation.ChildOrder; import ca.uhn.fhir.model.api.annotation.Compartment; import ca.uhn.fhir.model.api.annotation.DatatypeDef; -import ca.uhn.fhir.model.api.annotation.Description; -import ca.uhn.fhir.model.api.annotation.Extension; import ca.uhn.fhir.model.api.annotation.ResourceDef; import ca.uhn.fhir.model.api.annotation.SearchParamDefinition; -import ca.uhn.fhir.model.base.composite.BaseContainedDt; -import ca.uhn.fhir.model.base.composite.BaseNarrativeDt; -import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt; import ca.uhn.fhir.model.primitive.BoundCodeDt; import ca.uhn.fhir.model.primitive.XhtmlDt; import ca.uhn.fhir.rest.method.RestSearchParameterTypeEnum; @@ -129,17 +113,12 @@ class ModelScanner { throw new ConfigurationException("Field '" + theNext + "' has no parameter for " + BoundCodeDt.class.getSimpleName() + " to determine enum type"); } + String fieldName = "VALUESET_BINDER"; try { - Field bindingField = bound.getField("VALUESET_BINDER"); + Field bindingField = bound.getField(fieldName); return (IValueSetEnumBinder>) bindingField.get(null); - } catch (IllegalArgumentException e) { - throw new ConfigurationException("Field '" + theNext + "' has type parameter " + bound.getCanonicalName() + " but this class has no valueset binding field", e); - } catch (IllegalAccessException e) { - throw new ConfigurationException("Field '" + theNext + "' has type parameter " + bound.getCanonicalName() + " but this class has no valueset binding field", e); - } catch (NoSuchFieldException e) { - throw new ConfigurationException("Field '" + theNext + "' has type parameter " + bound.getCanonicalName() + " but this class has no valueset binding field", e); - } catch (SecurityException e) { - throw new ConfigurationException("Field '" + theNext + "' has type parameter " + bound.getCanonicalName() + " but this class has no valueset binding field", e); + } catch (Exception e) { + throw new ConfigurationException("Field '" + theNext + "' has type parameter " + bound.getCanonicalName() + " but this class has no valueset binding field (must have a field called " + fieldName + ")", e); } } diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/i391/OutcomeBinder.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/i391/OutcomeBinder.java new file mode 100644 index 00000000000..78416fc1ae8 --- /dev/null +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/i391/OutcomeBinder.java @@ -0,0 +1,34 @@ +package ca.uhn.fhir.parser.i391; + +import ca.uhn.fhir.model.api.IValueSetEnumBinder; + +class OutcomeBinder implements IValueSetEnumBinder { + + @Override + public OutcomeEnum fromCodeString(String theCodeString) { + if (theCodeString.equals("item1")) { + return OutcomeEnum.ITEM1; + } else { + return OutcomeEnum.ITEM2; + } + } + + @Override + public String toCodeString(OutcomeEnum theEnum) { + if (theEnum.equals(OutcomeEnum.ITEM1)){ + return "item1"; + }else{ + return "item2"; + } + } + + @Override + public String toSystemString(OutcomeEnum theEnum) { + return "system"; + } + + @Override + public OutcomeEnum fromCodeString(String theCodeString, String theSystemString) { + return fromCodeString(theCodeString); + } +} \ No newline at end of file diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/i391/OutcomeEnum.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/i391/OutcomeEnum.java new file mode 100644 index 00000000000..0af80bdb85e --- /dev/null +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/i391/OutcomeEnum.java @@ -0,0 +1,18 @@ +package ca.uhn.fhir.parser.i391; + +import ca.uhn.fhir.model.api.IValueSetEnumBinder; + +public enum OutcomeEnum { + + ITEM1("item1"), + ITEM2("item2"); + + public static final IValueSetEnumBinder VALUESET_BINDER = new OutcomeBinder(); + + private final String code; + + OutcomeEnum(String code) { + this.code = code; + } + +} \ No newline at end of file diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/i391/TestOutcome.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/i391/TestOutcome.java new file mode 100644 index 00000000000..7a57590e8aa --- /dev/null +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/i391/TestOutcome.java @@ -0,0 +1,40 @@ +package ca.uhn.fhir.parser.i391; + +import java.util.List; + +import ca.uhn.fhir.model.api.IElement; +import ca.uhn.fhir.model.api.annotation.Child; +import ca.uhn.fhir.model.api.annotation.Description; +import ca.uhn.fhir.model.api.annotation.ResourceDef; +import ca.uhn.fhir.model.dstu2.resource.OperationOutcome; +import ca.uhn.fhir.model.primitive.BoundCodeDt; +import ca.uhn.fhir.util.ElementUtil; + +@ResourceDef(profile = "test-outcome", id = "merge-operation-outcome") +public class TestOutcome extends OperationOutcome { + + private static final long serialVersionUID = 1L; + + @Child(name = "element", order = 0, min = 1, max = 1) + @Description(shortDefinition = "description") + private BoundCodeDt element; + + @Override + public List getAllPopulatedChildElementsOfType(Class theType) { + return ElementUtil.allPopulatedChildElements(theType, element); + } + + public BoundCodeDt getElement() { + return element; + } + + @Override + public boolean isEmpty() { + return super.isEmpty() && ElementUtil.isEmpty(element); + } + + public void setElement(BoundCodeDt theElement) { + element = theElement; + } + +} diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/i391/TestOutcomeTest.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/i391/TestOutcomeTest.java new file mode 100644 index 00000000000..1070a5bbc67 --- /dev/null +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/i391/TestOutcomeTest.java @@ -0,0 +1,45 @@ +package ca.uhn.fhir.parser.i391; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.model.primitive.BoundCodeDt; +import ca.uhn.fhir.parser.IParser; + +/** + * See #391 + */ +public class TestOutcomeTest { + + @Test + public void testParseBoundCodeDtJson() { + IParser jsonParser = FhirContext.forDstu2().newJsonParser(); + + TestOutcome outcome = new TestOutcome(); + outcome.setElement(new BoundCodeDt(new OutcomeBinder(), OutcomeEnum.ITEM1)); + + String xmlResource = jsonParser.encodeResourceToString(outcome); + TestOutcome operationOutcome = jsonParser.parseResource(TestOutcome.class, xmlResource); + + assertNotNull(operationOutcome.getElement()); + assertTrue(operationOutcome.getElement() instanceof BoundCodeDt); + assertEquals(outcome.getElement(), operationOutcome.getElement()); + } + + @Test + public void testParseBoundCodeDtXml() { + IParser xmlParser = FhirContext.forDstu2().newXmlParser(); + + TestOutcome outcome = new TestOutcome(); + outcome.setElement(new BoundCodeDt(new OutcomeBinder(), OutcomeEnum.ITEM1)); + + String xmlResource = xmlParser.encodeResourceToString(outcome); + TestOutcome operationOutcome = xmlParser.parseResource(TestOutcome.class, xmlResource); + + assertNotNull(operationOutcome.getElement()); + assertTrue(operationOutcome.getElement() instanceof BoundCodeDt); + assertEquals(outcome.getElement(), operationOutcome.getElement()); + } +} \ No newline at end of file