Merge branch 'master' of github.com:jamesagnew/hapi-fhir into hl7org_structs

Conflicts:
	hapi-fhir-android/pom.xml
	hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java
	hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java
	hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServerUtils.java
	hapi-fhir-base/src/main/java/ca/uhn/fhir/util/FhirTerser.java
	hapi-fhir-testpage-overlay/.gitignore
	src/changes/changes.xml
This commit is contained in:
jamesagnew 2015-04-21 13:30:58 -04:00
commit b222b76611
70 changed files with 1168 additions and 642 deletions

1
.gitignore vendored
View File

@ -12,6 +12,7 @@ Servers/
*.log* *.log*
nohup.out nohup.out
.DS_Store .DS_Store
*.orig
# Vagrant stuff. # Vagrant stuff.
.vagrant .vagrant

View File

@ -74,30 +74,30 @@ public class GenericClientExample {
// END SNIPPET: create // END SNIPPET: create
} }
{ {
Patient patient = new Patient(); Patient patient = new Patient();
// START SNIPPET: createConditional // START SNIPPET: createConditional
// One form // One form
MethodOutcome outcome = client.create() MethodOutcome outcome = client.create()
.resource(patient) .resource(patient)
.conditionalByUrl("Patient?identifier=system%7C00001") .conditionalByUrl("Patient?identifier=system%7C00001")
.execute(); .execute();
// Another form // Another form
MethodOutcome outcome2 = client.create() MethodOutcome outcome2 = client.create()
.resource(patient) .resource(patient)
.conditional() .conditional()
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001")) .where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001"))
.execute(); .execute();
// This will return true if the server responded with an HTTP 201 created, // This will return true if the server responded with an HTTP 201 created,
// otherwise it will return null. // otherwise it will return null.
Boolean created = outcome.getCreated(); Boolean created = outcome.getCreated();
// The ID of the created, or the pre-existing resource // The ID of the created, or the pre-existing resource
IdDt id = outcome.getId(); IdDt id = outcome.getId();
// END SNIPPET: createConditional // END SNIPPET: createConditional
} }
{ {
// START SNIPPET: update // START SNIPPET: update
Patient patient = new Patient(); Patient patient = new Patient();
// ..populate the patient object.. // ..populate the patient object..
@ -125,21 +125,21 @@ public class GenericClientExample {
// END SNIPPET: update // END SNIPPET: update
} }
{ {
Patient patient = new Patient(); Patient patient = new Patient();
// START SNIPPET: updateConditional // START SNIPPET: updateConditional
client.update() client.update()
.resource(patient) .resource(patient)
.conditionalByUrl("Patient?identifier=system%7C00001") .conditionalByUrl("Patient?identifier=system%7C00001")
.execute(); .execute();
client.update() client.update()
.resource(patient) .resource(patient)
.conditional() .conditional()
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001")) .where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001"))
.execute(); .execute();
// END SNIPPET: updateConditional // END SNIPPET: updateConditional
} }
{ {
// START SNIPPET: etagupdate // START SNIPPET: etagupdate
// First, let's retrive the latest version of a resource // First, let's retrive the latest version of a resource
// from the server // from the server
@ -176,26 +176,26 @@ public class GenericClientExample {
} }
{ {
// START SNIPPET: delete // START SNIPPET: delete
BaseOperationOutcome resp = client.delete().resourceById(new IdDt("Patient", "1234")).execute(); BaseOperationOutcome resp = client.delete().resourceById(new IdDt("Patient", "1234")).execute();
// outcome may be null if the server didn't return one // outcome may be null if the server didn't return one
if (resp != null) { if (resp != null) {
OperationOutcome outcome = (OperationOutcome) resp; OperationOutcome outcome = (OperationOutcome) resp;
System.out.println(outcome.getIssueFirstRep().getDetailsElement().getValue()); System.out.println(outcome.getIssueFirstRep().getDetailsElement().getValue());
} }
// END SNIPPET: delete // END SNIPPET: delete
} }
{ {
// START SNIPPET: deleteConditional // START SNIPPET: deleteConditional
client.delete() client.delete()
.resourceConditionalByUrl("Patient?identifier=system%7C00001") .resourceConditionalByUrl("Patient?identifier=system%7C00001")
.execute(); .execute();
client.delete() client.delete()
.resourceConditionalByType("Patient") .resourceConditionalByType("Patient")
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001")) .where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001"))
.execute(); .execute();
// END SNIPPET: deleteConditional // END SNIPPET: deleteConditional
} }
{ {
// START SNIPPET: search // START SNIPPET: search

View File

@ -63,20 +63,22 @@
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-android</artifactId> <artifactId>slf4j-android</artifactId>
<version>${slf4j_version}</version> <version>${slf4j_version}</version>
<scope>provided</scope>
</dependency> </dependency>
<!-- <dependency> <groupId>org.codehaus.woodstox</groupId> <artifactId>stax2-api</artifactId> <dependency>
<version>3.1.4</version> </dependency> --> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j_version}</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>commons-io</groupId> <groupId>commons-io</groupId>
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
<version>${commons_io_version}</version> <version>${commons_io_version}</version>
<scope>test</scope>
</dependency> </dependency>
<!-- <!-- Android does not come with the Servlet API bundled, and MethodUtil
Android does not come with the Servlet API bundled, and MethodUtil requires it requires it -->
-->
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId> <artifactId>javax.servlet-api</artifactId>
@ -135,11 +137,10 @@
</goals> </goals>
<configuration> <configuration>
<createDependencyReducedPom>true</createDependencyReducedPom> <createDependencyReducedPom>true</createDependencyReducedPom>
<!--<minimizeJar>true</minimizeJar>--> <!-- <minimizeJar>true</minimizeJar> -->
<artifactSet> <artifactSet>
<includes> <includes>
<include>commons-codec:commons-codec</include> <include>commons-codec:commons-codec</include>
<include>commons-io:commons-io</include>
<include>ca.uhn.hapi.fhir:hapi-fhir-base</include> <include>ca.uhn.hapi.fhir:hapi-fhir-base</include>
<include>ca.uhn.hapi.fhir:hapi-fhir-structures-dstu</include> <include>ca.uhn.hapi.fhir:hapi-fhir-structures-dstu</include>
<include>ca.uhn.hapi.fhir:hapi-fhir-structures-dstu2</include> <include>ca.uhn.hapi.fhir:hapi-fhir-structures-dstu2</include>
@ -148,7 +149,7 @@
<include>javax.xml.stream:stax-api</include> <include>javax.xml.stream:stax-api</include>
<include>javax.servlet:javax.servlet-api</include> <include>javax.servlet:javax.servlet-api</include>
<include>org.codehaus.woodstox:stax2-api</include> <include>org.codehaus.woodstox:stax2-api</include>
<!--<include>org.slf4j:slf4j*</include>--> <!-- <include>org.slf4j:slf4j*</include> -->
<include>org.apache.commons:*</include> <include>org.apache.commons:*</include>
<include>org.apache.httpcomponents:*</include> <include>org.apache.httpcomponents:*</include>
<include>org.glassfish:javax.json</include> <include>org.glassfish:javax.json</include>
@ -179,7 +180,7 @@
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
<profiles> <profiles>
<profile> <profile>
<id>DIST</id> <id>DIST</id>
@ -208,5 +209,5 @@
</build> </build>
</profile> </profile>
</profiles> </profiles>
</project> </project>

View File

@ -0,0 +1,14 @@
package ca.uhn.fhir.android;
import ca.uhn.fhir.context.FhirContext;
public class AndroidLoader {
public static void main(String[] theArgs) {
FhirContext ctx = FhirContext.forDstu2();
ctx.newJsonParser();
ctx.newXmlParser();
ctx.newRestfulGenericClient("");
}
}

View File

@ -85,29 +85,34 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
for (Class<? extends IBase> next : myChoiceTypes) { for (Class<? extends IBase> next : myChoiceTypes) {
String elementName; String elementName;
String alternateElementName = null;
BaseRuntimeElementDefinition<?> nextDef; BaseRuntimeElementDefinition<?> nextDef;
if (IBaseResource.class.isAssignableFrom(next)) { if (IBaseResource.class.isAssignableFrom(next)) {
elementName = getElementName() + StringUtils.capitalize(next.getSimpleName()); elementName = getElementName() + StringUtils.capitalize(next.getSimpleName());
alternateElementName = getElementName() + "Reference";
List<Class<? extends IBaseResource>> types = new ArrayList<Class<? extends IBaseResource>>(); List<Class<? extends IBaseResource>> types = new ArrayList<Class<? extends IBaseResource>>();
types.add((Class<? extends IBaseResource>) next); types.add((Class<? extends IBaseResource>) next);
nextDef = new RuntimeResourceReferenceDefinition(elementName, types); nextDef = new RuntimeResourceReferenceDefinition(elementName, types);
nextDef.sealAndInitialize(theContext, theClassToElementDefinitions); nextDef.sealAndInitialize(theContext, theClassToElementDefinitions);
myNameToChildDefinition.put(getElementName() + "Reference", nextDef);
myNameToChildDefinition.put(getElementName() + "Resource", nextDef);
} else { } else {
nextDef = theClassToElementDefinitions.get(next); nextDef = theClassToElementDefinitions.get(next);
elementName = getElementName() + StringUtils.capitalize(nextDef.getName()); elementName = getElementName() + StringUtils.capitalize(nextDef.getName());
} }
myNameToChildDefinition.put(elementName, nextDef); myNameToChildDefinition.put(elementName, nextDef);
if (alternateElementName != null) {
myNameToChildDefinition.put(alternateElementName, nextDef);
}
if (IBaseResource.class.isAssignableFrom(next)) { if (IBaseResource.class.isAssignableFrom(next)) {
Class<? extends IBase> refType = theContext.getVersion().getResourceReferenceType(); Class<? extends IBase> refType = theContext.getVersion().getResourceReferenceType();
myDatatypeToElementDefinition.put(refType, nextDef); myDatatypeToElementDefinition.put(refType, nextDef);
alternateElementName = getElementName() + "Reference";
String alternateElementName;
if (theContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU1)) {
alternateElementName = getElementName() + "Resource";
} else {
alternateElementName = getElementName() + "Reference";
}
myDatatypeToElementName.put(refType, alternateElementName); myDatatypeToElementName.put(refType, alternateElementName);
} }

View File

@ -38,6 +38,8 @@ import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildDefinition { public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildDefinition {
private static final String VALUE_REFERENCE = "valueReference";
private static final String VALUE_RESOURCE = "valueResource";
private Map<String, BaseRuntimeElementDefinition<?>> myAttributeNameToDefinition; private Map<String, BaseRuntimeElementDefinition<?>> myAttributeNameToDefinition;
private Map<Class<? extends IBase>, String> myDatatypeToAttributeName; private Map<Class<? extends IBase>, String> myDatatypeToAttributeName;
private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myDatatypeToDefinition; private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myDatatypeToDefinition;
@ -53,7 +55,7 @@ public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildD
public List<IBase> getValues(Object theTarget) { public List<IBase> getValues(Object theTarget) {
ExtensionDt target = (ExtensionDt) theTarget; ExtensionDt target = (ExtensionDt) theTarget;
if (target.getValue() != null) { if (target.getValue() != null) {
return Collections.singletonList((IBase)target.getValue()); return Collections.singletonList((IBase) target.getValue());
} }
ArrayList<IBase> retVal = new ArrayList<IBase>(target.getUndeclaredExtensions()); ArrayList<IBase> retVal = new ArrayList<IBase>(target.getUndeclaredExtensions());
return retVal; return retVal;
@ -118,10 +120,10 @@ public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildD
for (BaseRuntimeElementDefinition<?> next : theClassToElementDefinitions.values()) { for (BaseRuntimeElementDefinition<?> next : theClassToElementDefinitions.values()) {
if (next instanceof IRuntimeDatatypeDefinition) { if (next instanceof IRuntimeDatatypeDefinition) {
// if (next.getName().equals("CodeableConcept")) { // if (next.getName().equals("CodeableConcept")) {
// System.out.println(); // System.out.println();
// } // }
if (!((IRuntimeDatatypeDefinition) next).isSpecialization()) { if (!((IRuntimeDatatypeDefinition) next).isSpecialization()) {
String attrName = createExtensionChildName(next); String attrName = createExtensionChildName(next);
datatypeAttributeNameToDefinition.put(attrName, next); datatypeAttributeNameToDefinition.put(attrName, next);
@ -142,22 +144,29 @@ public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildD
} }
/* /*
* Resource reference - The correct name is 'valueReference', but * Resource reference - The correct name is 'valueReference' in DSTU2 and 'valueResource' in DSTU1
* we allow for valueResource because some incorrect parsers may use this
*/ */
addReferenceBinding(theContext, theClassToElementDefinitions, "valueResource"); addReferenceBinding(theContext, theClassToElementDefinitions, VALUE_RESOURCE);
addReferenceBinding(theContext, theClassToElementDefinitions, "valueReference"); addReferenceBinding(theContext, theClassToElementDefinitions, VALUE_REFERENCE);
} }
private void addReferenceBinding(FhirContext theContext, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions, String value) { private void addReferenceBinding(FhirContext theContext, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions, String value) {
myDatatypeToAttributeName.put(theContext.getVersion().getResourceReferenceType(), value);
List<Class<? extends IBaseResource>> types = new ArrayList<Class<? extends IBaseResource>>(); List<Class<? extends IBaseResource>> types = new ArrayList<Class<? extends IBaseResource>>();
types.add(IBaseResource.class); types.add(IBaseResource.class);
RuntimeResourceReferenceDefinition def = new RuntimeResourceReferenceDefinition(value, types); RuntimeResourceReferenceDefinition def = new RuntimeResourceReferenceDefinition(value, types);
def.sealAndInitialize(theContext, theClassToElementDefinitions); def.sealAndInitialize(theContext, theClassToElementDefinitions);
myAttributeNameToDefinition.put(value, def); myAttributeNameToDefinition.put(value, def);
myDatatypeToDefinition.put(BaseResourceReferenceDt.class, def); /*
myDatatypeToDefinition.put(theContext.getVersion().getResourceReferenceType(), def); * Resource reference - The correct name is 'valueReference' in DSTU2 and 'valueResource' in DSTU1
*/
boolean dstu1 = (theContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU1));
if ((dstu1 && (value != VALUE_REFERENCE)) || (!dstu1 && (value != VALUE_RESOURCE))) {
myDatatypeToAttributeName.put(theContext.getVersion().getResourceReferenceType(), value);
myDatatypeToDefinition.put(BaseResourceReferenceDt.class, def);
myDatatypeToDefinition.put(theContext.getVersion().getResourceReferenceType(), def);
}
} }
public static String createExtensionChildName(BaseRuntimeElementDefinition<?> next) { public static String createExtensionChildName(BaseRuntimeElementDefinition<?> next) {

View File

@ -293,6 +293,7 @@ public class Bundle extends BaseBundle /* implements IElement */{
return myLinkSelf; return myLinkSelf;
} }
/*
public InstantDt getPublished() { public InstantDt getPublished() {
InstantDt retVal = (InstantDt) getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED); InstantDt retVal = (InstantDt) getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED);
if (retVal == null) { if (retVal == null) {
@ -301,6 +302,7 @@ public class Bundle extends BaseBundle /* implements IElement */{
} }
return retVal; return retVal;
} }
*/
/** /**
* Retrieves a resource from a bundle given its logical ID. * Retrieves a resource from a bundle given its logical ID.
@ -394,9 +396,11 @@ public class Bundle extends BaseBundle /* implements IElement */{
myCategories = theCategories; myCategories = theCategories;
} }
/*
public void setPublished(InstantDt thePublished) { public void setPublished(InstantDt thePublished) {
getResourceMetadata().put(ResourceMetadataKeyEnum.PUBLISHED, thePublished); getResourceMetadata().put(ResourceMetadataKeyEnum.PUBLISHED, thePublished);
} }
/*
public void setType(BoundCodeDt<BundleTypeEnum> theType) { public void setType(BoundCodeDt<BundleTypeEnum> theType) {
myType = theType; myType = theType;

View File

@ -20,7 +20,7 @@ package ca.uhn.fhir.model.api;
* #L% * #L%
*/ */
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;

View File

@ -95,19 +95,20 @@ import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.base.composite.BaseContainedDt; import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt; import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt; import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.DecimalDt; import ca.uhn.fhir.model.primitive.DecimalDt;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.IntegerDt; import ca.uhn.fhir.model.primitive.IntegerDt;
import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.model.primitive.UriDt;
import ca.uhn.fhir.model.primitive.XhtmlDt; import ca.uhn.fhir.model.primitive.XhtmlDt;
import ca.uhn.fhir.narrative.INarrativeGenerator; import ca.uhn.fhir.narrative.INarrativeGenerator;
import ca.uhn.fhir.util.ElementUtil; import ca.uhn.fhir.util.ElementUtil;
import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.util.UrlUtil;
/** /**
* This class is the FHIR JSON parser/encoder. Users should not interact with this class directly, but should use * This class is the FHIR JSON parser/encoder. Users should not interact with this class directly, but should use {@link FhirContext#newJsonParser()} to get an instance.
* {@link FhirContext#newJsonParser()} to get an instance.
*/ */
public class JsonParser extends BaseParser implements IParser { public class JsonParser extends BaseParser implements IParser {
@ -196,7 +197,6 @@ public class JsonParser extends BaseParser implements IParser {
writeTagWithTextNode(eventWriter, "title", theBundle.getTitle()); writeTagWithTextNode(eventWriter, "title", theBundle.getTitle());
writeTagWithTextNode(eventWriter, "id", theBundle.getBundleId()); writeTagWithTextNode(eventWriter, "id", theBundle.getBundleId());
writeOptionalTagWithTextNode(eventWriter, "updated", theBundle.getUpdated()); writeOptionalTagWithTextNode(eventWriter, "updated", theBundle.getUpdated());
writeOptionalTagWithTextNode(eventWriter, "published", theBundle.getPublished());
boolean linkStarted = false; boolean linkStarted = false;
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "self", theBundle.getLinkSelf(), linkStarted); linkStarted = writeAtomLinkInDstu1Format(eventWriter, "self", theBundle.getLinkSelf(), linkStarted);
@ -353,7 +353,8 @@ public class JsonParser extends BaseParser implements IParser {
theEventWriter.writeEnd(); theEventWriter.writeEnd();
} }
private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theWriter, IBase theNextValue, BaseRuntimeElementDefinition<?> theChildDef, String theChildName, boolean theIsSubElementWithinResource) throws IOException { private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theWriter, IBase theNextValue,
BaseRuntimeElementDefinition<?> theChildDef, String theChildName, boolean theContainedResource) throws IOException {
switch (theChildDef.getChildType()) { switch (theChildDef.getChildType()) {
case ID_DATATYPE: { case ID_DATATYPE: {
@ -414,7 +415,7 @@ public class JsonParser extends BaseParser implements IParser {
if (theNextValue instanceof IBaseExtension) { if (theNextValue instanceof IBaseExtension) {
theWriter.write("url", ((IBaseExtension<?>) theNextValue).getUrl()); theWriter.write("url", ((IBaseExtension<?>) theNextValue).getUrl());
} }
encodeCompositeElementToStreamWriter(theResDef, theResource, theNextValue, theWriter, childCompositeDef, theIsSubElementWithinResource); encodeCompositeElementToStreamWriter(theResDef, theResource, theNextValue, theWriter, childCompositeDef, theContainedResource);
theWriter.writeEnd(); theWriter.writeEnd();
break; break;
} }
@ -488,7 +489,8 @@ public class JsonParser extends BaseParser implements IParser {
} }
private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theNextValue, JsonGenerator theEventWriter, List<? extends BaseRuntimeChildDefinition> theChildren, boolean theIsSubElementWithinResource) throws IOException { private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theNextValue, JsonGenerator theEventWriter,
List<? extends BaseRuntimeChildDefinition> theChildren, boolean theContainedResource) throws IOException {
for (BaseRuntimeChildDefinition nextChild : theChildren) { for (BaseRuntimeChildDefinition nextChild : theChildren) {
if (nextChild.getElementName().equals("extension") || nextChild.getElementName().equals("modifierExtension")) { if (nextChild.getElementName().equals("extension") || nextChild.getElementName().equals("modifierExtension")) {
continue; continue;
@ -507,15 +509,15 @@ public class JsonParser extends BaseParser implements IParser {
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild; RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
String childName = nextChild.getChildNameByDatatype(child.getDatatype()); String childName = nextChild.getChildNameByDatatype(child.getDatatype());
BaseRuntimeElementDefinition<?> type = child.getChildByName(childName); BaseRuntimeElementDefinition<?> type = child.getChildByName(childName);
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, narr, type, childName, theIsSubElementWithinResource); encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, narr, type, childName, theContainedResource);
continue; continue;
} }
} }
} else if (nextChild instanceof RuntimeChildContainedResources) { } else if (nextChild instanceof RuntimeChildContainedResources) {
if (theIsSubElementWithinResource == false) { if (theContainedResource == false) {
String childName = nextChild.getValidChildNames().iterator().next(); String childName = nextChild.getValidChildNames().iterator().next();
BaseRuntimeElementDefinition<?> child = nextChild.getChildByName(childName); BaseRuntimeElementDefinition<?> child = nextChild.getChildByName(childName);
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, null, child, childName, theIsSubElementWithinResource); encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, null, child, childName, theContainedResource);
} }
continue; continue;
} }
@ -535,7 +537,7 @@ public class JsonParser extends BaseParser implements IParser {
for (IBase nextValue : values) { for (IBase nextValue : values) {
if (nextValue == null || nextValue.isEmpty()) { if (nextValue == null || nextValue.isEmpty()) {
if (nextValue instanceof BaseContainedDt) { if (nextValue instanceof BaseContainedDt) {
if (theIsSubElementWithinResource || getContainedResources().isEmpty()) { if (theContainedResource || getContainedResources().isEmpty()) {
continue; continue;
} }
} else { } else {
@ -551,7 +553,7 @@ public class JsonParser extends BaseParser implements IParser {
} }
boolean primitive = childDef.getChildType() == ChildTypeEnum.PRIMITIVE_DATATYPE; boolean primitive = childDef.getChildType() == ChildTypeEnum.PRIMITIVE_DATATYPE;
if ((childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES||childDef.getChildType()==ChildTypeEnum.CONTAINED_RESOURCE_LIST) && theIsSubElementWithinResource) { if ((childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES||childDef.getChildType()==ChildTypeEnum.CONTAINED_RESOURCE_LIST) && theContainedResource) {
continue; continue;
} }
@ -573,15 +575,15 @@ public class JsonParser extends BaseParser implements IParser {
if (nextChild.getMax() > 1 || nextChild.getMax() == Child.MAX_UNLIMITED) { if (nextChild.getMax() > 1 || nextChild.getMax() == Child.MAX_UNLIMITED) {
theEventWriter.writeStartArray(childName); theEventWriter.writeStartArray(childName);
inArray = true; inArray = true;
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theIsSubElementWithinResource); encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theContainedResource);
} else if (nextChild instanceof RuntimeChildNarrativeDefinition && theIsSubElementWithinResource) { } else if (nextChild instanceof RuntimeChildNarrativeDefinition && theContainedResource) {
// suppress narratives from contained resources // suppress narratives from contained resources
} else { } else {
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, childName, theIsSubElementWithinResource); encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, childName, theContainedResource);
} }
currentChildName = childName; currentChildName = childName;
} else { } else {
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theIsSubElementWithinResource); encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theContainedResource);
} }
if (primitive) { if (primitive) {
@ -655,13 +657,15 @@ public class JsonParser extends BaseParser implements IParser {
} }
} }
private void encodeCompositeElementToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theNextValue, JsonGenerator theEventWriter, BaseRuntimeElementCompositeDefinition<?> resDef, boolean theIsSubElementWithinResource) throws IOException, DataFormatException { private void encodeCompositeElementToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theNextValue, JsonGenerator theEventWriter,
BaseRuntimeElementCompositeDefinition<?> resDef, boolean theContainedResource) throws IOException, DataFormatException {
extractAndWriteExtensionsAsDirectChild(theNextValue, theEventWriter, resDef, theResDef, theResource, null); extractAndWriteExtensionsAsDirectChild(theNextValue, theEventWriter, resDef, theResDef, theResource, null);
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theNextValue, theEventWriter, resDef.getExtensions(), theIsSubElementWithinResource); encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theNextValue, theEventWriter, resDef.getExtensions(), theContainedResource);
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theNextValue, theEventWriter, resDef.getChildren(), theIsSubElementWithinResource); encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theNextValue, theEventWriter, resDef.getChildren(), theContainedResource);
} }
private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull, boolean theContainedResource) throws IOException { private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull, boolean theContainedResource)
throws IOException {
String resourceId = null; String resourceId = null;
if (theResource instanceof IResource) { if (theResource instanceof IResource) {
IResource res = (IResource) theResource; IResource res = (IResource) theResource;
@ -702,20 +706,22 @@ public class JsonParser extends BaseParser implements IParser {
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1) && theResource instanceof IResource) { if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1) && theResource instanceof IResource) {
IResource resource = (IResource) theResource; IResource resource = (IResource) theResource;
// Object securityLabelRawObj =
List<BaseCodingDt> securityLabels = extractMetadataListNotNull(resource, ResourceMetadataKeyEnum.SECURITY_LABELS);
List<IdDt> profiles = extractMetadataListNotNull(resource, ResourceMetadataKeyEnum.PROFILES);
TagList tags = ResourceMetadataKeyEnum.TAG_LIST.get(resource);
InstantDt updated = (InstantDt) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED); InstantDt updated = (InstantDt) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED);
IdDt resourceId = resource.getId(); IdDt resourceId = resource.getId();
String versionIdPart = resourceId.getVersionIdPart(); String versionIdPart = resourceId.getVersionIdPart();
if (isBlank(versionIdPart)) { if (isBlank(versionIdPart)) {
versionIdPart = ResourceMetadataKeyEnum.VERSION.get(resource); versionIdPart = ResourceMetadataKeyEnum.VERSION.get(resource);
} }
List<BaseCodingDt> securityLabels = extractMetadataListNotNull(resource, ResourceMetadataKeyEnum.SECURITY_LABELS);
List<IdDt> profiles = extractMetadataListNotNull(resource, ResourceMetadataKeyEnum.PROFILES);
TagList tags = ResourceMetadataKeyEnum.TAG_LIST.get(resource);
if (ElementUtil.isEmpty(versionIdPart, updated, securityLabels, profiles) == false) { if (ElementUtil.isEmpty(versionIdPart, updated, securityLabels, profiles) == false) {
theEventWriter.writeStartObject("meta"); theEventWriter.writeStartObject("meta");
writeOptionalTagWithTextNode(theEventWriter, "versionId", resource.getId().getVersionIdPart()); writeOptionalTagWithTextNode(theEventWriter, "versionId", versionIdPart);
writeOptionalTagWithTextNode(theEventWriter, "lastUpdated", ResourceMetadataKeyEnum.UPDATED.get(resource)); writeOptionalTagWithTextNode(theEventWriter, "lastUpdated", updated);
if (profiles != null && profiles.isEmpty() == false) { if (profiles != null && profiles.isEmpty() == false) {
theEventWriter.writeStartArray("profile"); theEventWriter.writeStartArray("profile");
@ -1175,31 +1181,30 @@ public class JsonParser extends BaseParser implements IParser {
} }
} }
private void parseExtensionInDstu2Style(boolean theModifier, ParserState<?> theState, String theParentExtensionUrl, String theExtensionUrl, JsonArray theValues) { // private void parseExtensionInDstu2Style(boolean theModifier, ParserState<?> theState, String theParentExtensionUrl, String theExtensionUrl, JsonArray theValues) {
String extUrl = UrlUtil.constructAbsoluteUrl(theParentExtensionUrl, theExtensionUrl); // String extUrl = UrlUtil.constructAbsoluteUrl(theParentExtensionUrl, theExtensionUrl);
theState.enteringNewElementExtension(null, extUrl, theModifier); // theState.enteringNewElementExtension(null, extUrl, theModifier);
//
for (int extIdx = 0; extIdx < theValues.size(); extIdx++) { // for (int extIdx = 0; extIdx < theValues.size(); extIdx++) {
JsonObject nextExt = theValues.getJsonObject(extIdx); // JsonObject nextExt = theValues.getJsonObject(extIdx);
for (String nextKey : nextExt.keySet()) { // for (String nextKey : nextExt.keySet()) {
// if (nextKey.startsWith("value") && nextKey.length() > 5 && // // if (nextKey.startsWith("value") && nextKey.length() > 5 &&
// myContext.getRuntimeChildUndeclaredExtensionDefinition().getChildByName(nextKey) != null) { // // myContext.getRuntimeChildUndeclaredExtensionDefinition().getChildByName(nextKey) != null) {
JsonValue jsonVal = nextExt.get(nextKey); // JsonValue jsonVal = nextExt.get(nextKey);
if (jsonVal.getValueType() == ValueType.ARRAY) { // if (jsonVal.getValueType() == ValueType.ARRAY) {
/* // /*
* Extension children which are arrays are sub-extensions. Any other value type should be treated as // * Extension children which are arrays are sub-extensions. Any other value type should be treated as a value.
* a value. // */
*/ // JsonArray arrayValue = (JsonArray) jsonVal;
JsonArray arrayValue = (JsonArray) jsonVal; // parseExtensionInDstu2Style(theModifier, theState, extUrl, nextKey, arrayValue);
parseExtensionInDstu2Style(theModifier, theState, extUrl, nextKey, arrayValue); // } else {
} else { // parseChildren(theState, nextKey, jsonVal, null, null);
parseChildren(theState, nextKey, jsonVal, null, null); // }
} // }
} // }
} //
// theState.endingElement();
theState.endingElement(); // }
}
@Override @Override
public <T extends IBaseResource> T doParseResource(Class<T> theResourceType, Reader theReader) { public <T extends IBaseResource> T doParseResource(Class<T> theResourceType, Reader theReader) {

View File

@ -683,8 +683,6 @@ class ParserState<T> {
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException { public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if ("entry".equals(theLocalPart) && verifyNamespace(XmlParser.ATOM_NS, theNamespaceURI)) { if ("entry".equals(theLocalPart) && verifyNamespace(XmlParser.ATOM_NS, theNamespaceURI)) {
push(new AtomEntryState(myInstance, myResourceType)); push(new AtomEntryState(myInstance, myResourceType));
} else if (theLocalPart.equals("published")) {
push(new AtomPrimitiveState(myInstance.getPublished()));
} else if (theLocalPart.equals("title")) { } else if (theLocalPart.equals("title")) {
push(new AtomPrimitiveState(myInstance.getTitle())); push(new AtomPrimitiveState(myInstance.getTitle()));
} else if ("id".equals(theLocalPart)) { } else if ("id".equals(theLocalPart)) {
@ -900,7 +898,7 @@ class ParserState<T> {
if (myInstance instanceof IIdentifiableElement) { if (myInstance instanceof IIdentifiableElement) {
((IIdentifiableElement) myInstance).setElementSpecificId((theValue)); ((IIdentifiableElement) myInstance).setElementSpecificId((theValue));
} else { } else {
((IResource)myInstance).setId(new IdDt(theValue)); ((IResource) myInstance).setId(new IdDt(theValue));
} }
} else if ("contentType".equals(theName)) { } else if ("contentType".equals(theName)) {
myInstance.setContentType(theValue); myInstance.setContentType(theValue);
@ -1393,7 +1391,7 @@ class ParserState<T> {
res.getId().setValue('#' + res.getId().getIdPart()); res.getId().setValue('#' + res.getId().getIdPart());
} }
} }
IBaseResource preResCurrentElement = getPreResourceState().getCurrentElement(); IBaseResource preResCurrentElement = getPreResourceState().getCurrentElement();
RuntimeResourceDefinition def = myContext.getResourceDefinition(preResCurrentElement); RuntimeResourceDefinition def = myContext.getResourceDefinition(preResCurrentElement);
def.getChildByName("contained").getMutator().addValue(preResCurrentElement, res); def.getChildByName("contained").getMutator().addValue(preResCurrentElement, res);
@ -1496,6 +1494,7 @@ class ParserState<T> {
private class ElementCompositeState extends BaseState { private class ElementCompositeState extends BaseState {
private BaseRuntimeElementCompositeDefinition<?> myDefinition; private BaseRuntimeElementCompositeDefinition<?> myDefinition;
public BaseRuntimeElementCompositeDefinition<?> getDefinition() { public BaseRuntimeElementCompositeDefinition<?> getDefinition() {
return myDefinition; return myDefinition;
} }
@ -1623,8 +1622,8 @@ class ParserState<T> {
ParserState<T>.PreResourceStateHapi state = new PreResourceStateHapi(myInstance, child.getMutator(), null); ParserState<T>.PreResourceStateHapi state = new PreResourceStateHapi(myInstance, child.getMutator(), null);
push(state); push(state);
} else { } else {
ParserState<T>.PreResourceStateHl7Org state = new PreResourceStateHl7Org(myInstance, child.getMutator(), null); ParserState<T>.PreResourceStateHl7Org state = new PreResourceStateHl7Org(myInstance, child.getMutator(), null);
push(state); push(state);
} }
return; return;
} }
@ -1729,10 +1728,9 @@ class ParserState<T> {
} }
private class SecurityLabelElementStateHapi extends ElementCompositeState { private class SecurityLabelElementStateHapi extends ElementCompositeState {
public SecurityLabelElementStateHapi(ParserState<T>.PreResourceState thePreResourceState,BaseRuntimeElementCompositeDefinition<?> theDef, BaseCodingDt codingDt) { public SecurityLabelElementStateHapi(ParserState<T>.PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition<?> theDef, BaseCodingDt codingDt) {
super(thePreResourceState, theDef, codingDt); super(thePreResourceState, theDef, codingDt);
} }
@ -1741,7 +1739,6 @@ class ParserState<T> {
pop(); pop();
} }
} }
private class MetaElementState extends BaseState { private class MetaElementState extends BaseState {
@ -1761,8 +1758,8 @@ class ParserState<T> {
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException { public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if (theLocalPart.equals("versionId")) { if (theLocalPart.equals("versionId")) {
push(new MetaVersionElementState(getPreResourceState(), myMap)); push(new MetaVersionElementState(getPreResourceState(), myMap));
// } else if (theLocalPart.equals("profile")) { // } else if (theLocalPart.equals("profile")) {
// //
} else if (theLocalPart.equals("lastUpdated")) { } else if (theLocalPart.equals("lastUpdated")) {
InstantDt updated = new InstantDt(); InstantDt updated = new InstantDt();
push(new PrimitiveState(getPreResourceState(), updated)); push(new PrimitiveState(getPreResourceState(), updated));
@ -1774,7 +1771,7 @@ class ParserState<T> {
securityLabels = new ArrayList<BaseCodingDt>(); securityLabels = new ArrayList<BaseCodingDt>();
myMap.put(ResourceMetadataKeyEnum.SECURITY_LABELS, securityLabels); myMap.put(ResourceMetadataKeyEnum.SECURITY_LABELS, securityLabels);
} }
BaseCodingDt securityLabel= myContext.getVersion().newCodingDt(); BaseCodingDt securityLabel = myContext.getVersion().newCodingDt();
BaseRuntimeElementCompositeDefinition<?> codinfDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(securityLabel.getClass()); BaseRuntimeElementCompositeDefinition<?> codinfDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(securityLabel.getClass());
push(new SecurityLabelElementStateHapi(getPreResourceState(), codinfDef, securityLabel)); push(new SecurityLabelElementStateHapi(getPreResourceState(), codinfDef, securityLabel));
securityLabels.add(securityLabel); securityLabels.add(securityLabel);
@ -1903,33 +1900,30 @@ class ParserState<T> {
if (myEntry == null) { if (myEntry == null) {
myObject = (T) getCurrentElement(); myObject = (T) getCurrentElement();
} }
IResource nextResource = (IResource) getCurrentElement(); IResource nextResource = (IResource) getCurrentElement();
String version = ResourceMetadataKeyEnum.VERSION.get(nextResource); String version = ResourceMetadataKeyEnum.VERSION.get(nextResource);
String resourceName = myContext.getResourceDefinition(nextResource).getName(); String resourceName = myContext.getResourceDefinition(nextResource).getName();
String bundleIdPart = nextResource.getId().getIdPart(); String bundleIdPart = nextResource.getId().getIdPart();
if (isNotBlank(bundleIdPart)) { if (isNotBlank(bundleIdPart)) {
// if (isNotBlank(entryBaseUrl)) { // if (isNotBlank(entryBaseUrl)) {
// nextResource.setId(new IdDt(entryBaseUrl, resourceName, bundleIdPart, version)); // nextResource.setId(new IdDt(entryBaseUrl, resourceName, bundleIdPart, version));
// } else { // } else {
nextResource.setId(new IdDt(null, resourceName, bundleIdPart, version)); nextResource.setId(new IdDt(null, resourceName, bundleIdPart, version));
// } // }
} }
} }
@Override @Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException { public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
super.enteringNewElement(theNamespaceURI, theLocalPart); super.enteringNewElement(theNamespaceURI, theLocalPart);
if (myEntry != null) { if (myEntry != null) {
myEntry.setResource((IResource) getCurrentElement()); myEntry.setResource((IResource) getCurrentElement());
} }
if (myMutator != null) { if (myMutator != null) {
myMutator.addValue(myTarget, getCurrentElement()); myMutator.addValue(myTarget, getCurrentElement());
} }
} }
} }
@ -1956,13 +1950,15 @@ class ParserState<T> {
if (myTarget == null) { if (myTarget == null) {
myObject = (T) getCurrentElement(); myObject = (T) getCurrentElement();
} }
if (getCurrentElement() instanceof IDomainResource) { if (getCurrentElement() instanceof IDomainResource) {
IDomainResource elem = (IDomainResource) getCurrentElement(); IDomainResource elem = (IDomainResource) getCurrentElement();
String resourceName = myContext.getResourceDefinition(elem).getName(); String resourceName = myContext.getResourceDefinition(elem).getName();
String versionId = elem.getMeta().getVersionId(); String versionId = elem.getMeta().getVersionId();
if (StringUtils.isNotBlank(versionId)) { if (StringUtils.isBlank(elem.getId().getIdPart())) {
elem.getIdElement().setValue(resourceName + "/" + elem.getId().getIdPart() + "/_history/" + versionId); // Resource has no ID
} else if (StringUtils.isNotBlank(versionId)) {
elem.getIdElement().setValue(resourceName + "/" + elem.getId().getIdPart() + "/_history/" + versionId);
} else { } else {
elem.getIdElement().setValue(resourceName + "/" + elem.getId().getIdPart()); elem.getIdElement().setValue(resourceName + "/" + elem.getId().getIdPart());
} }
@ -2063,12 +2059,12 @@ class ParserState<T> {
@Override @Override
public void wereBack() { public void wereBack() {
final boolean bundle = "Bundle".equals(myContext.getResourceDefinition(myInstance).getName()); final boolean bundle = "Bundle".equals(myContext.getResourceDefinition(myInstance).getName());
FhirTerser terser = myContext.newTerser(); FhirTerser terser = myContext.newTerser();
terser.visit(myInstance, new IModelVisitor() { terser.visit(myInstance, new IModelVisitor() {
@Override @Override
public void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) { public void acceptElement(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
if (theElement instanceof BaseResourceReferenceDt) { if (theElement instanceof BaseResourceReferenceDt) {
BaseResourceReferenceDt nextRef = (BaseResourceReferenceDt) theElement; BaseResourceReferenceDt nextRef = (BaseResourceReferenceDt) theElement;
String ref = nextRef.getReference().getValue(); String ref = nextRef.getReference().getValue();
@ -2082,7 +2078,7 @@ class ParserState<T> {
} }
} }
} }
}else if (theElement instanceof IReference) { } else if (theElement instanceof IReference) {
IReference nextRef = (IReference) theElement; IReference nextRef = (IReference) theElement;
String ref = nextRef.getReference().getValue(); String ref = nextRef.getReference().getValue();
if (isNotBlank(ref)) { if (isNotBlank(ref)) {
@ -2099,8 +2095,8 @@ class ParserState<T> {
} }
@Override @Override
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) { public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) {
acceptElement(theNextExt.getValue(), null, null); acceptElement(theNextExt.getValue(), null, null, null);
} }
}); });
@ -2132,7 +2128,7 @@ class ParserState<T> {
} }
} }
} }
} }
@ -2547,13 +2543,12 @@ class ParserState<T> {
// TODO: this is not very efficient // TODO: this is not very efficient
String value = getDt().getValueAsString(); String value = getDt().getValueAsString();
myHl7OrgDatatype.setValueAsString(value); myHl7OrgDatatype.setValueAsString(value);
super.doPop(); super.doPop();
} }
} }
private class XhtmlState extends BaseState { private class XhtmlState extends BaseState {
private int myDepth; private int myDepth;
private XhtmlDt myDt; private XhtmlDt myDt;
@ -2583,7 +2578,7 @@ class ParserState<T> {
protected void doPop() { protected void doPop() {
pop(); pop();
} }
@Override @Override
public void endingElement() throws DataFormatException { public void endingElement() throws DataFormatException {
if (myJsonMode) { if (myJsonMode) {

View File

@ -271,7 +271,6 @@ public class XmlParser extends BaseParser implements IParser {
} }
writeOptionalTagWithTextNode(eventWriter, "updated", theBundle.getUpdated()); writeOptionalTagWithTextNode(eventWriter, "updated", theBundle.getUpdated());
writeOptionalTagWithTextNode(eventWriter, "published", theBundle.getPublished());
if (StringUtils.isNotBlank(theBundle.getAuthorName().getValue())) { if (StringUtils.isNotBlank(theBundle.getAuthorName().getValue())) {
eventWriter.writeStartElement("author"); eventWriter.writeStartElement("author");
@ -804,6 +803,7 @@ public class XmlParser extends BaseParser implements IParser {
if (updated != null) { if (updated != null) {
writeOptionalTagWithValue(theEventWriter, "lastUpdated", updated.getValueAsString()); writeOptionalTagWithValue(theEventWriter, "lastUpdated", updated.getValueAsString());
} }
for (IdDt profile : profiles) { for (IdDt profile : profiles) {
theEventWriter.writeStartElement("profile"); theEventWriter.writeStartElement("profile");
theEventWriter.writeAttribute("value", profile.getValue()); theEventWriter.writeAttribute("value", profile.getValue());

View File

@ -135,7 +135,7 @@ public class MethodOutcome {
} }
/** /**
* This will be set to {@link Boolean#TRUE} for instance of MethodOutcome which are * This will be set to {@link Boolean#TRUE} for instance of MethodOutcome which are
* returned to client instances, if the server has responded with an HTTP 201 Created. * returned to client instances, if the server has responded with an HTTP 201 Created.
*/ */
public Boolean getCreated() { public Boolean getCreated() {

View File

@ -20,8 +20,7 @@ package ca.uhn.fhir.rest.client;
* #L% * #L%
*/ */
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.*;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
@ -1413,7 +1412,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
+ "the bundle return type for the client by adding \".returnBundle(org.hl7.fhir.instance.model.Bundle.class)\" to your search method call before the \".execute()\" method"); + "the bundle return type for the client by adding \".returnBundle(org.hl7.fhir.instance.model.Bundle.class)\" to your search method call before the \".execute()\" method");
} }
IClientResponseHandler binding; IClientResponseHandler<? extends IBase> binding;
if (myReturnBundleType != null) { if (myReturnBundleType != null) {
binding = new ResourceResponseHandler(myReturnBundleType, null); binding = new ResourceResponseHandler(myReturnBundleType, null);
} else { } else {
@ -1581,8 +1580,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
myBundle = theResources; myBundle = theResources;
} }
public TransactionExecutable(List<IBaseResource> theResources) { public TransactionExecutable(List<? extends IBaseResource> theResources) {
myResources = theResources; myResources = new ArrayList<IBaseResource>(theResources);
} }
public TransactionExecutable(IBaseBundle theBundle) { public TransactionExecutable(IBaseBundle theBundle) {
@ -1619,7 +1618,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
} }
@Override @Override
public ITransactionTyped<List<IBaseResource>> withResources(List<IBaseResource> theResources) { public ITransactionTyped<List<IBaseResource>> withResources(List<? extends IBaseResource> theResources) {
Validate.notNull(theResources, "theResources must not be null"); Validate.notNull(theResources, "theResources must not be null");
return new TransactionExecutable<List<IBaseResource>>(theResources); return new TransactionExecutable<List<IBaseResource>>(theResources);
} }

View File

@ -32,7 +32,7 @@ public interface ITransaction {
/** /**
* Use a list of resources as the transaction input * Use a list of resources as the transaction input
*/ */
ITransactionTyped<List<IBaseResource>> withResources(List<IBaseResource> theResources); ITransactionTyped<List<IBaseResource>> withResources(List<? extends IBaseResource> theResources);
/** /**
* Use a DSTU1 Bundle (Atom) as the transaction input * Use a DSTU1 Bundle (Atom) as the transaction input

View File

@ -279,7 +279,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
return; return;
} }
} }
RestfulServerUtils.streamResponseAsResource(theServer, response, resource, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, respondGzip, theRequest.getFhirServerBase()); RestfulServerUtils.streamResponseAsResource(theServer, response, resource, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, respondGzip, theRequest.getFhirServerBase(), isAddContentLocationHeader());
break; break;
} else { } else {
Set<Include> includes = getRequestIncludesFromParams(params); Set<Include> includes = getRequestIncludesFromParams(params);
@ -312,7 +312,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
return; return;
} }
} }
RestfulServerUtils.streamResponseAsResource(theServer, response, (IResource) resBundle, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(), theRequest.getFhirServerBase()); RestfulServerUtils.streamResponseAsResource(theServer, response, (IResource) resBundle, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(), theRequest.getFhirServerBase(), isAddContentLocationHeader());
} }
break; break;
@ -336,12 +336,19 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
} }
} }
RestfulServerUtils.streamResponseAsResource(theServer, response, resource, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, respondGzip, theRequest.getFhirServerBase()); RestfulServerUtils.streamResponseAsResource(theServer, response, resource, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, respondGzip, theRequest.getFhirServerBase(), isAddContentLocationHeader());
break; break;
} }
} }
} }
/**
* Should the response include a Content-Location header. Search method bunding (and any others?) may override this to disable the content-location, since it doesn't make sense
*/
protected boolean isAddContentLocationHeader() {
return true;
}
/** /**
* Subclasses may override * Subclasses may override
* *

View File

@ -132,6 +132,11 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
return RestfulOperationTypeEnum.SEARCH_TYPE; return RestfulOperationTypeEnum.SEARCH_TYPE;
} }
@Override
protected BundleTypeEnum getResponseBundleType() {
return BundleTypeEnum.SEARCHSET;
}
@Override @Override
public ReturnTypeEnum getReturnType() { public ReturnTypeEnum getReturnType() {
return ReturnTypeEnum.BUNDLE; return ReturnTypeEnum.BUNDLE;
@ -289,13 +294,9 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
} }
public void setResourceType(Class<? extends IResource> resourceType) {
this.myDeclaredResourceType = resourceType;
}
@Override @Override
public String toString() { protected boolean isAddContentLocationHeader() {
return getMethod().toString(); return false;
} }
private List<String> processWhitelistAndBlacklist(List<String> theQualifiedNames, Set<String> theQualifierWhitelist, Set<String> theQualifierBlacklist) { private List<String> processWhitelistAndBlacklist(List<String> theQualifiedNames, Set<String> theQualifierWhitelist, Set<String> theQualifierBlacklist) {
@ -313,6 +314,15 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
return retVal; return retVal;
} }
public void setResourceType(Class<? extends IResource> resourceType) {
this.myDeclaredResourceType = resourceType;
}
@Override
public String toString() {
return getMethod().toString();
}
public static BaseHttpClientInvocation createSearchInvocation(FhirContext theContext, String theResourceName, Map<String, List<String>> theParameters, IdDt theId, String theCompartmentName, public static BaseHttpClientInvocation createSearchInvocation(FhirContext theContext, String theResourceName, Map<String, List<String>> theParameters, IdDt theId, String theCompartmentName,
SearchStyleEnum theSearchStyle) { SearchStyleEnum theSearchStyle) {
SearchStyleEnum searchStyle = theSearchStyle; SearchStyleEnum searchStyle = theSearchStyle;
@ -473,9 +483,4 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
} }
@Override
protected BundleTypeEnum getResponseBundleType() {
return BundleTypeEnum.SEARCHSET;
}
} }

View File

@ -203,8 +203,6 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
addResourcesToBundle(new ArrayList<IBaseResource>(resourceList), theBundleType, theServerBase, theServer.getBundleInclusionRule(), theIncludes); addResourcesToBundle(new ArrayList<IBaseResource>(resourceList), theBundleType, theServerBase, theServer.getBundleInclusionRule(), theIncludes);
addRootPropertiesToBundle(null, theServerBase, theCompleteUrl, theResult.size(), theBundleType); addRootPropertiesToBundle(null, theServerBase, theCompleteUrl, theResult.size(), theBundleType);
myBundle.setPublished(theResult.getPublished());
if (theServer.getPagingProvider() != null) { if (theServer.getPagingProvider() != null) {
int limit; int limit;
limit = theLimit != null ? theLimit : theServer.getPagingProvider().getDefaultPageSize(); limit = theLimit != null ? theLimit : theServer.getPagingProvider().getDefaultPageSize();
@ -232,10 +230,6 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
myBundle.getBundleId().setValue(UUID.randomUUID().toString()); myBundle.getBundleId().setValue(UUID.randomUUID().toString());
} }
if (myBundle.getPublished().isEmpty()) {
myBundle.getPublished().setToCurrentTimeInLocalTimeZone();
}
if (myBundle.getLinkBase().isEmpty()) { if (myBundle.getLinkBase().isEmpty()) {
myBundle.getLinkBase().setValue(theServerBase); myBundle.getLinkBase().setValue(theServerBase);
} }
@ -269,7 +263,6 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
myBundle.getAuthorName().setValue(theAuthor); myBundle.getAuthorName().setValue(theAuthor);
myBundle.getBundleId().setValue(UUID.randomUUID().toString()); myBundle.getBundleId().setValue(UUID.randomUUID().toString());
myBundle.getPublished().setToCurrentTimeInLocalTimeZone();
myBundle.getLinkBase().setValue(theServerBase); myBundle.getLinkBase().setValue(theServerBase);
myBundle.getLinkSelf().setValue(theCompleteUrl); myBundle.getLinkSelf().setValue(theCompleteUrl);
myBundle.getType().setValueAsEnum(theBundleType); myBundle.getType().setValueAsEnum(theBundleType);

View File

@ -30,10 +30,19 @@ import org.apache.commons.lang3.StringUtils;
*/ */
public class IncomingRequestAddressStrategy implements IServerAddressStrategy { public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
private String myServletPath;
@Override @Override
public String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest) { public String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest) {
String requestFullPath = StringUtils.defaultString(theRequest.getRequestURI()); String requestFullPath = StringUtils.defaultString(theRequest.getRequestURI());
String servletPath = StringUtils.defaultString(theRequest.getServletPath());
String servletPath;
if (myServletPath != null) {
servletPath = myServletPath;
} else {
servletPath = StringUtils.defaultString(theRequest.getServletPath());
}
StringBuffer requestUrl = theRequest.getRequestURL(); StringBuffer requestUrl = theRequest.getRequestURL();
String servletContextPath = ""; String servletContextPath = "";
if (theServletContext != null) { if (theServletContext != null) {
@ -48,7 +57,9 @@ public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
} }
int startOfPath = requestUrl.indexOf("//"); int startOfPath = requestUrl.indexOf("//");
if (startOfPath != -1 && (startOfPath + 2) < requestUrl.length()) { int requestUrlLength = requestUrl.length();
if (startOfPath != -1 && (startOfPath + 2) < requestUrlLength) {
startOfPath = requestUrl.indexOf("/", startOfPath + 2); startOfPath = requestUrl.indexOf("/", startOfPath + 2);
} }
if (startOfPath == -1) { if (startOfPath == -1) {
@ -56,9 +67,9 @@ public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
} }
int contextIndex; int contextIndex;
if (servletPath.length() == 0) { if (servletPath.length() == 0 || servletPath.equals("/")) {
if (requestPath.length() == 0) { if (requestPath.length() == 0) {
contextIndex = requestUrl.length(); contextIndex = requestUrlLength;
} else { } else {
contextIndex = requestUrl.indexOf(requestPath, startOfPath); contextIndex = requestUrl.indexOf(requestPath, startOfPath);
} }
@ -68,8 +79,30 @@ public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
String fhirServerBase; String fhirServerBase;
int length = contextIndex + servletPath.length(); int length = contextIndex + servletPath.length();
if (length > requestUrlLength) {
length = requestUrlLength;
}
fhirServerBase = requestUrl.substring(0, length); fhirServerBase = requestUrl.substring(0, length);
return fhirServerBase; return fhirServerBase;
} }
/**
* If set to a non-null value (default is <code>null</code>), this address strategy assumes that the FHIR endpoint is deployed to the given servlet path within the context. This is useful in some
* deployments where it isn't obvious to the servlet which part of the path is actually the root path to reach the servlet.
* <p>
* Example values could be:
* <ul>
* <li>null</li>
* <li>/</li>
* <li>/base</li>
* </ul>
* </p>
* <p>
* <b>Wildcards are not supported!</b>
* </p>
*/
public void setServletPath(String theServletPath) {
myServletPath = theServletPath;
}
} }

View File

@ -490,7 +490,7 @@ public class RestfulServer extends HttpServlet {
return; return;
} }
} }
RestfulServerUtils.streamResponseAsResource(this, theResponse, (IResource) resBundle, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(), theRequest.getFhirServerBase()); RestfulServerUtils.streamResponseAsResource(this, theResponse, (IResource) resBundle, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(), theRequest.getFhirServerBase(), false);
} }
} }

View File

@ -76,10 +76,10 @@ public class RestfulServerUtils {
} }
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IBaseResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint, public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IBaseResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, int stausCode, boolean theRespondGzip, String theServerBase) throws IOException { boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, int stausCode, boolean theRespondGzip, String theServerBase, boolean theAddContentLocationHeader) throws IOException {
theHttpResponse.setStatus(stausCode); theHttpResponse.setStatus(stausCode);
if (theResource.getId() != null && theResource.getId().hasIdPart() && isNotBlank(theServerBase)) { if (theAddContentLocationHeader && theResource.getId() != null && theResource.getId().hasIdPart() && isNotBlank(theServerBase)) {
String resName = theServer.getFhirContext().getResourceDefinition(theResource).getName(); String resName = theServer.getFhirContext().getResourceDefinition(theResource).getName();
IIdType fullId = theResource.getId().withServerBase(theServerBase, resName); IIdType fullId = theResource.getId().withServerBase(theServerBase, resName);
theHttpResponse.addHeader(Constants.HEADER_CONTENT_LOCATION, fullId.getValue()); theHttpResponse.addHeader(Constants.HEADER_CONTENT_LOCATION, fullId.getValue());
@ -413,12 +413,12 @@ public class RestfulServerUtils {
} }
} }
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IBaseResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint, // public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, boolean theRespondGzip, String theServerBase) throws IOException { // boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, boolean theRespondGzip, String theServerBase) throws IOException {
int stausCode = 200; // int stausCode = 200;
RestfulServerUtils.streamResponseAsResource(theServer, theHttpResponse, theResource, theResponseEncoding, thePrettyPrint, theRequestIsBrowser, theNarrativeMode, stausCode, theRespondGzip, // RestfulServerUtils.streamResponseAsResource(theServer, theHttpResponse, theResource, theResponseEncoding, thePrettyPrint, theRequestIsBrowser, theNarrativeMode, stausCode, theRespondGzip,
theServerBase); // theServerBase);
} // }
public static void validateResourceListNotNull(List<? extends IBaseResource> theResourceList) { public static void validateResourceListNotNull(List<? extends IBaseResource> theResourceList) {
if (theResourceList == null) { if (theResourceList == null) {

View File

@ -129,7 +129,7 @@ public class ExceptionHandlingInterceptor extends InterceptorAdapter {
boolean requestIsBrowser = RestfulServer.requestIsBrowser(theRequest); boolean requestIsBrowser = RestfulServer.requestIsBrowser(theRequest);
String fhirServerBase = ((Request) theRequestDetails).getFhirServerBase(); String fhirServerBase = ((Request) theRequestDetails).getFhirServerBase();
RestfulServerUtils.streamResponseAsResource(theRequestDetails.getServer(), theResponse, oo, RestfulServerUtils.determineResponseEncodingNoDefault(theRequest), true, requestIsBrowser, RestfulServerUtils.streamResponseAsResource(theRequestDetails.getServer(), theResponse, oo, RestfulServerUtils.determineResponseEncodingNoDefault(theRequest), true, requestIsBrowser,
NarrativeModeEnum.NORMAL, statusCode, false, fhirServerBase); NarrativeModeEnum.NORMAL, statusCode, false, fhirServerBase, false);
// theResponse.setStatus(statusCode); // theResponse.setStatus(statusCode);
// theRequestDetails.getServer().addHeadersToResponse(theResponse); // theRequestDetails.getServer().addHeadersToResponse(theResponse);

View File

@ -1,172 +0,0 @@
package ca.uhn.fhir.rest.server.interceptor;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 - 2015 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.exception.ExceptionUtils;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
import ca.uhn.fhir.rest.method.Request;
import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.RestfulServer.NarrativeModeEnum;
import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
public class ExceptionHandlingInterceptor extends InterceptorAdapter {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExceptionHandlingInterceptor.class);
private Class<?>[] myReturnStackTracesForExceptionTypes;
/**
* If any server methods throw an exception which extends any of the given exception types, the exception
* stack trace will be returned to the user. This can be useful for helping to diagnose issues, but may
* not be desirable for production situations.
*
* @param theExceptionTypes The exception types for which to return the stack trace to the user.
* @return Returns an instance of this interceptor, to allow for easy method chaining.
*/
public ExceptionHandlingInterceptor setReturnStackTracesForExceptionTypes(Class<?>... theExceptionTypes) {
myReturnStackTracesForExceptionTypes = theExceptionTypes;
return this;
}
@Override
<<<<<<< HEAD
public boolean handleException(RequestDetails theRequestDetails, Throwable theException, HttpServletRequest theRequest, HttpServletResponse theResponse) throws ServletException, IOException {
=======
public boolean handleException(RestfulServer theRestfulServer, RequestDetails theRequestDetails, Throwable theException, HttpServletRequest theRequest, HttpServletResponse theResponse) throws ServletException, IOException {
ourLog.error("AA", theException);
>>>>>>> 5956ab75fd9186ccc8b9836b60bc421b19d3d288
BaseOperationOutcome oo = null;
int statusCode = Constants.STATUS_HTTP_500_INTERNAL_ERROR;
FhirContext ctx = theRestfulServer.getFhirContext();
if (theException instanceof BaseServerResponseException) {
oo = ((BaseServerResponseException) theException).getOperationOutcome();
statusCode = ((BaseServerResponseException) theException).getStatusCode();
}
/*
* Generate an OperationOutcome to return, unless the exception throw by the resource provider had one
*/
if (oo == null) {
try {
oo = (BaseOperationOutcome) ctx.getResourceDefinition("OperationOutcome").getImplementingClass().newInstance();
} catch (Exception e1) {
ourLog.error("Failed to instantiate OperationOutcome resource instance", e1);
throw new ServletException("Failed to instantiate OperationOutcome resource instance", e1);
}
BaseIssue issue = oo.addIssue();
issue.getSeverityElement().setValue("error");
if (theException instanceof InternalErrorException) {
ourLog.error("Failure during REST processing", theException);
populateDetails(theException, issue);
} else if (theException instanceof BaseServerResponseException) {
ourLog.warn("Failure during REST processing: {}", theException);
BaseServerResponseException baseServerResponseException = (BaseServerResponseException) theException;
statusCode = baseServerResponseException.getStatusCode();
populateDetails(theException, issue);
if (baseServerResponseException.getAdditionalMessages() != null) {
for (String next : baseServerResponseException.getAdditionalMessages()) {
BaseIssue issue2 = oo.addIssue();
issue2.getSeverityElement().setValue("error");
issue2.setDetails(next);
}
}
} else {
ourLog.error("Failure during REST processing: " + theException.toString(), theException);
populateDetails(theException, issue);
statusCode = Constants.STATUS_HTTP_500_INTERNAL_ERROR;
}
} else {
ourLog.error("Unknown error during processing", theException);
}
// Add headers associated with the specific error code
if (theException instanceof BaseServerResponseException) {
Map<String, String[]> additional = ((BaseServerResponseException) theException).getAssociatedHeaders();
if (additional != null) {
for (Entry<String, String[]> next : additional.entrySet()) {
if (isNotBlank(next.getKey()) && next.getValue() != null) {
String nextKey = next.getKey();
for (String nextValue : next.getValue()) {
theResponse.addHeader(nextKey, nextValue);
}
}
}
}
}
boolean requestIsBrowser = RestfulServer.requestIsBrowser(theRequest);
String fhirServerBase = theRestfulServer.getServerBaseForRequest(theRequest);
RestfulServerUtils.streamResponseAsResource(theRestfulServer, theResponse, oo, RestfulServerUtils.determineResponseEncodingNoDefault(theRequest), true, requestIsBrowser,
NarrativeModeEnum.NORMAL, statusCode, false, fhirServerBase);
<<<<<<< HEAD
// theResponse.setStatus(statusCode);
// theRequestDetails.getServer().addHeadersToResponse(theResponse);
// theResponse.setContentType("text/plain");
// theResponse.setCharacterEncoding("UTF-8");
// theResponse.getWriter().append(theException.getMessage());
// theResponse.getWriter().close();
=======
theResponse.setStatus(statusCode);
theRestfulServer.addHeadersToResponse(theResponse);
theResponse.setContentType("text/plain");
theResponse.setCharacterEncoding("UTF-8");
theResponse.getWriter().append(theException.getMessage());
theResponse.getWriter().close();
>>>>>>> 5956ab75fd9186ccc8b9836b60bc421b19d3d288
return false;
}
private void populateDetails(Throwable theException, BaseIssue issue) {
if (myReturnStackTracesForExceptionTypes != null) {
for (Class<?> next : myReturnStackTracesForExceptionTypes) {
if (next.isAssignableFrom(theException.getClass())) {
issue.getDetailsElement().setValue(theException.getMessage() + "\n\n" + ExceptionUtils.getStackTrace(theException));
return;
}
}
}
issue.getDetailsElement().setValue(theException.getMessage());
}
}

View File

@ -61,7 +61,7 @@ public class FhirTerser {
if (theElement instanceof ISupportsUndeclaredExtensions) { if (theElement instanceof ISupportsUndeclaredExtensions) {
ISupportsUndeclaredExtensions containingElement = (ISupportsUndeclaredExtensions) theElement; ISupportsUndeclaredExtensions containingElement = (ISupportsUndeclaredExtensions) theElement;
for (ExtensionDt nextExt : containingElement.getUndeclaredExtensions()) { for (ExtensionDt nextExt : containingElement.getUndeclaredExtensions()) {
theCallback.acceptUndeclaredExtension(containingElement, theChildDefinition, theDefinition, nextExt); theCallback.acceptUndeclaredExtension(containingElement, null, theChildDefinition, theDefinition, nextExt);
addUndeclaredExtensions(nextExt, theDefinition, theChildDefinition, theCallback); addUndeclaredExtensions(nextExt, theDefinition, theChildDefinition, theCallback);
} }
} }
@ -90,10 +90,10 @@ public class FhirTerser {
public <T extends IBase> List<T> getAllPopulatedChildElementsOfType(IBaseResource theResource, final Class<T> theType) { public <T extends IBase> List<T> getAllPopulatedChildElementsOfType(IBaseResource theResource, final Class<T> theType) {
final ArrayList<T> retVal = new ArrayList<T>(); final ArrayList<T> retVal = new ArrayList<T>();
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource); BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
visit(theResource, null, def, new IModelVisitor() { visit(theResource, null, null, def, new IModelVisitor() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) { public void acceptElement(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
if (theElement == null || theElement.isEmpty()) { if (theElement == null || theElement.isEmpty()) {
return; return;
} }
@ -105,7 +105,8 @@ public class FhirTerser {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) { public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition,
ExtensionDt theNextExt) {
if (theType.isAssignableFrom(theNextExt.getClass())) { if (theType.isAssignableFrom(theNextExt.getClass())) {
retVal.add((T) theNextExt); retVal.add((T) theNextExt);
} }
@ -117,39 +118,34 @@ public class FhirTerser {
return retVal; return retVal;
} }
public List<ResourceReferenceInfo> getAllResourceReferences(final IBaseResource theResource) { public <T extends IBase> List<ResourceReferenceInfo> getAllResourceReferences(final IBaseResource theResource) {
final ArrayList<ResourceReferenceInfo> retVal = new ArrayList<ResourceReferenceInfo>(); final ArrayList<ResourceReferenceInfo> retVal = new ArrayList<ResourceReferenceInfo>();
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource); BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
visit(theResource, null, def, new IModelVisitor() { visit(theResource, null, null, def, new IModelVisitor() {
@Override @SuppressWarnings("unchecked")
public void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) { @Override
if (theElement == null || theElement.isEmpty()) { public void acceptElement(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
return; if (theElement == null || theElement.isEmpty()) {
} return;
String name = null; }
if (theChildDefinition != null) { if (BaseResourceReferenceDt.class.isAssignableFrom(theElement.getClass())) {
name = theChildDefinition.getElementName(); retVal.add(new ResourceReferenceInfo(theResource, thePathToElement, (BaseResourceReferenceDt)theElement));
} }
if (BaseResourceReferenceDt.class.isAssignableFrom(theElement.getClass())) { }
retVal.add(new ResourceReferenceInfo(theResource, name, (BaseResourceReferenceDt) theElement));
}
}
@Override @SuppressWarnings("unchecked")
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) { @Override
String name = null; public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition,
if (theChildDefinition != null) { ExtensionDt theNextExt) {
name = theChildDefinition.getElementName(); if (theNextExt.getValue() != null && BaseResourceReferenceDt.class.isAssignableFrom(theNextExt.getValue().getClass())) {
} retVal.add(new ResourceReferenceInfo(theResource, thePathToElement, (BaseResourceReferenceDt)theNextExt.getValue()));
if (theNextExt.getValue() != null && BaseResourceReferenceDt.class.isAssignableFrom(theNextExt.getValue().getClass())) { }
retVal.add(new ResourceReferenceInfo(theResource, name, (BaseResourceReferenceDt) theNextExt.getValue())); }
} });
} return retVal;
}); }
return retVal;
}
private BaseRuntimeChildDefinition getDefinition(BaseRuntimeElementCompositeDefinition<?> theCurrentDef, List<String> theSubList) { private BaseRuntimeChildDefinition getDefinition(BaseRuntimeElementCompositeDefinition<?> theCurrentDef, List<String> theSubList) {
BaseRuntimeChildDefinition nextDef = theCurrentDef.getChildByNameOrThrowDataFormatException(theSubList.get(0)); BaseRuntimeChildDefinition nextDef = theCurrentDef.getChildByNameOrThrowDataFormatException(theSubList.get(0));
if (theSubList.size() == 1) { if (theSubList.size() == 1) {
@ -222,8 +218,19 @@ public class FhirTerser {
} }
private void visit(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, IModelVisitor theCallback) { private List<String> addNameToList(List<String> theCurrentList, BaseRuntimeChildDefinition theChildDefinition) {
theCallback.acceptElement(theElement, theChildDefinition, theDefinition); if (theChildDefinition == null)
return null;
if (theCurrentList== null || theCurrentList.isEmpty())
return new ArrayList<String>(Arrays.asList(theChildDefinition.getElementName()));
List<String> newList = new ArrayList<String>(theCurrentList);
newList.add(theChildDefinition.getElementName());
return newList;
}
private void visit(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, IModelVisitor theCallback) {
List<String> pathToElement = addNameToList(thePathToElement, theChildDefinition);
theCallback.acceptElement(theElement, pathToElement, theChildDefinition, theDefinition);
addUndeclaredExtensions(theElement, theDefinition, theChildDefinition, theCallback); addUndeclaredExtensions(theElement, theDefinition, theChildDefinition, theCallback);
// if (theElement.isEmpty()) { // if (theElement.isEmpty()) {
@ -243,7 +250,7 @@ public class FhirTerser {
IBaseResource theResource = resRefDt.getResource(); IBaseResource theResource = resRefDt.getResource();
if (theResource.getId() == null || theResource.getId().isEmpty() || theResource.getId().isLocal()) { if (theResource.getId() == null || theResource.getId().isEmpty() || theResource.getId().isLocal()) {
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource); BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
visit(theResource, null, def, theCallback); visit(theResource, pathToElement, null, def, theCallback);
} }
} }
break; break;
@ -285,9 +292,9 @@ public class FhirTerser {
if (nextChild instanceof RuntimeChildDirectResource) { if (nextChild instanceof RuntimeChildDirectResource) {
// Don't descend into embedded resources // Don't descend into embedded resources
theCallback.acceptElement(nextValue, nextChild, childElementDef); theCallback.acceptElement(nextValue, null, nextChild, childElementDef);
} else { } else {
visit(nextValue, nextChild, childElementDef, theCallback); visit(nextValue, pathToElement, nextChild, childElementDef, theCallback);
} }
} }
} }
@ -298,7 +305,7 @@ public class FhirTerser {
BaseContainedDt value = (BaseContainedDt) theElement; BaseContainedDt value = (BaseContainedDt) theElement;
for (IResource next : value.getContainedResources()) { for (IResource next : value.getContainedResources()) {
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(next); BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(next);
visit(next, null, def, theCallback); visit(next, pathToElement, null, def, theCallback);
} }
break; break;
} }
@ -309,7 +316,7 @@ public class FhirTerser {
case CONTAINED_RESOURCE_LIST: case CONTAINED_RESOURCE_LIST:
if (theElement != null) { if (theElement != null) {
BaseRuntimeElementDefinition<?> def = myContext.getElementDefinition(theElement.getClass()); BaseRuntimeElementDefinition<?> def = myContext.getElementDefinition(theElement.getClass());
visit(theElement, null, def, theCallback); visit(theElement, pathToElement, null, def, theCallback);
} }
break; break;
} }
@ -454,7 +461,7 @@ public class FhirTerser {
*/ */
public void visit(IBaseResource theResource, IModelVisitor theVisitor) { public void visit(IBaseResource theResource, IModelVisitor theVisitor) {
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource); BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
visit(theResource, null, def, theVisitor); visit(theResource, null, null, def, theVisitor);
} }
/** /**

View File

@ -28,6 +28,8 @@ import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.model.api.ExtensionDt; import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions; import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
import java.util.List;
/** /**
* @see FhirTerser#visit(IBaseResource, IModelVisitor) * @see FhirTerser#visit(IBaseResource, IModelVisitor)
*/ */
@ -39,7 +41,7 @@ public interface IModelVisitor {
* @param theChildDefinition May be null if this is a root element * @param theChildDefinition May be null if this is a root element
* @param theDefinition * @param theDefinition
*/ */
void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition); void acceptElement(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition);
/** /**
* *
@ -48,7 +50,7 @@ public interface IModelVisitor {
* @param theDefinition * @param theDefinition
* @param theNextExt * @param theNextExt
*/ */
void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt); void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt);

View File

@ -28,58 +28,71 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import org.hl7.fhir.instance.model.IBaseResource; import org.hl7.fhir.instance.model.IBaseResource;
import java.util.Iterator;
import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
* Created by Bill de Beaubien on 2/26/2015. * Created by Bill de Beaubien on 2/26/2015.
*/ */
public class ResourceReferenceInfo { public class ResourceReferenceInfo {
private String myOwningResource; private String myOwningResource;
private String myName; private String myName;
private BaseResourceReferenceDt myResource; private BaseResourceReferenceDt myResource;
public ResourceReferenceInfo(IBaseResource theOwningResource, String theName, BaseResourceReferenceDt theResource) { public ResourceReferenceInfo(IBaseResource theOwningResource, List<String> thePathToElement, BaseResourceReferenceDt theResource) {
myOwningResource = theOwningResource.getClass().getAnnotation(ResourceDef.class).name(); myOwningResource = theOwningResource.getClass().getAnnotation(ResourceDef.class).name();
myName = theName; myResource = theResource;
myResource = theResource; if (thePathToElement != null && !thePathToElement.isEmpty()) {
} StringBuilder sb = new StringBuilder();
thePathToElement.iterator();
for (Iterator<String> iterator = thePathToElement.iterator(); iterator.hasNext(); ) {
sb.append(iterator.next());
if (iterator.hasNext())
sb.append(".");
}
myName = sb.toString();
} else {
myName = null;
}
}
@Override @Override
public String toString() { public String toString() {
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
b.append("name", myName); b.append("name", myName);
b.append("resource", myResource.getReference()); b.append("resource", myResource.getReference());
return b.build(); return b.build();
} }
public String getName() { public String getName() {
return myName; return myName;
} }
public BaseResourceReferenceDt getResourceReference() { public BaseResourceReferenceDt getResourceReference() {
return myResource; return myResource;
} }
public boolean matchesIncludeSet(Set<Include> theIncludes) { public boolean matchesIncludeSet(Set<Include> theIncludes) {
if (theIncludes == null) if (theIncludes == null)
return false; return false;
for (Include include : theIncludes) { for (Include include : theIncludes) {
if (matchesInclude(include)) if (matchesInclude(include))
return true; return true;
} }
return false; return false;
} }
public boolean matchesInclude(Include theInclude) { public boolean matchesInclude(Include theInclude) {
if (theInclude.getValue().equals("*")) { if (theInclude.getValue().equals("*")) {
return true; return true;
} }
if (theInclude.getValue().indexOf(':') != -1) { if (theInclude.getValue().indexOf(':') != -1) {
// DSTU2 style // DSTU2 style
return (theInclude.getValue().equals(myOwningResource + ':' + myName)); return (theInclude.getValue().equals(myOwningResource + ':' + myName));
} else { } else {
// DSTU1 style // DSTU1 style
return (theInclude.getValue().equals(myOwningResource + '.' + myName)); return (theInclude.getValue().equals(myOwningResource + '.' + myName));
} }
} }
} }

View File

@ -20,8 +20,7 @@ package ca.uhn.fhir.jpa.dao;
* #L% * #L%
*/ */
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.*;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URI; import java.net.URI;
@ -444,12 +443,12 @@ public abstract class BaseFhirDao implements IDao {
} }
@Override @Override
public List<IResource> getResources(final int theFromIndex, final int theToIndex) { public List<IBaseResource> getResources(final int theFromIndex, final int theToIndex) {
final StopWatch timer = new StopWatch(); final StopWatch timer = new StopWatch();
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager); TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
return template.execute(new TransactionCallback<List<IResource>>() { return template.execute(new TransactionCallback<List<IBaseResource>>() {
@Override @Override
public List<IResource> doInTransaction(TransactionStatus theStatus) { public List<IBaseResource> doInTransaction(TransactionStatus theStatus) {
List<BaseHasResource> resEntities = Lists.newArrayList(); List<BaseHasResource> resEntities = Lists.newArrayList();
List<HistoryTuple> tupleSubList = tuples.subList(theFromIndex, theToIndex); List<HistoryTuple> tupleSubList = tuples.subList(theFromIndex, theToIndex);
@ -471,7 +470,7 @@ public abstract class BaseFhirDao implements IDao {
resEntities = resEntities.subList(0, limit); resEntities = resEntities.subList(0, limit);
} }
ArrayList<IResource> retVal = new ArrayList<IResource>(); ArrayList<IBaseResource> retVal = new ArrayList<IBaseResource>();
for (BaseHasResource next : resEntities) { for (BaseHasResource next : resEntities) {
RuntimeResourceDefinition type; RuntimeResourceDefinition type;
try { try {
@ -514,7 +513,7 @@ public abstract class BaseFhirDao implements IDao {
return true; return true;
} }
protected List<IResource> loadResourcesById(Set<IdDt> theIncludePids) { protected List<IBaseResource> loadResourcesById(Set<IdDt> theIncludePids) {
Set<Long> pids = new HashSet<Long>(); Set<Long> pids = new HashSet<Long>();
for (IdDt next : theIncludePids) { for (IdDt next : theIncludePids) {
if (next.isIdPartValidLong()) { if (next.isIdPartValidLong()) {
@ -528,6 +527,10 @@ public abstract class BaseFhirDao implements IDao {
} }
} }
if (pids.isEmpty()) {
return new ArrayList<IBaseResource>();
}
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder(); CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
CriteriaQuery<ResourceTable> cq = builder.createQuery(ResourceTable.class); CriteriaQuery<ResourceTable> cq = builder.createQuery(ResourceTable.class);
Root<ResourceTable> from = cq.from(ResourceTable.class); Root<ResourceTable> from = cq.from(ResourceTable.class);
@ -538,7 +541,7 @@ public abstract class BaseFhirDao implements IDao {
// } // }
TypedQuery<ResourceTable> q = myEntityManager.createQuery(cq); TypedQuery<ResourceTable> q = myEntityManager.createQuery(cq);
ArrayList<IResource> retVal = new ArrayList<IResource>(); ArrayList<IBaseResource> retVal = new ArrayList<IBaseResource>();
for (ResourceTable next : q.getResultList()) { for (ResourceTable next : q.getResultList()) {
IResource resource = (IResource) toResource(next); IResource resource = (IResource) toResource(next);
retVal.add(resource); retVal.add(resource);

View File

@ -20,8 +20,7 @@ package ca.uhn.fhir.jpa.dao;
* #L% * #L%
*/ */
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.*;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
@ -660,12 +659,12 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
return new HashSet<Long>(q.getResultList()); return new HashSet<Long>(q.getResultList());
} }
private List<IResource> addResourcesAsIncludesById(List<IResource> theListToPopulate, Set<IdDt> includePids, List<IResource> resources) { private List<IBaseResource> addResourcesAsIncludesById(List<IBaseResource> theListToPopulate, Set<IdDt> includePids, List<IBaseResource> resources) {
if (!includePids.isEmpty()) { if (!includePids.isEmpty()) {
ourLog.info("Loading {} included resources", includePids.size()); ourLog.info("Loading {} included resources", includePids.size());
resources = loadResourcesById(includePids); resources = loadResourcesById(includePids);
for (IResource next : resources) { for (IBaseResource next : resources) {
ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put(next, BundleEntrySearchModeEnum.INCLUDE); ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put((IResource) next, BundleEntrySearchModeEnum.INCLUDE);
} }
theListToPopulate.addAll(resources); theListToPopulate.addAll(resources);
} }
@ -1000,7 +999,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
return tags; return tags;
} }
protected abstract List<Object> getIncludeValues(FhirTerser theTerser, Include theInclude, IResource theResource, RuntimeResourceDefinition theResourceDef); protected abstract List<Object> getIncludeValues(FhirTerser theTerser, Include theInclude, IBaseResource theResource, RuntimeResourceDefinition theResourceDef);
public Class<T> getResourceType() { public Class<T> getResourceType() {
return myResourceType; return myResourceType;
@ -1074,8 +1073,8 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
} }
@Override @Override
public List<IResource> getResources(int theFromIndex, int theToIndex) { public List<IBaseResource> getResources(int theFromIndex, int theToIndex) {
ArrayList<IResource> retVal = new ArrayList<IResource>(); List<IBaseResource> retVal = new ArrayList<IBaseResource>();
if (theFromIndex == 0 && current != null) { if (theFromIndex == 0 && current != null) {
retVal.add(current); retVal.add(current);
} }
@ -1128,7 +1127,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
return retVal; return retVal;
} }
private void loadResourcesByPid(Collection<Long> theIncludePids, List<IResource> theResourceListToPopulate, BundleEntrySearchModeEnum theBundleEntryStatus) { private void loadResourcesByPid(Collection<Long> theIncludePids, List<IBaseResource> theResourceListToPopulate, BundleEntrySearchModeEnum theBundleEntryStatus) {
if (theIncludePids.isEmpty()) { if (theIncludePids.isEmpty()) {
return; return;
} }
@ -1520,15 +1519,15 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
} }
@Override @Override
public List<IResource> getResources(final int theFromIndex, final int theToIndex) { public List<IBaseResource> getResources(final int theFromIndex, final int theToIndex) {
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager); TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
return template.execute(new TransactionCallback<List<IResource>>() { return template.execute(new TransactionCallback<List<IBaseResource>>() {
@Override @Override
public List<IResource> doInTransaction(TransactionStatus theStatus) { public List<IBaseResource> doInTransaction(TransactionStatus theStatus) {
List<Long> pidsSubList = pids.subList(theFromIndex, theToIndex); List<Long> pidsSubList = pids.subList(theFromIndex, theToIndex);
// Execute the query and make sure we return distinct results // Execute the query and make sure we return distinct results
List<IResource> retVal = new ArrayList<IResource>(); List<IBaseResource> retVal = new ArrayList<IBaseResource>();
loadResourcesByPid(pidsSubList, retVal, BundleEntrySearchModeEnum.MATCH); loadResourcesByPid(pidsSubList, retVal, BundleEntrySearchModeEnum.MATCH);
/* /*
@ -1538,18 +1537,18 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
*/ */
if (theParams.getIncludes() != null && theParams.getIncludes().isEmpty() == false) { if (theParams.getIncludes() != null && theParams.getIncludes().isEmpty() == false) {
Set<IdDt> previouslyLoadedPids = new HashSet<IdDt>(); Set<IdDt> previouslyLoadedPids = new HashSet<IdDt>();
for (IResource next : retVal) { for (IBaseResource next : retVal) {
previouslyLoadedPids.add(next.getId().toUnqualifiedVersionless()); previouslyLoadedPids.add((IdDt) next.getId().toUnqualifiedVersionless());
} }
Set<IdDt> includePids = new HashSet<IdDt>(); Set<IdDt> includePids = new HashSet<IdDt>();
List<IResource> resources = retVal; List<IBaseResource> resources = retVal;
do { do {
includePids.clear(); includePids.clear();
FhirTerser t = getContext().newTerser(); FhirTerser t = getContext().newTerser();
for (Include next : theParams.getIncludes()) { for (Include next : theParams.getIncludes()) {
for (IResource nextResource : resources) { for (IBaseResource nextResource : resources) {
RuntimeResourceDefinition def = getContext().getResourceDefinition(nextResource); RuntimeResourceDefinition def = getContext().getResourceDefinition(nextResource);
List<Object> values = getIncludeValues(t, next, nextResource, def); List<Object> values = getIncludeValues(t, next, nextResource, def);

View File

@ -24,6 +24,8 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.hl7.fhir.instance.model.IBaseResource;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.Include;
@ -32,7 +34,7 @@ import ca.uhn.fhir.util.FhirTerser;
public class FhirResourceDaoDstu1<T extends IResource> extends BaseFhirResourceDao<T> { public class FhirResourceDaoDstu1<T extends IResource> extends BaseFhirResourceDao<T> {
protected List<Object> getIncludeValues(FhirTerser t, Include next, IResource nextResource, RuntimeResourceDefinition def) { protected List<Object> getIncludeValues(FhirTerser t, Include next, IBaseResource nextResource, RuntimeResourceDefinition def) {
List<Object> values; List<Object> values;
if ("*".equals(next.getValue())) { if ("*".equals(next.getValue())) {
values = new ArrayList<Object>(); values = new ArrayList<Object>();

View File

@ -24,6 +24,8 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.hl7.fhir.instance.model.IBaseResource;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
@ -33,7 +35,7 @@ import ca.uhn.fhir.util.FhirTerser;
public class FhirResourceDaoDstu2<T extends IResource> extends BaseFhirResourceDao<T> { public class FhirResourceDaoDstu2<T extends IResource> extends BaseFhirResourceDao<T> {
protected List<Object> getIncludeValues(FhirTerser theTerser, Include theInclude, IResource theResource, RuntimeResourceDefinition theResourceDef) { protected List<Object> getIncludeValues(FhirTerser theTerser, Include theInclude, IBaseResource theResource, RuntimeResourceDefinition theResourceDef) {
List<Object> values; List<Object> values;
if ("*".equals(theInclude.getValue())) { if ("*".equals(theInclude.getValue())) {
values = new ArrayList<Object>(); values = new ArrayList<Object>();

View File

@ -31,6 +31,7 @@ import java.util.Set;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import org.hl7.fhir.instance.model.IBaseResource;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -241,9 +242,9 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
if (bundle.size() > configuredMax) { if (bundle.size() > configuredMax) {
oo.addIssue().setSeverity(IssueSeverityEnum.WARNING).setDetails("Search nested within transaction found more than " + configuredMax + " matches, but paging is not supported in nested transactions"); oo.addIssue().setSeverity(IssueSeverityEnum.WARNING).setDetails("Search nested within transaction found more than " + configuredMax + " matches, but paging is not supported in nested transactions");
} }
List<IResource> resourcesToAdd = bundle.getResources(0, Math.min(bundle.size(), configuredMax)); List<IBaseResource> resourcesToAdd = bundle.getResources(0, Math.min(bundle.size(), configuredMax));
for (IResource next : resourcesToAdd) { for (IBaseResource next : resourcesToAdd) {
searchBundle.addEntry().setResource(next); searchBundle.addEntry().setResource((IResource) next);
} }
response.addEntry().setResource(searchBundle); response.addEntry().setResource(searchBundle);

View File

@ -39,9 +39,11 @@
</bean> </bean>
</property> </property>
</bean> </bean>
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="myEntityManagerFactory" /> <property name="entityManagerFactory" ref="myEntityManagerFactory" />
</bean> </bean>
<tx:annotation-driven transaction-manager="myTxManager" /> <tx:annotation-driven transaction-manager="myTxManager" />
</beans> </beans>

View File

@ -27,6 +27,7 @@ import java.util.Set;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.hamcrest.core.StringContains; import org.hamcrest.core.StringContains;
import org.hl7.fhir.instance.model.IBaseResource;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@ -453,8 +454,8 @@ public class FhirResourceDaoDstu2Test {
IBundleProvider history = ourPatientDao.history(null); IBundleProvider history = ourPatientDao.history(null);
assertEquals(4 + initialHistory, history.size()); assertEquals(4 + initialHistory, history.size());
List<IResource> resources = history.getResources(0, 4); List<IBaseResource> resources = history.getResources(0, 4);
assertNotNull(resources.get(0).getResourceMetadata().get(ResourceMetadataKeyEnum.DELETED_AT)); assertNotNull(((IResource) resources.get(0)).getResourceMetadata().get(ResourceMetadataKeyEnum.DELETED_AT));
try { try {
ourPatientDao.delete(id2); ourPatientDao.delete(id2);
@ -534,9 +535,9 @@ public class FhirResourceDaoDstu2Test {
IBundleProvider history = ourPatientDao.history(id, null); IBundleProvider history = ourPatientDao.history(id, null);
assertEquals(2, history.size()); assertEquals(2, history.size());
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(0, 0).get(0))); assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(0, 0).get(0)));
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(0, 0).get(0)).getValue()); assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(0, 0).get(0)).getValue());
assertNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(1, 1).get(0))); assertNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(1, 1).get(0)));
} }
@ -879,7 +880,7 @@ public class FhirResourceDaoDstu2Test {
map.setRevIncludes(Collections.singleton(Patient.INCLUDE_ORGANIZATION)); map.setRevIncludes(Collections.singleton(Patient.INCLUDE_ORGANIZATION));
IBundleProvider resultsP = ourOrganizationDao.search(map); IBundleProvider resultsP = ourOrganizationDao.search(map);
assertEquals(2, resultsP.size()); assertEquals(2, resultsP.size());
List<IResource> results = resultsP.getResources(0, resultsP.size()); List<IBaseResource> results = resultsP.getResources(0, resultsP.size());
assertEquals(2, results.size()); assertEquals(2, results.size());
assertEquals(Organization.class, results.get(0).getClass()); assertEquals(Organization.class, results.get(0).getClass());
assertEquals(Patient.class, results.get(1).getClass()); assertEquals(Patient.class, results.get(1).getClass());
@ -2162,15 +2163,15 @@ public class FhirResourceDaoDstu2Test {
assertEquals(2, historyBundle.size()); assertEquals(2, historyBundle.size());
List<IResource> history = historyBundle.getResources(0, 2); List<IBaseResource> history = historyBundle.getResources(0, 2);
assertEquals("1", history.get(1).getId().getVersionIdPart()); assertEquals("1", history.get(1).getId().getVersionIdPart());
assertEquals("2", history.get(0).getId().getVersionIdPart()); assertEquals("2", history.get(0).getId().getVersionIdPart());
assertEquals(published, history.get(1).getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED)); assertEquals(published, ((IResource)history.get(1)).getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED));
assertEquals(published, history.get(1).getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED)); assertEquals(published, ((IResource)history.get(1)).getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED));
assertEquals(updated, history.get(1).getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED)); assertEquals(updated, ((IResource)history.get(1)).getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED));
assertEquals("001", ((Patient) history.get(1)).getIdentifierFirstRep().getValue()); assertEquals("001", ((Patient) history.get(1)).getIdentifierFirstRep().getValue());
assertEquals(published2, history.get(0).getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED)); assertEquals(published2, ((IResource)history.get(0)).getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED));
assertEquals(updated2, history.get(0).getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED)); assertEquals(updated2, ((IResource)history.get(0)).getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED));
assertEquals("002", ((Patient) history.get(0)).getIdentifierFirstRep().getValue()); assertEquals("002", ((Patient) history.get(0)).getIdentifierFirstRep().getValue());
} }
@ -2313,8 +2314,8 @@ public class FhirResourceDaoDstu2Test {
private List<IdDt> toUnqualifiedVersionlessIds(IBundleProvider theFound) { private List<IdDt> toUnqualifiedVersionlessIds(IBundleProvider theFound) {
List<IdDt> retVal = new ArrayList<IdDt>(); List<IdDt> retVal = new ArrayList<IdDt>();
for (IResource next : theFound.getResources(0, theFound.size())) { for (IBaseResource next : theFound.getResources(0, theFound.size())) {
retVal.add(next.getId().toUnqualifiedVersionless()); retVal.add((IdDt) next.getId().toUnqualifiedVersionless());
} }
return retVal; return retVal;
} }
@ -2353,9 +2354,9 @@ public class FhirResourceDaoDstu2Test {
IBundleProvider value = ourDeviceDao.search(new SearchParameterMap()); IBundleProvider value = ourDeviceDao.search(new SearchParameterMap());
ourLog.info("Initial size: " + value.size()); ourLog.info("Initial size: " + value.size());
for (IResource next : value.getResources(0, value.size())) { for (IBaseResource next : value.getResources(0, value.size())) {
ourLog.info("Deleting: {}", next.getId()); ourLog.info("Deleting: {}", next.getId());
ourDeviceDao.delete(next.getId()); ourDeviceDao.delete((IdDt) next.getId());
} }
value = ourDeviceDao.search(new SearchParameterMap()); value = ourDeviceDao.search(new SearchParameterMap());
@ -2365,7 +2366,7 @@ public class FhirResourceDaoDstu2Test {
} }
assertEquals(0, value.size()); assertEquals(0, value.size());
List<IResource> res = value.getResources(0, 0); List<IBaseResource> res = value.getResources(0, 0);
assertTrue(res.isEmpty()); assertTrue(res.isEmpty());
} }

View File

@ -11,6 +11,7 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.hl7.fhir.instance.model.IBaseResource;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@ -93,7 +94,7 @@ public class FhirSystemDaoDstu1Test {
IBundleProvider values = ourSystemDao.history(start); IBundleProvider values = ourSystemDao.history(start);
assertEquals(4, values.size()); assertEquals(4, values.size());
List<IResource> res = values.getResources(0, 4); List<IBaseResource> res = values.getResources(0, 4);
assertEquals(newpid3, res.get(0).getId()); assertEquals(newpid3, res.get(0).getId());
assertEquals(newpid2, res.get(1).getId()); assertEquals(newpid2, res.get(1).getId());
assertEquals(newpid, res.get(2).getId()); assertEquals(newpid, res.get(2).getId());
@ -146,7 +147,7 @@ public class FhirSystemDaoDstu1Test {
IBundleProvider patResults = ourPatientDao.search(Patient.SP_IDENTIFIER, new IdentifierDt("urn:system", "testPersistWithSimpleLinkP01")); IBundleProvider patResults = ourPatientDao.search(Patient.SP_IDENTIFIER, new IdentifierDt("urn:system", "testPersistWithSimpleLinkP01"));
assertEquals(1, obsResults.size()); assertEquals(1, obsResults.size());
IdDt foundPatientId = patResults.getResources(0, 1).get(0).getId(); IdDt foundPatientId = (IdDt) patResults.getResources(0, 1).get(0).getId();
ResourceReferenceDt subject = obs.getSubject(); ResourceReferenceDt subject = obs.getSubject();
assertEquals(foundPatientId.getIdPart(), subject.getReference().getIdPart()); assertEquals(foundPatientId.getIdPart(), subject.getReference().getIdPart());
@ -371,7 +372,7 @@ public class FhirSystemDaoDstu1Test {
*/ */
res = new ArrayList<IResource>(); res = new ArrayList<IResource>();
List<IResource> existing = results.getResources(0, 3); List<IBaseResource> existing = results.getResources(0, 3);
p1 = new Patient(); p1 = new Patient();
p1.setId(existing.get(0).getId()); p1.setId(existing.get(0).getId());
@ -391,7 +392,7 @@ public class FhirSystemDaoDstu1Test {
IBundleProvider results2 = ourPatientDao.search(Patient.SP_IDENTIFIER, new TokenParam("urn:system", "testTransactionWithDelete")); IBundleProvider results2 = ourPatientDao.search(Patient.SP_IDENTIFIER, new TokenParam("urn:system", "testTransactionWithDelete"));
assertEquals(1, results2.size()); assertEquals(1, results2.size());
List<IResource> existing2 = results2.getResources(0, 1); List<IBaseResource> existing2 = results2.getResources(0, 1);
assertEquals(existing2.get(0).getId(), existing.get(2).getId()); assertEquals(existing2.get(0).getId(), existing.get(2).getId());
} }

View File

@ -14,6 +14,7 @@ import static org.junit.Assert.fail;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.hl7.fhir.instance.model.IBaseResource;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@ -262,9 +263,9 @@ public class FhirSystemDaoDstu2Test {
IBundleProvider history = ourPatientDao.history(id, null); IBundleProvider history = ourPatientDao.history(id, null);
assertEquals(2, history.size()); assertEquals(2, history.size());
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(0, 0).get(0))); assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(0, 0).get(0)));
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(0, 0).get(0)).getValue()); assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(0, 0).get(0)).getValue());
assertNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(1, 1).get(0))); assertNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(1, 1).get(0)));
} }
@ -769,9 +770,9 @@ public class FhirSystemDaoDstu2Test {
static void doDeleteEverything(IFhirSystemDao<Bundle> systemDao) { static void doDeleteEverything(IFhirSystemDao<Bundle> systemDao) {
IBundleProvider all = systemDao.history(null); IBundleProvider all = systemDao.history(null);
List<IResource> allRes = all.getResources(0, all.size()); List<IBaseResource> allRes = all.getResources(0, all.size());
for (IResource iResource : allRes) { for (IBaseResource iResource : allRes) {
if (ResourceMetadataKeyEnum.DELETED_AT.get(iResource) == null) { if (ResourceMetadataKeyEnum.DELETED_AT.get((IResource) iResource) == null) {
ourLog.info("Deleting: {}", iResource.getId()); ourLog.info("Deleting: {}", iResource.getId());
Bundle b = new Bundle(); Bundle b = new Bundle();

View File

@ -26,6 +26,7 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletHolder;
import org.hl7.fhir.instance.model.IBaseResource;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@ -126,12 +127,7 @@ public class ResourceProviderDstu2Test {
CloseableHttpResponse response = ourHttpClient.execute(post); CloseableHttpResponse response = ourHttpClient.execute(post);
try { try {
assertEquals(400, response.getStatusLine().getStatusCode());
assertEquals(201, response.getStatusLine().getStatusCode());
assertThat(response.getFirstHeader(Constants.HEADER_LOCATION_LC).getValue(), startsWith(ourServerBase + "/Patient/"));
assertThat(response.getFirstHeader(Constants.HEADER_LOCATION_LC).getValue(), endsWith("/_history/1"));
assertThat(response.getFirstHeader(Constants.HEADER_LOCATION_LC).getValue(), not(containsString("1777")));
} finally { } finally {
response.close(); response.close();
} }
@ -452,7 +448,7 @@ public class ResourceProviderDstu2Test {
// NB this does not get used- The paging provider has its own limits built in // NB this does not get used- The paging provider has its own limits built in
ourDaoConfig.setHardSearchLimit(100); ourDaoConfig.setHardSearchLimit(100);
List<IResource> resources = new ArrayList<IResource>(); List<IBaseResource> resources = new ArrayList<IBaseResource>();
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
Organization org = new Organization(); Organization org = new Organization();
org.setName("rpdstu2_testCountParam_01"); org.setName("rpdstu2_testCountParam_01");

View File

@ -7,6 +7,7 @@ import java.util.List;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletHolder;
import org.hl7.fhir.instance.model.IBaseResource;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;

View File

@ -2,22 +2,25 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<!-- <!--
Note: HAPI projects use the Sonatype OSS parent project to Note: HAPI projects use the "hapi-fhir" POM as their base to provide
facilitate deployment to the global Maven repos. easy management.
You do not need to use this in your own projects, so the You do not need to use this in your own projects, so the
"parent" tag and it's contents below may be removed if you "parent" tag and it's contents below may be removed if you
are using this file as a basis for your own project. are using this file as a basis for your own project.
--> -->
<!--
<parent> <parent>
<groupId>org.sonatype.oss</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>oss-parent</artifactId> <artifactId>hapi-fhir</artifactId>
<version>7</version> <version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent> </parent>
-->
<groupId>ca.uhn.hapi.example</groupId> <groupId>ca.uhn.hapi.example</groupId>
<artifactId>hapi-fhir-jpaserver-example</artifactId> <artifactId>hapi-fhir-jpaserver-example</artifactId>
<version>0.9-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<packaging>war</packaging> <packaging>war</packaging>
<name>HAPI FHIR JPA Server - Example</name> <name>HAPI FHIR JPA Server - Example</name>

View File

@ -4,12 +4,11 @@ import java.util.List;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import ca.uhn.fhir.context.FhirVersionEnum;
import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao; import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu1; import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu1;
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2; import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
@ -23,7 +22,7 @@ import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider; import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
public class JpaServerDemo extends RestfulServer { public class JpaServerDemo extends RestfulServer {
@ -123,12 +122,12 @@ public class JpaServerDemo extends RestfulServer {
setPagingProvider(new FifoMemoryPagingProvider(10)); setPagingProvider(new FifoMemoryPagingProvider(10));
/* /*
* Do some fancy logging to create a nice access log that has details about each incoming request. * Load interceptors for the server from Spring (these are defined in hapi-fhir-server-config.xml
*/ */
LoggingInterceptor loggingInterceptor = new LoggingInterceptor(); List<IServerInterceptor> interceptorBeans = myAppCtx.getBean("myServerInterceptors", List.class);
loggingInterceptor.setLoggerName("fhir.access"); for (IServerInterceptor interceptor : interceptorBeans) {
loggingInterceptor.setMessageFormat("Path[${servletPath}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]"); this.registerInterceptor(interceptor);
this.registerInterceptor(loggingInterceptor); }
} }

View File

@ -21,4 +21,18 @@
</bean> </bean>
<tx:annotation-driven transaction-manager="myTxManager" /> <tx:annotation-driven transaction-manager="myTxManager" />
<util:list id="myServerInterceptors">
<ref bean="myLoggingInterceptor"/>
</util:list>
<!--
Do some fancy logging to create a nice access log that has details
about each incoming request.
-->
<bean id="myLoggingInterceptor" class="ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor">
<property name="loggerName" value="fhirtest.access"/>
<property name="messageFormat"
value="Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]"/>
</bean>
</beans> </beans>

View File

@ -7,17 +7,16 @@ import javax.servlet.ServletContext;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.ContextLoaderListener;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao; import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu1; import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu1;
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu1; import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu1;
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
import ca.uhn.fhir.rest.server.ETagSupportEnum; import ca.uhn.fhir.rest.server.ETagSupportEnum;
import ca.uhn.fhir.rest.server.EncodingEnum; import ca.uhn.fhir.rest.server.EncodingEnum;
@ -25,7 +24,7 @@ import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy; import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
public class TestRestfulServer extends RestfulServer { public class TestRestfulServer extends RestfulServer {
@ -164,13 +163,12 @@ public class TestRestfulServer extends RestfulServer {
setPagingProvider(new FifoMemoryPagingProvider(10)); setPagingProvider(new FifoMemoryPagingProvider(10));
/* /*
* Do some fancy logging to create a nice access log that has details * Load interceptors for the server from Spring (these are defined in hapi-fhir-server-config.xml
* about each incoming request.
*/ */
LoggingInterceptor loggingInterceptor = new LoggingInterceptor(); List<IServerInterceptor> interceptorBeans = myAppCtx.getBean("myServerInterceptors", List.class);
loggingInterceptor.setLoggerName("fhirtest.access"); for (IServerInterceptor interceptor : interceptorBeans) {
loggingInterceptor.setMessageFormat("Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]"); this.registerInterceptor(interceptor);
this.registerInterceptor(loggingInterceptor); }
} }

View File

@ -21,4 +21,18 @@
</bean> </bean>
<tx:annotation-driven transaction-manager="myTxManager" /> <tx:annotation-driven transaction-manager="myTxManager" />
<util:list id="myServerInterceptors">
<ref bean="myLoggingInterceptor"/>
</util:list>
<!--
Do some fancy logging to create a nice access log that has details
about each incoming request.
-->
<bean id="myLoggingInterceptor" class="ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor">
<property name="loggerName" value="fhirtest.access"/>
<property name="messageFormat"
value="Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]"/>
</bean>
</beans> </beans>

View File

@ -1,10 +1,12 @@
package ca.uhn.fhirtest; package ca.uhn.fhirtest;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.webapp.WebAppContext;
import org.hl7.fhir.instance.model.IBaseResource;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
@ -65,7 +67,8 @@ public class UhnFhirTestApp {
ResourceMetadataKeyEnum.TAG_LIST.put(p1, list); ResourceMetadataKeyEnum.TAG_LIST.put(p1, list);
client.create(p1); client.create(p1);
List<IResource> resources = ctx.newJsonParser().parseBundle(IOUtils.toString(UhnFhirTestApp.class.getResourceAsStream("/test-server-seed-bundle.json"))).toListOfResources(); List<IBaseResource> resources;
resources = new ArrayList<IBaseResource>(ctx.newJsonParser().parseBundle(IOUtils.toString(UhnFhirTestApp.class.getResourceAsStream("/test-server-seed-bundle.json"))).toListOfResources());
client.transaction(resources); client.transaction(resources);
// for (int i = 0; i < 1000; i++) { // for (int i = 0; i < 1000; i++) {

View File

@ -782,13 +782,13 @@ public class JsonParserTest {
private void parseAndEncode(String name) throws IOException { private void parseAndEncode(String name) throws IOException {
String msg = IOUtils.toString(XmlParser.class.getResourceAsStream(name)); String msg = IOUtils.toString(XmlParser.class.getResourceAsStream(name));
ourLog.info(msg); // ourLog.info(msg);
IParser p = ourCtx.newJsonParser(); IParser p = ourCtx.newJsonParser();
Profile res = p.parseResource(Profile.class, msg); Profile res = p.parseResource(Profile.class, msg);
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(res); String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(res);
ourLog.info(encoded); // ourLog.info(encoded);
JSON expected = JSONSerializer.toJSON(msg.trim()); JSON expected = JSONSerializer.toJSON(msg.trim());
JSON actual = JSONSerializer.toJSON(encoded.trim()); JSON actual = JSONSerializer.toJSON(encoded.trim());
@ -1219,7 +1219,6 @@ public class JsonParserTest {
Bundle b = new Bundle(); Bundle b = new Bundle();
InstantDt pub = InstantDt.withCurrentTime(); InstantDt pub = InstantDt.withCurrentTime();
b.setPublished(pub);
Thread.sleep(2); Thread.sleep(2);
Patient p1 = new Patient(); Patient p1 = new Patient();
@ -1245,7 +1244,6 @@ public class JsonParserTest {
ourLog.info(bundleString); ourLog.info(bundleString);
List<String> strings = new ArrayList<String>(); List<String> strings = new ArrayList<String>();
strings.addAll(Arrays.asList("\"published\":\"" + pub.getValueAsString() + "\""));
strings.addAll(Arrays.asList("\"id\":\"1\"")); strings.addAll(Arrays.asList("\"id\":\"1\""));
strings.addAll(Arrays.asList("this is the summary")); strings.addAll(Arrays.asList("this is the summary"));
strings.addAll(Arrays.asList("\"id\":\"2\"", "\"rel\":\"alternate\"", "\"href\":\"http://foo/bar\"")); strings.addAll(Arrays.asList("\"id\":\"2\"", "\"rel\":\"alternate\"", "\"href\":\"http://foo/bar\""));

View File

@ -314,7 +314,6 @@ public class XmlParserTest {
b.getCategories().addTag("http://hl7.org/fhir/tag", "http://hl7.org/fhir/tag/message", "Message"); b.getCategories().addTag("http://hl7.org/fhir/tag", "http://hl7.org/fhir/tag/message", "Message");
InstantDt pub = InstantDt.withCurrentTime(); InstantDt pub = InstantDt.withCurrentTime();
b.setPublished(pub);
Thread.sleep(2); Thread.sleep(2);
Patient p1 = new Patient(); Patient p1 = new Patient();
@ -340,7 +339,6 @@ public class XmlParserTest {
ourLog.info(bundleString); ourLog.info(bundleString);
List<String> strings = new ArrayList<String>(); List<String> strings = new ArrayList<String>();
strings.addAll(Arrays.asList("<published>", pub.getValueAsString(), "</published>"));
strings.add("<category term=\"http://hl7.org/fhir/tag/message\" label=\"Message\" scheme=\"http://hl7.org/fhir/tag\"/>"); strings.add("<category term=\"http://hl7.org/fhir/tag/message\" label=\"Message\" scheme=\"http://hl7.org/fhir/tag\"/>");
strings.addAll(Arrays.asList("<entry>", "<id>1</id>", "</Patient>", "<summary type=\"xhtml\">", "<div", "</entry>")); strings.addAll(Arrays.asList("<entry>", "<id>1</id>", "</Patient>", "<summary type=\"xhtml\">", "<div", "</entry>"));
strings.addAll(Arrays.asList("<entry>", "<id>2</id>", "<link rel=\"alternate\" href=\"http://foo/bar\"/>", "<link rel=\"search\" href=\"http://foo/bar/search\"/>", "</entry>")); strings.addAll(Arrays.asList("<entry>", "<id>2</id>", "<link rel=\"alternate\" href=\"http://foo/bar\"/>", "<link rel=\"search\" href=\"http://foo/bar/search\"/>", "</entry>"));
@ -380,7 +378,6 @@ public class XmlParserTest {
b.getCategories().addTag("http://hl7.org/fhir/tag", "http://hl7.org/fhir/tag/message", "Message"); b.getCategories().addTag("http://hl7.org/fhir/tag", "http://hl7.org/fhir/tag/message", "Message");
InstantDt pub = InstantDt.withCurrentTime(); InstantDt pub = InstantDt.withCurrentTime();
b.setPublished(pub);
Thread.sleep(2); Thread.sleep(2);
Patient p1 = new Patient(); Patient p1 = new Patient();
@ -406,7 +403,6 @@ public class XmlParserTest {
ourLog.info(bundleString); ourLog.info(bundleString);
List<String> strings = new ArrayList<String>(); List<String> strings = new ArrayList<String>();
strings.addAll(Arrays.asList("<published>", pub.getValueAsString(), "</published>"));
strings.add("<category term=\"http://hl7.org/fhir/tag/message\" label=\"Message\" scheme=\"http://hl7.org/fhir/tag\"/>"); strings.add("<category term=\"http://hl7.org/fhir/tag/message\" label=\"Message\" scheme=\"http://hl7.org/fhir/tag\"/>");
strings.addAll(Arrays.asList("<entry>", "<id>1</id>", "</Patient>", "<summary type=\"xhtml\">", "<div", "</entry>")); strings.addAll(Arrays.asList("<entry>", "<id>1</id>", "</Patient>", "<summary type=\"xhtml\">", "<div", "</entry>"));
strings.addAll(Arrays.asList("<entry>", "<id>2</id>", "<link rel=\"alternate\" href=\"http://foo/bar\"/>", "<link rel=\"search\" href=\"http://foo/bar/search\"/>", "</entry>")); strings.addAll(Arrays.asList("<entry>", "<id>2</id>", "<link rel=\"alternate\" href=\"http://foo/bar\"/>", "<link rel=\"search\" href=\"http://foo/bar/search\"/>", "</entry>"));

View File

@ -102,8 +102,7 @@ public class ClientTest {
"<title/>\n" + "<title/>\n" +
"<id>d039f91a-cc3c-4013-988e-af4d8d0614bd</id>\n" + "<id>d039f91a-cc3c-4013-988e-af4d8d0614bd</id>\n" +
"<os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">1</os:totalResults>\n" + "<os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">1</os:totalResults>\n" +
"<published>2014-03-11T16:35:07-04:00</published>\n" + "<author>\n" +
"<author>\n" +
"<name>ca.uhn.fhir.rest.server.DummyRestfulServer</name>\n" + "<name>ca.uhn.fhir.rest.server.DummyRestfulServer</name>\n" +
"</author>\n" + "</author>\n" +
"<entry>\n" + "<entry>\n" +
@ -301,7 +300,6 @@ public class ClientTest {
String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id>" String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id>"
+ "<link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/>" + "<link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/>"
+ "<link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>" + "<link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>"
+ "<published>2014-04-13T18:24:50-04:00</published>"
+ "<author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author>" + "<author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author>"
+ "<entry><title>Patient 222</title><id>222</id>" + "<entry><title>Patient 222</title><id>222</id>"
+ "<updated>"+date1.getValueAsString()+"</updated>" + "<updated>"+date1.getValueAsString()+"</updated>"
@ -374,7 +372,6 @@ public class ClientTest {
String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id>" String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id>"
+ "<link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/>" + "<link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/>"
+ "<link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>" + "<link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>"
+ "<published>2014-04-13T18:24:50-04:00</published>"
+ "<author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author>" + "<author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author>"
+ "<entry><title>Patient 222</title><id>222</id>" + "<entry><title>Patient 222</title><id>222</id>"
+ "<updated>"+date1.getValueAsString()+"</updated>" + "<updated>"+date1.getValueAsString()+"</updated>"
@ -446,7 +443,6 @@ public class ClientTest {
String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id>" String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id>"
+ "<link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/>" + "<link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/>"
+ "<link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>" + "<link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>"
+ "<published>2014-04-13T18:24:50-04:00</published>"
+ "<author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author>" + "<author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author>"
+ "<entry><title>Patient 222</title><id>222</id>" + "<entry><title>Patient 222</title><id>222</id>"
+ "<updated>"+date1.getValueAsString()+"</updated>" + "<updated>"+date1.getValueAsString()+"</updated>"
@ -511,7 +507,7 @@ public class ClientTest {
public void testHistoryWithParams() throws Exception { public void testHistoryWithParams() throws Exception {
//@formatter:off //@formatter:off
final String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id><link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/><link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults><published>2014-04-13T18:24:50-04:00</published><author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author><entry><title>Patient 222</title><id>222</id><updated>1969-12-31T19:00:20.000-05:00</updated><published>1969-12-31T19:00:10.000-05:00</published><link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history/1\"/><content type=\"text/xml\"><Patient xmlns=\"http://hl7.org/fhir\"><identifier><use value=\"official\"/><system value=\"urn:hapitest:mrns\"/><value value=\"00001\"/></identifier><name><family value=\"OlderFamily\"/><given value=\"PatientOne\"/></name><gender><text value=\"M\"/></gender></Patient></content></entry><entry><title>Patient 222</title><id>222</id><updated>1969-12-31T19:00:30.000-05:00</updated><published>1969-12-31T19:00:10.000-05:00</published><link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history/2\"/><content type=\"text/xml\"><Patient xmlns=\"http://hl7.org/fhir\"><identifier><use value=\"official\"/><system value=\"urn:hapitest:mrns\"/><value value=\"00001\"/></identifier><name><family value=\"NewerFamily\"/><given value=\"PatientOne\"/></name><gender><text value=\"M\"/></gender></Patient></content></entry></feed>"; final String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id><link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/><link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults><author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author><entry><title>Patient 222</title><id>222</id><updated>1969-12-31T19:00:20.000-05:00</updated><published>1969-12-31T19:00:10.000-05:00</published><link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history/1\"/><content type=\"text/xml\"><Patient xmlns=\"http://hl7.org/fhir\"><identifier><use value=\"official\"/><system value=\"urn:hapitest:mrns\"/><value value=\"00001\"/></identifier><name><family value=\"OlderFamily\"/><given value=\"PatientOne\"/></name><gender><text value=\"M\"/></gender></Patient></content></entry><entry><title>Patient 222</title><id>222</id><updated>1969-12-31T19:00:30.000-05:00</updated><published>1969-12-31T19:00:10.000-05:00</published><link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history/2\"/><content type=\"text/xml\"><Patient xmlns=\"http://hl7.org/fhir\"><identifier><use value=\"official\"/><system value=\"urn:hapitest:mrns\"/><value value=\"00001\"/></identifier><name><family value=\"NewerFamily\"/><given value=\"PatientOne\"/></name><gender><text value=\"M\"/></gender></Patient></content></entry></feed>";
//@formatter:on //@formatter:on
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);

View File

@ -85,8 +85,7 @@ public class GenericClientTest {
"<title/>\n" + "<title/>\n" +
"<id>d039f91a-cc3c-4013-988e-af4d8d0614bd</id>\n" + "<id>d039f91a-cc3c-4013-988e-af4d8d0614bd</id>\n" +
"<os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">1</os:totalResults>\n" + "<os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">1</os:totalResults>\n" +
"<published>2014-03-11T16:35:07-04:00</published>\n" + "<author>\n" +
"<author>\n" +
"<name>ca.uhn.fhir.rest.server.DummyRestfulServer</name>\n" + "<name>ca.uhn.fhir.rest.server.DummyRestfulServer</name>\n" +
"</author>\n" + "</author>\n" +
"<entry>\n" + "<entry>\n" +
@ -132,7 +131,7 @@ public class GenericClientTest {
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); when(myHttpResponse.getAllHeaders()).thenReturn(new Header[]{new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22")});
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"))); when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8")));
@ -141,14 +140,14 @@ public class GenericClientTest {
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK"));
MethodOutcome resp = client.create().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).execute(); MethodOutcome resp = client.create().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).execute();
assertTrue(resp.getCreated()); assertTrue(resp.getCreated());
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
resp = client.create().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).execute(); resp = client.create().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).execute();
assertNull(resp.getCreated()); assertNull(resp.getCreated());
} }
@Test @Test
public void testCreateWithStringAutoDetectsEncoding() throws Exception { public void testCreateWithStringAutoDetectsEncoding() throws Exception {

View File

@ -114,8 +114,7 @@ public class IncludedResourceStitchingClientTest {
" <link rel=\"self\" href=\"http://localhost:49782/Patient?_query=declaredExtInclude&amp;_pretty=true\"/>\n" + " <link rel=\"self\" href=\"http://localhost:49782/Patient?_query=declaredExtInclude&amp;_pretty=true\"/>\n" +
" <link rel=\"fhir-base\" href=\"http://localhost:49782\"/>\n" + " <link rel=\"fhir-base\" href=\"http://localhost:49782\"/>\n" +
" <os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>\n" + " <os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>\n" +
" <published>2014-08-12T10:22:19.097-04:00</published>\n" + " <author>\n" +
" <author>\n" +
" <name>HAPI FHIR Server</name>\n" + " <name>HAPI FHIR Server</name>\n" +
" </author>\n" + " </author>\n" +
" <entry>\n" + " <entry>\n" +
@ -192,8 +191,7 @@ public class IncludedResourceStitchingClientTest {
" <link rel=\"self\" href=\"http://localhost:49627/Patient?_query=extInclude&amp;_pretty=true\"/>\n" + " <link rel=\"self\" href=\"http://localhost:49627/Patient?_query=extInclude&amp;_pretty=true\"/>\n" +
" <link rel=\"fhir-base\" href=\"http://localhost:49627\"/>\n" + " <link rel=\"fhir-base\" href=\"http://localhost:49627\"/>\n" +
" <os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>\n" + " <os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>\n" +
" <published>2014-08-05T15:22:08.512-04:00</published>\n" + " <author>\n" +
" <author>\n" +
" <name>HAPI FHIR Server</name>\n" + " <name>HAPI FHIR Server</name>\n" +
" </author>\n" + " </author>\n" +
" <entry>\n" + " <entry>\n" +

File diff suppressed because one or more lines are too long

View File

@ -20,6 +20,7 @@ import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt; import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport; import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
import ca.uhn.fhir.model.dstu.resource.Medication;
import ca.uhn.fhir.model.dstu.resource.Observation; import ca.uhn.fhir.model.dstu.resource.Observation;
import ca.uhn.fhir.model.dstu.resource.Patient; import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.resource.Practitioner; import ca.uhn.fhir.model.dstu.resource.Practitioner;
@ -86,6 +87,23 @@ public class Dstu1BundleFactoryTest {
myBundleFactory = new Dstu1BundleFactory(ourCtx); myBundleFactory = new Dstu1BundleFactory(ourCtx);
} }
@Test
public void whenMedicationHasIngredients_include_shouldIncludeThem() throws Exception {
Medication medication = new Medication();
medication.setName("Main Medication");
medication.setId("Medication/1");
Medication ingredientMedication = new Medication();
ingredientMedication.setName("Ingredient");
ingredientMedication.setId("Medication/2");
Medication.ProductIngredient ingredient = new Medication.ProductIngredient();
ingredient.setItem(new ResourceReferenceDt(ingredientMedication));
medication.getProduct().getIngredient().add(ingredient);
myResourceList = Arrays.asList(new IBaseResource[]{medication});
Bundle bundle = makeBundle(BundleInclusionRule.BASED_ON_INCLUDES, includes("Medication.product.ingredient.item"));
assertEquals(2, bundle.getEntries().size());
}
@Test @Test
public void whenIncludeIsAsterisk_bundle_shouldContainAllReferencedResources() throws Exception { public void whenIncludeIsAsterisk_bundle_shouldContainAllReferencedResources() throws Exception {
Bundle bundle = makeBundle(BundleInclusionRule.BASED_ON_INCLUDES, includes("*")); Bundle bundle = makeBundle(BundleInclusionRule.BASED_ON_INCLUDES, includes("*"));

View File

@ -1,30 +1,236 @@
package ca.uhn.fhir.rest.server; package ca.uhn.fhir.rest.server;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHolder;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import ca.uhn.fhir.util.RandomServerPortProvider;
public class IncomingRequestAddressStrategyTest { public class IncomingRequestAddressStrategyTest {
private static CloseableHttpClient ourClient;
private static String ourLastBase;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(IncomingRequestAddressStrategyTest.class);
private static IncomingRequestAddressStrategy ourStrategy;
private Server myServer;
public void after() throws Exception {
if (myServer != null) {
myServer.stop();
}
}
@Before
public void before() {
ourLastBase = null;
ourStrategy = new IncomingRequestAddressStrategy();
}
private void httpGet(String url) throws IOException, ClientProtocolException {
ourLastBase = null;
HttpGet httpPost = new HttpGet(url);
HttpResponse status = ourClient.execute(httpPost);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info(responseContent);
}
private void startServer(int port, String contextPath, String servletPath) throws Exception {
myServer = new Server(port);
org.eclipse.jetty.servlet.ServletContextHandler proxyHandler = new org.eclipse.jetty.servlet.ServletContextHandler();
proxyHandler.setContextPath(contextPath);
ServletHolder handler = new ServletHolder();
handler.setServlet(new MyServlet());
proxyHandler.addServlet(handler, servletPath);
myServer.setHandler(proxyHandler);
myServer.start();
}
/** /**
* This is an incoming request from an instance of Tomcat on AWS, provided by * This is an incoming request from an instance of Tomcat on AWS, provided by Simon Ling of Systems Made Simple
* Simon Ling of Systems Made Simple
*/ */
@Test @Test
public void testAwsUrl() { public void testAwsUrl() {
HttpServletRequest req = mock(HttpServletRequest.class); HttpServletRequest req = mock(HttpServletRequest.class);
when(req.getRequestURI()).thenReturn("/FhirStorm/fhir/Patient/_search"); when(req.getRequestURI()).thenReturn("/FhirStorm/fhir/Patient/_search");
when(req.getServletPath()).thenReturn("/fhir"); when(req.getServletPath()).thenReturn("/fhir");
when(req.getRequestURL()).thenReturn(new StringBuffer().append("http://fhirstorm.dyndns.org:8080/FhirStorm/fhir/Patient/_search")); when(req.getRequestURL()).thenReturn(new StringBuffer().append("http://fhirstorm.dyndns.org:8080/FhirStorm/fhir/Patient/_search"));
when(req.getContextPath()).thenReturn("/FhirStorm"); when(req.getContextPath()).thenReturn("/FhirStorm");
IncomingRequestAddressStrategy incomingRequestAddressStrategy = new IncomingRequestAddressStrategy(); IncomingRequestAddressStrategy incomingRequestAddressStrategy = new IncomingRequestAddressStrategy();
String actual = incomingRequestAddressStrategy.determineServerBase(null,req); String actual = incomingRequestAddressStrategy.determineServerBase(null, req);
assertEquals("http://fhirstorm.dyndns.org:8080/FhirStorm/fhir", actual); assertEquals("http://fhirstorm.dyndns.org:8080/FhirStorm/fhir", actual);
} }
@Test
public void testUnderJettyWithContextPathServletRoot() throws Exception {
int port = RandomServerPortProvider.findFreePort();
String contextPath = "/ctx";
String servletPath = "/*";
startServer(port, contextPath, servletPath);
httpGet("http://localhost:" + port + "/ctx");
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
httpGet("http://localhost:" + port + "/ctx/");
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
httpGet("http://localhost:" + port + "/ctx/Patient?_pretty=true");
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
httpGet("http://localhost:" + port + "/ctx/Patient/123/_history/222");
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
httpGet("http://localhost:" + port);
assertEquals(null, ourLastBase);
}
@Test
public void testUnderJettyWithContextPathServletRootContextOnly() throws Exception {
int port = RandomServerPortProvider.findFreePort();
String contextPath = "/ctx";
String servletPath = "/";
startServer(port, contextPath, servletPath);
ourStrategy.setServletPath("");
httpGet("http://localhost:" + port + "/ctx");
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
httpGet("http://localhost:" + port + "/ctx/");
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
httpGet("http://localhost:" + port + "/ctx/Patient?_pretty=true");
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
httpGet("http://localhost:" + port + "/ctx/Patient/123/_history/222");
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
httpGet("http://localhost:" + port);
assertEquals(null, ourLastBase);
}
@Test
public void testUnderJettyWithContextPathServletRoot2() throws Exception {
int port = RandomServerPortProvider.findFreePort();
String contextPath = "/ctx";
String servletPath = "/foo/bar/*"; // not /* but still this should work
startServer(port, contextPath, servletPath);
httpGet("http://localhost:" + port + "/ctx/foo/bar/Patient?_pretty=true");
assertEquals("http://localhost:" + port + "/ctx/foo/bar", ourLastBase);
httpGet("http://localhost:" + port + "/ctx/foo/bar");
assertEquals("http://localhost:" + port + "/ctx/foo/bar", ourLastBase);
httpGet("http://localhost:" + port + "/ctx/foo/bar/");
assertEquals("http://localhost:" + port + "/ctx/foo/bar", ourLastBase);
httpGet("http://localhost:" + port + "/ctx/foo/bar/Patient/123/_history/222");
assertEquals("http://localhost:" + port + "/ctx/foo/bar", ourLastBase);
httpGet("http://localhost:" + port);
assertEquals(null, ourLastBase);
}
@Test
public void testUnderJettyWithContextPathServletPath() throws Exception {
int port = RandomServerPortProvider.findFreePort();
String contextPath = "/ctx";
String servletPath = "/servlet/*";
startServer(port, contextPath, servletPath);
httpGet("http://localhost:" + port);
assertEquals(null, ourLastBase);
httpGet("http://localhost:" + port + "/ctx/servlet/");
assertEquals("http://localhost:" + port + "/ctx/servlet", ourLastBase);
httpGet("http://localhost:" + port + "/ctx/servlet/Patient?_pretty=true");
assertEquals("http://localhost:" + port + "/ctx/servlet", ourLastBase);
httpGet("http://localhost:" + port + "/ctx/servlet/Patient/123/_history/222");
assertEquals("http://localhost:" + port + "/ctx/servlet", ourLastBase);
}
@Test
public void testUnderJettyWithContextRootServletRoot() throws Exception {
int port = RandomServerPortProvider.findFreePort();
String contextPath = "/";
String servletPath = "/*";
startServer(port, contextPath, servletPath);
httpGet("http://localhost:" + port);
assertEquals("http://localhost:" + port + contextPath, ourLastBase);
httpGet("http://localhost:" + port + "/Patient?_pretty=true");
assertEquals("http://localhost:" + port + contextPath, ourLastBase);
httpGet("http://localhost:" + port + "/Patient/123/_history/222");
assertEquals("http://localhost:" + port + contextPath, ourLastBase);
}
@BeforeClass
public static void beforeClass() {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setConnectionManager(connectionManager);
ourClient = builder.build();
}
private static class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest theReq, HttpServletResponse theResp) throws ServletException, IOException {
// ourLog.info("Ctx: {}", theReq.)
ourLastBase = ourStrategy.determineServerBase(getServletContext(), theReq);
theResp.setContentType("text/plain");
theResp.getWriter().append("Success");
theResp.getWriter().close();
}
}
} }

View File

@ -0,0 +1,36 @@
package ca.uhn.fhir.util;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.List;
/**
* Provides server ports
*/
public class RandomServerPortProvider {
private static List<Integer> ourPorts = new ArrayList<Integer>();
public static int findFreePort() {
ServerSocket server;
try {
server = new ServerSocket(0);
int port = server.getLocalPort();
ourPorts.add(port);
server.close();
Thread.sleep(500);
return port;
} catch (IOException e) {
throw new Error(e);
} catch (InterruptedException e) {
throw new Error(e);
}
}
public static List<Integer> list() {
return ourPorts;
}
}

View File

@ -4,7 +4,6 @@
<link rel="self" href="http://localhost:8888/fhir/context/Patient?_pretty=true&amp;_include=Patient.managingOrganization&amp;_pretty=true"/> <link rel="self" href="http://localhost:8888/fhir/context/Patient?_pretty=true&amp;_include=Patient.managingOrganization&amp;_pretty=true"/>
<link rel="fhir-base" href="http://localhost:8888/fhir/context"/> <link rel="fhir-base" href="http://localhost:8888/fhir/context"/>
<os:totalResults xmlns:os="http://a9.com/-/spec/opensearch/1.1/">2</os:totalResults> <os:totalResults xmlns:os="http://a9.com/-/spec/opensearch/1.1/">2</os:totalResults>
<published>2014-06-22T21:37:05-04:00</published>
<author> <author>
<name>HAPI FHIR Server</name> <name>HAPI FHIR Server</name>
</author> </author>

View File

@ -105,7 +105,7 @@ public class FhirDstu2 implements IFhirVersion {
public Class<? extends BaseContainedDt> getContainedType() { public Class<? extends BaseContainedDt> getContainedType() {
return ContainedDt.class; return ContainedDt.class;
} }
@Override @Override
public BaseCodingDt newCodingDt() { public BaseCodingDt newCodingDt() {
return new CodingDt(); return new CodingDt();

View File

@ -468,7 +468,7 @@ public class XmlParserDstu2Test {
//@formatter:on //@formatter:on
Patient p = ourCtx.newXmlParser().parseResource(Patient.class, res); Patient p = ourCtx.newXmlParser().parseResource(Patient.class, res);
assertEquals(htmlNoNs, p.getText().getDiv().getValueAsString()); assertEquals(htmlNs, p.getText().getDiv().getValueAsString());
} }
/** /**

View File

@ -1,6 +1,6 @@
package ca.uhn.fhir.rest.server; package ca.uhn.fhir.rest.server;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -49,6 +49,7 @@ public class SearchDstu2Test {
Patient patient = (Patient) ourCtx.newXmlParser().parseResource(Bundle.class, responseContent).getEntry().get(0).getResource(); Patient patient = (Patient) ourCtx.newXmlParser().parseResource(Bundle.class, responseContent).getEntry().get(0).getResource();
String ref = patient.getManagingOrganization().getReference().getValue(); String ref = patient.getManagingOrganization().getReference().getValue();
assertEquals("Organization/555", ref); assertEquals("Organization/555", ref);
assertNull(status.getFirstHeader(Constants.HEADER_CONTENT_LOCATION));
} }

View File

@ -1062,7 +1062,7 @@ public class XmlParserHl7OrgDstu2Test {
Patient patient = ourCtx.newXmlParser().parseResource(Patient.class, msg); Patient patient = ourCtx.newXmlParser().parseResource(Patient.class, msg);
assertEquals(NarrativeStatus.GENERATED, patient.getText().getStatus()); assertEquals(NarrativeStatus.GENERATED, patient.getText().getStatus());
assertEquals("<div>John Cardinal: 444333333 </div>", patient.getText().getDiv().getValueAsString()); assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal: 444333333 </div>", patient.getText().getDiv().getValueAsString());
assertEquals("PRP1660", patient.getIdentifier().get(0).getValue()); assertEquals("PRP1660", patient.getIdentifier().get(0).getValue());
String encoded = ourCtx.newXmlParser().encodeResourceToString(patient); String encoded = ourCtx.newXmlParser().encodeResourceToString(patient);
@ -1197,6 +1197,8 @@ public class XmlParserHl7OrgDstu2Test {
Patient patient1 = ourCtx.newXmlParser().parseResource(Patient.class, msg); Patient patient1 = ourCtx.newXmlParser().parseResource(Patient.class, msg);
String encoded1 = ourCtx.newXmlParser().encodeResourceToString(patient1); String encoded1 = ourCtx.newXmlParser().encodeResourceToString(patient1);
ourLog.info(encoded1);
Diff d = new Diff(new StringReader(msg), new StringReader(encoded1)); Diff d = new Diff(new StringReader(msg), new StringReader(encoded1));
assertTrue(d.toString(), d.identical()); assertTrue(d.toString(), d.identical());

View File

@ -1 +1,128 @@
/target/
# Created by https://www.gitignore.io
### Java ###
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
### Vim ###
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
*.un~
Session.vim
.netrwhist
*~
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Eclipse ###
*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
# Eclipse Core
.project
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# JDT-specific (Eclipse Java Development Tools)
.classpath
# PDT-specific
.buildpath
# sbteclipse plugin
.target
# TeXlipse plugin
.texlipse
/build/ /build/

View File

@ -1203,7 +1203,7 @@ public class Controller {
private String parseNarrative(HomeRequest theRequest, EncodingEnum theCtEnum, String theResultBody) { private String parseNarrative(HomeRequest theRequest, EncodingEnum theCtEnum, String theResultBody) {
try { try {
IResource resource = theCtEnum.newParser(getContext(theRequest)).parseResource(theResultBody); IResource resource = (IResource) theCtEnum.newParser(getContext(theRequest)).parseResource(theResultBody);
String retVal = resource.getText().getDiv().getValueAsString(); String retVal = resource.getText().getDiv().getValueAsString();
return StringUtils.defaultString(retVal); return StringUtils.defaultString(retVal);
} catch (Exception e) { } catch (Exception e) {

View File

@ -49,7 +49,9 @@ public class HomeRequest {
} }
if (retVal.contains("${serverBase}")) { if (retVal.contains("${serverBase}")) {
String base = new IncomingRequestAddressStrategy().determineServerBase(theRequest.getServletContext(), theRequest); IncomingRequestAddressStrategy strategy = new IncomingRequestAddressStrategy();
strategy.setServletPath("");
String base = strategy.determineServerBase(theRequest.getServletContext(), theRequest);
if (base.endsWith("/")) { if (base.endsWith("/")) {
base = base.substring(0, base.length() - 1); base = base.substring(0, base.length() - 1);
} }

View File

@ -8,6 +8,7 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.webapp.WebAppContext;
import org.hl7.fhir.instance.model.IBaseResource;
import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
@ -129,7 +130,7 @@ public class OverlayTestApp {
client.create(p1); client.create(p1);
List<IResource> resources = restServerDstu1.getFhirContext().newJsonParser().parseBundle(IOUtils.toString(OverlayTestApp.class.getResourceAsStream("/test-server-seed-bundle.json"))).toListOfResources(); List<IResource> resources = restServerDstu1.getFhirContext().newJsonParser().parseBundle(IOUtils.toString(OverlayTestApp.class.getResourceAsStream("/test-server-seed-bundle.json"))).toListOfResources();
client.transaction(resources); client.transaction(new ArrayList<IBaseResource>(resources));
client.create(p1); client.create(p1);
client.create(p1); client.create(p1);

View File

@ -0,0 +1,175 @@
package ca.uhn.fhir.model.dstu2.resource;
/*
* #%L
* HAPI FHIR Structures - DSTU2 (FHIR v0.4.0)
* %%
* Copyright (C) 2014 - 2015 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.model.api.BaseElement;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.SearchParamDefinition;
import ca.uhn.fhir.model.base.resource.ResourceMetadataMap;
import ca.uhn.fhir.model.dstu2.composite.ContainedDt;
import ca.uhn.fhir.model.dstu2.composite.NarrativeDt;
import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.gclient.StringClientParam;
import ca.uhn.fhir.util.ElementUtil;
public abstract class BaseResource extends BaseElement implements IResource {
/**
* Search parameter constant for <b>_language</b>
*/
@SearchParamDefinition(name="_language", path="", description="The language of the resource", type="string" )
public static final String SP_RES_LANGUAGE = "_language";
/**
* Search parameter constant for <b>_id</b>
*/
@SearchParamDefinition(name="_id", path="", description="The ID of the resource", type="string" )
public static final String SP_RES_ID = "_id";
/**
* <b>Fluent Client</b> search parameter constant for <b>_id</b>
* <p>
* Description: <b>the _id of a resource</b><br>
* Type: <b>string</b><br>
* Path: <b>Resource._id</b><br>
* </p>
*/
public static final StringClientParam RES_ID = new StringClientParam(BaseResource.SP_RES_ID);
@Child(name = "contained", order = 2, min = 0, max = 1)
private ContainedDt myContained;
private IdDt myId;
@Child(name = "language", order = 0, min = 0, max = Child.MAX_UNLIMITED)
private CodeDt myLanguage;
private ResourceMetadataMap myResourceMetadata;
@Child(name = "text", order = 1, min = 0, max = 1)
private NarrativeDt myText;
@Override
public ContainedDt getContained() {
if (myContained == null) {
myContained = new ContainedDt();
}
return myContained;
}
public IdDt getId() {
if (myId == null) {
myId = new IdDt();
}
return myId;
}
@Override
public CodeDt getLanguage() {
if (myLanguage == null) {
myLanguage = new CodeDt();
}
return myLanguage;
}
@Override
public ResourceMetadataMap getResourceMetadata() {
if (myResourceMetadata == null) {
myResourceMetadata = new ResourceMetadataMap();
}
return myResourceMetadata;
}
@Override
public NarrativeDt getText() {
if (myText == null) {
myText = new NarrativeDt();
}
return myText;
}
public void setContained(ContainedDt theContained) {
myContained = theContained;
}
public void setId(IdDt theId) {
myId = theId;
}
public BaseResource setId(IIdType theId) {
if (theId instanceof IdDt) {
myId = (IdDt) theId;
} else if (theId != null) {
myId = new IdDt(theId.getValue());
}
return this;
}
public BaseResource setId(String theId) {
if (theId == null) {
myId = null;
} else {
myId = new IdDt(theId);
}
return this;
}
@Override
public void setLanguage(CodeDt theLanguage) {
myLanguage = theLanguage;
}
@Override
public void setResourceMetadata(ResourceMetadataMap theMap) {
Validate.notNull(theMap, "The Map must not be null");
myResourceMetadata = theMap;
}
public void setText(NarrativeDt theText) {
myText = theText;
}
@Override
public String toString() {
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
b.append("id", getId().toUnqualified());
return b.toString();
}
/**
* Intended to be called by extending classes {@link #isEmpty()} implementations, returns <code>true</code> if all
* content in this superclass instance is empty per the semantics of {@link #isEmpty()}.
*/
@Override
protected boolean isBaseEmpty() {
return super.isBaseEmpty() && ElementUtil.isEmpty(myLanguage, myText, myId);
}
}

View File

@ -21,7 +21,7 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-dstu</artifactId> <artifactId>hapi-fhir-structures-dstu2</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>

View File

@ -1,7 +1,6 @@
package ca.uhn.example; package ca.uhn.example;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import static org.junit.Assert.assertThat;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.webapp.WebAppContext;
@ -12,7 +11,7 @@ import org.junit.Test;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.dstu.resource.Patient; import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.rest.client.IGenericClient; import ca.uhn.fhir.rest.client.IGenericClient;
public class ExampleTest { public class ExampleTest {

View File

@ -14,7 +14,7 @@
<groupId>ca.uhn.hapi.example</groupId> <groupId>ca.uhn.hapi.example</groupId>
<artifactId>restful-server-example</artifactId> <artifactId>restful-server-example</artifactId>
<version>0.8-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<packaging>war</packaging> <packaging>war</packaging>
<name>HAPI FHIR Sample RESTful Server</name> <name>HAPI FHIR Sample RESTful Server</name>
@ -40,7 +40,7 @@
<!-- At least one "structures" JAR must also be included --> <!-- At least one "structures" JAR must also be included -->
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-dstu</artifactId> <artifactId>hapi-fhir-structures-dstu2</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</dependency> </dependency>

View File

@ -3,7 +3,6 @@ package ca.uhn.example.model;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import ca.uhn.fhir.model.api.BaseElement;
import ca.uhn.fhir.model.api.BaseIdentifiableElement; import ca.uhn.fhir.model.api.BaseIdentifiableElement;
import ca.uhn.fhir.model.api.IElement; import ca.uhn.fhir.model.api.IElement;
import ca.uhn.fhir.model.api.IExtension; import ca.uhn.fhir.model.api.IExtension;
@ -12,8 +11,8 @@ import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.Description; import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.api.annotation.Extension; import ca.uhn.fhir.model.api.annotation.Extension;
import ca.uhn.fhir.model.api.annotation.ResourceDef; import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.dstu.composite.ContactDt; import ca.uhn.fhir.model.dstu2.composite.ContactPointDt;
import ca.uhn.fhir.model.dstu.resource.Organization; import ca.uhn.fhir.model.dstu2.resource.Organization;
import ca.uhn.fhir.model.primitive.BooleanDt; import ca.uhn.fhir.model.primitive.BooleanDt;
import ca.uhn.fhir.model.primitive.CodeDt; import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.util.ElementUtil; import ca.uhn.fhir.util.ElementUtil;
@ -115,7 +114,7 @@ public class MyOrganization extends Organization {
@Description(shortDefinition = "Contains the actual contact details") @Description(shortDefinition = "Contains the actual contact details")
@Extension(url = "http://foo#emergencyContactContact", isModifier = false, definedLocally = true) @Extension(url = "http://foo#emergencyContactContact", isModifier = false, definedLocally = true)
@Child(name = "contact") @Child(name = "contact")
private ContactDt myContact; private ContactPointDt myContact;
/* ***************************** /* *****************************
* Getters and setters * Getters and setters
@ -132,14 +131,14 @@ public class MyOrganization extends Organization {
myActive = theActive; myActive = theActive;
} }
public ContactDt getContact() { public ContactPointDt getContact() {
if (myContact == null) { if (myContact == null) {
myContact = new ContactDt(); myContact = new ContactPointDt();
} }
return myContact; return myContact;
} }
public void setContact(ContactDt theContact) { public void setContact(ContactPointDt theContact) {
myContact = theContact; myContact = theContact;
} }

View File

@ -1,9 +1,8 @@
package ca.uhn.example.provider; package ca.uhn.example.provider;
import ca.uhn.example.model.MyOrganization; import ca.uhn.example.model.MyOrganization;
import ca.uhn.example.model.MyOrganization.EmergencyContact; import ca.uhn.fhir.model.dstu2.composite.ContactPointDt;
import ca.uhn.fhir.model.dstu.composite.ContactDt; import ca.uhn.fhir.model.dstu2.valueset.ContactPointUseEnum;
import ca.uhn.fhir.model.dstu.valueset.ContactUseEnum;
import ca.uhn.fhir.model.primitive.BooleanDt; import ca.uhn.fhir.model.primitive.BooleanDt;
import ca.uhn.fhir.model.primitive.CodeDt; import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
@ -51,9 +50,9 @@ public class OrganizationResourceProvider implements IResourceProvider {
MyOrganization retVal = new MyOrganization(); MyOrganization retVal = new MyOrganization();
retVal.setId("1"); retVal.setId("1");
retVal.addIdentifier("urn:example:orgs", "FooOrganization"); retVal.addIdentifier().setSystem("urn:example:orgs").setValue("FooOrganization");
retVal.addAddress().addLine("123 Fake Street").setCity("Toronto"); retVal.addAddress().addLine("123 Fake Street").setCity("Toronto");
retVal.addTelecom().setUse(ContactUseEnum.WORK).setValue("1-888-123-4567"); retVal.addTelecom().setUse(ContactPointUseEnum.WORK).setValue("1-888-123-4567");
// Populate the first, primitive extension // Populate the first, primitive extension
retVal.setBillingCode(new CodeDt("00102-1")); retVal.setBillingCode(new CodeDt("00102-1"));
@ -61,7 +60,7 @@ public class OrganizationResourceProvider implements IResourceProvider {
// The second extension is repeatable and takes a block type // The second extension is repeatable and takes a block type
MyOrganization.EmergencyContact contact = new MyOrganization.EmergencyContact(); MyOrganization.EmergencyContact contact = new MyOrganization.EmergencyContact();
contact.setActive(new BooleanDt(true)); contact.setActive(new BooleanDt(true));
contact.setContact(new ContactDt()); contact.setContact(new ContactPointDt());
retVal.getEmergencyContact().add(contact); retVal.getEmergencyContact().add(contact);
return retVal; return retVal;

View File

@ -7,11 +7,11 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.dstu.composite.HumanNameDt; import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome; import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
import ca.uhn.fhir.model.dstu.resource.Patient; import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.model.dstu.valueset.AdministrativeGenderCodesEnum; import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
import ca.uhn.fhir.model.dstu.valueset.IssueSeverityEnum; import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.StringDt;
@ -59,7 +59,7 @@ public class PatientResourceProvider implements IResourceProvider {
patient.getIdentifier().get(0).setValue("00002"); patient.getIdentifier().get(0).setValue("00002");
patient.addName().addFamily("Test"); patient.addName().addFamily("Test");
patient.getName().get(0).addGiven("PatientOne"); patient.getName().get(0).addGiven("PatientOne");
patient.setGender(AdministrativeGenderCodesEnum.F); patient.setGender(AdministrativeGenderEnum.FEMALE);
LinkedList<Patient> list = new LinkedList<Patient>(); LinkedList<Patient> list = new LinkedList<Patient>();
list.add(patient); list.add(patient);

View File

@ -5,6 +5,7 @@ import java.util.List;
import ca.uhn.example.provider.OrganizationResourceProvider; import ca.uhn.example.provider.OrganizationResourceProvider;
import ca.uhn.example.provider.PatientResourceProvider; import ca.uhn.example.provider.PatientResourceProvider;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
import ca.uhn.fhir.narrative.INarrativeGenerator; import ca.uhn.fhir.narrative.INarrativeGenerator;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
@ -23,6 +24,7 @@ public class ExampleRestfulServlet extends RestfulServer {
*/ */
@Override @Override
public void initialize() { public void initialize() {
setFhirContext(FhirContext.forDstu2());// Support DSTU2
/* /*
* Two resource providers are defined. Each one handles a specific * Two resource providers are defined. Each one handles a specific

View File

@ -136,6 +136,16 @@
configures the parser to preserve versions in resource reference links when configures the parser to preserve versions in resource reference links when
encoding. By default, these are removed. encoding. By default, these are removed.
</action> </action>
<action type="fix" issue="155" dev="wdebeau1">
Terser's IModelVisitor now supplies to the path to the element. This is
an API change, but I don't think there are many users of the IModelVisitor yet.
Please let us know if this is a big hardship and we can find an alternate way
of making this change.
</action>
<action type="fix">
Prevent server from returning a Content-Location header for search
response when using the DSTU2 bundle format
</action>
</release> </release>
<release version="0.9" date="2015-Mar-14"> <release version="0.9" date="2015-Mar-14">
<action type="add"> <action type="add">

View File

@ -165,8 +165,10 @@
<h4>Search - Using HTTP POST</h4> <h4>Search - Using HTTP POST</h4>
<p> <p>
The FHIR specification allows the use of an HTTP POST to transmit a search to a server instead of using The FHIR specification allows the use of an HTTP POST to transmit a search to a server instead of
an HTTP GET. With this style of search, the search parameters are included in the request body instead using
an HTTP GET. With this style of search, the search parameters are included in the request body
instead
of the request URL, which can be useful if you need to transmit a search with a large number of the request URL, which can be useful if you need to transmit a search with a large number
of parameters. of parameters.
</p> </p>
@ -176,7 +178,7 @@
case the client automatically switches to POST. case the client automatically switches to POST.
</p> </p>
<p> <p>
An alternate form of the search URL (using a URL ending with <code>_search</code>) was also An alternate form of the search URL (using a URL ending with<code>_search</code>) was also
supported in FHIR DSTU1. This form is no longer valid in FHIR DSTU2, but HAPI retains support supported in FHIR DSTU1. This form is no longer valid in FHIR DSTU2, but HAPI retains support
for using this form in order to interoperate with servers which use it. for using this form in order to interoperate with servers which use it.
</p> </p>
@ -211,18 +213,18 @@
<param name="file" <param name="file"
value="examples/src/main/java/example/GenericClientExample.java" /> value="examples/src/main/java/example/GenericClientExample.java" />
</macro> </macro>
<h4>Conditional Creates</h4> <h4>Conditional Creates</h4>
<p> <p>
FHIR also specifies a type of update called "conditional create", where FHIR also specifies a type of update called "conditional create", where
a set of search parameters are provided and a new resource is only a set of search parameters are provided and a new resource is only
created if no existing resource matches those parameters. See the created if no existing resource matches those parameters. See the
FHIR specification for more information on conditional creation. FHIR specification for more information on conditional creation.
</p> </p>
<macro name="snippet"> <macro name="snippet">
<param name="id" value="updateConditional" /> <param name="id" value="updateConditional"/>
<param name="file" <param name="file"
value="examples/src/main/java/example/GenericClientExample.java" /> value="examples/src/main/java/example/GenericClientExample.java"/>
</macro> </macro>
</subsection> </subsection>
@ -276,7 +278,7 @@
</macro> </macro>
<h4>Conditional Deletes</h4> <h4>Conditional Deletes</h4>
<p> <p>
Conditional deletions are also possible, which is a form where Conditional deletions are also possible, which is a form where
instead of deleting a resource using its logical ID, you specify instead of deleting a resource using its logical ID, you specify
a set of search criteria and a single resource is deleted if a set of search criteria and a single resource is deleted if
it matches that criteria. Note that this is not a mechanism it matches that criteria. Note that this is not a mechanism
@ -284,9 +286,9 @@
on conditional deletes and how they are used. on conditional deletes and how they are used.
</p> </p>
<macro name="snippet"> <macro name="snippet">
<param name="id" value="deleteConditional" /> <param name="id" value="deleteConditional"/>
<param name="file" <param name="file"
value="examples/src/main/java/example/GenericClientExample.java" /> value="examples/src/main/java/example/GenericClientExample.java"/>
</macro> </macro>
</subsection> </subsection>
@ -305,19 +307,19 @@
<param name="file" <param name="file"
value="examples/src/main/java/example/GenericClientExample.java" /> value="examples/src/main/java/example/GenericClientExample.java" />
</macro> </macro>
<h4>Conditional Updates</h4> <h4>Conditional Updates</h4>
<p> <p>
FHIR also specifies a type of update called "conditional updates", where FHIR also specifies a type of update called "conditional updates", where
insetad of using the logical ID of a resource to update, a set of insetad of using the logical ID of a resource to update, a set of
search parameters is provided. If a single resource matches that set of search parameters is provided. If a single resource matches that set of
parameters, that resource is updated. See the FHIR specification for parameters, that resource is updated. See the FHIR specification for
information on how conditional updates work. information on how conditional updates work.
</p> </p>
<macro name="snippet"> <macro name="snippet">
<param name="id" value="updateConditional" /> <param name="id" value="updateConditional"/>
<param name="file" <param name="file"
value="examples/src/main/java/example/GenericClientExample.java" /> value="examples/src/main/java/example/GenericClientExample.java"/>
</macro> </macro>
<h4>ETags and Resource Contention</h4> <h4>ETags and Resource Contention</h4>