XML parser finally almost working
This commit is contained in:
parent
5296e8121c
commit
d097553f11
|
@ -1,59 +1,56 @@
|
||||||
|
<?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="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="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
<attributes>
|
|
||||||
<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/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>
|
|
||||||
<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>
|
|
||||||
</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">
|
<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:/Users/james/.m2/repository/com/google/code/gson/gson/2.2.4/gson-2.2.4-javadoc.jar!/" name="javadoc_location"/>
|
<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"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</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">
|
<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>
|
<attributes>
|
||||||
<attribute value="jar:file:/Users/james/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-javadoc.jar!/" name="javadoc_location"/>
|
<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>
|
</attributes>
|
||||||
</classpathentry>
|
</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">
|
<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>
|
<attributes>
|
||||||
<attribute value="jar:file:/Users/james/.m2/repository/junit/junit/4.11/junit-4.11-javadoc.jar!/" name="javadoc_location"/>
|
<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/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/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>
|
</attributes>
|
||||||
</classpathentry>
|
</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">
|
<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>
|
<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"/>
|
<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>
|
</attributes>
|
||||||
</classpathentry>
|
</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">
|
<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>
|
<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"/>
|
<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>
|
</attributes>
|
||||||
</classpathentry>
|
</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">
|
<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>
|
<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"/>
|
<attribute value="jar:file:/home/t3903uhn/.m2/repository/junit/junit/4.11/junit-4.11-javadoc.jar!/" name="javadoc_location"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</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/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">
|
||||||
<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>
|
<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"/>
|
<attribute value="jar:file:/home/t3903uhn/.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/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>
|
||||||
|
<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"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</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,3 +1,4 @@
|
||||||
|
<?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,10 +1,11 @@
|
||||||
package ca.uhn.fhir.context;
|
package ca.uhn.fhir.context;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.*;
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -44,49 +45,21 @@ public abstract class BaseRuntimeChildDefinition {
|
||||||
|
|
||||||
// TODO: handle lists (max>0), and maybe max=0?
|
// TODO: handle lists (max>0), and maybe max=0?
|
||||||
|
|
||||||
if (myMax == 1) {
|
Class<?> declaringClass = myField.getDeclaringClass();
|
||||||
Class<?> declaringClass = myField.getDeclaringClass();
|
final Class<?> targetReturnType = myField.getType();
|
||||||
Class<?> targetReturnType = myField.getType();
|
try {
|
||||||
try {
|
final Method accessor = BeanUtils.findAccessor(declaringClass, targetReturnType, myElementName);
|
||||||
final Method accessor = BeanUtils.findAccessor(declaringClass, targetReturnType, myElementName);
|
final Method mutator = BeanUtils.findMutator(declaringClass, targetReturnType, myElementName);
|
||||||
final Method mutator = BeanUtils.findMutator(declaringClass, targetReturnType, myElementName);
|
|
||||||
myAccessor = new IAccessor() {
|
if (List.class.isAssignableFrom(targetReturnType)) {
|
||||||
@Override
|
myAccessor = new ListAccessor(accessor);
|
||||||
public List<Object> getValues(Object theTarget) {
|
myMutator = new ListMutator(mutator);
|
||||||
try {
|
}else {
|
||||||
return Collections.singletonList(accessor.invoke(theTarget));
|
myAccessor = new PlainAccessor(accessor);
|
||||||
} catch (IllegalAccessException e) {
|
myMutator = new PlainMutator(targetReturnType, mutator);
|
||||||
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 {
|
} catch (NoSuchFieldException e) {
|
||||||
|
throw new ConfigurationException(e);
|
||||||
// replace this with an implementation
|
|
||||||
myAccessor = null;
|
|
||||||
myMutator = null;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -121,6 +94,101 @@ public abstract class BaseRuntimeChildDefinition {
|
||||||
|
|
||||||
abstract void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions);
|
abstract void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions);
|
||||||
|
|
||||||
|
private final class ListMutator implements IMutator {
|
||||||
|
private final Method myMutator;
|
||||||
|
|
||||||
|
private ListMutator(Method theMutator) {
|
||||||
|
myMutator = theMutator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addValue(Object theTarget, Object theValue) {
|
||||||
|
List<Object> existingList = myAccessor.getValues(theTarget);
|
||||||
|
if (existingList == null) {
|
||||||
|
existingList = new ArrayList<Object>();
|
||||||
|
try {
|
||||||
|
myMutator.invoke(theTarget, existingList);
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
existingList.add(theValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class ListAccessor implements IAccessor {
|
||||||
|
private final Method myAccessor;
|
||||||
|
|
||||||
|
private ListAccessor(Method theAccessor) {
|
||||||
|
myAccessor = theAccessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public List<Object> getValues(Object theTarget) {
|
||||||
|
try {
|
||||||
|
return (List<Object>) myAccessor.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class PlainMutator implements IMutator {
|
||||||
|
private final Class<?> myTargetReturnType;
|
||||||
|
private final Method myMutator;
|
||||||
|
|
||||||
|
private PlainMutator(Class<?> theTargetReturnType, Method theMutator) {
|
||||||
|
myTargetReturnType = theTargetReturnType;
|
||||||
|
myMutator = theMutator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addValue(Object theTarget, Object theValue) {
|
||||||
|
try {
|
||||||
|
if (theValue != null && !myTargetReturnType.isAssignableFrom(theValue.getClass())) {
|
||||||
|
throw new ConfigurationException("Value for field " + myElementName + " expects type " + myTargetReturnType + " but got " + theValue.getClass());
|
||||||
|
}
|
||||||
|
myMutator.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class PlainAccessor implements IAccessor {
|
||||||
|
private final Method myAccessor;
|
||||||
|
|
||||||
|
private PlainAccessor(Method theAccessor) {
|
||||||
|
myAccessor = theAccessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Object> getValues(Object theTarget) {
|
||||||
|
try {
|
||||||
|
return Collections.singletonList(myAccessor.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public interface IMutator {
|
public interface IMutator {
|
||||||
void addValue(Object theTarget, Object theValue);
|
void addValue(Object theTarget, Object theValue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ public abstract class BaseRuntimeElementDefinition<T extends IElement> {
|
||||||
public abstract ChildTypeEnum getChildType();
|
public abstract ChildTypeEnum getChildType();
|
||||||
|
|
||||||
public enum ChildTypeEnum {
|
public enum ChildTypeEnum {
|
||||||
COMPOSITE_DATATYPE, PRIMITIVE_DATATYPE, RESOURCE
|
COMPOSITE_DATATYPE, PRIMITIVE_DATATYPE, RESOURCE, RESOURCE_REF
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
package ca.uhn.fhir.context;
|
package ca.uhn.fhir.context;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.*;
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -14,7 +13,6 @@ 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 java.util.TreeMap;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.CodeableConceptElement;
|
import ca.uhn.fhir.model.api.CodeableConceptElement;
|
||||||
|
@ -88,7 +86,8 @@ 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() + ": " + theClass.getCanonicalName());
|
throw new ConfigurationException("Resource type contains a @" + ResourceDef.class.getSimpleName() + " annotation but does not implement " + IResource.class.getCanonicalName() + ": "
|
||||||
|
+ theClass.getCanonicalName());
|
||||||
}
|
}
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Class<? extends IResource> resClass = (Class<? extends IResource>) theClass;
|
Class<? extends IResource> resClass = (Class<? extends IResource>) theClass;
|
||||||
|
@ -106,7 +105,8 @@ class ModelScanner {
|
||||||
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() + ": " + theClass.getCanonicalName());
|
throw new ConfigurationException("Resource type contains a @" + DatatypeDef.class.getSimpleName() + " annotation but does not implement " + IDatatype.class.getCanonicalName() + ": "
|
||||||
|
+ theClass.getCanonicalName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,11 +117,13 @@ 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() + ": " + theClass.getCanonicalName());
|
throw new ConfigurationException("Resource type contains a @" + CodeTableDef.class.getSimpleName() + " annotation but does not implement " + ICodeEnum.class.getCanonicalName() + ": "
|
||||||
|
+ theClass.getCanonicalName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ConfigurationException("Resource type does not contain a @" + ResourceDef.class.getSimpleName() + " annotation or a @" + DatatypeDef.class.getSimpleName() + " annotation: " + theClass.getCanonicalName());
|
throw new ConfigurationException("Resource type does not contain a @" + ResourceDef.class.getSimpleName() + " annotation or a @" + DatatypeDef.class.getSimpleName() + " annotation: "
|
||||||
|
+ theClass.getCanonicalName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String scanCompositeDatatype(Class<? extends ICompositeDatatype> theClass, DatatypeDef theDatatypeDefinition) {
|
private String scanCompositeDatatype(Class<? extends ICompositeDatatype> theClass, DatatypeDef theDatatypeDefinition) {
|
||||||
|
@ -164,7 +166,8 @@ 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 '" + myNameToResourceDefinitions.get(resourceName).getImplementingClass() + "'");
|
throw new ConfigurationException("Detected duplicate element name '" + resourceName + "' in types '" + theClass.getCanonicalName() + "' and '"
|
||||||
|
+ myNameToResourceDefinitions.get(resourceName).getImplementingClass() + "'");
|
||||||
}
|
}
|
||||||
return resourceName;
|
return resourceName;
|
||||||
}
|
}
|
||||||
|
@ -189,10 +192,10 @@ class ModelScanner {
|
||||||
classes.push(current);
|
classes.push(current);
|
||||||
if (ICompositeElement.class.isAssignableFrom(current.getSuperclass())) {
|
if (ICompositeElement.class.isAssignableFrom(current.getSuperclass())) {
|
||||||
current = (Class<? extends ICompositeElement>) current.getSuperclass();
|
current = (Class<? extends ICompositeElement>) current.getSuperclass();
|
||||||
}else {
|
} else {
|
||||||
current = null;
|
current = null;
|
||||||
}
|
}
|
||||||
}while (current != null);
|
} while (current != null);
|
||||||
|
|
||||||
for (Class<? extends ICompositeElement> next : classes) {
|
for (Class<? extends ICompositeElement> next : classes) {
|
||||||
scanCompositeElementForChildren(next, theDefinition, elementNames, orderToElementDef);
|
scanCompositeElementForChildren(next, theDefinition, elementNames, orderToElementDef);
|
||||||
|
@ -202,14 +205,15 @@ class ModelScanner {
|
||||||
BaseRuntimeChildDefinition elementDef = orderToElementDef.remove(orderToElementDef.firstKey());
|
BaseRuntimeChildDefinition elementDef = orderToElementDef.remove(orderToElementDef.firstKey());
|
||||||
if (elementDef.getElementName().equals("identifier")) {
|
if (elementDef.getElementName().equals("identifier")) {
|
||||||
orderToElementDef.put(theIdentifierOrder, elementDef);
|
orderToElementDef.put(theIdentifierOrder, elementDef);
|
||||||
}else {
|
} else {
|
||||||
throw new ConfigurationException("Don't know how to handle element: " + elementDef.getElementName());
|
throw new ConfigurationException("Don't know how to handle element: " + elementDef.getElementName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < orderToElementDef.size(); i++) {
|
for (int i = 0; i < orderToElementDef.size(); i++) {
|
||||||
if (!orderToElementDef.containsKey(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)");
|
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);
|
BaseRuntimeChildDefinition next = orderToElementDef.get(i);
|
||||||
theDefinition.addChild(next);
|
theDefinition.addChild(next);
|
||||||
|
@ -218,7 +222,8 @@ class ModelScanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void scanCompositeElementForChildren(Class<? extends ICompositeElement> theClass, BaseRuntimeElementCompositeDefinition<?> theDefinition, Set<String> elementNames, TreeMap<Integer, BaseRuntimeChildDefinition> orderToElementDef) {
|
private void scanCompositeElementForChildren(Class<? extends ICompositeElement> theClass, BaseRuntimeElementCompositeDefinition<?> theDefinition, Set<String> elementNames,
|
||||||
|
TreeMap<Integer, BaseRuntimeChildDefinition> orderToElementDef) {
|
||||||
for (Field next : theClass.getDeclaredFields()) {
|
for (Field next : theClass.getDeclaredFields()) {
|
||||||
|
|
||||||
Narrative hasNarrative = next.getAnnotation(Narrative.class);
|
Narrative hasNarrative = next.getAnnotation(Narrative.class);
|
||||||
|
@ -230,11 +235,12 @@ class ModelScanner {
|
||||||
throw new ConfigurationException("Failed to find narrative field", e);
|
throw new ConfigurationException("Failed to find narrative field", e);
|
||||||
}
|
}
|
||||||
theDefinition.addChild(def);
|
theDefinition.addChild(def);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
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() + "' on target type: " + theClass);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +281,8 @@ 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 @" + ChildResource.class.getSimpleName() + " annotation");
|
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is a resource reference but does not have a @"
|
||||||
|
+ ChildResource.class.getSimpleName() + " annotation");
|
||||||
}
|
}
|
||||||
|
|
||||||
Class<? extends IResource>[] refType = resRefAnnotation.types();
|
Class<? extends IResource>[] refType = resRefAnnotation.types();
|
||||||
|
@ -286,7 +293,8 @@ 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 @" + ChildResource.class.getSimpleName() + " annotation");
|
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is not a resource reference but has a @"
|
||||||
|
+ ChildResource.class.getSimpleName() + " annotation");
|
||||||
}
|
}
|
||||||
|
|
||||||
Class<? extends IDatatype> nextDatatype;
|
Class<? extends IDatatype> nextDatatype;
|
||||||
|
@ -294,19 +302,25 @@ class ModelScanner {
|
||||||
if (IDatatype.class.isAssignableFrom(next.getType())) {
|
if (IDatatype.class.isAssignableFrom(next.getType())) {
|
||||||
nextDatatype = (Class<? extends IDatatype>) next.getType();
|
nextDatatype = (Class<? extends IDatatype>) next.getType();
|
||||||
} else {
|
} else {
|
||||||
if (Collection.class.isAssignableFrom(next.getType())) {
|
if (List.class.isAssignableFrom(next.getType())) {
|
||||||
Class<?> type = (Class<?>) ((ParameterizedType) next.getType().getGenericSuperclass()).getActualTypeArguments()[0];
|
|
||||||
|
Class<?> type = getGenericCollectionTypeOfField(next);
|
||||||
|
|
||||||
if (IDatatype.class.isAssignableFrom(type)) {
|
if (IDatatype.class.isAssignableFrom(type)) {
|
||||||
nextDatatype=(Class<? extends IDatatype>) type;
|
nextDatatype = (Class<? extends IDatatype>) type;
|
||||||
}else {
|
} else {
|
||||||
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is not a resource reference and is not an instance of type " + IDatatype.class.getName());
|
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is not a resource reference and is not an instance of type "
|
||||||
|
+ IDatatype.class.getName());
|
||||||
}
|
}
|
||||||
}else {
|
} else {
|
||||||
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is not a resource reference and is not an instance of type " + IDatatype.class.getName());
|
/* TODO: detect when someone has used a different collection (set, etc.) and
|
||||||
|
* give a nice error that indicates that they need to use List..
|
||||||
|
*/
|
||||||
|
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is not a resource reference and is not an instance of type "
|
||||||
|
+ IDatatype.class.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
myScanAlso.add(nextDatatype);
|
myScanAlso.add(nextDatatype);
|
||||||
|
|
||||||
BaseRuntimeChildDatatypeDefinition def;
|
BaseRuntimeChildDatatypeDefinition def;
|
||||||
|
@ -319,7 +333,8 @@ 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() + " but type is not a subtype of " + ICodedDatatype.class.getName());
|
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());
|
||||||
} else {
|
} else {
|
||||||
Class<? extends ICodeEnum> type = concept.type();
|
Class<? extends ICodeEnum> type = concept.type();
|
||||||
myScanAlsoCodeTable.add(type);
|
myScanAlsoCodeTable.add(type);
|
||||||
|
@ -350,6 +365,19 @@ class ModelScanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Class<?> getGenericCollectionTypeOfField(Field next) {
|
||||||
|
// Type genericSuperclass = next.getType().getGenericSuperclass();
|
||||||
|
Class<?> type;
|
||||||
|
// if (genericSuperclass == null) {
|
||||||
|
ParameterizedType collectionType = (ParameterizedType) next.getGenericType();
|
||||||
|
type = (Class<?>) collectionType.getActualTypeArguments()[0];
|
||||||
|
// }else {
|
||||||
|
// Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass).getActualTypeArguments();
|
||||||
|
// type = (Class<?>) actualTypeArguments[0];
|
||||||
|
// }
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
private String scanCodeTable(Class<? extends ICodeEnum> theCodeType, CodeTableDef theCodeTableDefinition) {
|
private String scanCodeTable(Class<? extends ICodeEnum> theCodeType, CodeTableDef theCodeTableDefinition) {
|
||||||
return null; // TODO: implement
|
return null; // TODO: implement
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,40 +11,24 @@ import ca.uhn.fhir.model.api.IResource;
|
||||||
|
|
||||||
public class RuntimeChildResourceDefinition extends BaseRuntimeChildDefinition {
|
public class RuntimeChildResourceDefinition extends BaseRuntimeChildDefinition {
|
||||||
|
|
||||||
private static final String REFERENCE = "reference";
|
|
||||||
|
|
||||||
private String myResourceName;
|
|
||||||
private Set<String> myValidChildNames;
|
|
||||||
private List<Class<? extends IResource>> myChildTypes;
|
|
||||||
|
|
||||||
public RuntimeChildResourceDefinition(Field theField, String theElementName, int theMin, int theMax, List<Class<? extends IResource>> theChildTypes) {
|
public RuntimeChildResourceDefinition(Field theField, String theElementName, int theMin, int theMax, List<Class<? extends IResource>> theChildTypes) {
|
||||||
super(theField, theMin,theMax, theElementName);
|
super(theField, theMin, theMax, theElementName);
|
||||||
|
|
||||||
myChildTypes = theChildTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getResourceName() {
|
|
||||||
return myResourceName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getValidChildNames() {
|
public Set<String> getValidChildNames() {
|
||||||
return Collections.singleton(REFERENCE);
|
return Collections.singleton(getElementName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseRuntimeElementDefinition<?> getChildByName(String theName) {
|
public BaseRuntimeElementDefinition<?> getChildByName(String theName) {
|
||||||
if (REFERENCE.equals(theName)) {
|
return new RuntimeResourceReferenceDefinition(null, null);
|
||||||
return null; // TODO: implement
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
|
void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
|
||||||
// TODO Auto-generated method stub
|
// nothing
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package ca.uhn.fhir.context;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.IElement;
|
||||||
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
|
||||||
|
public class RuntimeResourceReferenceDefinition extends BaseRuntimeElementDefinition<IResource> {
|
||||||
|
|
||||||
|
public RuntimeResourceReferenceDefinition(String theName, Class<? extends IResource> theImplementingClass) {
|
||||||
|
super(theName, theImplementingClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum getChildType() {
|
||||||
|
return ChildTypeEnum.RESOURCE_REF;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,24 @@
|
||||||
package ca.uhn.fhir.model.api;
|
package ca.uhn.fhir.model.api;
|
||||||
|
|
||||||
|
public class ResourceReference /* <T extends BaseResource> */{
|
||||||
|
|
||||||
public class ResourceReference /*<T extends BaseResource>*/ {
|
private String myDisplay;
|
||||||
|
private String myReference;
|
||||||
|
|
||||||
|
public String getDisplay() {
|
||||||
|
return myDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReference() {
|
||||||
|
return myReference;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplay(String theDisplay) {
|
||||||
|
myDisplay = theDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReference(String theReference) {
|
||||||
|
myReference = theReference;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,11 @@ public @interface Child {
|
||||||
*/
|
*/
|
||||||
int ORDER_UNKNOWN = -1;
|
int ORDER_UNKNOWN = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* COnstant value to supply for {@link #max()} to indicate '*' (no maximum)
|
||||||
|
*/
|
||||||
|
int MAX_UNLIMITED = -1;
|
||||||
|
|
||||||
String name();
|
String name();
|
||||||
|
|
||||||
int order();
|
int order();
|
||||||
|
|
|
@ -9,10 +9,10 @@ import ca.uhn.fhir.model.api.annotation.Description;
|
||||||
public class AttachmentDt extends BaseCompositeDatatype {
|
public class AttachmentDt extends BaseCompositeDatatype {
|
||||||
|
|
||||||
@Child(name="contentType", order=0, min=1)
|
@Child(name="contentType", order=0, min=1)
|
||||||
private CodeDt myContentType;
|
private CodeDt<?> myContentType;
|
||||||
|
|
||||||
@Child(name="language", order=1)
|
@Child(name="language", order=1)
|
||||||
private CodeDt myLanguage;
|
private CodeDt<?> myLanguage;
|
||||||
|
|
||||||
@Child(name="data", order=2)
|
@Child(name="data", order=2)
|
||||||
private Base64BinaryDt myData;
|
private Base64BinaryDt myData;
|
||||||
|
@ -27,8 +27,66 @@ public class AttachmentDt extends BaseCompositeDatatype {
|
||||||
@Description("Hash of the data (sha-1, base64ed )")
|
@Description("Hash of the data (sha-1, base64ed )")
|
||||||
private Base64BinaryDt myHash;
|
private Base64BinaryDt myHash;
|
||||||
|
|
||||||
@Child(name="title", order=5)
|
@Child(name="title", order=6)
|
||||||
@Description("Label to display in place of the data")
|
@Description("Label to display in place of the data")
|
||||||
private StringDt myLabel;
|
private StringDt myTitle;
|
||||||
|
|
||||||
|
public CodeDt<?> getContentType() {
|
||||||
|
return myContentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentType(CodeDt<?> theContentType) {
|
||||||
|
myContentType = theContentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeDt<?> getLanguage() {
|
||||||
|
return myLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLanguage(CodeDt<?> theLanguage) {
|
||||||
|
myLanguage = theLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Base64BinaryDt getData() {
|
||||||
|
return myData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(Base64BinaryDt theData) {
|
||||||
|
myData = theData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UriDt getUrl() {
|
||||||
|
return myUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(UriDt theUrl) {
|
||||||
|
myUrl = theUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Base64BinaryDt getHash() {
|
||||||
|
return myHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHash(Base64BinaryDt theHash) {
|
||||||
|
myHash = theHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringDt getTitle() {
|
||||||
|
return myTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(StringDt theTitle) {
|
||||||
|
myTitle = theTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntegerDt getSize() {
|
||||||
|
return mySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize(IntegerDt theSize) {
|
||||||
|
mySize = theSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,28 @@ import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
@DatatypeDef(name="CodeableConcept")
|
@DatatypeDef(name="CodeableConcept")
|
||||||
public class CodeableConceptDt<T extends ICodeEnum> extends BaseCompositeDatatype implements ICodedDatatype {
|
public class CodeableConceptDt<T extends ICodeEnum> extends BaseCompositeDatatype implements ICodedDatatype {
|
||||||
|
|
||||||
@Child(name="coding", order=0)
|
@Child(name="coding", order=0, min=0, max=Child.MAX_UNLIMITED)
|
||||||
private List<CodingDt> myCoding;
|
private List<CodingDt> myCoding;
|
||||||
|
|
||||||
@Child(name="text",order=1)
|
@Child(name="text",order=1)
|
||||||
private StringDt myText;
|
private StringDt myText;
|
||||||
|
|
||||||
|
public List<CodingDt> getCoding() {
|
||||||
|
return myCoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCoding(List<CodingDt> theCoding) {
|
||||||
|
myCoding = theCoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringDt getText() {
|
||||||
|
return myText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(StringDt theText) {
|
||||||
|
myText = theText;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,58 @@ public class CodingDt extends BaseCompositeDatatype {
|
||||||
@Child(name="primary", order=4)
|
@Child(name="primary", order=4)
|
||||||
private BooleanDt myPrimary;
|
private BooleanDt myPrimary;
|
||||||
|
|
||||||
@Child(name="valueSet", order=5)
|
@Child(name="assigner", order=5)
|
||||||
@ChildResource(types= {ValueSet.class})
|
@ChildResource(types= {ValueSet.class})
|
||||||
private ResourceReference myAssigner;
|
private ResourceReference myAssigner;
|
||||||
|
|
||||||
|
public UriDt getSystem() {
|
||||||
|
return mySystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSystem(UriDt theSystem) {
|
||||||
|
mySystem = theSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringDt getVersion() {
|
||||||
|
return myVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(StringDt theVersion) {
|
||||||
|
myVersion = theVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeDt<?> getCode() {
|
||||||
|
return myCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(CodeDt<?> theCode) {
|
||||||
|
myCode = theCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringDt getDisplay() {
|
||||||
|
return myDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplay(StringDt theDisplay) {
|
||||||
|
myDisplay = theDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanDt getPrimary() {
|
||||||
|
return myPrimary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrimary(BooleanDt thePrimary) {
|
||||||
|
myPrimary = thePrimary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceReference getAssigner() {
|
||||||
|
return myAssigner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAssigner(ResourceReference theAssigner) {
|
||||||
|
myAssigner = theAssigner;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,4 +15,22 @@ public class RatioDt extends BaseCompositeDatatype {
|
||||||
@Child(name="denominator", order=1)
|
@Child(name="denominator", order=1)
|
||||||
@Constraint(coRequirements= {"numerator"})
|
@Constraint(coRequirements= {"numerator"})
|
||||||
private QuantityDt myDenominator;
|
private QuantityDt myDenominator;
|
||||||
|
|
||||||
|
public QuantityDt getNumerator() {
|
||||||
|
return myNumerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumerator(QuantityDt theNumerator) {
|
||||||
|
myNumerator = theNumerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QuantityDt getDenominator() {
|
||||||
|
return myDenominator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDenominator(QuantityDt theDenominator) {
|
||||||
|
myDenominator = theDenominator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,4 +29,62 @@ public class SampledDataDt extends BaseCompositeDatatype {
|
||||||
@Child(name="data", order=6, min=1)
|
@Child(name="data", order=6, min=1)
|
||||||
@Description("Decimal values with spaces, or \"E\" | \"U\" | \"L\"")
|
@Description("Decimal values with spaces, or \"E\" | \"U\" | \"L\"")
|
||||||
private StringDt myData;
|
private StringDt myData;
|
||||||
|
|
||||||
|
public QuantityDt getOrigin() {
|
||||||
|
return myOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrigin(QuantityDt theOrigin) {
|
||||||
|
myOrigin = theOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DecimalDt getPeriod() {
|
||||||
|
return myPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPeriod(DecimalDt thePeriod) {
|
||||||
|
myPeriod = thePeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DecimalDt getFactor() {
|
||||||
|
return myFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFactor(DecimalDt theFactor) {
|
||||||
|
myFactor = theFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DecimalDt getLowerLimit() {
|
||||||
|
return myLowerLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLowerLimit(DecimalDt theLowerLimit) {
|
||||||
|
myLowerLimit = theLowerLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DecimalDt getUpperLimit() {
|
||||||
|
return myUpperLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpperLimit(DecimalDt theUpperLimit) {
|
||||||
|
myUpperLimit = theUpperLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntegerDt getDimensions() {
|
||||||
|
return myDimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDimensions(IntegerDt theDimensions) {
|
||||||
|
myDimensions = theDimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringDt getData() {
|
||||||
|
return myData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(StringDt theData) {
|
||||||
|
myData = theData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,14 +6,70 @@ 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.RuntimePrimitiveDatatypeDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.model.api.BaseCompositeDatatype;
|
import ca.uhn.fhir.context.RuntimeResourceReferenceDefinition;
|
||||||
import ca.uhn.fhir.model.api.ICompositeDatatype;
|
import ca.uhn.fhir.model.api.ICompositeDatatype;
|
||||||
import ca.uhn.fhir.model.api.ICompositeElement;
|
import ca.uhn.fhir.model.api.ICompositeElement;
|
||||||
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
import ca.uhn.fhir.model.api.ResourceReference;
|
||||||
|
|
||||||
class ParserState {
|
class ParserState {
|
||||||
|
|
||||||
|
private enum ResourceReferenceSubState {
|
||||||
|
INITIAL, REFERENCE, DISPLAY
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ResourceReferenceState extends BaseState {
|
||||||
|
|
||||||
|
private ResourceReferenceSubState mySubState;
|
||||||
|
private RuntimeResourceReferenceDefinition myDefinition;
|
||||||
|
private ResourceReference myInstance;
|
||||||
|
|
||||||
|
public ResourceReferenceState(RuntimeResourceReferenceDefinition theDefinition, ResourceReference theInstance) {
|
||||||
|
myDefinition=theDefinition;
|
||||||
|
myInstance = theInstance;
|
||||||
|
mySubState = ResourceReferenceSubState.INITIAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attributeValue(String theValue) throws DataFormatException {
|
||||||
|
switch (mySubState) {
|
||||||
|
case DISPLAY:
|
||||||
|
myInstance.setDisplay(theValue);
|
||||||
|
break;
|
||||||
|
case INITIAL:
|
||||||
|
throw new DataFormatException("Unexpected attribute: "+theValue);
|
||||||
|
case REFERENCE:
|
||||||
|
myInstance.setReference(theValue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enteringNewElement(String theLocalPart) throws DataFormatException {
|
||||||
|
switch (mySubState) {
|
||||||
|
case INITIAL:
|
||||||
|
if ("display".equals(theLocalPart)) {
|
||||||
|
mySubState = ResourceReferenceSubState.DISPLAY;
|
||||||
|
break;
|
||||||
|
} else if ("reference".equals(theLocalPart)) {
|
||||||
|
mySubState = ResourceReferenceSubState.REFERENCE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// ...else fall through...
|
||||||
|
case DISPLAY:
|
||||||
|
case REFERENCE:
|
||||||
|
throw new DataFormatException("Unexpected element: "+theLocalPart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endingElement(String theLocalPart) {
|
||||||
|
mySubState=ResourceReferenceSubState.INITIAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ParserState.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ParserState.class);
|
||||||
private FhirContext myContext;
|
private FhirContext myContext;
|
||||||
|
|
||||||
|
@ -106,11 +162,17 @@ private abstract class BaseState {
|
||||||
push(newState);
|
push(newState);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RESOURCE: {
|
case RESOURCE_REF: {
|
||||||
|
RuntimeResourceReferenceDefinition resourceRefTarget = (RuntimeResourceReferenceDefinition) target;
|
||||||
|
ResourceReference newChildInstance = new ResourceReference();
|
||||||
|
child.getMutator().addValue(myInstance, newChildInstance);
|
||||||
|
ResourceReferenceState newState = new ResourceReferenceState(resourceRefTarget, newChildInstance);
|
||||||
|
push(newState);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case RESOURCE:
|
||||||
default:
|
default:
|
||||||
throw new DataFormatException("Illegal resource position");
|
throw new DataFormatException("Illegal resource position: " + target.getChildType());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import org.junit.Test;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.resource.Observation;
|
import ca.uhn.fhir.model.resource.Observation;
|
||||||
|
|
||||||
public class XmlParserTest {
|
public class XmlParserTest {
|
||||||
|
@ -17,7 +18,9 @@ public class XmlParserTest {
|
||||||
FhirContext ctx = new FhirContext(Observation.class);
|
FhirContext ctx = new FhirContext(Observation.class);
|
||||||
XmlParser p = new XmlParser(ctx);
|
XmlParser p = new XmlParser(ctx);
|
||||||
|
|
||||||
p.parseResource(IOUtils.toString(XmlParserTest.class.getResourceAsStream("/observation-example-eeg.xml")));
|
IResource resource = p.parseResource(IOUtils.toString(XmlParserTest.class.getResourceAsStream("/observation-example-eeg.xml")));
|
||||||
|
|
||||||
|
System.out.println(resource);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue