Client working

This commit is contained in:
jamesagnew 2014-03-06 17:12:05 -05:00
parent 82193017d8
commit b33d4028ab
42 changed files with 1758 additions and 598 deletions

View File

@ -1,86 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry including="**/*.java" kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry excluding="**/*.java" kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry including="**/*.java" kind="src" path="src/main/java"/>
<classpathentry kind="var" path="M2_REPO/javax/servlet/javax.servlet-api/3.0.1/javax.servlet-api-3.0.1.jar" sourcepath="M2_REPO/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0-javadoc.jar!/"/>
</attributes>
</classpathentry>
<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">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/commons-codec/commons-codec/1.9/commons-codec-1.9-javadoc.jar!/"/>
</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 name="javadoc_location" value="jar:file:/Users/james/.m2/repository/commons-io/commons-io/1.3.2/commons-io-1.3.2-javadoc.jar!/"/>
</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 name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar" sourcepath="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1-javadoc.jar!/"/>
</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 name="javadoc_location" value="jar:file:/Users/james/.m2/repository/com/google/code/gson/gson/2.2.4/gson-2.2.4-javadoc.jar!/"/>
</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 name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/apache/httpcomponents/httpclient/4.2.3/httpclient-4.2.3.jar" sourcepath="M2_REPO/org/apache/httpcomponents/httpclient/4.2.3/httpclient-4.2.3-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/httpcomponents/httpcore/4.2.2/httpcore-4.2.2.jar" sourcepath="M2_REPO/org/apache/httpcomponents/httpcore/4.2.2/httpcore-4.2.2-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-continuation/9.1.1.v20140108/jetty-continuation-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-continuation/9.1.1.v20140108/jetty-continuation-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-http/9.1.1.v20140108/jetty-http-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-http/9.1.1.v20140108/jetty-http-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-io/9.1.1.v20140108/jetty-io-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-io/9.1.1.v20140108/jetty-io-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-security/9.1.1.v20140108/jetty-security-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-security/9.1.1.v20140108/jetty-security-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-server/9.1.1.v20140108/jetty-server-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-server/9.1.1.v20140108/jetty-server-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-servlet/9.1.1.v20140108/jetty-servlet-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-servlet/9.1.1.v20140108/jetty-servlet-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-servlets/9.1.1.v20140108/jetty-servlets-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-servlets/9.1.1.v20140108/jetty-servlets-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-util/9.1.1.v20140108/jetty-util-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-util/9.1.1.v20140108/jetty-util-9.1.1.v20140108-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>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/junit/junit/4.11/junit-4.11-javadoc.jar!/"/>
</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 name="javadoc_location" value="jar:file:/Users/james/.m2/repository/ch/qos/logback/logback-classic/1.1.1/logback-classic-1.1.1-javadoc.jar!/"/>
</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 name="javadoc_location" value="jar:file:/Users/james/.m2/repository/ch/qos/logback/logback-core/1.1.1/logback-core-1.1.1-javadoc.jar!/"/>
</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 name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/slf4j/slf4j-api/1.7.6/slf4j-api-1.7.6-javadoc.jar!/"/>
</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 name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/xmlunit/xmlunit/1.5/xmlunit-1.5.jar" sourcepath="M2_REPO/xmlunit/xmlunit/1.5/xmlunit-1.5-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/xmlunit/xmlunit/1.5/xmlunit-1.5-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="var" path="M2_REPO/org/mockito/mockito-all/1.9.5/mockito-all-1.9.5.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
<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/main/java" including="**/*.java"/>
<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/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar" sourcepath="M2_REPO/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0-sources.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<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:/home/t3903uhn/.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/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/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>
</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/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar" sourcepath="M2_REPO/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar" sourcepath="M2_REPO/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar" sourcepath="M2_REPO/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3-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>
<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>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/commons-io/commons-io/2.4/commons-io-2.4.jar" sourcepath="M2_REPO/commons-io/commons-io/2.4/commons-io-2.4-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/xmlunit/xmlunit/1.5/xmlunit-1.5.jar" sourcepath="M2_REPO/xmlunit/xmlunit/1.5/xmlunit-1.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-servlets/9.1.1.v20140108/jetty-servlets-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-servlets/9.1.1.v20140108/jetty-servlets-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-continuation/9.1.1.v20140108/jetty-continuation-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-continuation/9.1.1.v20140108/jetty-continuation-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-http/9.1.1.v20140108/jetty-http-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-http/9.1.1.v20140108/jetty-http-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-util/9.1.1.v20140108/jetty-util-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-util/9.1.1.v20140108/jetty-util-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-io/9.1.1.v20140108/jetty-io-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-io/9.1.1.v20140108/jetty-io-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-servlet/9.1.1.v20140108/jetty-servlet-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-servlet/9.1.1.v20140108/jetty-servlet-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-security/9.1.1.v20140108/jetty-security-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-security/9.1.1.v20140108/jetty-security-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-server/9.1.1.v20140108/jetty-server-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-server/9.1.1.v20140108/jetty-server-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/mockito/mockito-all/1.9.5/mockito-all-1.9.5.jar" sourcepath="M2_REPO/org/mockito/mockito-all/1.9.5/mockito-all-1.9.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-httpclient/commons-httpclient/3.1/commons-httpclient-3.1.jar" sourcepath="M2_REPO/commons-httpclient/commons-httpclient/3.1/commons-httpclient-3.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/directory-naming/naming-java/0.8/naming-java-0.8.jar"/>
<classpathentry kind="var" path="M2_REPO/directory-naming/naming-core/0.8/naming-core-0.8.jar"/>
</classpath>

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>hapi-fhir-base</name>
<comment>NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment>

View File

@ -61,7 +61,12 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.3</version>
<version>4.3.3</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.3.2</version>
</dependency>
<!-- Server -->

View File

@ -8,7 +8,9 @@ import java.util.Set;
import ca.uhn.fhir.model.api.IElement;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.parser.XmlParser;
import ca.uhn.fhir.rest.client.RestfulClientFactory;
public class FhirContext {
@ -47,8 +49,12 @@ public class FhirContext {
return (RuntimeResourceDefinition) myClassToElementDefinition.get(theResource.getClass());
}
public XmlParser newXmlParser() {
public IParser newXmlParser() {
return new XmlParser(this);
}
public RestfulClientFactory newClientFactory() {
return new RestfulClientFactory(this);
}
}

View File

@ -20,7 +20,16 @@ public class Bundle extends BaseBundle implements IElement {
private InstantDt myPublished;
private StringDt myTitle;
private IntegerDt myTotalResults;
private InstantDt myUpdated;
private InstantDt myUpdated;
/**
* Adds and returns a new bundle entry
*/
public BundleEntry addEntry() {
BundleEntry retVal = new BundleEntry();
getEntries().add(retVal);
return retVal;
}
public List<BundleEntry> getEntries() {
if (myEntries == null) {
@ -87,25 +96,39 @@ public class Bundle extends BaseBundle implements IElement {
public StringDt getTitle() {
if (myTitle == null) {
myTitle= new StringDt();
myTitle = new StringDt();
}
return myTitle;
}
public IntegerDt getTotalResults() {
if (myTotalResults== null) {
myTotalResults= new IntegerDt();
if (myTotalResults == null) {
myTotalResults = new IntegerDt();
}
return myTotalResults;
}
public InstantDt getUpdated() {
if (myUpdated == null) {
myUpdated= new InstantDt();
myUpdated = new InstantDt();
}
return myUpdated;
}
public List<IResource> toListOfResources() {
ArrayList<IResource> retVal = new ArrayList<IResource>();
for (BundleEntry next : getEntries()) {
if (next.getResource() != null) {
retVal.add(next.getResource());
}
}
return retVal;
}
public static Bundle withSingleResource(IResource theResource) {
Bundle retVal = new Bundle();
retVal.addEntry().setResource(theResource);
return retVal;
}
}

View File

@ -0,0 +1,33 @@
package ca.uhn.fhir.model.api;
public class BundleCategory {
private String myLabel;
private String myScheme;
private String myTerm;
public String getLabel() {
return myLabel;
}
public String getScheme() {
return myScheme;
}
public String getTerm() {
return myTerm;
}
public void setLabel(String theLabel) {
myLabel = theLabel;
}
public void setScheme(String theScheme) {
myScheme = theScheme;
}
public void setTerm(String theTerm) {
myTerm = theTerm;
}
}

View File

@ -1,5 +1,8 @@
package ca.uhn.fhir.model.api;
import java.util.ArrayList;
import java.util.List;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.model.primitive.XhtmlDt;
@ -12,6 +15,7 @@ public class BundleEntry extends BaseBundle {
private StringDt myTitle;
private InstantDt myUpdated;
private XhtmlDt mySummary;
private List<BundleCategory> myCategories;
public StringDt getId() {
if (myId == null) {
@ -70,4 +74,17 @@ public class BundleEntry extends BaseBundle {
return mySummary;
}
public BundleCategory addCategory() {
BundleCategory retVal = new BundleCategory();
getCategories().add(retVal);
return retVal;
}
public List<BundleCategory> getCategories() {
if (myCategories == null) {
myCategories = new ArrayList<BundleCategory>();
}
return myCategories;
}
}

View File

@ -1,6 +1,7 @@
package ca.uhn.fhir.model.api;
public interface ICompositeDatatype extends IDatatype, ICompositeElement {
public interface ICompositeDatatype extends IDatatype, ICompositeElement {
}

View File

@ -0,0 +1,26 @@
package ca.uhn.fhir.model.api;
public interface IQueryParameterType {
/**
* Sets the value of this type using the <b>token</b> format. This
* format is used in HTTP queries as a parameter format.
*
* @see See FHIR specification
* <a href="http://www.hl7.org/implement/standards/fhir/search.html#ptypes">2.2.2 Search Parameter Types</a>
* for information on the <b>token</b> format
*/
public void setValueAsQueryToken(String theParameter);
/**
* Returns the value of this type using the <b>token</b> format. This
* format is used in HTTP queries as a parameter format.
*
* @see See FHIR specification
* <a href="http://www.hl7.org/implement/standards/fhir/search.html#ptypes">2.2.2 Search Parameter Types</a>
* for information on the <b>token</b> format
*/
public String getValueAsQueryToken();
}

View File

@ -17,6 +17,7 @@
package ca.uhn.fhir.model.dstu.composite;
import java.util.*;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.api.annotation.*;
import ca.uhn.fhir.model.primitive.*;
@ -38,7 +39,7 @@ import ca.uhn.fhir.model.dstu.resource.*;
* </p>
*/
@DatatypeDef(name="Identifier")
public class IdentifierDt extends BaseElement implements ICompositeDatatype {
public class IdentifierDt extends BaseElement implements ICompositeDatatype, IQueryParameterType {
@Child(name="use", type=CodeDt.class, order=0, min=0, max=1)
private BoundCodeDt<IdentifierUseEnum> myUse;
@ -61,6 +62,21 @@ public class IdentifierDt extends BaseElement implements ICompositeDatatype {
})
private ResourceReference myAssigner;
/**
* Creates a new identifier
*/
public IdentifierDt() {
// nothing
}
/**
* Creates a new identifier with the given system and value
*/
public IdentifierDt(String theSystem, String theValue) {
setSystem(theSystem);
setValue(theValue);
}
/**
* Gets the value(s) for <b>use</b> (usual | official | temp | secondary (If known)
).
@ -303,13 +319,21 @@ public class IdentifierDt extends BaseElement implements ICompositeDatatype {
}
/**
* Sets the value of this <code>IdentifierDt</code> using the <b>token</b> format. This
* format is used in HTTP queries as a parameter format.
*
* @see See FHIR specification
* <a href="http://www.hl7.org/implement/standards/fhir/search.html#ptypes">2.2.2 Search Parameter Types</a>
* for information on the <b>token</b> format
* {@inheritDoc}
*/
@Override
public String getValueAsQueryToken() {
if (org.apache.commons.lang3.StringUtils.isNotBlank(getSystem().getValueAsString())) {
return getSystem().getValueAsString() + '|' + getValue().getValueAsString();
} else {
return getValue().getValueAsString();
}
}
/**
* {@inheritDoc}
*/
@Override
public void setValueAsQueryToken(String theParameter) {
int barIndex = theParameter.indexOf('|');
if (barIndex != -1) {

View File

@ -4,12 +4,13 @@ import org.apache.commons.lang3.StringUtils;
import ca.uhn.fhir.model.api.BaseElement;
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
import ca.uhn.fhir.model.api.annotation.SimpleSetter;
import ca.uhn.fhir.parser.DataFormatException;
@DatatypeDef(name = "string")
public class StringDt extends BaseElement implements IPrimitiveDatatype<String> {
public class StringDt extends BaseElement implements IPrimitiveDatatype<String>, IQueryParameterType {
private String myValue;
@ -84,6 +85,22 @@ public class StringDt extends BaseElement implements IPrimitiveDatatype<String>
return false;
return true;
}
/**
* {@inheritDoc}
*/
@Override
public void setValueAsQueryToken(String theParameter) {
setValue(theParameter);
}
/**
* {@inheritDoc}
*/
@Override
public String getValueAsQueryToken() {
return getValue();
}
}

View File

@ -0,0 +1,36 @@
package ca.uhn.fhir.parser;
import java.io.Reader;
import java.io.Writer;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
public interface IParser {
String encodeBundleToString(Bundle theBundle) throws DataFormatException;
void encodeBundleToWriter(Bundle theBundle, Writer theWriter);
String encodeResourceToString(IResource theResource) throws DataFormatException;
void encodeResourceToWriter(IResource theResource, Writer stringWriter);
void encodeResourceToXmlStreamWriter(IResource theResource, XMLStreamWriter eventWriter) throws XMLStreamException, DataFormatException;
Bundle parseBundle(Reader theReader);
Bundle parseBundle(String theXml) throws ConfigurationException, DataFormatException;
IResource parseResource(String theXml) throws ConfigurationException, DataFormatException;
IResource parseResource(Reader theReader) throws ConfigurationException, DataFormatException;
IResource parseResource(XMLEventReader theStreamReader);
}

View File

@ -15,7 +15,6 @@ import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
import ca.uhn.fhir.context.RuntimeChildPrimitiveBoundCodeDatatypeDefinition;
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition;
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeNarrativeDefinition;
import ca.uhn.fhir.context.RuntimeResourceBlockDefinition;
@ -23,6 +22,7 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeResourceReferenceDefinition;
import ca.uhn.fhir.model.api.BaseBundle;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleCategory;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.ICompositeDatatype;
import ca.uhn.fhir.model.api.ICompositeElement;
@ -84,9 +84,7 @@ class ParserState<T extends IElement> {
}
/**
* Invoked after any new XML event is individually processed, containing a
* copy of the XML event. This is basically intended for embedded XHTML
* content
* Invoked after any new XML event is individually processed, containing a copy of the XML event. This is basically intended for embedded XHTML content
*/
public void xmlEvent(XMLEvent theNextEvent) {
myState.xmlEvent(theNextEvent);
@ -140,6 +138,37 @@ class ParserState<T extends IElement> {
}
public class AtomCategoryState extends BaseState {
private BundleCategory myInstance;
public AtomCategoryState(BundleCategory theEntry) {
myInstance = theEntry;
}
@Override
public void endingElement(EndElement theElem) throws DataFormatException {
pop();
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
throw new DataFormatException("Unexpected element: " + theLocalPart);
}
@Override
public void attributeValue(String theName, String theValue) throws DataFormatException {
if ("term".equals(theName)) {
myInstance.setTerm(theValue);
} else if ("label".equals(theName)) {
myInstance.setLabel(theValue);
} else if ("scheme".equals(theName)) {
myInstance.setScheme(theValue);
}
}
}
public class AtomEntryState extends BaseState {
private BundleEntry myEntry;
@ -171,7 +200,9 @@ class ParserState<T extends IElement> {
} else if ("content".equals(theLocalPart)) {
push(new PreResourceState(myEntry));
} else if ("summary".equals(theLocalPart)) {
push(new XhtmlState(myEntry.getSummary(),false));
push(new XhtmlState(myEntry.getSummary(), false));
} else if ("category".equals(theLocalPart)) {
push(new AtomCategoryState(myEntry.addCategory()));
} else {
throw new DataFormatException("Unexpected element in entry: " + theLocalPart);
}
@ -281,8 +312,6 @@ class ParserState<T extends IElement> {
myInstance = theInstance;
}
@Override
public void endingElement(EndElement theElem) throws DataFormatException {
pop();
@ -307,7 +336,7 @@ class ParserState<T extends IElement> {
} else if ("author".equals(theLocalPart)) {
push(new AtomAuthorState(myInstance));
} else {
throw new DataFormatException("Unexpected element: "+ theLocalPart);
throw new DataFormatException("Unexpected element: " + theLocalPart);
}
// TODO: handle category and DSig
@ -387,7 +416,6 @@ class ParserState<T extends IElement> {
myParentInstance = theParentInstance;
}
@Override
public void endingElement(EndElement theElem) throws DataFormatException {
pop();
@ -522,7 +550,7 @@ class ParserState<T extends IElement> {
RuntimePrimitiveDatatypeNarrativeDefinition xhtmlTarget = (RuntimePrimitiveDatatypeNarrativeDefinition) target;
XhtmlDt newDt = xhtmlTarget.newInstance();
child.getMutator().addValue(myInstance, newDt);
XhtmlState state = new XhtmlState(newDt,true);
XhtmlState state = new XhtmlState(newDt, true);
push(state);
return;
}
@ -562,7 +590,6 @@ class ParserState<T extends IElement> {
myExtension = theExtension;
}
@Override
public void endingElement(EndElement theElem) throws DataFormatException {
if (myExtension.getValue() != null && myExtension.getUndeclaredExtensions().size() > 0) {
@ -622,7 +649,6 @@ class ParserState<T extends IElement> {
private Bundle myInstance;
@Override
public void endingElement(EndElement theElem) throws DataFormatException {
// ignore
@ -666,7 +692,6 @@ class ParserState<T extends IElement> {
myEntry = theEntry;
}
@Override
public void endingElement(EndElement theElem) throws DataFormatException {
pop();
@ -723,14 +748,14 @@ class ParserState<T extends IElement> {
pop();
}
// @Override
// public void enteringNewElementExtension(StartElement theElement, String theUrlAttr) {
// if (myInstance instanceof ISupportsUndeclaredExtensions) {
// UndeclaredExtension ext = new UndeclaredExtension(theUrlAttr);
// ((ISupportsUndeclaredExtensions) myInstance).getUndeclaredExtensions().add(ext);
// push(new ExtensionState(ext));
// }
// }
// @Override
// public void enteringNewElementExtension(StartElement theElement, String theUrlAttr) {
// if (myInstance instanceof ISupportsUndeclaredExtensions) {
// UndeclaredExtension ext = new UndeclaredExtension(theUrlAttr);
// ((ISupportsUndeclaredExtensions) myInstance).getUndeclaredExtensions().add(ext);
// push(new ExtensionState(ext));
// }
// }
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
@ -761,7 +786,7 @@ class ParserState<T extends IElement> {
if (!"value".equals(theName)) {
return;
}
switch (mySubState) {
case DISPLAY:
myInstance.setDisplay(theValue);
@ -840,7 +865,7 @@ class ParserState<T extends IElement> {
if (theEvent.isStartElement()) {
myDepth++;
}
if (theEvent.isEndElement()) {
if (myDepth == 0) {
myDt.setValue(myEvents);

View File

@ -3,6 +3,7 @@ package ca.uhn.fhir.parser;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
@ -48,7 +49,7 @@ import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.model.primitive.XhtmlDt;
import ca.uhn.fhir.util.PrettyPrintWriterWrapper;
public class XmlParser {
public class XmlParser implements IParser {
static final String ATOM_NS = "http://www.w3.org/2005/Atom";
static final String FHIR_NS = "http://hl7.org/fhir";
static final String OPENSEARCH_NS = "http://a9.com/-/spec/opensearch/1.1/";
@ -139,6 +140,10 @@ public class XmlParser {
}
}
/* (non-Javadoc)
* @see ca.uhn.fhir.parser.IParser#encodeBundleToString(ca.uhn.fhir.model.api.Bundle)
*/
@Override
public String encodeBundleToString(Bundle theBundle) throws DataFormatException {
StringWriter stringWriter = new StringWriter();
encodeBundleToWriter(theBundle, stringWriter);
@ -146,6 +151,10 @@ public class XmlParser {
return stringWriter.toString();
}
/* (non-Javadoc)
* @see ca.uhn.fhir.parser.IParser#encodeBundleToWriter(ca.uhn.fhir.model.api.Bundle, java.io.Writer)
*/
@Override
public void encodeBundleToWriter(Bundle theBundle, Writer theWriter) {
try {
XMLStreamWriter eventWriter;
@ -336,12 +345,20 @@ public class XmlParser {
}
}
/* (non-Javadoc)
* @see ca.uhn.fhir.parser.IParser#encodeResourceToString(ca.uhn.fhir.model.api.IResource)
*/
@Override
public String encodeResourceToString(IResource theResource) throws DataFormatException {
Writer stringWriter = new StringWriter();
encodeResourceToWriter(theResource, stringWriter);
return stringWriter.toString();
}
/* (non-Javadoc)
* @see ca.uhn.fhir.parser.IParser#encodeResourceToWriter(ca.uhn.fhir.model.api.IResource, java.io.Writer)
*/
@Override
public void encodeResourceToWriter(IResource theResource, Writer stringWriter) {
XMLStreamWriter eventWriter;
try {
@ -354,6 +371,10 @@ public class XmlParser {
}
}
/* (non-Javadoc)
* @see ca.uhn.fhir.parser.IParser#encodeResourceToXmlStreamWriter(ca.uhn.fhir.model.api.IResource, javax.xml.stream.XMLStreamWriter)
*/
@Override
public void encodeResourceToXmlStreamWriter(IResource theResource, XMLStreamWriter eventWriter) throws XMLStreamException, DataFormatException {
RuntimeResourceDefinition resDef = myContext.getResourceDefinition(theResource);
eventWriter.writeStartElement(resDef.getName());
@ -411,13 +432,22 @@ public class XmlParser {
StartElement se = event.asStartElement();
if (firstEvent) {
theEventWriter.writeStartElement(se.getName().getLocalPart());
theEventWriter.writeNamespace(se.getName().getPrefix(), se.getName().getNamespaceURI());
if (StringUtils.isBlank(se.getName().getPrefix())) {
theEventWriter.writeDefaultNamespace(se.getName().getNamespaceURI());
}else {
theEventWriter.writeNamespace(se.getName().getPrefix(), se.getName().getNamespaceURI());
}
} else {
if (isBlank(se.getName().getPrefix())) {
if (isBlank(se.getName().getNamespaceURI())) {
theEventWriter.writeStartElement(se.getName().getLocalPart());
} else {
if (StringUtils.isBlank(se.getName().getPrefix())) {
theEventWriter.writeStartElement(se.getName().getLocalPart());
theEventWriter.writeDefaultNamespace(se.getName().getNamespaceURI());
}else {
theEventWriter.writeStartElement(se.getName().getNamespaceURI(), se.getName().getLocalPart());
}
}
} else {
theEventWriter.writeStartElement(se.getName().getPrefix(), se.getName().getLocalPart(), se.getName().getNamespaceURI());
@ -437,17 +467,13 @@ public class XmlParser {
}
}
/* (non-Javadoc)
* @see ca.uhn.fhir.parser.IParser#parseBundle(java.lang.String)
*/
@Override
public Bundle parseBundle(String theXml) throws ConfigurationException, DataFormatException {
XMLEventReader streamReader;
try {
streamReader = myXmlInputFactory.createXMLEventReader(new StringReader(theXml));
} catch (XMLStreamException e) {
throw new DataFormatException(e);
} catch (FactoryConfigurationError e) {
throw new ConfigurationException("Failed to initialize STaX event factory", e);
}
return parseBundle(streamReader);
StringReader reader = new StringReader(theXml);
return parseBundle(reader);
}
private Bundle parseBundle(XMLEventReader theStreamReader) {
@ -455,19 +481,19 @@ public class XmlParser {
return doXmlLoop(theStreamReader, parserState);
}
/* (non-Javadoc)
* @see ca.uhn.fhir.parser.IParser#parseResource(java.lang.String)
*/
@Override
public IResource parseResource(String theXml) throws ConfigurationException, DataFormatException {
XMLEventReader streamReader;
try {
streamReader = myXmlInputFactory.createXMLEventReader(new StringReader(theXml));
} catch (XMLStreamException e) {
throw new DataFormatException(e);
} catch (FactoryConfigurationError e) {
throw new ConfigurationException("Failed to initialize STaX event factory", e);
}
return parseResource(streamReader);
StringReader reader = new StringReader(theXml);
return parseResource(reader);
}
/* (non-Javadoc)
* @see ca.uhn.fhir.parser.IParser#parseResource(javax.xml.stream.XMLEventReader)
*/
@Override
public IResource parseResource(XMLEventReader theStreamReader) {
ParserState<IResource> parserState = ParserState.getPreResourceInstance(myContext);
return doXmlLoop(theStreamReader, parserState);
@ -504,4 +530,32 @@ public class XmlParser {
}
theEventWriter.writeEndElement();
}
@Override
public Bundle parseBundle(Reader theReader) {
XMLEventReader streamReader;
try {
streamReader = myXmlInputFactory.createXMLEventReader(theReader);
} catch (XMLStreamException e) {
throw new DataFormatException(e);
} catch (FactoryConfigurationError e) {
throw new ConfigurationException("Failed to initialize STaX event factory", e);
}
return parseBundle(streamReader);
}
@Override
public IResource parseResource(Reader theReader) throws ConfigurationException, DataFormatException {
XMLEventReader streamReader;
try {
streamReader = myXmlInputFactory.createXMLEventReader(theReader);
} catch (XMLStreamException e) {
throw new DataFormatException(e);
} catch (FactoryConfigurationError e) {
throw new ConfigurationException("Failed to initialize STaX event factory", e);
}
return parseResource(streamReader);
}
}

View File

@ -0,0 +1,14 @@
package ca.uhn.fhir.rest.client;
import org.apache.http.client.methods.HttpRequestBase;
public abstract class BaseClientInvocation {
/**
* Create an HTTP request out of this client request
*
* @param theUrlBase The FHIR server base url (with a trailing "/")
*/
public abstract HttpRequestBase asHttpRequest(String theUrlBase);
}

View File

@ -1,5 +0,0 @@
package ca.uhn.fhir.rest.client;
public class ClientInvocation {
}

View File

@ -1,35 +1,117 @@
package ca.uhn.fhir.rest.client;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ContentType;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.client.exceptions.InvalidResponseException;
import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
import ca.uhn.fhir.rest.common.BaseMethodBinding;
import ca.uhn.fhir.rest.server.Constants;
public class ClientInvocationHandler implements InvocationHandler {
private HttpClient myClient;
private Map<Method, BaseMethodBinding> myBindings = new HashMap<Method, BaseMethodBinding>();
private FhirContext myContext;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ClientInvocationHandler.class);
private final Map<Method, BaseMethodBinding> myBindings = new HashMap<Method, BaseMethodBinding>();
private final HttpClient myClient;
private final FhirContext myContext;
private final String myUrlBase;
public ClientInvocationHandler(HttpClient theClient, FhirContext theContext) {
public ClientInvocationHandler(HttpClient theClient, FhirContext theContext, String theUrlBase) {
myClient = theClient;
myContext = theContext;
}
@Override
public Object invoke(Object theProxy, Method theMethod, Object[] theArgs) throws Throwable {
BaseMethodBinding binding = myBindings.get(theMethod);
ClientInvocation clientInvocation = binding.invokeClient(theArgs);
return null;
myUrlBase = theUrlBase;
}
public void addBinding(Method theMethod, BaseMethodBinding theBinding) {
myBindings.put(theMethod, theBinding);
}
@Override
public Object invoke(Object theProxy, Method theMethod, Object[] theArgs) throws Throwable {
BaseMethodBinding binding = myBindings.get(theMethod);
GetClientInvocation clientInvocation = binding.invokeClient(theArgs);
HttpRequestBase httpRequest = clientInvocation.asHttpRequest(myUrlBase);
HttpResponse response = myClient.execute(httpRequest);
ContentType ct = ContentType.get(response.getEntity());
Charset charset = ct.getCharset();
if (charset == null) {
ourLog.warn("Response did not specify a charset.");
charset = Charset.forName("UTF-8");
}
Reader reader = new InputStreamReader(response.getEntity().getContent(), charset);
if (ourLog.isTraceEnabled()) {
String responseString = IOUtils.toString(reader);
ourLog.trace("FHIR response:\n{}\n{}", response, responseString);
reader = new StringReader(responseString);
}
IParser parser;
String mimeType = ct.getMimeType();
if (Constants.CT_ATOM_XML.equals(mimeType)) {
parser = myContext.newXmlParser();
} else if (Constants.CT_FHIR_XML.equals(mimeType)) {
parser = myContext.newXmlParser();
} else {
throw new NonFhirResponseException("Response contains non-FHIR content-type: " + mimeType, mimeType, response.getStatusLine().getStatusCode(), IOUtils.toString(reader));
}
switch (binding.getReturnType()) {
case BUNDLE: {
Bundle bundle = parser.parseBundle(reader);
switch (binding.getMethodReturnType()) {
case BUNDLE:
return bundle;
case LIST_OF_RESOURCES:
return bundle.toListOfResources();
case RESOURCE:
List<IResource> list = bundle.toListOfResources();
if (list.size() == 0) {
return null;
} else if (list.size() == 1) {
return list.get(1);
} else {
throw new InvalidResponseException("FHIR server call returned a bundle with multiple resources, but this method is only able to returns one.");
}
}
break;
}
case RESOURCE: {
IResource resource = parser.parseResource(reader);
switch (binding.getMethodReturnType()) {
case BUNDLE:
return Bundle.withSingleResource(resource);
case LIST_OF_RESOURCES:
return Collections.singletonList(resource);
case RESOURCE:
return resource;
}
break;
}
}
throw new IllegalStateException("Should not get here!");
}
}

View File

@ -0,0 +1,41 @@
package ca.uhn.fhir.rest.client;
import java.util.Collections;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestBase;
import ca.uhn.fhir.rest.common.BaseMethodBinding;
public class GetClientInvocation extends BaseClientInvocation {
private final Map<String, String> myParameters;
private final String myUrlPath;
public GetClientInvocation(Map<String, String> theParameters, String... theUrlFragments) {
myParameters = theParameters;
myUrlPath = StringUtils.join(theUrlFragments, '/');
}
public GetClientInvocation(String... theUrlFragments) {
myParameters = Collections.emptyMap();
myUrlPath = StringUtils.join(theUrlFragments, '/');
}
public Map<String, String> getParameters() {
return myParameters;
}
public String getUrlPath() {
return myUrlPath;
}
@Override
public HttpRequestBase asHttpRequest(String theUrlBase) {
return new HttpGet(theUrlBase + myUrlPath);
}
}

View File

@ -6,8 +6,11 @@ import java.lang.reflect.Proxy;
import java.util.concurrent.TimeUnit;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.conn.SchemeRegistryFactory;
import ca.uhn.fhir.context.ConfigurationException;
@ -46,10 +49,12 @@ public class RestfulClientFactory {
throw new ConfigurationException(theClientType.getCanonicalName() + " is not an interface");
}
PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager(SchemeRegistryFactory.createDefault(), 5000, TimeUnit.MILLISECONDS);
HttpClient client = new DefaultHttpClient(connectionManager);
ClientInvocationHandler theInvocationHandler = new ClientInvocationHandler(client, myContext);
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setConnectionManager(connectionManager);
CloseableHttpClient client = builder.build();
ClientInvocationHandler theInvocationHandler = new ClientInvocationHandler(client, myContext, theServerBase);
for (Method nextMethod : theClientType.getMethods()) {
BaseMethodBinding binding = BaseMethodBinding.bindMethod(nextMethod);

View File

@ -0,0 +1,39 @@
package ca.uhn.fhir.rest.client.exceptions;
public abstract class BaseServerResponseException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
* Constructor
*
* @param theMessage
* The message
*/
public BaseServerResponseException(String theMessage) {
super(theMessage);
}
/**
* Constructor
*
* @param theMessage
* The message
* @param theCause The cause
*/
public BaseServerResponseException(String theMessage, Throwable theCause) {
super(theMessage, theCause);
}
/**
* Constructor
*
* @param theCause
* The underlying cause exception
*/
public BaseServerResponseException(Throwable theCause) {
super(theCause.toString(), theCause);
}
}

View File

@ -0,0 +1,38 @@
package ca.uhn.fhir.rest.client.exceptions;
public class InvalidResponseException extends BaseServerResponseException {
private static final long serialVersionUID = 1L;
/**
* Constructor
*
* @param theMessage
* The message
*/
public InvalidResponseException(String theMessage) {
super(theMessage);
}
/**
* Constructor
*
* @param theMessage
* The message
* @param theCause The cause
*/
public InvalidResponseException(String theMessage, Throwable theCause) {
super(theMessage, theCause);
}
/**
* Constructor
*
* @param theCause
* The underlying cause exception
*/
public InvalidResponseException(Throwable theCause) {
super(theCause.toString(), theCause);
}
}

View File

@ -0,0 +1,40 @@
package ca.uhn.fhir.rest.client.exceptions;
public class NonFhirResponseException extends BaseServerResponseException {
private static final long serialVersionUID = 1L;
private final String myContentType;
private final int myStatusCode;
private final String myResponseText;
/**
* Constructor
*
* @param theMessage
* The message
* @param theResponseText
* @param theStatusCode
* @param theContentType
*/
public NonFhirResponseException(String theMessage, String theContentType, int theStatusCode, String theResponseText) {
super(theMessage);
myContentType=theContentType;
myStatusCode=theStatusCode;
myResponseText=theResponseText;
}
public String getContentType() {
return myContentType;
}
public int getStatusCode() {
return myStatusCode;
}
public String getResponseText() {
return myResponseText;
}
}

View File

@ -9,11 +9,12 @@ import java.util.Map;
import java.util.Set;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.client.ClientInvocation;
import ca.uhn.fhir.rest.client.GetClientInvocation;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.Resource;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
@ -23,23 +24,23 @@ import ca.uhn.fhir.rest.server.operations.Search;
public abstract class BaseMethodBinding {
private String myResourceName;
private MethodReturnTypeEnum myMethodReturnType;
public BaseMethodBinding(Class<? extends IResource> theAnnotatedResourceType) {
public BaseMethodBinding(MethodReturnTypeEnum theMethodReturnType, Class<? extends IResource> theAnnotatedResourceType) {
ResourceDef resourceDefAnnotation = theAnnotatedResourceType.getAnnotation(ResourceDef.class);
if (resourceDefAnnotation == null) {
throw new ConfigurationException(theAnnotatedResourceType.getCanonicalName() + " has no @" + ResourceDef.class.getSimpleName()+ " annotation");
throw new ConfigurationException(theAnnotatedResourceType.getCanonicalName() + " has no @" + ResourceDef.class.getSimpleName() + " annotation");
}
myResourceName = resourceDefAnnotation.name();
myMethodReturnType = theMethodReturnType;
}
public abstract ReturnTypeEnum getReturnType();
public ClientInvocation invokeClient(Object[] theArgs) {
// TODO Auto-generated method stub
return null;
}
public abstract GetClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException;
public abstract List<IResource> invokeServer(IResourceProvider theResourceProvider, IdDt theId, IdDt theVersionId, Map<String, String[]> theParameterValues) throws InvalidRequestException, InternalErrorException;
public abstract List<IResource> invokeServer(IResourceProvider theResourceProvider, IdDt theId, IdDt theVersionId, Map<String, String[]> theParameterValues) throws InvalidRequestException,
InternalErrorException;
public abstract boolean matches(String theResourceName, IdDt theId, IdDt theVersion, Set<String> theParameterNames);
@ -60,11 +61,21 @@ public abstract class BaseMethodBinding {
}
Class<?> methodReturnType = theMethod.getReturnType();
MethodReturnTypeEnum methodReturnTypeEnum;
if (methodReturnType.equals(List.class)) {
methodReturnTypeEnum = MethodReturnTypeEnum.LIST_OF_RESOURCES;
} else if (methodReturnType.isAssignableFrom(annotatedResourceType)) {
methodReturnTypeEnum = MethodReturnTypeEnum.RESOURCE;
} else if (Bundle.class.isAssignableFrom(methodReturnType)) {
methodReturnTypeEnum = MethodReturnTypeEnum.LIST_OF_RESOURCES;
} else {
throw new ConfigurationException("Invalid return type '" + methodReturnType.getCanonicalName() + "' on method '" + theMethod.getName() + "' on type: " + theMethod.getDeclaringClass().getCanonicalName());
}
if (read != null) {
return new ReadMethodBinding(annotatedResourceType, theMethod);
return new ReadMethodBinding(methodReturnTypeEnum, annotatedResourceType, theMethod);
} else if (search != null) {
return new SearchMethodBinding(annotatedResourceType, theMethod);
return new SearchMethodBinding(methodReturnTypeEnum, annotatedResourceType, theMethod);
} else {
throw new ConfigurationException("Did not detect any FHIR annotations on method '" + theMethod.getName() + "' on type: " + theMethod.getDeclaringClass().getCanonicalName());
}
@ -98,8 +109,8 @@ public abstract class BaseMethodBinding {
if (obj1 == null) {
obj1 = object;
} else {
throw new ConfigurationException("Method " + theNextMethod.getName() + " on type '" + theNextMethod.getDeclaringClass().getSimpleName() + " has annotations @" + obj1.getClass().getSimpleName() + " and @" + object.getClass().getSimpleName()
+ ". Can not have both.");
throw new ConfigurationException("Method " + theNextMethod.getName() + " on type '" + theNextMethod.getDeclaringClass().getSimpleName() + " has annotations @"
+ obj1.getClass().getSimpleName() + " and @" + object.getClass().getSimpleName() + ". Can not have both.");
}
}
@ -125,7 +136,15 @@ public abstract class BaseMethodBinding {
}
}
public enum MethodReturnTypeEnum {
RESOURCE, BUNDLE, LIST_OF_RESOURCES
}
public enum ReturnTypeEnum {
BUNDLE, RESOURCE
}
public MethodReturnTypeEnum getMethodReturnType() {
return myMethodReturnType;
}
}

View File

@ -10,6 +10,8 @@ import org.apache.commons.lang3.Validate;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.client.GetClientInvocation;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.Util;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
@ -22,8 +24,8 @@ public class ReadMethodBinding extends BaseMethodBinding {
private Integer myVersionIdIndex;
private int myParameterCount;
public ReadMethodBinding(Class<? extends IResource> theAnnotatedResourceType, Method theMethod) {
super(theAnnotatedResourceType);
public ReadMethodBinding(MethodReturnTypeEnum theMethodReturnType, Class<? extends IResource> theAnnotatedResourceType, Method theMethod) {
super(theMethodReturnType, theAnnotatedResourceType);
Validate.notNull(theMethod, "Method must not be null");
@ -86,4 +88,15 @@ public class ReadMethodBinding extends BaseMethodBinding {
return toResourceList(response);
}
@Override
public GetClientInvocation invokeClient(Object[] theArgs) {
String id = ((IdDt)theArgs[myIdIndex]).getValue();
if (myVersionIdIndex == null) {
return new GetClientInvocation(getResourceName(), id);
}else {
String vid = ((IdDt)theArgs[myVersionIdIndex]).getValue();
return new GetClientInvocation(getResourceName(), id, Constants.URL_TOKEN_HISTORY, vid);
}
}
}

View File

@ -2,6 +2,7 @@ package ca.uhn.fhir.rest.common;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -9,9 +10,9 @@ import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.client.GetClientInvocation;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.Parameter;
import ca.uhn.fhir.rest.server.Util;
@ -26,14 +27,14 @@ public class SearchMethodBinding extends BaseMethodBinding {
private Method method;
private List<Parameter> parameters;
private List<Parameter> myParameters;
private RequestType requestType;
private Class<?> myDeclaredResourceType;
public SearchMethodBinding(Class<? extends IResource> theAnnotatedResourceType, Method theMethod) {
super(theAnnotatedResourceType);
public SearchMethodBinding(MethodReturnTypeEnum theMethodReturnTypeEnum, Class<? extends IResource> theAnnotatedResourceType, Method theMethod) {
super(theMethodReturnTypeEnum, theAnnotatedResourceType);
this.method = theMethod;
this.parameters = Util.getResourceParameters(theMethod);
this.myParameters = Util.getResourceParameters(theMethod);
this.myDeclaredResourceType = theMethod.getReturnType();
}
@ -43,7 +44,7 @@ public class SearchMethodBinding extends BaseMethodBinding {
}
public List<Parameter> getParameters() {
return parameters;
return myParameters;
}
public RequestType getRequestType() {
@ -64,9 +65,9 @@ public class SearchMethodBinding extends BaseMethodBinding {
assert theId == null;
assert theVersionId == null;
Object[] params = new Object[parameters.size()];
for (int i = 0; i < parameters.size(); i++) {
Parameter param = parameters.get(i);
Object[] params = new Object[myParameters.size()];
for (int i = 0; i < myParameters.size(); i++) {
Parameter param = myParameters.get(i);
String[] value = parameterValues.get(param.getName());
if (value == null || value.length == 0 || StringUtils.isBlank(value[0])) {
continue;
@ -104,8 +105,8 @@ public class SearchMethodBinding extends BaseMethodBinding {
}
Set<String> methodParamsTemp = new HashSet<String>();
for (int i = 0; i < this.parameters.size(); i++) {
Parameter temp = this.parameters.get(i);
for (int i = 0; i < this.myParameters.size(); i++) {
Parameter temp = this.myParameters.get(i);
methodParamsTemp.add(temp.getName());
if (temp.isRequired() && !theParameterNames.contains(temp.getName())) {
ourLog.trace("Method {} doesn't match param '{}' is not present", method.getName(), temp.getName());
@ -124,7 +125,7 @@ public class SearchMethodBinding extends BaseMethodBinding {
}
public void setParameters(List<Parameter> parameters) {
this.parameters = parameters;
this.myParameters = parameters;
}
public void setRequestType(RequestType requestType) {
@ -139,4 +140,20 @@ public class SearchMethodBinding extends BaseMethodBinding {
DELETE, GET, POST, PUT
}
@Override
public GetClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
assert theArgs.length == myParameters.size() : "Wrong number of arguments: " + theArgs.length;
Map<String, String> args = new HashMap<String, String>();
for (int idx = 0; idx < theArgs.length; idx++) {
Object object = theArgs[idx];
Parameter nextParam = myParameters.get(idx);
String value = nextParam.encode(object);
args.put(nextParam.getName(), value);
}
return new GetClientInvocation(args, getResourceName());
}
}

View File

@ -4,5 +4,7 @@ public class Constants {
public static final String CT_FHIR_XML = "application/xml+fhir";
public static final String PARAM_FORMAT = "_format";
public static final String URL_TOKEN_HISTORY = "_history";
public static final String CT_ATOM_XML = "application/atom+xml";
}

View File

@ -1,88 +1,104 @@
package ca.uhn.fhir.rest.server;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
/**
* Created by dsotnikov on 2/25/2014.
*/
public class Parameter {
private String name;
private String name;
private IParamBinder parser;
private boolean required;
private Class<?> type;
private IParser parser;
public Parameter(){}
public Parameter(){}
public Parameter(String name, boolean required) {
this.name = name;
this.required = required;
}
public Class<?> getType() {
return type;
}
public void setType(final Class<?> type) {
this.type = type;
if (type.getSimpleName().equals("IdentifierDt")) {
this.parser = new IParser() {
@Override
public Object parse(String theString) throws InternalErrorException {
Object dt;
try {
dt = type.newInstance();
Method method = dt.getClass().getMethod("setValueAsQueryToken", String.class);
method.invoke(dt, theString);
} catch (InstantiationException e) {
throw new InternalErrorException(e);
} catch (IllegalAccessException e) {
throw new InternalErrorException(e);
} catch (NoSuchMethodException e) {
throw new InternalErrorException(e);
} catch (SecurityException e) {
throw new InternalErrorException(e);
} catch (IllegalArgumentException e) {
throw new InternalErrorException(e);
} catch (InvocationTargetException e) {
throw new InternalErrorException(e);
}
return dt;
}
};
} else {
throw new ConfigurationException("Unsupported data type for parameter: " + type.getCanonicalName());
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
public Class<?> getType() {
return type;
}
public boolean isRequired() {
return required;
}
public Object parse(String theString) throws InternalErrorException {
return parser.parse(theString);
}
public void setName(String name) {
this.name = name;
}
public void setRequired(boolean required) {
this.required = required;
}
public Object parse(String theString) throws InternalErrorException {
return parser.parse(theString);
}
@SuppressWarnings("unchecked")
public void setType(final Class<?> type) {
this.type = type;
if (IQueryParameterType.class.isAssignableFrom(type)) {
this.parser = new IdentifierParamBinder((Class<? extends IQueryParameterType>) type);
} else {
throw new ConfigurationException("Unsupported data type for parameter: " + type.getCanonicalName());
}
}
private interface IParser
private final class IdentifierParamBinder implements IParamBinder {
private final Class<? extends IQueryParameterType> myType;
private IdentifierParamBinder(Class<? extends IQueryParameterType> theType) {
myType = theType;
}
@Override
public Object parse(String theString) throws InternalErrorException {
IQueryParameterType dt;
try {
dt = myType.newInstance();
dt.setValueAsQueryToken(theString);
} catch (InstantiationException e) {
throw new InternalErrorException(e);
} catch (IllegalAccessException e) {
throw new InternalErrorException(e);
} catch (SecurityException e) {
throw new InternalErrorException(e);
}
return dt;
}
@Override
public String encode(Object theString) throws InternalErrorException {
return ((IQueryParameterType)theString).getValueAsQueryToken();
}
}
private interface IParamBinder
{
Object parse(String theString) throws InternalErrorException;
String encode(Object theString) throws InternalErrorException;
}
public String encode(Object theObject) throws InternalErrorException {
return parser.encode(theObject);
}
}

View File

@ -26,7 +26,7 @@ import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.common.BaseMethodBinding;
import ca.uhn.fhir.rest.common.SearchMethodBinding;
import ca.uhn.fhir.rest.server.exceptions.AbstractResponseException;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.MethodNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
@ -174,7 +174,7 @@ public abstract class RestfulServer extends HttpServlet {
}
// resourceMethod.get
} catch (AbstractResponseException e) {
} catch (BaseServerResponseException e) {
if (e instanceof InternalErrorException) {
ourLog.error("Failure during REST processing", e);

View File

@ -1,331 +0,0 @@
package ca.uhn.fhir.server;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.parser.XmlParser;
import ca.uhn.fhir.server.exceptions.AbstractResponseException;
import ca.uhn.fhir.server.exceptions.InternalErrorException;
import ca.uhn.fhir.server.exceptions.MethodNotFoundException;
import ca.uhn.fhir.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.server.operations.DELETE;
import ca.uhn.fhir.server.operations.GET;
import ca.uhn.fhir.server.operations.POST;
import ca.uhn.fhir.server.operations.PUT;
public abstract class RestfulServer extends HttpServlet {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RestfulServer.class);
private static final long serialVersionUID = 1L;
<<<<<<< HEAD:hapi-fhir-base/src/main/java/ca/uhn/fhir/server/RestfulServer.java
private FhirContext myFhirContext;
private Map<Class<? extends IResource>, IResourceProvider<?>> myTypeToProvider = new HashMap<Class<? extends IResource>, IResourceProvider<?>>();
=======
private Map<Class<? extends IResource>, IResourceProvider<?>> myTypeToProvider = new HashMap<Class<? extends IResource>, IResourceProvider<?>>();
private FhirContext myFhirContext;
public abstract Collection<IResourceProvider<?>> getResourceProviders();
@Override
public void init() throws ServletException {
try {
ourLog.info("Initializing HAPI FHIR restful server");
Collection<IResourceProvider<?>> resourceProvider = getResourceProviders();
for (IResourceProvider<?> nextProvider : resourceProvider) {
if (myTypeToProvider.containsKey(nextProvider.getResourceType())) {
throw new ServletException("Multiple providers for type: " + nextProvider.getResourceType().getCanonicalName());
}
myTypeToProvider.put(nextProvider.getResourceType(), nextProvider);
}
ourLog.info("Got {} resource providers",myTypeToProvider.size());
myFhirContext = new FhirContext(myTypeToProvider.keySet());
// findResourceMethods(nextProvider.getClass());
>>>>>>> b15504ab6af00727419d4888cd3a1c5215f5b5e3:hapi-fhir-base/src/main/java/ca/uhn/fhir/ws/RestfulServer.java
// map of request handler resources keyed by resource name
private Map<String, Resource> resources = new HashMap<String, Resource>();
private boolean addResourceMethod(Resource resource, Method method) throws Exception {
ResourceMethod rm = new ResourceMethod();
// each operation name must have a request type annotation and be unique
if (null != method.getAnnotation(GET.class)) {
rm.setRequestType(ResourceMethod.RequestType.GET);
} else if (null != method.getAnnotation(PUT.class)) {
rm.setRequestType(ResourceMethod.RequestType.PUT);
} else if (null != method.getAnnotation(POST.class)) {
rm.setRequestType(ResourceMethod.RequestType.POST);
} else if (null != method.getAnnotation(DELETE.class)) {
rm.setRequestType(ResourceMethod.RequestType.DELETE);
} else {
return false;
}
rm.setMethod(method);
rm.setResourceType(method.getReturnType());
rm.setParameters(Util.getResourceParameters(method));
resource.addMethod(rm);
return true;
}
@SuppressWarnings("unused")
private EncodingUtil determineResponseEncoding(Map<String, String[]> theParams) {
String[] format = theParams.remove(Constants.PARAM_FORMAT);
// TODO: handle this once we support JSON
return EncodingUtil.XML;
}
@Override
protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
handleRequest(ResourceMethod.RequestType.DELETE, request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
handleRequest(ResourceMethod.RequestType.GET, request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
handleRequest(ResourceMethod.RequestType.POST, request, response);
}
@Override
protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
handleRequest(ResourceMethod.RequestType.PUT, request, response);
}
private void findResourceMethods(IResourceProvider<? extends IResource> theProvider) throws Exception {
Class<? extends IResource> resourceType = theProvider.getResourceType();
RuntimeResourceDefinition definition = myFhirContext.getResourceDefinition(resourceType);
Resource r = new Resource();
r.setResourceProvider(theProvider);
r.setResourceName(definition.getName());
resources.put(definition.getName(), r);
Class<?> clazz = theProvider.getClass();
for (Method m : clazz.getDeclaredMethods()) {
if (Modifier.isPublic(m.getModifiers())) {
boolean foundMethod = addResourceMethod(r, m);
if (foundMethod) {
ourLog.debug("found handler: " + m.getName());
}
}
}
}
public abstract Collection<IResourceProvider<?>> getResourceProviders();
protected void handleRequest(ResourceMethod.RequestType requestType, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String resourceName = null;
Long identity = null;
Map<String, String[]> params = new HashMap<String, String[]>(request.getParameterMap());
EncodingUtil responseEncoding = determineResponseEncoding(params);
StringTokenizer tok = new StringTokenizer(request.getRequestURI(), "/");
if (!tok.hasMoreTokens()) {
throw new MethodNotFoundException("No resource name specified");
}
resourceName = tok.nextToken();
Resource resourceBinding = resources.get(resourceName);
if (resourceBinding == null) {
throw new MethodNotFoundException("Unknown resource type: " + resourceBinding);
}
if (tok.hasMoreTokens()) {
String identityString = tok.nextToken();
try {
identity = Long.parseLong(identityString);
} catch (NumberFormatException e) {
throw new NumberFormatException("Invalid identity token: " + identity);
}
}
if (identity != null && !tok.hasMoreTokens()) {
if (params == null || params.isEmpty()) {
IResource resource = resourceBinding.getResourceProvider().getResourceById(identity);
if (resource == null) {
throw new ResourceNotFoundException(identity);
}
streamResponseAsResource(response, resource, resourceBinding, responseEncoding);
return;
}
}
ResourceMethod resourceMethod = resourceBinding.getMethod(params.keySet());
if (null == resourceMethod) {
throw new MethodNotFoundException("No resource method available for the supplied parameters " + params);
}
List<IResource> result = resourceMethod.invoke(resourceBinding.getResourceProvider(), params);
streamResponseAsBundle(response, result, responseEncoding);
// resourceMethod.get
} catch (AbstractResponseException e) {
response.setStatus(e.getStatusCode());
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
response.getWriter().append(e.getMessage());
response.getWriter().close();
} catch (Throwable t) {
// TODO: handle this better
ourLog.error("Failed to process invocation", t);
throw new ServletException(t);
}
}
@Override
public void init() throws ServletException {
try {
ourLog.info("Initializing HAPI FHIR restful server");
Collection<IResourceProvider<?>> resourceProvider = getResourceProviders();
for (IResourceProvider<?> nextProvider : resourceProvider) {
if (myTypeToProvider.containsKey(nextProvider.getResourceType())) {
throw new ServletException("Multiple providers for type: " + nextProvider.getResourceType().getCanonicalName());
}
myTypeToProvider.put(nextProvider.getResourceType(), nextProvider);
}
ourLog.info("Got {} resource providers",myTypeToProvider.size());
myFhirContext = new FhirContext(myTypeToProvider.keySet());
for (IResourceProvider<?> provider : myTypeToProvider.values()) {
findResourceMethods(provider);
}
} catch (Exception ex) {
ourLog.error("An error occurred while loading request handlers!", ex);
throw new ServletException("Failed to initialize FHIR Restful server", ex);
}
}
private void streamResponseAsBundle(HttpServletResponse theHttpResponse, List<IResource> theResult, EncodingUtil theResponseEncoding) throws IOException {
theHttpResponse.setStatus(200);
theHttpResponse.setContentType(Constants.CT_FHIR_XML);
theHttpResponse.setCharacterEncoding("UTF-8");
Bundle bundle = new Bundle();
bundle.getAuthorName().setValue(getClass().getCanonicalName());
bundle.getId().setValue(UUID.randomUUID().toString());
bundle.getPublished().setToCurrentTimeInLocalTimeZone();
for (IResource next : theResult) {
BundleEntry entry = new BundleEntry();
bundle.getEntries().add(entry);
entry.setResource(next);
}
bundle.getTotalResults().setValue(theResult.size());
PrintWriter writer = theHttpResponse.getWriter();
myFhirContext.newXmlParser().encodeBundleToWriter(bundle, writer);
writer.close();
}
private void streamResponseAsResource(HttpServletResponse theHttpResponse, IResource theResource, Resource theResourceBinding, EncodingUtil theResponseEncoding) throws IOException {
theHttpResponse.setStatus(200);
theHttpResponse.setContentType(Constants.CT_FHIR_XML);
theHttpResponse.setCharacterEncoding("UTF-8");
PrintWriter writer = theHttpResponse.getWriter();
myFhirContext.newXmlParser().encodeResourceToWriter(theResource, writer);
writer.close();
}
/**
* Recursive method used to find all classes in a given directory and
* subdirs.
*
* @param directory
* The base directory
* @param packageName
* The package name for classes found inside the base directory
* @return The classes
* @throws ClassNotFoundException
*/
private static List<Class<?>> findClasses(File directory, String packageName) throws ClassNotFoundException {
List<Class<?>> classes = new ArrayList<Class<?>>();
if (!directory.exists()) {
return classes;
}
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
assert !file.getName().contains(".");
classes.addAll(findClasses(file, packageName + "." + file.getName()));
} else if (file.getName().endsWith(".class")) {
classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
}
}
return classes;
}
private static List<Class<?>> getClasses(String packageName) throws ClassNotFoundException, IOException {
if (null == packageName)
throw new ClassNotFoundException("package name must be specified for JSON operations");
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
assert classLoader != null;
String path = packageName.replace('.', '/');
Enumeration<URL> resources = classLoader.getResources(path);
List<File> dirs = new ArrayList<File>();
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
dirs.add(new File(resource.getFile()));
}
ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
for (File directory : dirs) {
classes.addAll(findClasses(directory, packageName));
}
return classes;
}
}

View File

@ -1,6 +1,6 @@
package ca.uhn.fhir.rest.server.exceptions;
public abstract class AbstractResponseException extends Exception {
public abstract class BaseServerResponseException extends Exception {
private static final long serialVersionUID = 1L;
@ -14,7 +14,7 @@ public abstract class AbstractResponseException extends Exception {
* @param theMessage
* The message
*/
public AbstractResponseException(int theStatusCode, String theMessage) {
public BaseServerResponseException(int theStatusCode, String theMessage) {
super(theMessage);
myStatusCode = theStatusCode;
}
@ -28,7 +28,7 @@ public abstract class AbstractResponseException extends Exception {
* The message
* @param theCause The cause
*/
public AbstractResponseException(int theStatusCode, String theMessage, Throwable theCause) {
public BaseServerResponseException(int theStatusCode, String theMessage, Throwable theCause) {
super(theMessage, theCause);
myStatusCode = theStatusCode;
}
@ -41,7 +41,7 @@ public abstract class AbstractResponseException extends Exception {
* @param theCause
* The underlying cause exception
*/
public AbstractResponseException(int theStatusCode, Throwable theCause) {
public BaseServerResponseException(int theStatusCode, Throwable theCause) {
super(theCause.toString(), theCause);
myStatusCode = theStatusCode;
}

View File

@ -1,6 +1,6 @@
package ca.uhn.fhir.rest.server.exceptions;
public class InternalErrorException extends AbstractResponseException {
public class InternalErrorException extends BaseServerResponseException {
private static final long serialVersionUID = 1L;

View File

@ -1,6 +1,6 @@
package ca.uhn.fhir.rest.server.exceptions;
public class InvalidRequestException extends AbstractResponseException {
public class InvalidRequestException extends BaseServerResponseException {
private static final long serialVersionUID = 1L;

View File

@ -3,7 +3,7 @@ package ca.uhn.fhir.rest.server.exceptions;
/**
* Created by dsotnikov on 2/27/2014.
*/
public class MethodNotFoundException extends AbstractResponseException {
public class MethodNotFoundException extends BaseServerResponseException {
private static final long serialVersionUID = 1L;
public MethodNotFoundException(String error) {

View File

@ -2,7 +2,7 @@ package ca.uhn.fhir.rest.server.exceptions;
import ca.uhn.fhir.model.primitive.IdDt;
public class ResourceNotFoundException extends AbstractResponseException {
public class ResourceNotFoundException extends BaseServerResponseException {
public ResourceNotFoundException(IdDt theId) {
super(404, "Resource " + (theId != null ? theId.getValue() : "") + " is not known");

View File

@ -20,10 +20,20 @@ import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Observation;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.resource.ValueSet;
public class XmlParserTest {
@Test
public void testParseBundleLarge() throws IOException {
String msg = IOUtils.toString(XmlParser.class.getResourceAsStream("/atom-document-large.xml"));
IParser p = new FhirContext(Patient.class).newXmlParser();
Bundle bundle = p.parseBundle(msg);
}
@Test
public void testParseBundle() {
@ -85,7 +95,7 @@ public class XmlParserTest {
"</feed>";
//@formatter:on
XmlParser p = new FhirContext(ValueSet.class).newXmlParser();
IParser p = new FhirContext(ValueSet.class).newXmlParser();
Bundle bundle = p.parseBundle(msg);
assertEquals("FHIR Core Valuesets", bundle.getTitle().getValue());
@ -105,7 +115,7 @@ public class XmlParserTest {
@Test
public void testLoadAndEncodeExtensions() throws ConfigurationException, DataFormatException, SAXException, IOException {
FhirContext ctx = new FhirContext(ResourceWithExtensionsA.class);
XmlParser p = new XmlParser(ctx);
IParser p = new XmlParser(ctx);
//@formatter:off
String msg = "<ResourceWithExtensionsA xmlns=\"http://hl7.org/fhir\">\n" +
@ -169,7 +179,7 @@ public class XmlParserTest {
public void testLoadObservation() throws ConfigurationException, DataFormatException, IOException {
FhirContext ctx = new FhirContext(Observation.class);
XmlParser p = new XmlParser(ctx);
IParser p = new XmlParser(ctx);
IResource resource = p.parseResource(IOUtils.toString(XmlParserTest.class.getResourceAsStream("/observation-example-eeg.xml")));

View File

@ -19,4 +19,6 @@ public interface ITestClient extends IRestfulClient {
@Search(value=Patient.class)
Bundle findPatientByLastName(@Required(name = Patient.SP_FAMILY) IdentifierDt theId);
}

View File

@ -0,0 +1,32 @@
package ca.uhn.fhir.rest.client;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
public class Tester {
public static final void main(String[] args) {
try {
FhirContext ctx = new FhirContext(Patient.class);
RestfulClientFactory factory = ctx.newClientFactory();
ITestClient client = factory.newClient(ITestClient.class, "http://spark.furore.com/fhir/");
// Patient patient = client.getPatientById(new IdDt("1"));
// System.out.println(ctx.newXmlParser().encodeResourceToString(patient));
Patient patient2 = client.findPatientByMrn(new IdentifierDt("http://orionhealth.com/mrn", "PRP1660"));
System.out.println(ctx.newXmlParser().encodeResourceToString(patient2));
} catch (NonFhirResponseException e) {
e.printStackTrace();
System.out.println(e.getResponseText());
}
}
}

View File

@ -12,6 +12,7 @@ import org.junit.Test;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.rest.common.SearchMethodBinding;
import ca.uhn.fhir.rest.common.BaseMethodBinding.MethodReturnTypeEnum;
import ca.uhn.fhir.rest.server.Parameter;
public class ResourceMethodTest {
@ -20,7 +21,7 @@ public class ResourceMethodTest {
@Before
public void before() throws NoSuchMethodException, SecurityException {
rm = new SearchMethodBinding(Patient.class, ResourceMethodTest.class.getMethod("before"));
rm = new SearchMethodBinding(MethodReturnTypeEnum.RESOURCE, Patient.class, ResourceMethodTest.class.getMethod("before"));
}
@Test

View File

@ -0,0 +1,838 @@
<feed xmlns="http://www.w3.org/2005/Atom">
<title type="text">Search on resources in collection 'Patient'</title>
<id>urn:uuid:8b8428a5-ba56-4fc7-b176-36d13346c1ad</id>
<updated>2014-03-06T22:09:58.9121174Z</updated>
<author>
<name>Spark MatchBox Search Engine</name>
</author>
<totalResults xmlns="http://a9.com/-/spec/opensearch/1.1/">676</totalResults>
<link rel="self"
href="http://spark.furore.com/fhir/_snapshot?id=327d6bb9-83b0-4929-aa91-6dd9c41e587b&amp;start=0&amp;_count=20" />
<link rel="first"
href="http://spark.furore.com/fhir/_snapshot?id=327d6bb9-83b0-4929-aa91-6dd9c41e587b&amp;start=0" />
<link rel="last"
href="http://spark.furore.com/fhir/_snapshot?id=327d6bb9-83b0-4929-aa91-6dd9c41e587b&amp;start=660" />
<link rel="next"
href="http://spark.furore.com/fhir/_snapshot?id=327d6bb9-83b0-4929-aa91-6dd9c41e587b&amp;start=20" />
<link rel="fhir-base" href="http://spark.furore.com/fhir" />
<entry>
<title type="text">Patient resource with id 3216379</title>
<id>http://spark.furore.com/fhir/Patient/3216379</id>
<updated>2014-03-06T18:07:52.2209263Z</updated>
<published>2014-03-06T18:07:52.2209263Z</published>
<author>
<name>(unauthenticated)</name>
</author>
<link rel="related" href="http://spark.furore.com/fhir/Patient/3216379" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3216379/_history/6655" />
<category term="http://client/scheme/tag/123" label="tag 123"
scheme="http://client/scheme" />
<category term="http://client/scheme/tag/456" label="tag 456"
scheme="http://client/scheme" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<name>
<text value="Jsuis Malade" />
<family value="Malade" />
<given value="Jsuis" />
</name>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="F" />
</coding>
</gender>
<birthDate value="2008-08-08" />
</Patient>
</content>
</entry>
<entry>
<title type="text">Patient resource with id 3212416</title>
<id>http://spark.furore.com/fhir/Patient/3212416</id>
<updated>2014-01-18T19:48:05.7634661Z</updated>
<published>2014-01-18T19:48:05.747866Z</published>
<author>
<name>(unauthenticated)</name>
</author>
<link rel="related" href="http://spark.furore.com/fhir/Patient/3212416" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3212416/_history/2406" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<name>
<text value="Jsuis Malade" />
<family value="Malade" />
<given value="Jsuis" />
</name>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="F" />
</coding>
</gender>
<birthDate value="2008-08-08" />
</Patient>
</content>
</entry>
<entry>
<title type="text">Patient resource with id 3212417</title>
<id>http://spark.furore.com/fhir/Patient/3212417</id>
<updated>2014-01-18T19:48:40.9572917Z</updated>
<published>2014-01-18T19:48:40.9416916Z</published>
<author>
<name>(unauthenticated)</name>
</author>
<link rel="related" href="http://spark.furore.com/fhir/Patient/3212417" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3212417/_history/2407" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<name>
<text value="Jsuis Malade" />
<family value="Malade" />
<given value="Jsuis" />
</name>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="F" />
</coding>
</gender>
<birthDate value="2008-08-08" />
</Patient>
</content>
</entry>
<entry>
<title type="text">Patient resource with id 3212429</title>
<id>http://spark.furore.com/fhir/Patient/3212429</id>
<updated>2014-01-18T19:52:14.7410621Z</updated>
<published>2014-01-18T19:52:14.6786617Z</published>
<author>
<name>(unauthenticated)</name>
</author>
<link rel="related" href="http://spark.furore.com/fhir/Patient/3212429" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3212429/_history/2431" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<name>
<text value="Jsuis Malade" />
<family value="Malade" />
<given value="Jsuis" />
</name>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="F" />
</coding>
</gender>
<birthDate value="2008-08-08" />
</Patient>
</content>
</entry>
<entry>
<id>http://spark.furore.com/fhir/Patient/3212430</id>
<updated>2014-01-18T19:52:16.6442743Z</updated>
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3212430/_history/2434" />
<link rel="related" href="http://spark.furore.com/fhir/Patient/3212430" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<name>
<text value="Jsuis Malade" />
<family value="Malade" />
<given value="Jsuis" />
</name>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="F" />
</coding>
</gender>
<birthDate value="1966-01-10" />
</Patient>
</content>
</entry>
<entry>
<id>http://spark.furore.com/fhir/Patient/3212433</id>
<updated>2014-01-18T19:52:17.5490801Z</updated>
<link rel="related" href="cid:Patient/temp1" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3212433/_history/2440" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<name>
<text value="Jsuis Malade" />
<family value="Malade" />
<given value="Jsuis" />
</name>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="F" />
</coding>
</gender>
<birthDate value="2008-08-08" />
</Patient>
</content>
</entry>
<entry>
<title type="text">Patient resource with id 3212435</title>
<id>http://spark.furore.com/fhir/Patient/3212435</id>
<updated>2014-01-18T19:52:18.7658879Z</updated>
<published>2014-01-18T19:52:18.7658879Z</published>
<author>
<name>(unauthenticated)</name>
</author>
<link rel="related" href="http://spark.furore.com/fhir/Patient/3212435" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3212435/_history/2444" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<name>
<text value="Jsuis Malade" />
<family value="Malade" />
<given value="Jsuis" />
</name>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="F" />
</coding>
</gender>
<birthDate value="2008-08-08" />
</Patient>
</content>
</entry>
<entry>
<title type="text">Patient Resource</title>
<id>http://spark.furore.com/fhir/Patient/3212446</id>
<updated>2014-01-18T19:55:50.8346474Z</updated>
<link rel="related" href="cid:d4fccfb5-797c-4a12-9713-7fb5731b68ff" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3212446/_history/2460" />
<content type="text/xml">
<Patient id="cid:b01227b1-2701-4f9f-93b3-428146aa3ed3" xmlns="http://hl7.org/fhir">
<language value="en-US" />
<text>
<div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div>
</text>
<identifier>
<use value="official" />
<label value="MRN" />
<system value="http://snomed.info/sct" />
<value value="32123" />
</identifier>
<name>
<use value="official" />
<family value="Parkerson" />
<given value="Parkie" />
</name>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="M" />
</coding>
<text value="Male" />
</gender>
<birthDate value="19840101" />
<address>
<text value="4016 Canal St." />
<city value="New Orleans" />
<state value="LA" />
<zip value="70001" />
<country value="USA" />
</address>
<active value="true" />
</Patient>
</content>
<summary type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div>
</summary>
</entry>
<entry>
<title type="text">Patient Resource</title>
<id>http://spark.furore.com/fhir/Patient/3212492</id>
<updated>2014-01-18T22:09:21.1526936Z</updated>
<link rel="related" href="cid:b600d4ee-829f-49f3-be28-5abeb604f567" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3212492/_history/2507" />
<content type="text/xml">
<Patient id="cid:dd85a42b-eab0-4863-b4e4-2296e8369e9a" xmlns="http://hl7.org/fhir">
<language value="en-US" />
<text>
<div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div>
</text>
<identifier>
<use value="official" />
<label value="MRN" />
<system value="http://snomed.info/sct" />
<value value="32123" />
</identifier>
<name>
<use value="official" />
<family value="Parkerson" />
<given value="Parkie" />
</name>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="M" />
</coding>
<text value="Male" />
</gender>
<birthDate value="19840101" />
<address>
<text value="4016 Canal St." />
<city value="New Orleans" />
<state value="LA" />
<zip value="70001" />
<country value="USA" />
</address>
<active value="true" />
</Patient>
</content>
<summary type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div>
</summary>
</entry>
<entry>
<title type="text">patient record</title>
<id>http://spark.furore.com/fhir/Patient/3212516</id>
<updated>2014-01-18T22:30:06.8604936Z</updated>
<link rel="search" href="http://localhost/patient/search?identifier=89765a87b" />
<link rel="related" href="cid:patient_id@hl7.org" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3212516/_history/2537" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<text>
<status value="generated" />
<div xmlns="http://www.w3.org/1999/xhtml">Person DOE, John, M, dob: 27/05/1956</div>
</text>
<identifier>
<system value="usual" />
<value value="MRN" />
</identifier>
<name>
<use value="usual" />
<text value="DOE, John" />
<family value="Doe" />
<given value="John" />
</name>
<birthDate value="1956-05-27" />
</Patient>
</content>
<summary type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">Person DOE, John, M, dob: 27/05/1956</div>
</summary>
</entry>
<entry>
<title type="text">Patient Resource</title>
<id>http://spark.furore.com/fhir/Patient/3212576</id>
<updated>2014-01-18T22:47:32.8716936Z</updated>
<link rel="related" href="cid:c392c2da-7f17-4f95-b50e-22c8a20088fa" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3212576/_history/2601" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<language value="en-US" />
<text>
<div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div>
</text>
<identifier>
<use value="official" />
<label value="MRN" />
<system value="http://snomed.info/sct" />
<value value="32123" />
</identifier>
<name>
<use value="official" />
<family value="Parkerson" />
<given value="Parkie" />
</name>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="M" />
</coding>
<text value="Male" />
</gender>
<birthDate value="19840101" />
<address>
<text value="4016 Canal St." />
<city value="New Orleans" />
<state value="LA" />
<zip value="70001" />
<country value="USA" />
</address>
<active value="true" />
</Patient>
</content>
<summary type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div>
</summary>
</entry>
<entry>
<title type="text">Patient Resource</title>
<id>http://spark.furore.com/fhir/Composition/3212638</id>
<updated>2014-01-18T23:16:43.9026936Z</updated>
<link rel="related" href="cid:ebc56008-02c0-48d9-bfec-992a2a65e20d" />
<link rel="self"
href="http://spark.furore.com/fhir/Composition/3212638/_history/2666" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<language value="en-US" />
<text>
<div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div>
</text>
<identifier>
<use value="official" />
<label value="MRN" />
<system value="http://snomed.info/sct" />
<value value="32123" />
</identifier>
<name>
<use value="official" />
<family value="Parkerson" />
<given value="Parkie" />
</name>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="M" />
</coding>
<text value="Male" />
</gender>
<birthDate value="19840101" />
<address>
<text value="4016 Canal St." />
<city value="New Orleans" />
<state value="LA" />
<zip value="70001" />
<country value="USA" />
</address>
<active value="true" />
</Patient>
</content>
<summary type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div>
</summary>
</entry>
<entry>
<title type="text">Patient Resource</title>
<id>http://spark.furore.com/fhir/Patient/3212673</id>
<updated>2014-01-18T23:43:42.9527548Z</updated>
<link rel="related" href="cid:b150b48b-f78c-4462-9001-a019569979e1" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3212673/_history/2701" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<language value="en-US" />
<text>
<div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div>
</text>
<identifier>
<use value="official" />
<label value="MRN" />
<system value="http://snomed.info/sct" />
<value value="32123" />
</identifier>
<name>
<use value="official" />
<family value="Parkerson" />
<given value="Parkie" />
</name>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="M" />
</coding>
<text value="Male" />
</gender>
<birthDate value="19840101" />
<address>
<text value="4016 Canal St." />
<city value="New Orleans" />
<state value="LA" />
<zip value="70001" />
<country value="USA" />
</address>
<active value="true" />
</Patient>
</content>
<summary type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div>
</summary>
</entry>
<entry>
<title type="text">Patient resource with id 3212861</title>
<id>http://spark.furore.com/fhir/Patient/3212861</id>
<updated>2014-01-19T15:06:57.8105834Z</updated>
<published>2014-01-19T15:06:57.8105834Z</published>
<author>
<name>(unauthenticated)</name>
</author>
<link rel="related" href="http://spark.furore.com/fhir/Patient/3212861" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3212861/_history/2905" />
<content type="text/xml">
<Patient id="226AA97C-B597-4F89-8AC3-59300126D1DC" xmlns="http://hl7.org/fhir">
<text>
<status value="generated" />
<div xmlns="http://www.w3.org/1999/xhtml">
BizTalk Test
</div>
</text>
<telecom>
<system value="phone" />
<value value="555-555-2003" />
<use value="work" />
</telecom>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="M" />
</coding>
</gender>
<birthDate value="1978-05-31" />
<address>
<use value="home" />
<line value="2222 Home Street" />
</address>
<managingOrganization>
<reference value="Organization/hl7" />
</managingOrganization>
<active value="true" />
</Patient>
</content>
<summary type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
BizTalk Test
</div>
</summary>
</entry>
<entry>
<title type="text">Patient resource with id 3213112</title>
<id>http://spark.furore.com/fhir/Patient/3213112</id>
<updated>2014-01-19T16:17:08.4218784Z</updated>
<published>2014-01-19T16:17:08.4218784Z</published>
<author>
<name>(unauthenticated)</name>
</author>
<link rel="related" href="http://spark.furore.com/fhir/Patient/3213112" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3213112/_history/3158" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<identifier>
<label value="hl7v2" />
<value value="PID-55101" />
</identifier>
<name>
<family value="Jetson" />
<given value="George" />
</name>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="M" />
<display value="Male" />
</coding>
</gender>
<birthDate value="1974-02-18" />
<address>
<line value="2345 Skyview Drive" />
<city value="Rockville" />
<state value="MD" />
<zip value="20850" />
</address>
</Patient>
</content>
</entry>
<entry>
<title type="text">Patient resource with id 3213341</title>
<id>http://spark.furore.com/fhir/Patient/3213341</id>
<updated>2014-01-19T16:29:22.0804724Z</updated>
<published>2014-01-19T16:29:22.0648726Z</published>
<author>
<name>(unauthenticated)</name>
</author>
<link rel="related" href="http://spark.furore.com/fhir/Patient/3213341" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3213341/_history/3397" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<identifier>
<label value="hl7v2" />
<value value="PID-55101" />
</identifier>
<name>
<use value="official" />
<family value="Jetson" />
<given value="George" />
</name>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="M" />
<display value="Male" />
</coding>
</gender>
<birthDate value="1974-02-18" />
<address>
<use value="home" />
<line value="2345 Skyview Drive" />
<city value="Rockville" />
<state value="MD" />
<zip value="20850" />
</address>
</Patient>
</content>
</entry>
<entry>
<title type="text">Patient resource with id 3213417</title>
<id>http://spark.furore.com/fhir/Patient/3213417</id>
<updated>2014-01-19T16:33:17.1694584Z</updated>
<published>2014-01-19T16:33:17.1538586Z</published>
<author>
<name>(unauthenticated)</name>
</author>
<link rel="related" href="http://spark.furore.com/fhir/Patient/3213417" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3213417/_history/3475" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<identifier>
<label value="hl7v2" />
<value value="PID-55101" />
</identifier>
<name>
<use value="official" />
<family value="Jetson" />
<given value="George" />
</name>
<birthDate value="1960-01-15" />
<address>
<use value="home" />
<line value="2345 Skyview Drive" />
<city value="Rockville" />
<state value="MD" />
<zip value="20850" />
</address>
<active value="true" />
</Patient>
</content>
</entry>
<entry>
<title type="text">Patient</title>
<id>http://spark.furore.com/fhir/Patient/3213445</id>
<updated>2014-01-19T16:39:43.3113078Z</updated>
<link rel="related" href="cid:d8e40" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3213445/_history/3511" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<text>
<status value="generated" />
<xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml">Isabella Isa Jones</xhtml:div>
</text>
<identifier>
<system value="urn:oid:2.16.840.1.113883.4.1" />
<value value="http://hl7.org/fhir/sid/us-ssn/111-00-2330" />
</identifier>
<name>
<text value="Isabella Isa Jones" />
<family value="Jones" />
<given value="Isabella" />
<given value="Isa" />
</name>
<telecom>
<system value="phone" />
<value value="(816)276-6909" />
<use value="home" />
</telecom>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/vs/AdministrativeGender" />
<code value="F" />
<display value="Female" />
</coding>
</gender>
<birthDate value="1975-05-01T00:00:00Z" />
<address>
<line value="1357 Amber Drive" />
<city value="Beaverton" />
<state value="OR" />
<zip value="97867" />
<country value="US" />
</address>
<maritalStatus>
<coding>
<system value="http://hl7.org/fhir/v3/MaritalStatus" />
<code value="M" />
<display value="Married" />
</coding>
</maritalStatus>
<contact>
<relationship>
<coding>
<system value="http://hl7.org/fhir/patient-contact-relationship" />
<code value="guardian" />
</coding>
</relationship>
<name>
<text value="Ralph Jones" />
<family value="Jones" />
<given value="Ralph" />
</name>
<telecom>
<system value="phone" />
<value value="(816)276-6909" />
<use value="home" />
</telecom>
<address>
<line value="1357 Amber Drive" />
<city value="Beaverton" />
<state value="OR" />
<zip value="97867" />
<country value="US" />
</address>
</contact>
<managingOrganization>
<reference value="Organization/3213443" />
<display value="Community Health and Hospitals" />
</managingOrganization>
</Patient>
</content>
<summary type="xhtml">
<xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml">Isabella Isa Jones</xhtml:div>
</summary>
</entry>
<entry>
<title type="text">Patient resource with id 3213586</title>
<id>http://spark.furore.com/fhir/Patient/3213586</id>
<updated>2014-01-19T16:41:54.9432766Z</updated>
<published>2014-01-19T16:41:54.9432766Z</published>
<author>
<name>(unauthenticated)</name>
</author>
<link rel="related" href="http://spark.furore.com/fhir/Patient/3213586" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3213586/_history/3652" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<identifier>
<label value="hl7v2" />
<value value="PID-55101" />
</identifier>
<name>
<use value="official" />
<family value="Jetson" />
<given value="George" />
</name>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/AdministrativeGender" />
<code value="M" />
<display value="Male" />
</coding>
</gender>
<birthDate value="1974-02-18" />
<address>
<use value="home" />
<line value="2345 Skyview Drive" />
<city value="Rockville" />
<state value="MD" />
<zip value="20850" />
</address>
</Patient>
</content>
</entry>
<entry>
<title type="text">Patient</title>
<id>http://spark.furore.com/fhir/Patient/3213739</id>
<updated>2014-01-19T16:51:12.1772766Z</updated>
<link rel="related" href="cid:d8e40" />
<link rel="self"
href="http://spark.furore.com/fhir/Patient/3213739/_history/3809" />
<content type="text/xml">
<Patient xmlns="http://hl7.org/fhir">
<text>
<status value="generated" />
<xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml">Isabella Isa Jones</xhtml:div>
</text>
<identifier>
<system value="urn:oid:2.16.840.1.113883.4.1" />
<value value="http://hl7.org/fhir/sid/us-ssn/111-00-2330" />
</identifier>
<name>
<text value="Isabella Isa Jones" />
<family value="Jones" />
<given value="Isabella" />
<given value="Isa" />
</name>
<telecom>
<system value="phone" />
<value value="(816)276-6909" />
<use value="home" />
</telecom>
<gender>
<coding>
<system value="http://hl7.org/fhir/v3/vs/AdministrativeGender" />
<code value="F" />
<display value="Female" />
</coding>
</gender>
<birthDate value="1975-05-01T00:00:00Z" />
<address>
<line value="1357 Amber Drive" />
<city value="Beaverton" />
<state value="OR" />
<zip value="97867" />
<country value="US" />
</address>
<maritalStatus>
<coding>
<system value="http://hl7.org/fhir/v3/MaritalStatus" />
<code value="M" />
<display value="Married" />
</coding>
</maritalStatus>
<contact>
<relationship>
<coding>
<system value="http://hl7.org/fhir/patient-contact-relationship" />
<code value="guardian" />
</coding>
</relationship>
<name>
<text value="Ralph Jones" />
<family value="Jones" />
<given value="Ralph" />
</name>
<telecom>
<system value="phone" />
<value value="(816)276-6909" />
<use value="home" />
</telecom>
<address>
<line value="1357 Amber Drive" />
<city value="Beaverton" />
<state value="OR" />
<zip value="97867" />
<country value="US" />
</address>
</contact>
<managingOrganization>
<reference value="Organization/3213737" />
<display value="Community Health and Hospitals" />
</managingOrganization>
</Patient>
</content>
<summary type="xhtml">
<xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml">Isabella Isa Jones</xhtml:div>
</summary>
</entry>
</feed>

View File

@ -10,6 +10,10 @@
<logger name="org.eclipse" additivity="false">
</logger>
<logger name="ca.uhn.fhir.rest.client" additivity="false" level="trace">
<appender-ref ref="STDOUT" />
</logger>
<root level="info">
<appender-ref ref="STDOUT" />
</root>

View File

@ -28,7 +28,7 @@ import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.dstu.resource.ValueSet;
import ca.uhn.fhir.model.dstu.resource.ValueSet.DefineConcept;
import ca.uhn.fhir.parser.XmlParser;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.tinder.model.ValueSetTm;
import ca.uhn.fhir.tinder.model.ValueSetTm.Code;
@ -53,7 +53,7 @@ public class ValueSetGenerator {
}
public void parse() throws FileNotFoundException, IOException {
XmlParser newXmlParser = new FhirContext(ValueSet.class).newXmlParser();
IParser newXmlParser = new FhirContext(ValueSet.class).newXmlParser();
ourLog.info("Parsing built-in ValueSets");
String vs = IOUtils.toString(ValueSetGenerator.class.getResourceAsStream("/vs/all-valuesets-bundle.xml"));

View File

@ -24,7 +24,31 @@ import ${packageBase}.resource.*;
* </p>
*/
@DatatypeDef(name="${className}")
public class ${className}Dt extends BaseElement implements ICompositeDatatype {
public class ${className}Dt extends BaseElement implements ICompositeDatatype
#if ( ${className} == "Identifier" )
, IQueryParameter
#end
{
#########################
### Type-specific constructors
#########################
#if ( ${className} == "Identifier" )
/**
* Creates a new identifier
*/
public IdentifierDt() {
// nothing
}
/**
* Creates a new identifier with the given system and value
*/
public IdentifierDt(String theSystem, String theValue) {
setSystem(theSystem);
setValue(theValue);
}
#end
#childExtensionFields( $childExtensionTypes )
#childVars( $children )
@ -48,13 +72,21 @@ public class ${className}Dt extends BaseElement implements ICompositeDatatype {
}
/**
* Sets the value of this <code>IdentifierDt</code> using the <b>token</b> format. This
* format is used in HTTP queries as a parameter format.
*
* @see See FHIR specification
* <a href="http://www.hl7.org/implement/standards/fhir/search.html#[[#]]#ptypes">2.2.2 Search Parameter Types</a>
* for information on the <b>token</b> format
* {@inheritDoc}
*/
@Override
public String getValueAsQueryToken() {
if (org.apache.commons.lang3.StringUtils.isNotBlank(getSystem().getValueAsString())) {
return getSystem().getValueAsString() + '|' + getValue().getValueAsString();
} else {
return getValue().getValueAsString();
}
}
/**
* {@inheritDoc}
*/
@Override
public void setValueAsQueryToken(String theParameter) {
int barIndex = theParameter.indexOf('|');
if (barIndex != -1) {