Skip to content

Commit

Permalink
Fix #315 - Allow declaring of custom types for specific profiles
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesagnew committed Mar 22, 2016
1 parent 5895881 commit 1adfc4b
Show file tree
Hide file tree
Showing 58 changed files with 2,550 additions and 11,055 deletions.
7 changes: 7 additions & 0 deletions examples/src/main/java/example/CustomObservation.java
@@ -0,0 +1,7 @@
package example;

import org.hl7.fhir.dstu3.model.Observation;

public class CustomObservation extends Observation {

}
Expand Up @@ -12,7 +12,7 @@
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.parser.DataFormatException;

public class Extensions {
public class ExtensionsDstu2 {

@SuppressWarnings("unused")
public static void main(String[] args) throws DataFormatException, IOException {
Expand Down
140 changes: 140 additions & 0 deletions examples/src/main/java/example/ExtensionsDstu3.java
@@ -0,0 +1,140 @@
package example;

import java.io.IOException;
import java.util.List;

import org.hl7.fhir.dstu3.model.DateTimeType;
import org.hl7.fhir.dstu3.model.Extension;
import org.hl7.fhir.dstu3.model.HumanName;
import org.hl7.fhir.dstu3.model.Identifier.IdentifierUse;
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.dstu3.model.StringType;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.client.IGenericClient;

public class ExtensionsDstu3 {

public void customType() {

IGenericClient client = FhirContext.forDstu3().newRestfulGenericClient("http://foo");

//START SNIPPET: customTypeClientSimple
// Create an example patient
MyPatient custPatient = new MyPatient();
custPatient.addName().addFamily("Smith").addGiven("John");
custPatient.setPetName(new StringType("Rover")); // populate the extension

// Create the resource like normal
client.create().resource(custPatient).execute();

// You can also read the resource back like normal
custPatient = client.read().resource(MyPatient.class).withId("123").execute();
//END SNIPPET: customTypeClientSimple


}

public void customTypeDeclared() {


//START SNIPPET: customTypeClientDeclared
FhirContext ctx = FhirContext.forDstu3();

// Instruct the context that if it receives a resource which
// claims to conform to the given profile (by URL), it should
// use the MyPatient type to parse this resource
ctx.setDefaultTypeForProfile("http://example.com/StructureDefinition/mypatient", MyPatient.class);

// You can declare as many default types as you like
ctx.setDefaultTypeForProfile("http://foo.com/anotherProfile", CustomObservation.class);

// Create a client
IGenericClient client = ctx.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu3");

// You can also read the resource back like normal
Patient patient = client.read().resource(Patient.class).withId("123").execute();
if (patient instanceof MyPatient) {
// If the server supplied a resource which declared to conform
// to the given profile, MyPatient will have been returned so
// process it differently..
}

//END SNIPPET: customTypeClientDeclared


}

@SuppressWarnings("unused")
public static void main(String[] args) throws DataFormatException, IOException {


// START SNIPPET: resourceExtension
// Create an example patient
Patient patient = new Patient();
patient.addIdentifier().setUse(IdentifierUse.OFFICIAL).setSystem("urn:example").setValue("7000135");

// Create an extension
Extension ext = new Extension();
ext.setUrl("http://example.com/extensions#someext");
ext.setValue(new DateTimeType("2011-01-02T11:13:15"));

// Add the extension to the resource
patient.addExtension(ext);
//END SNIPPET: resourceExtension


//START SNIPPET: resourceStringExtension
// Continuing the example from above, we will add a name to the patient, and then
// add an extension to part of that name
HumanName name = patient.addName();
name.addFamily("Shmoe");

// Add a new "given name", which is of type String
StringType given = name.addGivenElement();
given.setValue("Joe");

// Create an extension and add it to the String
Extension givenExt = new Extension("http://examples.com#moreext", new StringType("Hello"));
given.addExtension(givenExt);
//END SNIPPET: resourceStringExtension

FhirContext ctx = FhirContext.forDstu3();
String output = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
System.out.println(output);


//START SNIPPET: parseExtension
// Get all extensions (modifier or not) for a given URL
List<Extension> resourceExts = patient.getExtensionsByUrl("http://fooextensions.com#exts");

// Get all non-modifier extensions regardless of URL
List<Extension> nonModExts = patient.getExtension();

//Get all non-modifier extensions regardless of URL
List<Extension> modExts = patient.getModifierExtension();
//END SNIPPET: parseExtension

}


public void foo() {
//START SNIPPET: subExtension
Patient patient = new Patient();

// Add an extension (initially with no contents) to the resource
Extension parent = new Extension("http://example.com#parent");
patient.addExtension(parent);

// Add two extensions as children to the parent extension
Extension child1 = new Extension("http://example.com#childOne", new StringType("value1"));
parent.addExtension(child1);

Extension child2 = new Extension("http://example.com#chilwo", new StringType("value1"));
parent.addExtension(child2);
//END SNIPPET: subExtension

}

}
27 changes: 15 additions & 12 deletions examples/src/main/java/example/MyPatient.java
Expand Up @@ -4,13 +4,14 @@
import java.util.ArrayList;
import java.util.List;

import org.hl7.fhir.dstu3.model.DateTimeType;
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.dstu3.model.StringType;

import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.api.annotation.Extension;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.util.ElementUtil;

/**
Expand All @@ -25,7 +26,9 @@
@ResourceDef(name="Patient", profile="http://example.com/StructureDefinition/mypatient")
public class MyPatient extends Patient {

/**
private static final long serialVersionUID = 1L;

/**
* Each extension is defined in a field. Any valid HAPI Data Type
* can be used for the field type. Note that the [name=""] attribute
* in the @Child annotation needs to match the name for the bean accessor
Expand All @@ -34,7 +37,7 @@ public class MyPatient extends Patient {
@Child(name="petName")
@Extension(url="http://example.com/dontuse#petname", definedLocally=false, isModifier=false)
@Description(shortDefinition="The name of the patient's favourite pet")
private StringDt myPetName;
private StringType myPetName;

/**
* The second example extension uses a List type to provide
Expand All @@ -46,7 +49,7 @@ public class MyPatient extends Patient {
@Child(name="importantDates", max=Child.MAX_UNLIMITED)
@Extension(url="http://example.com/dontuse#importantDates", definedLocally=false, isModifier=true)
@Description(shortDefinition="Some dates of note for this patient")
private List<DateTimeDt> myImportantDates;
private List<DateTimeType> myImportantDates;

/**
* It is important to override the isEmpty() method, adding a check for any
Expand All @@ -67,28 +70,28 @@ public boolean isEmpty() {
********/

/** Getter for important dates */
public List<DateTimeDt> getImportantDates() {
public List<DateTimeType> getImportantDates() {
if (myImportantDates==null) {
myImportantDates = new ArrayList<DateTimeDt>();
myImportantDates = new ArrayList<DateTimeType>();
}
return myImportantDates;
}

/** Getter for pet name */
public StringDt getPetName() {
public StringType getPetName() {
if (myPetName == null) {
myPetName = new StringDt();
myPetName = new StringType();
}
return myPetName;
}

/** Setter for important dates */
public void setImportantDates(List<DateTimeDt> theImportantDates) {
public void setImportantDates(List<DateTimeType> theImportantDates) {
myImportantDates = theImportantDates;
}

/** Setter for pet name */
public void setPetName(StringDt thePetName) {
public void setPetName(StringType thePetName) {
myPetName = thePetName;
}

Expand Down
2 changes: 1 addition & 1 deletion examples/src/main/java/example/MyPatientUse.java
Expand Up @@ -18,7 +18,7 @@

public class MyPatientUse {

@ResourceDef
@ResourceDef()
public static class MyPatient extends Patient {

@Child(name="petName")
Expand Down
10 changes: 2 additions & 8 deletions hapi-fhir-base-test-mindeps-server/.classpath
Expand Up @@ -6,20 +6,14 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry combineaccessrules="false" kind="src" path="/hapi-fhir-base"/>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
Expand Down
12 changes: 12 additions & 0 deletions hapi-fhir-base-test-mindeps-server/.project
Expand Up @@ -5,6 +5,16 @@
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
Expand All @@ -13,5 +23,7 @@
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<installed facet="java" version="1.7"/>
</faceted-project>
@@ -1,5 +1,6 @@
package ca.uhn.fhir.parser;

import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.Assert.assertThat;

import org.hamcrest.core.StringContains;
Expand All @@ -22,7 +23,10 @@ public void testEncodeExtensionFromDifferentVersion() {
String str = FhirContext.forDstu2().newJsonParser().encodeResourceToString(p);
ourLog.info(str);

assertThat(str, StringContains.containsString("{\"resourceType\":\"Patient\",\"extension\":[{\"url\":\"http://foo#ext\",\"valueQuantity\":{\"value\":2.2}}],\"identifier\":[{\"system\":\"urn:sys\",\"value\":\"001\"}]}"));
assertThat(str, stringContainsInOrder(
"{\"resourceType\":\"Patient\"",
"\"extension\":[{\"url\":\"http://foo#ext\",\"valueQuantity\":{\"value\":2.2}}]",
"\"identifier\":[{\"system\":\"urn:sys\",\"value\":\"001\"}]"));
}

}

0 comments on commit 1adfc4b

Please sign in to comment.