Still not passing
This commit is contained in:
parent
5e97109f4c
commit
9aa5e52911
|
@ -1,55 +1,59 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="src" path="src/test/java" output="target/test-classes" including="**/*.java"/>
|
<classpathentry kind="src" path="src/test/java" output="target/test-classes" including="**/*.java"/>
|
||||||
<classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
|
<classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
|
||||||
<classpathentry kind="src" path="src/main/java" including="**/*.java"/>
|
<classpathentry kind="src" path="src/main/java" including="**/*.java"/>
|
||||||
<classpathentry kind="output" path="target/classes"/>
|
<classpathentry kind="output" path="target/classes"/>
|
||||||
<classpathentry kind="var" path="M2_REPO/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2.jar" sourcepath="M2_REPO/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2-sources.jar"/>
|
<classpathentry kind="var" path="M2_REPO/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2.jar" sourcepath="M2_REPO/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2-sources.jar"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
<classpathentry kind="var" path="M2_REPO/commons-codec/commons-codec/1.9/commons-codec-1.9.jar" sourcepath="M2_REPO/commons-codec/commons-codec/1.9/commons-codec-1.9-sources.jar">
|
||||||
<classpathentry kind="var" path="M2_REPO/com/google/code/gson/gson/2.2.4/gson-2.2.4.jar" sourcepath="M2_REPO/com/google/code/gson/gson/2.2.4/gson-2.2.4-sources.jar">
|
|
||||||
<attributes>
|
<attributes>
|
||||||
<attribute value="jar:file:/home/t3903uhn/.m2/repository/com/google/code/gson/gson/2.2.4/gson-2.2.4-javadoc.jar!/" name="javadoc_location"/>
|
<attribute value="jar:file:/Users/james/.m2/repository/commons-codec/commons-codec/1.9/commons-codec-1.9-javadoc.jar!/" name="javadoc_location"/>
|
||||||
</attributes>
|
|
||||||
</classpathentry>
|
|
||||||
<classpathentry kind="var" path="M2_REPO/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0.jar" sourcepath="M2_REPO/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0-sources.jar">
|
|
||||||
<attributes>
|
|
||||||
<attribute value="jar:file:/home/t3903uhn/.m2/repository/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0-javadoc.jar!/" name="javadoc_location"/>
|
|
||||||
</attributes>
|
|
||||||
</classpathentry>
|
|
||||||
<classpathentry kind="var" path="M2_REPO/org/codehaus/woodstox/stax2-api/3.1.1/stax2-api-3.1.1.jar" sourcepath="M2_REPO/org/codehaus/woodstox/stax2-api/3.1.1/stax2-api-3.1.1-sources.jar"/>
|
|
||||||
<classpathentry kind="var" path="M2_REPO/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1.jar" sourcepath="M2_REPO/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1-sources.jar">
|
|
||||||
<attributes>
|
|
||||||
<attribute value="jar:file:/home/t3903uhn/.m2/repository/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1-javadoc.jar!/" name="javadoc_location"/>
|
|
||||||
</attributes>
|
|
||||||
</classpathentry>
|
|
||||||
<classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.7.6/slf4j-api-1.7.6.jar" sourcepath="M2_REPO/org/slf4j/slf4j-api/1.7.6/slf4j-api-1.7.6-sources.jar">
|
|
||||||
<attributes>
|
|
||||||
<attribute value="jar:file:/home/t3903uhn/.m2/repository/org/slf4j/slf4j-api/1.7.6/slf4j-api-1.7.6-javadoc.jar!/" name="javadoc_location"/>
|
|
||||||
</attributes>
|
|
||||||
</classpathentry>
|
|
||||||
<classpathentry kind="var" path="M2_REPO/ch/qos/logback/logback-classic/1.1.1/logback-classic-1.1.1.jar" sourcepath="M2_REPO/ch/qos/logback/logback-classic/1.1.1/logback-classic-1.1.1-sources.jar">
|
|
||||||
<attributes>
|
|
||||||
<attribute value="jar:file:/home/t3903uhn/.m2/repository/ch/qos/logback/logback-classic/1.1.1/logback-classic-1.1.1-javadoc.jar!/" name="javadoc_location"/>
|
|
||||||
</attributes>
|
|
||||||
</classpathentry>
|
|
||||||
<classpathentry kind="var" path="M2_REPO/ch/qos/logback/logback-core/1.1.1/logback-core-1.1.1.jar" sourcepath="M2_REPO/ch/qos/logback/logback-core/1.1.1/logback-core-1.1.1-sources.jar">
|
|
||||||
<attributes>
|
|
||||||
<attribute value="jar:file:/home/t3903uhn/.m2/repository/ch/qos/logback/logback-core/1.1.1/logback-core-1.1.1-javadoc.jar!/" name="javadoc_location"/>
|
|
||||||
</attributes>
|
|
||||||
</classpathentry>
|
|
||||||
<classpathentry kind="var" path="M2_REPO/junit/junit/4.11/junit-4.11.jar" sourcepath="M2_REPO/junit/junit/4.11/junit-4.11-sources.jar">
|
|
||||||
<attributes>
|
|
||||||
<attribute value="jar:file:/home/t3903uhn/.m2/repository/junit/junit/4.11/junit-4.11-javadoc.jar!/" name="javadoc_location"/>
|
|
||||||
</attributes>
|
|
||||||
</classpathentry>
|
|
||||||
<classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar" sourcepath="M2_REPO/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar">
|
|
||||||
<attributes>
|
|
||||||
<attribute value="jar:file:/home/t3903uhn/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-javadoc.jar!/" name="javadoc_location"/>
|
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
<classpathentry kind="var" path="M2_REPO/commons-io/commons-io/1.3.2/commons-io-1.3.2.jar" sourcepath="M2_REPO/commons-io/commons-io/1.3.2/commons-io-1.3.2-sources.jar">
|
<classpathentry kind="var" path="M2_REPO/commons-io/commons-io/1.3.2/commons-io-1.3.2.jar" sourcepath="M2_REPO/commons-io/commons-io/1.3.2/commons-io-1.3.2-sources.jar">
|
||||||
<attributes>
|
<attributes>
|
||||||
<attribute value="jar:file:/home/t3903uhn/.m2/repository/commons-io/commons-io/1.3.2/commons-io-1.3.2-javadoc.jar!/" name="javadoc_location"/>
|
<attribute value="jar:file:/Users/james/.m2/repository/commons-io/commons-io/1.3.2/commons-io-1.3.2-javadoc.jar!/" name="javadoc_location"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
|
<classpathentry kind="var" path="M2_REPO/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1.jar" sourcepath="M2_REPO/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1-sources.jar">
|
||||||
|
<attributes>
|
||||||
|
<attribute value="jar:file:/Users/james/.m2/repository/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1-javadoc.jar!/" name="javadoc_location"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="var" path="M2_REPO/com/google/code/gson/gson/2.2.4/gson-2.2.4.jar" sourcepath="M2_REPO/com/google/code/gson/gson/2.2.4/gson-2.2.4-sources.jar">
|
||||||
|
<attributes>
|
||||||
|
<attribute value="jar:file:/Users/james/.m2/repository/com/google/code/gson/gson/2.2.4/gson-2.2.4-javadoc.jar!/" name="javadoc_location"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar" sourcepath="M2_REPO/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar">
|
||||||
|
<attributes>
|
||||||
|
<attribute value="jar:file:/Users/james/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-javadoc.jar!/" name="javadoc_location"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="var" path="M2_REPO/junit/junit/4.11/junit-4.11.jar" sourcepath="M2_REPO/junit/junit/4.11/junit-4.11-sources.jar">
|
||||||
|
<attributes>
|
||||||
|
<attribute value="jar:file:/Users/james/.m2/repository/junit/junit/4.11/junit-4.11-javadoc.jar!/" name="javadoc_location"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="var" path="M2_REPO/ch/qos/logback/logback-classic/1.1.1/logback-classic-1.1.1.jar" sourcepath="M2_REPO/ch/qos/logback/logback-classic/1.1.1/logback-classic-1.1.1-sources.jar">
|
||||||
|
<attributes>
|
||||||
|
<attribute value="jar:file:/Users/james/.m2/repository/ch/qos/logback/logback-classic/1.1.1/logback-classic-1.1.1-javadoc.jar!/" name="javadoc_location"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="var" path="M2_REPO/ch/qos/logback/logback-core/1.1.1/logback-core-1.1.1.jar" sourcepath="M2_REPO/ch/qos/logback/logback-core/1.1.1/logback-core-1.1.1-sources.jar">
|
||||||
|
<attributes>
|
||||||
|
<attribute value="jar:file:/Users/james/.m2/repository/ch/qos/logback/logback-core/1.1.1/logback-core-1.1.1-javadoc.jar!/" name="javadoc_location"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.7.6/slf4j-api-1.7.6.jar" sourcepath="M2_REPO/org/slf4j/slf4j-api/1.7.6/slf4j-api-1.7.6-sources.jar">
|
||||||
|
<attributes>
|
||||||
|
<attribute value="jar:file:/Users/james/.m2/repository/org/slf4j/slf4j-api/1.7.6/slf4j-api-1.7.6-javadoc.jar!/" name="javadoc_location"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="var" path="M2_REPO/org/codehaus/woodstox/stax2-api/3.1.1/stax2-api-3.1.1.jar" sourcepath="M2_REPO/org/codehaus/woodstox/stax2-api/3.1.1/stax2-api-3.1.1-sources.jar"/>
|
||||||
|
<classpathentry kind="var" path="M2_REPO/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0.jar" sourcepath="M2_REPO/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0-sources.jar">
|
||||||
|
<attributes>
|
||||||
|
<attribute value="jar:file:/Users/james/.m2/repository/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0-javadoc.jar!/" name="javadoc_location"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||||
</classpath>
|
</classpath>
|
|
@ -1,4 +1,3 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
<projectDescription>
|
||||||
<name>hapi-fhir-base</name>
|
<name>hapi-fhir-base</name>
|
||||||
<comment>NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment>
|
<comment>NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment>
|
||||||
|
|
|
@ -1,5 +1,92 @@
|
||||||
#Sun Feb 16 17:15:18 EST 2014
|
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
org.eclipse.jdt.core.compiler.source=1.6
|
org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
|
||||||
|
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
|
||||||
|
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
|
||||||
|
org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||||
|
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.deadCode=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.deprecation=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.nullReference=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.parameterAssignment=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.potentialNullReference=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||||
|
org.eclipse.jdt.core.compiler.source=1.6
|
||||||
|
|
|
@ -29,6 +29,14 @@
|
||||||
<artifactId>woodstox-core-asl</artifactId>
|
<artifactId>woodstox-core-asl</artifactId>
|
||||||
<version>4.2.0</version>
|
<version>4.2.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.codehaus.woodstox</groupId>
|
||||||
|
<artifactId>stax2-api</artifactId>
|
||||||
|
<version>3.1.3</version>
|
||||||
|
</dependency>
|
||||||
|
-->
|
||||||
|
|
||||||
<!-- General -->
|
<!-- General -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -36,6 +44,11 @@
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>3.2.1</version>
|
<version>3.2.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-codec</groupId>
|
||||||
|
<artifactId>commons-codec</artifactId>
|
||||||
|
<version>1.9</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Logging -->
|
<!-- Logging -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -63,7 +76,7 @@
|
||||||
<version>1.3.2</version>
|
<version>1.3.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -1,19 +1,26 @@
|
||||||
package ca.uhn.fhir.context;
|
package ca.uhn.fhir.context;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.IElement;
|
import ca.uhn.fhir.model.api.IElement;
|
||||||
|
import ca.uhn.fhir.util.BeanUtils;
|
||||||
|
|
||||||
public abstract class BaseRuntimeChildDefinition {
|
public abstract class BaseRuntimeChildDefinition {
|
||||||
|
|
||||||
private final Field myField;
|
private final IAccessor myAccessor;
|
||||||
private final int myMin;
|
|
||||||
private final int myMax;
|
|
||||||
private final String myElementName;
|
private final String myElementName;
|
||||||
|
private final Field myField;
|
||||||
|
private final int myMax;
|
||||||
|
private final int myMin;
|
||||||
|
private final IMutator myMutator;
|
||||||
|
|
||||||
BaseRuntimeChildDefinition(Field theField, int theMin, int theMax, String theElementName) throws ConfigurationException {
|
BaseRuntimeChildDefinition(Field theField, int theMin, int theMax, String theElementName) throws ConfigurationException {
|
||||||
super();
|
super();
|
||||||
|
@ -29,34 +36,96 @@ public abstract class BaseRuntimeChildDefinition {
|
||||||
if (isBlank(theElementName)) {
|
if (isBlank(theElementName)) {
|
||||||
throw new ConfigurationException("Element name must not be blank");
|
throw new ConfigurationException("Element name must not be blank");
|
||||||
}
|
}
|
||||||
|
|
||||||
myField=theField;
|
myField = theField;
|
||||||
myMin=theMin;
|
myMin = theMin;
|
||||||
myMax=theMax;
|
myMax = theMax;
|
||||||
myElementName = theElementName;
|
myElementName = theElementName;
|
||||||
|
|
||||||
|
// TODO: handle lists (max>0), and maybe max=0?
|
||||||
|
|
||||||
|
if (myMax == 1) {
|
||||||
|
Class<?> declaringClass = myField.getDeclaringClass();
|
||||||
|
Class<?> targetReturnType = myField.getType();
|
||||||
|
try {
|
||||||
|
final Method accessor = BeanUtils.findAccessor(declaringClass, targetReturnType, myElementName);
|
||||||
|
final Method mutator = BeanUtils.findMutator(declaringClass, targetReturnType, myElementName);
|
||||||
|
myAccessor = new IAccessor() {
|
||||||
|
@Override
|
||||||
|
public List<Object> getValues(Object theTarget) {
|
||||||
|
try {
|
||||||
|
return Collections.singletonList(accessor.invoke(theTarget));
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new ConfigurationException("Failed to get value", e);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new ConfigurationException("Failed to get value", e);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
throw new ConfigurationException("Failed to get value", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
myMutator = new IMutator() {
|
||||||
|
@Override
|
||||||
|
public void addValue(Object theTarget, Object theValue) {
|
||||||
|
try {
|
||||||
|
mutator.invoke(theTarget, theValue);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new ConfigurationException("Failed to get value", e);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new ConfigurationException("Failed to get value", e);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
throw new ConfigurationException("Failed to get value", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
throw new ConfigurationException(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// replace this with an implementation
|
||||||
|
myAccessor = null;
|
||||||
|
myMutator = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IAccessor getAccessor() {
|
||||||
|
return myAccessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract BaseRuntimeElementDefinition<?> getChildByName(String theName);
|
||||||
|
|
||||||
public String getElementName() {
|
public String getElementName() {
|
||||||
return myElementName;
|
return myElementName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMin() {
|
public Field getField() {
|
||||||
return myMin;
|
return myField;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMax() {
|
public int getMax() {
|
||||||
return myMax;
|
return myMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Field getField() {
|
public int getMin() {
|
||||||
return myField;
|
return myMin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IMutator getMutator() {
|
||||||
|
return myMutator;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract Set<String> getValidChildNames();
|
public abstract Set<String> getValidChildNames();
|
||||||
|
|
||||||
public abstract BaseRuntimeElementDefinition<?> getChildByName(String theName);
|
|
||||||
|
|
||||||
abstract void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions);
|
abstract void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions);
|
||||||
|
|
||||||
|
public interface IMutator {
|
||||||
|
void addValue(Object theTarget, Object theValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IAccessor {
|
||||||
|
List<Object> getValues(Object theTarget);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,8 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IComposite
|
||||||
myChildren.add(theNext);
|
myChildren.add(theNext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseRuntimeElementDefinition<?> getChildByNameOrThrowDataFormatException(String theName) throws DataFormatException {
|
public BaseRuntimeChildDefinition getChildByNameOrThrowDataFormatException(String theName) throws DataFormatException {
|
||||||
BaseRuntimeElementDefinition<?> retVal = myNameToChild.get(theName);
|
BaseRuntimeChildDefinition retVal = myNameToChild.get(theName);
|
||||||
if (retVal == null) {
|
if (retVal == null) {
|
||||||
throw new DataFormatException("Unknown child name: " + theName);
|
throw new DataFormatException("Unknown child name: " + theName);
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IComposite
|
||||||
next.sealAndInitialize(theClassToElementDefinitions);
|
next.sealAndInitialize(theClassToElementDefinitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
myNameToChild = new HashMap<String, BaseRuntimeElementDefinition<?>>();
|
myNameToChild = new HashMap<String, BaseRuntimeChildDefinition>();
|
||||||
for (BaseRuntimeChildDefinition next : myChildren) {
|
for (BaseRuntimeChildDefinition next : myChildren) {
|
||||||
for (String nextName : next.getValidChildNames()) {
|
for (String nextName : next.getValidChildNames()) {
|
||||||
if (myNameToChild.containsKey(nextName)) {
|
if (myNameToChild.containsKey(nextName)) {
|
||||||
|
|
|
@ -22,6 +22,16 @@ public abstract class BaseRuntimeElementDefinition<T extends IElement> {
|
||||||
return myName;
|
return myName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T newInstance() {
|
||||||
|
try {
|
||||||
|
return getImplementingClass().newInstance();
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
throw new ConfigurationException("Failed to instantiate type:"+getImplementingClass().getName(), e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new ConfigurationException("Failed to instantiate type:"+getImplementingClass().getName(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Class<? extends T> getImplementingClass() {
|
public Class<? extends T> getImplementingClass() {
|
||||||
return myImplementingClass;
|
return myImplementingClass;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package ca.uhn.fhir.context;
|
package ca.uhn.fhir.context;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -8,9 +8,12 @@ import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.Stack;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.CodeableConceptElement;
|
import ca.uhn.fhir.model.api.CodeableConceptElement;
|
||||||
import ca.uhn.fhir.model.api.ICodeEnum;
|
import ca.uhn.fhir.model.api.ICodeEnum;
|
||||||
|
@ -24,10 +27,12 @@ import ca.uhn.fhir.model.api.ResourceReference;
|
||||||
import ca.uhn.fhir.model.api.annotation.Child;
|
import ca.uhn.fhir.model.api.annotation.Child;
|
||||||
import ca.uhn.fhir.model.api.annotation.ChildResource;
|
import ca.uhn.fhir.model.api.annotation.ChildResource;
|
||||||
import ca.uhn.fhir.model.api.annotation.Choice;
|
import ca.uhn.fhir.model.api.annotation.Choice;
|
||||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
|
||||||
import ca.uhn.fhir.model.api.annotation.CodeTableDef;
|
import ca.uhn.fhir.model.api.annotation.CodeTableDef;
|
||||||
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
import ca.uhn.fhir.model.api.annotation.Narrative;
|
||||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||||
import ca.uhn.fhir.model.datatype.ICodedDatatype;
|
import ca.uhn.fhir.model.datatype.ICodedDatatype;
|
||||||
|
import ca.uhn.fhir.model.datatype.NarrativeDt;
|
||||||
|
|
||||||
class ModelScanner {
|
class ModelScanner {
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ModelScanner.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ModelScanner.class);
|
||||||
|
@ -35,6 +40,7 @@ class ModelScanner {
|
||||||
private Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> myClassToElementDefinitions = new HashMap<Class<? extends IElement>, BaseRuntimeElementDefinition<?>>();
|
private Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> myClassToElementDefinitions = new HashMap<Class<? extends IElement>, BaseRuntimeElementDefinition<?>>();
|
||||||
private Map<String, RuntimeResourceDefinition> myNameToResourceDefinitions = new HashMap<String, RuntimeResourceDefinition>();
|
private Map<String, RuntimeResourceDefinition> myNameToResourceDefinitions = new HashMap<String, RuntimeResourceDefinition>();
|
||||||
private Set<Class<? extends IElement>> myScanAlso = new HashSet<Class<? extends IElement>>();
|
private Set<Class<? extends IElement>> myScanAlso = new HashSet<Class<? extends IElement>>();
|
||||||
|
private Set<Class<? extends ICodeEnum>> myScanAlsoCodeTable = new HashSet<Class<? extends ICodeEnum>>();
|
||||||
|
|
||||||
// private Map<String, RuntimeResourceDefinition>
|
// private Map<String, RuntimeResourceDefinition>
|
||||||
// myNameToDatatypeDefinitions = new HashMap<String,
|
// myNameToDatatypeDefinitions = new HashMap<String,
|
||||||
|
@ -47,11 +53,13 @@ class ModelScanner {
|
||||||
ModelScanner(Class<? extends IResource>... theResourceTypes) throws ConfigurationException {
|
ModelScanner(Class<? extends IResource>... theResourceTypes) throws ConfigurationException {
|
||||||
|
|
||||||
Set<Class<? extends IElement>> toScan = new HashSet<Class<? extends IElement>>(Arrays.asList(theResourceTypes));
|
Set<Class<? extends IElement>> toScan = new HashSet<Class<? extends IElement>>(Arrays.asList(theResourceTypes));
|
||||||
|
toScan.add(NarrativeDt.class);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
for (Class<? extends IElement> nextClass : toScan) {
|
for (Class<? extends IElement> nextClass : toScan) {
|
||||||
scan(nextClass);
|
scan(nextClass);
|
||||||
}
|
}
|
||||||
for (Iterator<Class<? extends IElement>> iter = myScanAlso.iterator(); iter.hasNext(); ) {
|
for (Iterator<Class<? extends IElement>> iter = myScanAlso.iterator(); iter.hasNext();) {
|
||||||
if (myClassToElementDefinitions.containsKey(iter.next())) {
|
if (myClassToElementDefinitions.containsKey(iter.next())) {
|
||||||
iter.remove();
|
iter.remove();
|
||||||
}
|
}
|
||||||
|
@ -60,11 +68,13 @@ class ModelScanner {
|
||||||
toScan.addAll(myScanAlso);
|
toScan.addAll(myScanAlso);
|
||||||
myScanAlso.clear();
|
myScanAlso.clear();
|
||||||
} while (!myScanAlso.isEmpty());
|
} while (!myScanAlso.isEmpty());
|
||||||
|
|
||||||
for (BaseRuntimeElementDefinition<?> next : myClassToElementDefinitions.values()) {
|
for (BaseRuntimeElementDefinition<?> next : myClassToElementDefinitions.values()) {
|
||||||
next.sealAndInitialize(myClassToElementDefinitions);
|
next.sealAndInitialize(myClassToElementDefinitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ourLog.info("Done scanning FHIR library, found {} model entries", myClassToElementDefinitions.size());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String scan(Class<? extends IElement> theClass) throws ConfigurationException {
|
private String scan(Class<? extends IElement> theClass) throws ConfigurationException {
|
||||||
|
@ -76,8 +86,7 @@ class ModelScanner {
|
||||||
ResourceDef resourceDefinition = theClass.getAnnotation(ResourceDef.class);
|
ResourceDef resourceDefinition = theClass.getAnnotation(ResourceDef.class);
|
||||||
if (resourceDefinition != null) {
|
if (resourceDefinition != null) {
|
||||||
if (!IResource.class.isAssignableFrom(theClass)) {
|
if (!IResource.class.isAssignableFrom(theClass)) {
|
||||||
throw new ConfigurationException("Resource type contains a @" + ResourceDef.class.getSimpleName() + " annotation but does not implement " + IResource.class.getCanonicalName()
|
throw new ConfigurationException("Resource type contains a @" + ResourceDef.class.getSimpleName() + " annotation but does not implement " + IResource.class.getCanonicalName() + ": " + theClass.getCanonicalName());
|
||||||
+ ": " + theClass.getCanonicalName());
|
|
||||||
}
|
}
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Class<? extends IResource> resClass = (Class<? extends IResource>) theClass;
|
Class<? extends IResource> resClass = (Class<? extends IResource>) theClass;
|
||||||
|
@ -91,12 +100,11 @@ class ModelScanner {
|
||||||
Class<? extends ICompositeDatatype> resClass = (Class<? extends ICompositeDatatype>) theClass;
|
Class<? extends ICompositeDatatype> resClass = (Class<? extends ICompositeDatatype>) theClass;
|
||||||
return scanCompositeDatatype(resClass, datatypeDefinition);
|
return scanCompositeDatatype(resClass, datatypeDefinition);
|
||||||
} else if (IPrimitiveDatatype.class.isAssignableFrom(theClass)) {
|
} else if (IPrimitiveDatatype.class.isAssignableFrom(theClass)) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
Class<? extends IPrimitiveDatatype> resClass = (Class<? extends IPrimitiveDatatype>) theClass;
|
Class<? extends IPrimitiveDatatype> resClass = (Class<? extends IPrimitiveDatatype>) theClass;
|
||||||
return scanPrimitiveDatatype(resClass, datatypeDefinition);
|
return scanPrimitiveDatatype(resClass, datatypeDefinition);
|
||||||
} else {
|
} else {
|
||||||
throw new ConfigurationException("Resource type contains a @" + DatatypeDef.class.getSimpleName() + " annotation but does not implement " + IDatatype.class.getCanonicalName() + ": "
|
throw new ConfigurationException("Resource type contains a @" + DatatypeDef.class.getSimpleName() + " annotation but does not implement " + IDatatype.class.getCanonicalName() + ": " + theClass.getCanonicalName());
|
||||||
+ theClass.getCanonicalName());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,13 +115,11 @@ class ModelScanner {
|
||||||
Class<? extends ICodeEnum> resClass = (Class<? extends ICodeEnum>) theClass;
|
Class<? extends ICodeEnum> resClass = (Class<? extends ICodeEnum>) theClass;
|
||||||
return scanCodeTable(resClass, codeTableDefinition);
|
return scanCodeTable(resClass, codeTableDefinition);
|
||||||
} else {
|
} else {
|
||||||
throw new ConfigurationException("Resource type contains a @" + CodeTableDef.class.getSimpleName() + " annotation but does not implement " + ICodeEnum.class.getCanonicalName() + ": "
|
throw new ConfigurationException("Resource type contains a @" + CodeTableDef.class.getSimpleName() + " annotation but does not implement " + ICodeEnum.class.getCanonicalName() + ": " + theClass.getCanonicalName());
|
||||||
+ theClass.getCanonicalName());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ConfigurationException("Resource type does not contain a @" + ResourceDef.class.getSimpleName() + " annotation or a @" + DatatypeDef.class.getSimpleName() + " annotation: "
|
throw new ConfigurationException("Resource type does not contain a @" + ResourceDef.class.getSimpleName() + " annotation or a @" + DatatypeDef.class.getSimpleName() + " annotation: " + theClass.getCanonicalName());
|
||||||
+ theClass.getCanonicalName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String scanCompositeDatatype(Class<? extends ICompositeDatatype> theClass, DatatypeDef theDatatypeDefinition) {
|
private String scanCompositeDatatype(Class<? extends ICompositeDatatype> theClass, DatatypeDef theDatatypeDefinition) {
|
||||||
|
@ -126,8 +132,7 @@ class ModelScanner {
|
||||||
|
|
||||||
if (myNameToResourceDefinitions.containsKey(resourceName)) {
|
if (myNameToResourceDefinitions.containsKey(resourceName)) {
|
||||||
if (!myNameToResourceDefinitions.get(resourceName).getImplementingClass().equals(theClass)) {
|
if (!myNameToResourceDefinitions.get(resourceName).getImplementingClass().equals(theClass)) {
|
||||||
throw new ConfigurationException("Detected duplicate element name '" + resourceName + "' in types '" + theClass.getCanonicalName() + "' and '"
|
throw new ConfigurationException("Detected duplicate element name '" + resourceName + "' in types '" + theClass.getCanonicalName() + "' and '" + myNameToResourceDefinitions.get(resourceName).getImplementingClass() + "'");
|
||||||
+ myNameToResourceDefinitions.get(resourceName).getImplementingClass() + "'");
|
|
||||||
}
|
}
|
||||||
return resourceName;
|
return resourceName;
|
||||||
}
|
}
|
||||||
|
@ -150,8 +155,7 @@ class ModelScanner {
|
||||||
|
|
||||||
if (myNameToResourceDefinitions.containsKey(resourceName)) {
|
if (myNameToResourceDefinitions.containsKey(resourceName)) {
|
||||||
if (!myNameToResourceDefinitions.get(resourceName).getImplementingClass().equals(theClass)) {
|
if (!myNameToResourceDefinitions.get(resourceName).getImplementingClass().equals(theClass)) {
|
||||||
throw new ConfigurationException("Detected duplicate element name '" + resourceName + "' in types '" + theClass.getCanonicalName() + "' and '"
|
throw new ConfigurationException("Detected duplicate element name '" + resourceName + "' in types '" + theClass.getCanonicalName() + "' and '" + myNameToResourceDefinitions.get(resourceName).getImplementingClass() + "'");
|
||||||
+ myNameToResourceDefinitions.get(resourceName).getImplementingClass() + "'");
|
|
||||||
}
|
}
|
||||||
return resourceName;
|
return resourceName;
|
||||||
}
|
}
|
||||||
|
@ -172,8 +176,7 @@ class ModelScanner {
|
||||||
|
|
||||||
if (myNameToResourceDefinitions.containsKey(resourceName)) {
|
if (myNameToResourceDefinitions.containsKey(resourceName)) {
|
||||||
if (!myNameToResourceDefinitions.get(resourceName).getImplementingClass().equals(theClass)) {
|
if (!myNameToResourceDefinitions.get(resourceName).getImplementingClass().equals(theClass)) {
|
||||||
throw new ConfigurationException("Detected duplicate element name '" + resourceName + "' in types '" + theClass.getCanonicalName() + "' and '"
|
throw new ConfigurationException("Detected duplicate element name '" + resourceName + "' in types '" + theClass.getCanonicalName() + "' and '" + myNameToResourceDefinitions.get(resourceName).getImplementingClass() + "'");
|
||||||
+ myNameToResourceDefinitions.get(resourceName).getImplementingClass() + "'");
|
|
||||||
}
|
}
|
||||||
return resourceName;
|
return resourceName;
|
||||||
}
|
}
|
||||||
|
@ -187,10 +190,52 @@ class ModelScanner {
|
||||||
return resourceName;
|
return resourceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private void scanCompositeElementForChildren(Class<? extends ICompositeElement> theClass, BaseRuntimeElementCompositeDefinition<?> theDefinition) {
|
private void scanCompositeElementForChildren(Class<? extends ICompositeElement> theClass, BaseRuntimeElementCompositeDefinition<?> theDefinition) {
|
||||||
Set<String> elementNames = new HashSet<String>();
|
Set<String> elementNames = new HashSet<String>();
|
||||||
Map<Integer, BaseRuntimeChildDefinition> orderToElementDef = new HashMap<Integer, BaseRuntimeChildDefinition>();
|
TreeMap<Integer, BaseRuntimeChildDefinition> orderToElementDef = new TreeMap<Integer, BaseRuntimeChildDefinition>();
|
||||||
for (Field next : theClass.getFields()) {
|
|
||||||
|
LinkedList<Class<? extends ICompositeElement>> classes = new LinkedList<Class<? extends ICompositeElement>>();
|
||||||
|
Class<? extends ICompositeElement> current = theClass;
|
||||||
|
do {
|
||||||
|
classes.push(current);
|
||||||
|
if (ICompositeElement.class.isAssignableFrom(current.getSuperclass())) {
|
||||||
|
current = (Class<? extends ICompositeElement>) current.getSuperclass();
|
||||||
|
}else {
|
||||||
|
current = null;
|
||||||
|
}
|
||||||
|
}while (current != null);
|
||||||
|
|
||||||
|
for (Class<? extends ICompositeElement> next : classes) {
|
||||||
|
scanCompositeElementForChildren(next, theDefinition, elementNames, orderToElementDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
dealwithnegative
|
||||||
|
|
||||||
|
for (int i = 0; i < orderToElementDef.size(); i++) {
|
||||||
|
if (!orderToElementDef.containsKey(i)) {
|
||||||
|
throw new ConfigurationException("Type '" + theClass.getCanonicalName() + "' does not have a child with order " + i + " (in other words, there are gaps between specified child orders)");
|
||||||
|
}
|
||||||
|
BaseRuntimeChildDefinition next = orderToElementDef.get(i);
|
||||||
|
theDefinition.addChild(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scanCompositeElementForChildren(Class<? extends ICompositeElement> theClass, BaseRuntimeElementCompositeDefinition<?> theDefinition, Set<String> elementNames, TreeMap<Integer, BaseRuntimeChildDefinition> orderToElementDef) {
|
||||||
|
for (Field next : theClass.getDeclaredFields()) {
|
||||||
|
|
||||||
|
Narrative hasNarrative = next.getAnnotation(Narrative.class);
|
||||||
|
if (hasNarrative != null) {
|
||||||
|
RuntimeChildNarrativeDefinition def;
|
||||||
|
try {
|
||||||
|
def = new RuntimeChildNarrativeDefinition(next, hasNarrative.name());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ConfigurationException("Failed to find narrative field", e);
|
||||||
|
}
|
||||||
|
theDefinition.addChild(def);
|
||||||
|
}
|
||||||
|
|
||||||
Child element = next.getAnnotation(Child.class);
|
Child element = next.getAnnotation(Child.class);
|
||||||
if (element == null) {
|
if (element == null) {
|
||||||
ourLog.debug("Ignoring non-type field: " + next.getName());
|
ourLog.debug("Ignoring non-type field: " + next.getName());
|
||||||
|
@ -202,6 +247,10 @@ class ModelScanner {
|
||||||
int min = element.min();
|
int min = element.min();
|
||||||
int max = element.max();
|
int max = element.max();
|
||||||
|
|
||||||
|
while (order == Child.ORDER_UNKNOWN && orderToElementDef.containsKey(order)) {
|
||||||
|
order--;
|
||||||
|
}
|
||||||
|
|
||||||
Choice choiceAttr = element.choice();
|
Choice choiceAttr = element.choice();
|
||||||
List<Class<? extends IElement>> choiceTypes = new ArrayList<Class<? extends IElement>>();
|
List<Class<? extends IElement>> choiceTypes = new ArrayList<Class<? extends IElement>>();
|
||||||
for (Class<? extends IElement> nextChoiceType : choiceAttr.types()) {
|
for (Class<? extends IElement> nextChoiceType : choiceAttr.types()) {
|
||||||
|
@ -230,8 +279,7 @@ class ModelScanner {
|
||||||
* Child is a resource reference
|
* Child is a resource reference
|
||||||
*/
|
*/
|
||||||
if (resRefAnnotation == null) {
|
if (resRefAnnotation == null) {
|
||||||
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is a resource reference but does not have a @"
|
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is a resource reference but does not have a @" + ChildResource.class.getSimpleName() + " annotation");
|
||||||
+ ChildResource.class.getSimpleName() + " annotation");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Class<? extends IResource>[] refType = resRefAnnotation.types();
|
Class<? extends IResource>[] refType = resRefAnnotation.types();
|
||||||
|
@ -242,12 +290,10 @@ class ModelScanner {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (resRefAnnotation != null) {
|
if (resRefAnnotation != null) {
|
||||||
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is not a resource reference but has a @"
|
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is not a resource reference but has a @" + ChildResource.class.getSimpleName() + " annotation");
|
||||||
+ ChildResource.class.getSimpleName() + " annotation");
|
|
||||||
}
|
}
|
||||||
if (!IDatatype.class.isAssignableFrom(next.getType())) {
|
if (!IDatatype.class.isAssignableFrom(next.getType())) {
|
||||||
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is not a resource reference and is not an instance of type "
|
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is not a resource reference and is not an instance of type " + IDatatype.class.getName());
|
||||||
+ IDatatype.class.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -264,11 +310,10 @@ class ModelScanner {
|
||||||
CodeableConceptElement concept = next.getAnnotation(CodeableConceptElement.class);
|
CodeableConceptElement concept = next.getAnnotation(CodeableConceptElement.class);
|
||||||
if (concept != null) {
|
if (concept != null) {
|
||||||
if (!ICodedDatatype.class.isAssignableFrom(nextDatatype)) {
|
if (!ICodedDatatype.class.isAssignableFrom(nextDatatype)) {
|
||||||
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is marked as @" + CodeableConceptElement.class.getCanonicalName()
|
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is marked as @" + CodeableConceptElement.class.getCanonicalName() + " but type is not a subtype of " + ICodedDatatype.class.getName());
|
||||||
+ " but type is not a subtype of " + ICodedDatatype.class.getName());
|
|
||||||
} else {
|
} else {
|
||||||
Class<? extends ICodeEnum> type = concept.type();
|
Class<? extends ICodeEnum> type = concept.type();
|
||||||
myScanAlso.add(type);
|
myScanAlsoCodeTable.add(type);
|
||||||
def.setCodeType(type);
|
def.setCodeType(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,8 +325,11 @@ class ModelScanner {
|
||||||
// Class<? extends ICodeEnum> codeType = concept.type();
|
// Class<? extends ICodeEnum> codeType = concept.type();
|
||||||
// String codeTableName = scanCodeTable(codeType);
|
// String codeTableName = scanCodeTable(codeType);
|
||||||
// @SuppressWarnings("unchecked")
|
// @SuppressWarnings("unchecked")
|
||||||
// String datatypeName = scan((Class<? extends IDatatype>) next.getType());
|
// String datatypeName = scan((Class<? extends IDatatype>)
|
||||||
// RuntimeChildCompositeDatatypeDefinition def = new RuntimeChildCompositeDatatypeDefinition(next, elementName, datatypeName, min, max, codeTableName);
|
// next.getType());
|
||||||
|
// RuntimeChildCompositeDatatypeDefinition def = new
|
||||||
|
// RuntimeChildCompositeDatatypeDefinition(next, elementName,
|
||||||
|
// datatypeName, min, max, codeTableName);
|
||||||
// orderToElementDef.put(order, def);
|
// orderToElementDef.put(order, def);
|
||||||
// } else {
|
// } else {
|
||||||
// @SuppressWarnings("unchecked")
|
// @SuppressWarnings("unchecked")
|
||||||
|
@ -291,16 +339,6 @@ class ModelScanner {
|
||||||
|
|
||||||
elementNames.add(elementName);
|
elementNames.add(elementName);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < orderToElementDef.size(); i++) {
|
|
||||||
if (!orderToElementDef.containsKey(i)) {
|
|
||||||
throw new ConfigurationException("Type '" + theClass.getCanonicalName() + "' does not have a child with order " + i
|
|
||||||
+ " (in other words, there are gaps between specified child orders)");
|
|
||||||
}
|
|
||||||
BaseRuntimeChildDefinition next = orderToElementDef.get(i);
|
|
||||||
theDefinition.addChild(next);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String scanCodeTable(Class<? extends ICodeEnum> theCodeType, CodeTableDef theCodeTableDefinition) {
|
private String scanCodeTable(Class<? extends ICodeEnum> theCodeType, CodeTableDef theCodeTableDefinition) {
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package ca.uhn.fhir.context;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.datatype.NarrativeDt;
|
||||||
|
|
||||||
|
public class RuntimeChildNarrativeDefinition extends BaseRuntimeChildDatatypeDefinition {
|
||||||
|
|
||||||
|
public RuntimeChildNarrativeDefinition(Field theField, String theElementName) {
|
||||||
|
super(theField, theElementName, 1, 1, NarrativeDt.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -8,16 +8,6 @@ public class RuntimeResourceDefinition extends BaseRuntimeElementCompositeDefini
|
||||||
super(theName, theClass);
|
super(theName, theClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IResource newInstance() {
|
|
||||||
try {
|
|
||||||
return getImplementingClass().newInstance();
|
|
||||||
} catch (InstantiationException e) {
|
|
||||||
throw new ConfigurationException("Failed to instantiate type:"+getImplementingClass().getName(), e);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
throw new ConfigurationException("Failed to instantiate type:"+getImplementingClass().getName(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum getChildType() {
|
public ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum getChildType() {
|
||||||
return ChildTypeEnum.RESOURCE;
|
return ChildTypeEnum.RESOURCE;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package ca.uhn.fhir.model.api;
|
package ca.uhn.fhir.model.api;
|
||||||
|
|
||||||
|
|
||||||
public class BasePrimitiveDatatype extends BaseDatatype implements IPrimitiveDatatype {
|
public abstract class BasePrimitiveDatatype<T> extends BaseDatatype implements IPrimitiveDatatype<T> {
|
||||||
|
|
||||||
|
// nothing yet
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
package ca.uhn.fhir.model.api;
|
package ca.uhn.fhir.model.api;
|
||||||
|
|
||||||
public interface ICodeEnum extends IPrimitiveDatatype {
|
public interface ICodeEnum {
|
||||||
|
// nothing yet
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
package ca.uhn.fhir.model.api;
|
package ca.uhn.fhir.model.api;
|
||||||
|
|
||||||
public interface IPrimitiveDatatype extends IDatatype {
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
|
||||||
|
public interface IPrimitiveDatatype<T> extends IDatatype {
|
||||||
|
|
||||||
|
void setValueAsString(String theValue) throws DataFormatException;
|
||||||
|
|
||||||
|
String getValueAsString();
|
||||||
|
|
||||||
|
T getValue();
|
||||||
|
|
||||||
|
void setValue(T theValue) throws DataFormatException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package ca.uhn.fhir.model.api.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(value= {ElementType.FIELD})
|
||||||
|
public @interface IsIdentifier {
|
||||||
|
|
||||||
|
// nothing
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package ca.uhn.fhir.model.api.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(value= {ElementType.FIELD})
|
||||||
|
public @interface Narrative {
|
||||||
|
|
||||||
|
String name();
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,41 @@
|
||||||
package ca.uhn.fhir.model.datatype;
|
package ca.uhn.fhir.model.datatype;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
|
import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
|
||||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
|
||||||
@DatatypeDef(name="base64Binary")
|
@DatatypeDef(name = "base64Binary")
|
||||||
public class Base64BinaryDt extends BasePrimitiveDatatype {
|
public class Base64BinaryDt extends BasePrimitiveDatatype<byte[]> {
|
||||||
|
|
||||||
private byte[] myValue;
|
private byte[] myValue;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValueAsString(String theValue) {
|
||||||
|
if (theValue == null) {
|
||||||
|
myValue = null;
|
||||||
|
} else {
|
||||||
|
myValue = Base64.decodeBase64(theValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValueAsString() {
|
||||||
|
if (myValue == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return Base64.encodeBase64String(myValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(byte[] theValue) {
|
||||||
|
myValue = theValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getValue() {
|
||||||
|
return myValue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
package ca.uhn.fhir.model.datatype;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.time.FastDateFormat;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
|
||||||
|
public abstract class BaseDateTimeDt extends BasePrimitiveDatatype<Date> {
|
||||||
|
|
||||||
|
private static final FastDateFormat ourYearFormat = FastDateFormat.getInstance("yyyy");
|
||||||
|
private static final FastDateFormat ourYearMonthDayFormat = FastDateFormat.getInstance("yyyy-MM-dd");
|
||||||
|
private static final FastDateFormat ourYearMonthFormat = FastDateFormat.getInstance("yyyy-MM");
|
||||||
|
private static final FastDateFormat ourYearMonthDayTimeFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss");
|
||||||
|
private static final FastDateFormat ourYearMonthDayTimeZoneFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssX");
|
||||||
|
|
||||||
|
private int myPrecision = Calendar.SECOND;
|
||||||
|
private Date myValue;
|
||||||
|
private TimeZone myTimeZone;
|
||||||
|
private boolean myTimeZoneZulu = false;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the precision for this datatype using field values from
|
||||||
|
* {@link Calendar}, such as {@link Calendar#MONTH}. Default is
|
||||||
|
* {@link Calendar#DAY_OF_MONTH}
|
||||||
|
*
|
||||||
|
* @see #setPrecision(int)
|
||||||
|
*/
|
||||||
|
public int getPrecision() {
|
||||||
|
return myPrecision;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getValue() {
|
||||||
|
return myValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValueAsString() {
|
||||||
|
if (myValue == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
switch (myPrecision) {
|
||||||
|
case Calendar.DAY_OF_MONTH:
|
||||||
|
return ourYearMonthDayFormat.format(myValue);
|
||||||
|
case Calendar.MONTH:
|
||||||
|
return ourYearMonthFormat.format(myValue);
|
||||||
|
case Calendar.YEAR:
|
||||||
|
return ourYearFormat.format(myValue);
|
||||||
|
case Calendar.SECOND:
|
||||||
|
if (myTimeZoneZulu) {
|
||||||
|
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
|
||||||
|
cal.setTime(myValue);
|
||||||
|
return ourYearMonthDayTimeZoneFormat.format(cal)+"Z";
|
||||||
|
} else if (myTimeZone != null) {
|
||||||
|
GregorianCalendar cal = new GregorianCalendar(myTimeZone);
|
||||||
|
cal.setTime(myValue);
|
||||||
|
return ourYearMonthDayTimeZoneFormat.format(cal);
|
||||||
|
} else {
|
||||||
|
return ourYearMonthDayTimeFormat.format(myValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Invalid precition (this is a HAPI bug, shouldn't happen): " + myPrecision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the precision for this datatype using field values from
|
||||||
|
* {@link Calendar}. Valid values are:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link Calendar#SECOND}
|
||||||
|
* <li>{@link Calendar#DAY_OF_MONTH}
|
||||||
|
* <li>{@link Calendar#MONTH}
|
||||||
|
* <li>{@link Calendar#YEAR}
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @throws DataFormatException
|
||||||
|
*/
|
||||||
|
public void setPrecision(int thePrecision) throws DataFormatException {
|
||||||
|
switch (thePrecision) {
|
||||||
|
case Calendar.DAY_OF_MONTH:
|
||||||
|
case Calendar.MONTH:
|
||||||
|
case Calendar.YEAR:
|
||||||
|
case Calendar.SECOND:
|
||||||
|
myPrecision = thePrecision;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new DataFormatException("Invalid precision value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(Date theValue) throws DataFormatException {
|
||||||
|
myValue = theValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValueAsString(String theValue) throws DataFormatException {
|
||||||
|
try {
|
||||||
|
if (theValue == null) {
|
||||||
|
myValue = null;
|
||||||
|
clearTimeZone();
|
||||||
|
} else if (theValue.length() == 4 && isPrecisionAllowed(Calendar.YEAR)) {
|
||||||
|
setValue(ourYearFormat.parse(theValue));
|
||||||
|
setPrecision(Calendar.YEAR);
|
||||||
|
clearTimeZone();
|
||||||
|
} else if (theValue.length() == 7 && isPrecisionAllowed(Calendar.MONTH)) {
|
||||||
|
setValue(ourYearMonthFormat.parse(theValue));
|
||||||
|
setPrecision(Calendar.MONTH);
|
||||||
|
clearTimeZone();
|
||||||
|
} else if (theValue.length() == 9 && isPrecisionAllowed(Calendar.DAY_OF_MONTH)) {
|
||||||
|
setValue(ourYearMonthDayFormat.parse(theValue));
|
||||||
|
setPrecision(Calendar.DAY_OF_MONTH);
|
||||||
|
clearTimeZone();
|
||||||
|
} else if ((theValue.length() == 18 || theValue.length() == 19 || theValue.length() == 24) && isPrecisionAllowed(Calendar.SECOND)) {
|
||||||
|
ourYearMonthDayTimeZoneFormat.parse(theValue);
|
||||||
|
setPrecision(Calendar.SECOND);
|
||||||
|
clearTimeZone();
|
||||||
|
if (theValue.length() == 19 && theValue.charAt(theValue.length()-1) == 'Z') {
|
||||||
|
myTimeZoneZulu = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new DataFormatException("Invalid date string");
|
||||||
|
}
|
||||||
|
} catch (ParseException e) {
|
||||||
|
throw new DataFormatException("Invalid date string");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeZone getTimeZone() {
|
||||||
|
return myTimeZone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeZone(TimeZone theTimeZone) {
|
||||||
|
myTimeZone = theTimeZone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTimeZoneZulu() {
|
||||||
|
return myTimeZoneZulu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeZoneZulu(boolean theTimeZoneZulu) {
|
||||||
|
myTimeZoneZulu = theTimeZoneZulu;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearTimeZone() {
|
||||||
|
myTimeZone=null;
|
||||||
|
myTimeZoneZulu=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be implemented by subclasses to indicate whether the given precision is allowed by this type
|
||||||
|
*/
|
||||||
|
abstract boolean isPrecisionAllowed(int thePrecision);
|
||||||
|
|
||||||
|
}
|
|
@ -2,10 +2,37 @@ package ca.uhn.fhir.model.datatype;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
|
import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
|
||||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
|
||||||
@DatatypeDef(name="boolean")
|
@DatatypeDef(name="boolean")
|
||||||
public class BooleanDt extends BasePrimitiveDatatype {
|
public class BooleanDt extends BasePrimitiveDatatype<Boolean> {
|
||||||
|
|
||||||
private boolean myValue;
|
private Boolean myValue;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValueAsString(String theValue) throws DataFormatException {
|
||||||
|
if ("true".equals(theValue)) {
|
||||||
|
myValue = Boolean.TRUE;
|
||||||
|
}else if ("false".equals(theValue)) {
|
||||||
|
myValue=Boolean.FALSE;
|
||||||
|
}else {
|
||||||
|
throw new DataFormatException("Invalid boolean string: '" + theValue + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValueAsString() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(Boolean theValue) {
|
||||||
|
myValue = theValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean getValue() {
|
||||||
|
return myValue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,39 @@ package ca.uhn.fhir.model.datatype;
|
||||||
import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
|
import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
|
||||||
import ca.uhn.fhir.model.api.ICodeEnum;
|
import ca.uhn.fhir.model.api.ICodeEnum;
|
||||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
|
||||||
@DatatypeDef(name="code")
|
@DatatypeDef(name = "code")
|
||||||
public class CodeDt<T extends ICodeEnum> extends BasePrimitiveDatatype implements ICodedDatatype {
|
public class CodeDt<T extends ICodeEnum> extends BasePrimitiveDatatype<String> implements ICodedDatatype {
|
||||||
|
|
||||||
|
private String myValue;
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return myValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String theValue) throws DataFormatException {
|
||||||
|
if (theValue == null) {
|
||||||
|
myValue = null;
|
||||||
|
} else {
|
||||||
|
if (theValue.length() == 0) {
|
||||||
|
throw new DataFormatException("Value can not be empty");
|
||||||
|
}
|
||||||
|
if (Character.isWhitespace(theValue.charAt(0)) || Character.isWhitespace(theValue.charAt(theValue.length()-1))){
|
||||||
|
throw new DataFormatException("Value must not contain trailing or leading whitespace");
|
||||||
|
}
|
||||||
|
myValue = theValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValueAsString(String theValue) throws DataFormatException {
|
||||||
|
setValue(theValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValueAsString() {
|
||||||
|
return getValue();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,23 @@
|
||||||
package ca.uhn.fhir.model.datatype;
|
package ca.uhn.fhir.model.datatype;
|
||||||
|
|
||||||
import java.util.GregorianCalendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.BaseDatatype;
|
|
||||||
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
|
||||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
|
||||||
@DatatypeDef(name="date")
|
@DatatypeDef(name = "date")
|
||||||
public class DateDt extends BaseDatatype implements IPrimitiveDatatype {
|
public class DateDt extends BaseDateTimeDt {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean isPrecisionAllowed(int thePrecision) {
|
||||||
|
switch (thePrecision) {
|
||||||
|
case Calendar.YEAR:
|
||||||
|
case Calendar.MONTH:
|
||||||
|
case Calendar.DATE:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private GregorianCalendar myValue;
|
|
||||||
private int myPrecision;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,23 @@
|
||||||
package ca.uhn.fhir.model.datatype;
|
package ca.uhn.fhir.model.datatype;
|
||||||
|
|
||||||
import java.util.GregorianCalendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
|
|
||||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
|
||||||
@DatatypeDef(name="dateTime")
|
@DatatypeDef(name = "dateTime")
|
||||||
public class DateTimeDt extends BasePrimitiveDatatype {
|
public class DateTimeDt extends BaseDateTimeDt {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean isPrecisionAllowed(int thePrecision) {
|
||||||
|
switch (thePrecision) {
|
||||||
|
case Calendar.YEAR:
|
||||||
|
case Calendar.MONTH:
|
||||||
|
case Calendar.DATE:
|
||||||
|
case Calendar.SECOND:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private GregorianCalendar myValue;
|
|
||||||
|
|
||||||
private int myPrecision;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,46 @@ import java.math.BigDecimal;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
|
import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
|
||||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
|
||||||
@DatatypeDef(name="decimal")
|
@DatatypeDef(name = "decimal")
|
||||||
public class DecimalDt extends BasePrimitiveDatatype {
|
public class DecimalDt extends BasePrimitiveDatatype<BigDecimal> {
|
||||||
|
|
||||||
private BigDecimal myValue;
|
private BigDecimal myValue;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValueAsString(String theValue) throws DataFormatException {
|
||||||
|
if (theValue == null) {
|
||||||
|
myValue = null;
|
||||||
|
} else {
|
||||||
|
myValue = new BigDecimal(theValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValueAsString() {
|
||||||
|
if (myValue == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return myValue.toPlainString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal getValue() {
|
||||||
|
return myValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(BigDecimal theValue) throws DataFormatException {
|
||||||
|
myValue = theValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValueAsInteger(int theValue) {
|
||||||
|
myValue = new BigDecimal(theValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValueAsInteger() {
|
||||||
|
return myValue.intValue();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
package ca.uhn.fhir.model.datatype;
|
package ca.uhn.fhir.model.datatype;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Calendar;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
|
|
||||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
|
||||||
@DatatypeDef(name="instant")
|
@DatatypeDef(name="instant")
|
||||||
public class InstantDt extends BasePrimitiveDatatype {
|
public class InstantDt extends BaseDateTimeDt {
|
||||||
|
|
||||||
private Date myValue;
|
@Override
|
||||||
|
boolean isPrecisionAllowed(int thePrecision) {
|
||||||
|
return thePrecision == Calendar.SECOND;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,36 @@ package ca.uhn.fhir.model.datatype;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
|
import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
|
||||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
|
||||||
@DatatypeDef(name="integer")
|
@DatatypeDef(name="integer")
|
||||||
public class IntegerDt extends BasePrimitiveDatatype {
|
public class IntegerDt extends BasePrimitiveDatatype<Integer> {
|
||||||
|
|
||||||
private int myValue;
|
private Integer myValue;
|
||||||
|
|
||||||
|
public Integer getValue() {
|
||||||
|
return myValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(Integer theValue) {
|
||||||
|
myValue = theValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValueAsString(String theValue) throws DataFormatException {
|
||||||
|
if (theValue == null) {
|
||||||
|
myValue = null;
|
||||||
|
}else {
|
||||||
|
myValue = Integer.parseInt(theValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValueAsString() {
|
||||||
|
if (myValue==null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Integer.toString(myValue);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package ca.uhn.fhir.model.datatype;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.BaseCompositeDatatype;
|
||||||
|
import ca.uhn.fhir.model.api.CodeableConceptElement;
|
||||||
|
import ca.uhn.fhir.model.api.annotation.Child;
|
||||||
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
import ca.uhn.fhir.model.enm.NarrativeStatusEnum;
|
||||||
|
|
||||||
|
@DatatypeDef(name="Narrative")
|
||||||
|
public class NarrativeDt extends BaseCompositeDatatype {
|
||||||
|
|
||||||
|
@Child(name="status", order=0, min=1)
|
||||||
|
@CodeableConceptElement(type=NarrativeStatusEnum.class)
|
||||||
|
private CodeDt<NarrativeStatusEnum> myStatus;
|
||||||
|
|
||||||
|
@Child(name="div", order=1)
|
||||||
|
private StringDt myDiv;
|
||||||
|
|
||||||
|
public StringDt getDiv() {
|
||||||
|
return myDiv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeDt<NarrativeStatusEnum> getStatus() {
|
||||||
|
return myStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setDiv(StringDt theDiv) {
|
||||||
|
myDiv = theDiv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(CodeDt<NarrativeStatusEnum> theStatus) {
|
||||||
|
myStatus = theStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -2,10 +2,31 @@ package ca.uhn.fhir.model.datatype;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
|
import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
|
||||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
|
||||||
@DatatypeDef(name="string")
|
@DatatypeDef(name = "string")
|
||||||
public class StringDt extends BasePrimitiveDatatype {
|
public class StringDt extends BasePrimitiveDatatype<String> {
|
||||||
|
|
||||||
private String myValue;
|
private String myValue;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValue() {
|
||||||
|
return myValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValueAsString() {
|
||||||
|
return myValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(String theValue) throws DataFormatException {
|
||||||
|
myValue = theValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValueAsString(String theValue) throws DataFormatException {
|
||||||
|
myValue = theValue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,46 @@
|
||||||
package ca.uhn.fhir.model.datatype;
|
package ca.uhn.fhir.model.datatype;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.BaseDatatype;
|
import ca.uhn.fhir.model.api.BaseDatatype;
|
||||||
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
||||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
|
||||||
@DatatypeDef(name="uri")
|
@DatatypeDef(name = "uri")
|
||||||
public class UriDt extends BaseDatatype implements IPrimitiveDatatype {
|
public class UriDt extends BaseDatatype implements IPrimitiveDatatype<URI> {
|
||||||
|
|
||||||
|
private URI myValue;
|
||||||
|
|
||||||
|
public URI getValue() {
|
||||||
|
return myValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(URI theValue) {
|
||||||
|
myValue = theValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValueAsString(String theValue) throws DataFormatException {
|
||||||
|
if (theValue==null) {
|
||||||
|
myValue=null;
|
||||||
|
}else {
|
||||||
|
try {
|
||||||
|
myValue = new URI(theValue);
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
throw new DataFormatException("Unable to parse URI value", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValueAsString() {
|
||||||
|
if (myValue == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return myValue.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String myValue;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package ca.uhn.fhir.model.enm;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.ICodeEnum;
|
||||||
|
import ca.uhn.fhir.model.api.annotation.Description;
|
||||||
|
import ca.uhn.fhir.model.api.annotation.EnumeratedCodeValue;
|
||||||
|
import ca.uhn.fhir.model.api.annotation.CodeTableDef;
|
||||||
|
|
||||||
|
@CodeTableDef(tableId = 28, name = "narrative-status")
|
||||||
|
public enum NarrativeStatusEnum implements ICodeEnum {
|
||||||
|
|
||||||
|
@EnumeratedCodeValue(value = "generated")
|
||||||
|
@Description("The contents of the narrative are entirely generated from the structured data in the resource.")
|
||||||
|
GENERATED,
|
||||||
|
|
||||||
|
@EnumeratedCodeValue(value = "extensions")
|
||||||
|
@Description("The contents of the narrative are entirely generated from the structured data in the resource and some of the content is generated from extensions.")
|
||||||
|
EXTENSIONS,
|
||||||
|
|
||||||
|
@EnumeratedCodeValue(value = "additional")
|
||||||
|
@Description("The contents of the narrative contain additional information not found in the structured data.")
|
||||||
|
ADDITIONAL,
|
||||||
|
|
||||||
|
@EnumeratedCodeValue(value = "empty")
|
||||||
|
@Description("the contents of the narrative are some equivalent of \"No human-readable text provided for this resource\".")
|
||||||
|
EMPTY
|
||||||
|
}
|
|
@ -2,9 +2,22 @@ package ca.uhn.fhir.model.resource;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.BaseElement;
|
import ca.uhn.fhir.model.api.BaseElement;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
import ca.uhn.fhir.model.api.annotation.Narrative;
|
||||||
|
import ca.uhn.fhir.model.datatype.NarrativeDt;
|
||||||
|
|
||||||
public abstract class BaseResource extends BaseElement implements IResource {
|
public abstract class BaseResource extends BaseElement implements IResource {
|
||||||
|
|
||||||
|
@Narrative(name="text")
|
||||||
|
private NarrativeDt myText;
|
||||||
|
|
||||||
|
public NarrativeDt getText() {
|
||||||
|
return myText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(NarrativeDt theText) {
|
||||||
|
myText = theText;
|
||||||
|
}
|
||||||
|
|
||||||
// public abstract void setAllChildValues(List<IElement> theChildren);
|
// public abstract void setAllChildValues(List<IElement> theChildren);
|
||||||
//
|
//
|
||||||
// public abstract List<IElement> getAllChildValues();
|
// public abstract List<IElement> getAllChildValues();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package ca.uhn.fhir.model.resource;
|
package ca.uhn.fhir.model.resource;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.annotation.Child;
|
import ca.uhn.fhir.model.api.annotation.Child;
|
||||||
|
import ca.uhn.fhir.model.api.annotation.IsIdentifier;
|
||||||
import ca.uhn.fhir.model.datatype.IdentifierDt;
|
import ca.uhn.fhir.model.datatype.IdentifierDt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,6 +10,15 @@ import ca.uhn.fhir.model.datatype.IdentifierDt;
|
||||||
public abstract class BaseResourceWithIdentifier extends BaseResource {
|
public abstract class BaseResourceWithIdentifier extends BaseResource {
|
||||||
|
|
||||||
@Child(name="identifier", order=Child.ORDER_UNKNOWN)
|
@Child(name="identifier", order=Child.ORDER_UNKNOWN)
|
||||||
|
@IsIdentifier
|
||||||
private IdentifierDt myIdentifier;
|
private IdentifierDt myIdentifier;
|
||||||
|
|
||||||
|
public IdentifierDt getIdentifier() {
|
||||||
|
return myIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdentifier(IdentifierDt theIdentifier) {
|
||||||
|
myIdentifier = theIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,13 @@ import ca.uhn.fhir.model.api.ResourceReference;
|
||||||
import ca.uhn.fhir.model.api.annotation.Child;
|
import ca.uhn.fhir.model.api.annotation.Child;
|
||||||
import ca.uhn.fhir.model.api.annotation.ChildResource;
|
import ca.uhn.fhir.model.api.annotation.ChildResource;
|
||||||
import ca.uhn.fhir.model.api.annotation.Choice;
|
import ca.uhn.fhir.model.api.annotation.Choice;
|
||||||
|
import ca.uhn.fhir.model.api.annotation.Narrative;
|
||||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||||
import ca.uhn.fhir.model.datatype.AttachmentDt;
|
import ca.uhn.fhir.model.datatype.AttachmentDt;
|
||||||
import ca.uhn.fhir.model.datatype.CodeableConceptDt;
|
import ca.uhn.fhir.model.datatype.CodeableConceptDt;
|
||||||
import ca.uhn.fhir.model.datatype.DateTimeDt;
|
import ca.uhn.fhir.model.datatype.DateTimeDt;
|
||||||
import ca.uhn.fhir.model.datatype.InstantDt;
|
import ca.uhn.fhir.model.datatype.InstantDt;
|
||||||
|
import ca.uhn.fhir.model.datatype.NarrativeDt;
|
||||||
import ca.uhn.fhir.model.datatype.PeriodDt;
|
import ca.uhn.fhir.model.datatype.PeriodDt;
|
||||||
import ca.uhn.fhir.model.datatype.QuantityDt;
|
import ca.uhn.fhir.model.datatype.QuantityDt;
|
||||||
import ca.uhn.fhir.model.datatype.RatioDt;
|
import ca.uhn.fhir.model.datatype.RatioDt;
|
||||||
|
@ -77,6 +79,96 @@ public class Observation extends BaseResourceWithIdentifier {
|
||||||
Patient.class, Group.class // TODO: add device, location
|
Patient.class, Group.class // TODO: add device, location
|
||||||
})
|
})
|
||||||
private ResourceReference mySubject;
|
private ResourceReference mySubject;
|
||||||
|
|
||||||
|
public CodeableConceptDt<ObservationCodesEnum> getName() {
|
||||||
|
return myName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(CodeableConceptDt<ObservationCodesEnum> theName) {
|
||||||
|
myName = theName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDatatype getValue() {
|
||||||
|
return myValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(IDatatype theValue) {
|
||||||
|
myValue = theValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeableConceptDt<ObservationInterpretationEnum> getInterpretation() {
|
||||||
|
return myInterpretation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterpretation(CodeableConceptDt<ObservationInterpretationEnum> theInterpretation) {
|
||||||
|
myInterpretation = theInterpretation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringDt getComments() {
|
||||||
|
return myComments;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setComments(StringDt theComments) {
|
||||||
|
myComments = theComments;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDatatype getApplies() {
|
||||||
|
return myApplies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApplies(IDatatype theApplies) {
|
||||||
|
myApplies = theApplies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstantDt getIssued() {
|
||||||
|
return myIssued;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIssued(InstantDt theIssued) {
|
||||||
|
myIssued = theIssued;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeableConceptDt<ObservationStatusEnum> getStatus() {
|
||||||
|
return myStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(CodeableConceptDt<ObservationStatusEnum> theStatus) {
|
||||||
|
myStatus = theStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeableConceptDt<ObservationStatusEnum> getReliability() {
|
||||||
|
return myReliability;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReliability(CodeableConceptDt<ObservationStatusEnum> theReliability) {
|
||||||
|
myReliability = theReliability;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeableConceptDt<BodySiteEnum> getBodySite() {
|
||||||
|
return myBodySite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBodySite(CodeableConceptDt<BodySiteEnum> theBodySite) {
|
||||||
|
myBodySite = theBodySite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeableConceptDt<ObservationMethodEnum> getMethod() {
|
||||||
|
return myMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMethod(CodeableConceptDt<ObservationMethodEnum> theMethod) {
|
||||||
|
myMethod = theMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceReference getSubject() {
|
||||||
|
return mySubject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubject(ResourceReference theSubject) {
|
||||||
|
mySubject = theSubject;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,44 @@
|
||||||
package ca.uhn.fhir.parser;
|
package ca.uhn.fhir.parser;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||||
|
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
|
import ca.uhn.fhir.model.api.BaseCompositeDatatype;
|
||||||
|
import ca.uhn.fhir.model.api.ICompositeDatatype;
|
||||||
|
import ca.uhn.fhir.model.api.ICompositeElement;
|
||||||
|
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
|
||||||
class ParserState {
|
class ParserState {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ParserState.class);
|
||||||
private FhirContext myContext;
|
private FhirContext myContext;
|
||||||
|
|
||||||
private BaseState myState;
|
private BaseState myState;
|
||||||
|
private Object myObject;
|
||||||
|
|
||||||
public ParserState(FhirContext theContext) {
|
public ParserState(FhirContext theContext) {
|
||||||
myContext=theContext;
|
myContext = theContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void attributeValue(String theValue) throws DataFormatException {
|
||||||
|
myState.attributeValue(theValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enteringNewElement(String theLocalPart) throws DataFormatException {
|
||||||
|
myState.enteringNewElement(theLocalPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void push(BaseState theState) {
|
||||||
|
theState.setStack(myState);
|
||||||
|
myState = theState;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setState(BaseState theState) {
|
||||||
|
myState = theState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ParserState getResourceInstance(FhirContext theContext, String theLocalPart) throws DataFormatException {
|
public static ParserState getResourceInstance(FhirContext theContext, String theLocalPart) throws DataFormatException {
|
||||||
|
@ -20,58 +46,126 @@ class ParserState {
|
||||||
if (!(definition instanceof RuntimeResourceDefinition)) {
|
if (!(definition instanceof RuntimeResourceDefinition)) {
|
||||||
throw new DataFormatException("Element '" + theLocalPart + "' is not a resource, expected a resource at this position");
|
throw new DataFormatException("Element '" + theLocalPart + "' is not a resource, expected a resource at this position");
|
||||||
}
|
}
|
||||||
|
|
||||||
RuntimeResourceDefinition def = (RuntimeResourceDefinition) definition;
|
RuntimeResourceDefinition def = (RuntimeResourceDefinition) definition;
|
||||||
IResource instance = def.newInstance();
|
IResource instance = def.newInstance();
|
||||||
|
|
||||||
ParserState retVal = new ParserState(theContext);
|
ParserState retVal = new ParserState(theContext);
|
||||||
retVal.setState(retVal.new ResourceParserState(def, instance));
|
retVal.setState(retVal.new ContainerState(def, instance));
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
private abstract class BaseState {
|
||||||
|
private BaseState myStack;
|
||||||
|
|
||||||
private void setState(BaseState theState) {
|
public abstract void attributeValue(String theValue) throws DataFormatException;
|
||||||
myState = theState;
|
|
||||||
|
public abstract void enteringNewElement(String theLocalPart) throws DataFormatException;
|
||||||
|
|
||||||
|
public void setStack(BaseState theState) {
|
||||||
|
myStack = theState;
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract class BaseState
|
public abstract void endingElement(String theLocalPart);
|
||||||
{
|
|
||||||
private BaseState myStack;
|
|
||||||
|
|
||||||
public abstract void enteringNewElement(String theLocalPart) throws DataFormatException;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ResourceParserState extends BaseState
|
|
||||||
{
|
|
||||||
|
|
||||||
private RuntimeResourceDefinition myResourceDefinition;
|
}
|
||||||
private IResource myInstance;
|
private class ContainerState extends BaseState {
|
||||||
|
|
||||||
public ResourceParserState(RuntimeResourceDefinition theDef, IResource theInstance) {
|
private BaseRuntimeElementCompositeDefinition<?> myDefinition;
|
||||||
myResourceDefinition = theDef;
|
private ICompositeElement myInstance;
|
||||||
|
|
||||||
|
public ContainerState(BaseRuntimeElementCompositeDefinition<?> theDef, ICompositeElement theInstance) {
|
||||||
|
myDefinition = theDef;
|
||||||
myInstance = theInstance;
|
myInstance = theInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enteringNewElement(String theChildName) throws DataFormatException {
|
public void attributeValue(String theValue) {
|
||||||
BaseRuntimeElementDefinition<?> child = myResourceDefinition.getChildByNameOrThrowDataFormatException(theChildName);
|
ourLog.debug("Ignoring attribute value: {}", theValue);
|
||||||
switch (child.getChildType()) {
|
|
||||||
case COMPOSITE_DATATYPE:
|
|
||||||
break;
|
|
||||||
case PRIMITIVE_DATATYPE:
|
|
||||||
break;
|
|
||||||
case RESOURCE:
|
|
||||||
default:
|
|
||||||
throw new DataFormatException("Illegal resource position");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enteringNewElement(String theChildName) throws DataFormatException {
|
||||||
|
BaseRuntimeChildDefinition child = myDefinition.getChildByNameOrThrowDataFormatException(theChildName);
|
||||||
|
BaseRuntimeElementDefinition<?> target = child.getChildByName(theChildName);
|
||||||
|
|
||||||
|
switch (target.getChildType()) {
|
||||||
|
case COMPOSITE_DATATYPE: {
|
||||||
|
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
||||||
|
ICompositeDatatype newChildInstance = (ICompositeDatatype) compositeTarget.newInstance();
|
||||||
|
child.getMutator().addValue(myInstance, newChildInstance);
|
||||||
|
ContainerState newState = new ContainerState(compositeTarget, newChildInstance);
|
||||||
|
push(newState);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PRIMITIVE_DATATYPE: {
|
||||||
|
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
||||||
|
IPrimitiveDatatype<?> newChildInstance = primitiveTarget.newInstance();
|
||||||
|
child.getMutator().addValue(myInstance, newChildInstance);
|
||||||
|
PrimitiveState newState = new PrimitiveState(primitiveTarget, newChildInstance);
|
||||||
|
push(newState);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RESOURCE: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new DataFormatException("Illegal resource position");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endingElement(String theLocalPart) {
|
||||||
|
pop();
|
||||||
|
if (myState == null) {
|
||||||
|
myObject = myInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enteringNewElement(String theLocalPart) throws DataFormatException {
|
private class PrimitiveState extends BaseState {
|
||||||
myState.enteringNewElement(theLocalPart);
|
private RuntimePrimitiveDatatypeDefinition myDefinition;
|
||||||
|
private IPrimitiveDatatype<?> myInstance;
|
||||||
|
|
||||||
|
public PrimitiveState(RuntimePrimitiveDatatypeDefinition theDefinition, IPrimitiveDatatype<?> theInstance) {
|
||||||
|
super();
|
||||||
|
myDefinition = theDefinition;
|
||||||
|
myInstance = theInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attributeValue(String theValue) throws DataFormatException {
|
||||||
|
myInstance.setValueAsString(theValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enteringNewElement(String theLocalPart) throws DataFormatException {
|
||||||
|
throw new Error("?? can this happen?"); // TODO: can this happen?
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endingElement(String theLocalPart) {
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Object getObject() {
|
||||||
|
return myObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pop() {
|
||||||
|
myState = myState.myStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isComplete() {
|
||||||
|
return myObject != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endingElement(String theLocalPart) {
|
||||||
|
myState.endingElement(theLocalPart);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ import javax.xml.stream.XMLEventFactory;
|
||||||
import javax.xml.stream.XMLEventReader;
|
import javax.xml.stream.XMLEventReader;
|
||||||
import javax.xml.stream.XMLInputFactory;
|
import javax.xml.stream.XMLInputFactory;
|
||||||
import javax.xml.stream.XMLStreamException;
|
import javax.xml.stream.XMLStreamException;
|
||||||
|
import javax.xml.stream.events.Attribute;
|
||||||
|
import javax.xml.stream.events.EndElement;
|
||||||
import javax.xml.stream.events.StartElement;
|
import javax.xml.stream.events.StartElement;
|
||||||
import javax.xml.stream.events.XMLEvent;
|
import javax.xml.stream.events.XMLEvent;
|
||||||
|
|
||||||
|
@ -52,6 +54,30 @@ public class XmlParser {
|
||||||
} else {
|
} else {
|
||||||
parserState.enteringNewElement(elem.getName().getLocalPart());
|
parserState.enteringNewElement(elem.getName().getLocalPart());
|
||||||
}
|
}
|
||||||
|
} else if (nextEvent.isAttribute()) {
|
||||||
|
Attribute elem = (Attribute) nextEvent;
|
||||||
|
if (!FHIR_NS.equals(elem.getName().getNamespaceURI())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!"value".equals(elem.getName().getLocalPart())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (parserState == null) {
|
||||||
|
throw new DataFormatException("Detected attribute before element");
|
||||||
|
}
|
||||||
|
parserState.attributeValue(elem.getValue());
|
||||||
|
} else if (nextEvent.isEndElement()) {
|
||||||
|
EndElement elem = nextEvent.asEndElement();
|
||||||
|
if (!FHIR_NS.equals(elem.getName().getNamespaceURI())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (parserState == null) {
|
||||||
|
throw new DataFormatException("Detected unexpected end-element");
|
||||||
|
}
|
||||||
|
parserState.endingElement(elem.getName().getLocalPart());
|
||||||
|
if (parserState.isComplete()) {
|
||||||
|
return (IResource) parserState.getObject();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
package ca.uhn.fhir.util;
|
||||||
|
|
||||||
|
import java.beans.BeanInfo;
|
||||||
|
import java.beans.IntrospectionException;
|
||||||
|
import java.beans.Introspector;
|
||||||
|
import java.beans.PropertyDescriptor;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class BeanUtils {
|
||||||
|
|
||||||
|
public static Method findAccessor(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName) throws NoSuchFieldException {
|
||||||
|
BeanInfo info;
|
||||||
|
try {
|
||||||
|
info = Introspector.getBeanInfo(theClassToIntrospect);
|
||||||
|
} catch (IntrospectionException e) {
|
||||||
|
throw new NoSuchFieldException(e.getMessage());
|
||||||
|
}
|
||||||
|
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
|
||||||
|
if (thePropertyName.equals(pd.getName())) {
|
||||||
|
if (theTargetReturnType.isAssignableFrom(pd.getPropertyType())) {
|
||||||
|
return pd.getReadMethod();
|
||||||
|
}else {
|
||||||
|
throw new NoSuchFieldException(theClassToIntrospect + " has an accessor for field " + thePropertyName + " but it does not return type " + theTargetReturnType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(theClassToIntrospect + " has no accessor for field " + thePropertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Method findMutator(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName) throws NoSuchFieldException {
|
||||||
|
BeanInfo info;
|
||||||
|
try {
|
||||||
|
info = Introspector.getBeanInfo(theClassToIntrospect);
|
||||||
|
} catch (IntrospectionException e) {
|
||||||
|
throw new NoSuchFieldException(e.getMessage());
|
||||||
|
}
|
||||||
|
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
|
||||||
|
if (thePropertyName.equals(pd.getName())) {
|
||||||
|
if (theTargetReturnType.isAssignableFrom(pd.getPropertyType())) {
|
||||||
|
return pd.getWriteMethod();
|
||||||
|
}else {
|
||||||
|
throw new NoSuchFieldException(theClassToIntrospect + " has an mutator for field " + thePropertyName + " but it does not return type " + theTargetReturnType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(theClassToIntrospect + " has no mutator for field " + thePropertyName);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package ca.uhn.fhir.model.datatype;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
|
public class Base64BinaryDtTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDecodeNull() {
|
||||||
|
new Base64BinaryDt().setValueAsString(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue