mirror of
https://github.com/hapifhir/hapi-fhir.git
synced 2025-03-09 14:33:32 +00:00
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:
commit
b222b76611
1
.gitignore
vendored
1
.gitignore
vendored
@ -12,6 +12,7 @@ Servers/
|
||||
*.log*
|
||||
nohup.out
|
||||
.DS_Store
|
||||
*.orig
|
||||
|
||||
# Vagrant stuff.
|
||||
.vagrant
|
||||
|
@ -74,30 +74,30 @@ public class GenericClientExample {
|
||||
// END SNIPPET: create
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
// START SNIPPET: createConditional
|
||||
// One form
|
||||
MethodOutcome outcome = client.create()
|
||||
.resource(patient)
|
||||
.conditionalByUrl("Patient?identifier=system%7C00001")
|
||||
.execute();
|
||||
Patient patient = new Patient();
|
||||
// START SNIPPET: createConditional
|
||||
// One form
|
||||
MethodOutcome outcome = client.create()
|
||||
.resource(patient)
|
||||
.conditionalByUrl("Patient?identifier=system%7C00001")
|
||||
.execute();
|
||||
|
||||
// Another form
|
||||
MethodOutcome outcome2 = client.create()
|
||||
.resource(patient)
|
||||
.conditional()
|
||||
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001"))
|
||||
.execute();
|
||||
|
||||
// This will return true if the server responded with an HTTP 201 created,
|
||||
// otherwise it will return null.
|
||||
Boolean created = outcome.getCreated();
|
||||
|
||||
// The ID of the created, or the pre-existing resource
|
||||
IdDt id = outcome.getId();
|
||||
// END SNIPPET: createConditional
|
||||
// Another form
|
||||
MethodOutcome outcome2 = client.create()
|
||||
.resource(patient)
|
||||
.conditional()
|
||||
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001"))
|
||||
.execute();
|
||||
|
||||
// This will return true if the server responded with an HTTP 201 created,
|
||||
// otherwise it will return null.
|
||||
Boolean created = outcome.getCreated();
|
||||
|
||||
// The ID of the created, or the pre-existing resource
|
||||
IdDt id = outcome.getId();
|
||||
// END SNIPPET: createConditional
|
||||
}
|
||||
{
|
||||
{
|
||||
// START SNIPPET: update
|
||||
Patient patient = new Patient();
|
||||
// ..populate the patient object..
|
||||
@ -125,21 +125,21 @@ public class GenericClientExample {
|
||||
// END SNIPPET: update
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
// START SNIPPET: updateConditional
|
||||
client.update()
|
||||
.resource(patient)
|
||||
.conditionalByUrl("Patient?identifier=system%7C00001")
|
||||
.execute();
|
||||
|
||||
client.update()
|
||||
.resource(patient)
|
||||
.conditional()
|
||||
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001"))
|
||||
.execute();
|
||||
// END SNIPPET: updateConditional
|
||||
Patient patient = new Patient();
|
||||
// START SNIPPET: updateConditional
|
||||
client.update()
|
||||
.resource(patient)
|
||||
.conditionalByUrl("Patient?identifier=system%7C00001")
|
||||
.execute();
|
||||
|
||||
client.update()
|
||||
.resource(patient)
|
||||
.conditional()
|
||||
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001"))
|
||||
.execute();
|
||||
// END SNIPPET: updateConditional
|
||||
}
|
||||
{
|
||||
{
|
||||
// START SNIPPET: etagupdate
|
||||
// First, let's retrive the latest version of a resource
|
||||
// from the server
|
||||
@ -176,26 +176,26 @@ public class GenericClientExample {
|
||||
}
|
||||
{
|
||||
// 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
|
||||
if (resp != null) {
|
||||
OperationOutcome outcome = (OperationOutcome) resp;
|
||||
if (resp != null) {
|
||||
OperationOutcome outcome = (OperationOutcome) resp;
|
||||
System.out.println(outcome.getIssueFirstRep().getDetailsElement().getValue());
|
||||
}
|
||||
// END SNIPPET: delete
|
||||
}
|
||||
{
|
||||
// START SNIPPET: deleteConditional
|
||||
client.delete()
|
||||
.resourceConditionalByUrl("Patient?identifier=system%7C00001")
|
||||
.execute();
|
||||
|
||||
client.delete()
|
||||
.resourceConditionalByType("Patient")
|
||||
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001"))
|
||||
.execute();
|
||||
// END SNIPPET: deleteConditional
|
||||
{
|
||||
// START SNIPPET: deleteConditional
|
||||
client.delete()
|
||||
.resourceConditionalByUrl("Patient?identifier=system%7C00001")
|
||||
.execute();
|
||||
|
||||
client.delete()
|
||||
.resourceConditionalByType("Patient")
|
||||
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001"))
|
||||
.execute();
|
||||
// END SNIPPET: deleteConditional
|
||||
}
|
||||
{
|
||||
// START SNIPPET: search
|
||||
|
@ -63,20 +63,22 @@
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-android</artifactId>
|
||||
<version>${slf4j_version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- <dependency> <groupId>org.codehaus.woodstox</groupId> <artifactId>stax2-api</artifactId>
|
||||
<version>3.1.4</version> </dependency> -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${slf4j_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons_io_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
Android does not come with the Servlet API bundled, and MethodUtil requires it
|
||||
-->
|
||||
<!-- Android does not come with the Servlet API bundled, and MethodUtil
|
||||
requires it -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
@ -135,11 +137,10 @@
|
||||
</goals>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>true</createDependencyReducedPom>
|
||||
<!--<minimizeJar>true</minimizeJar>-->
|
||||
<!-- <minimizeJar>true</minimizeJar> -->
|
||||
<artifactSet>
|
||||
<includes>
|
||||
<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-structures-dstu</include>
|
||||
<include>ca.uhn.hapi.fhir:hapi-fhir-structures-dstu2</include>
|
||||
@ -148,7 +149,7 @@
|
||||
<include>javax.xml.stream:stax-api</include>
|
||||
<include>javax.servlet:javax.servlet-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.httpcomponents:*</include>
|
||||
<include>org.glassfish:javax.json</include>
|
||||
@ -179,7 +180,7 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>DIST</id>
|
||||
@ -208,5 +209,5 @@
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
|
||||
</project>
|
||||
|
@ -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("");
|
||||
}
|
||||
|
||||
}
|
@ -85,29 +85,34 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
||||
for (Class<? extends IBase> next : myChoiceTypes) {
|
||||
|
||||
String elementName;
|
||||
String alternateElementName = null;
|
||||
BaseRuntimeElementDefinition<?> nextDef;
|
||||
if (IBaseResource.class.isAssignableFrom(next)) {
|
||||
elementName = getElementName() + StringUtils.capitalize(next.getSimpleName());
|
||||
alternateElementName = getElementName() + "Reference";
|
||||
List<Class<? extends IBaseResource>> types = new ArrayList<Class<? extends IBaseResource>>();
|
||||
types.add((Class<? extends IBaseResource>) next);
|
||||
nextDef = new RuntimeResourceReferenceDefinition(elementName, types);
|
||||
nextDef.sealAndInitialize(theContext, theClassToElementDefinitions);
|
||||
|
||||
myNameToChildDefinition.put(getElementName() + "Reference", nextDef);
|
||||
myNameToChildDefinition.put(getElementName() + "Resource", nextDef);
|
||||
|
||||
} else {
|
||||
nextDef = theClassToElementDefinitions.get(next);
|
||||
elementName = getElementName() + StringUtils.capitalize(nextDef.getName());
|
||||
}
|
||||
|
||||
myNameToChildDefinition.put(elementName, nextDef);
|
||||
if (alternateElementName != null) {
|
||||
myNameToChildDefinition.put(alternateElementName, nextDef);
|
||||
}
|
||||
|
||||
if (IBaseResource.class.isAssignableFrom(next)) {
|
||||
Class<? extends IBase> refType = theContext.getVersion().getResourceReferenceType();
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,8 @@ import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
||||
|
||||
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<Class<? extends IBase>, String> myDatatypeToAttributeName;
|
||||
private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myDatatypeToDefinition;
|
||||
@ -53,7 +55,7 @@ public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildD
|
||||
public List<IBase> getValues(Object theTarget) {
|
||||
ExtensionDt target = (ExtensionDt) theTarget;
|
||||
if (target.getValue() != null) {
|
||||
return Collections.singletonList((IBase)target.getValue());
|
||||
return Collections.singletonList((IBase) target.getValue());
|
||||
}
|
||||
ArrayList<IBase> retVal = new ArrayList<IBase>(target.getUndeclaredExtensions());
|
||||
return retVal;
|
||||
@ -118,10 +120,10 @@ public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildD
|
||||
|
||||
for (BaseRuntimeElementDefinition<?> next : theClassToElementDefinitions.values()) {
|
||||
if (next instanceof IRuntimeDatatypeDefinition) {
|
||||
// if (next.getName().equals("CodeableConcept")) {
|
||||
// System.out.println();
|
||||
// }
|
||||
|
||||
// if (next.getName().equals("CodeableConcept")) {
|
||||
// System.out.println();
|
||||
// }
|
||||
|
||||
if (!((IRuntimeDatatypeDefinition) next).isSpecialization()) {
|
||||
String attrName = createExtensionChildName(next);
|
||||
datatypeAttributeNameToDefinition.put(attrName, next);
|
||||
@ -142,22 +144,29 @@ public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildD
|
||||
}
|
||||
|
||||
/*
|
||||
* Resource reference - The correct name is 'valueReference', but
|
||||
* we allow for valueResource because some incorrect parsers may use this
|
||||
* Resource reference - The correct name is 'valueReference' in DSTU2 and 'valueResource' in DSTU1
|
||||
*/
|
||||
addReferenceBinding(theContext, theClassToElementDefinitions, "valueResource");
|
||||
addReferenceBinding(theContext, theClassToElementDefinitions, "valueReference");
|
||||
addReferenceBinding(theContext, theClassToElementDefinitions, VALUE_RESOURCE);
|
||||
addReferenceBinding(theContext, theClassToElementDefinitions, VALUE_REFERENCE);
|
||||
}
|
||||
|
||||
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>>();
|
||||
types.add(IBaseResource.class);
|
||||
RuntimeResourceReferenceDefinition def = new RuntimeResourceReferenceDefinition(value, types);
|
||||
def.sealAndInitialize(theContext, theClassToElementDefinitions);
|
||||
|
||||
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) {
|
||||
|
@ -293,6 +293,7 @@ public class Bundle extends BaseBundle /* implements IElement */{
|
||||
return myLinkSelf;
|
||||
}
|
||||
|
||||
/*
|
||||
public InstantDt getPublished() {
|
||||
InstantDt retVal = (InstantDt) getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED);
|
||||
if (retVal == null) {
|
||||
@ -301,6 +302,7 @@ public class Bundle extends BaseBundle /* implements IElement */{
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieves a resource from a bundle given its logical ID.
|
||||
@ -394,9 +396,11 @@ public class Bundle extends BaseBundle /* implements IElement */{
|
||||
myCategories = theCategories;
|
||||
}
|
||||
|
||||
/*
|
||||
public void setPublished(InstantDt thePublished) {
|
||||
getResourceMetadata().put(ResourceMetadataKeyEnum.PUBLISHED, thePublished);
|
||||
}
|
||||
/*
|
||||
|
||||
public void setType(BoundCodeDt<BundleTypeEnum> theType) {
|
||||
myType = theType;
|
||||
|
@ -20,7 +20,7 @@ package ca.uhn.fhir.model.api;
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -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.BaseNarrativeDt;
|
||||
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.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.primitive.IntegerDt;
|
||||
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.narrative.INarrativeGenerator;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
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
|
||||
* {@link FhirContext#newJsonParser()} to get an instance.
|
||||
* 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.
|
||||
*/
|
||||
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, "id", theBundle.getBundleId());
|
||||
writeOptionalTagWithTextNode(eventWriter, "updated", theBundle.getUpdated());
|
||||
writeOptionalTagWithTextNode(eventWriter, "published", theBundle.getPublished());
|
||||
|
||||
boolean linkStarted = false;
|
||||
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "self", theBundle.getLinkSelf(), linkStarted);
|
||||
@ -353,7 +353,8 @@ public class JsonParser extends BaseParser implements IParser {
|
||||
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()) {
|
||||
case ID_DATATYPE: {
|
||||
@ -414,7 +415,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||
if (theNextValue instanceof IBaseExtension) {
|
||||
theWriter.write("url", ((IBaseExtension<?>) theNextValue).getUrl());
|
||||
}
|
||||
encodeCompositeElementToStreamWriter(theResDef, theResource, theNextValue, theWriter, childCompositeDef, theIsSubElementWithinResource);
|
||||
encodeCompositeElementToStreamWriter(theResDef, theResource, theNextValue, theWriter, childCompositeDef, theContainedResource);
|
||||
theWriter.writeEnd();
|
||||
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) {
|
||||
if (nextChild.getElementName().equals("extension") || nextChild.getElementName().equals("modifierExtension")) {
|
||||
continue;
|
||||
@ -507,15 +509,15 @@ public class JsonParser extends BaseParser implements IParser {
|
||||
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
|
||||
String childName = nextChild.getChildNameByDatatype(child.getDatatype());
|
||||
BaseRuntimeElementDefinition<?> type = child.getChildByName(childName);
|
||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, narr, type, childName, theIsSubElementWithinResource);
|
||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, narr, type, childName, theContainedResource);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else if (nextChild instanceof RuntimeChildContainedResources) {
|
||||
if (theIsSubElementWithinResource == false) {
|
||||
if (theContainedResource == false) {
|
||||
String childName = nextChild.getValidChildNames().iterator().next();
|
||||
BaseRuntimeElementDefinition<?> child = nextChild.getChildByName(childName);
|
||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, null, child, childName, theIsSubElementWithinResource);
|
||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, null, child, childName, theContainedResource);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -535,7 +537,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||
for (IBase nextValue : values) {
|
||||
if (nextValue == null || nextValue.isEmpty()) {
|
||||
if (nextValue instanceof BaseContainedDt) {
|
||||
if (theIsSubElementWithinResource || getContainedResources().isEmpty()) {
|
||||
if (theContainedResource || getContainedResources().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
@ -551,7 +553,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@ -573,15 +575,15 @@ public class JsonParser extends BaseParser implements IParser {
|
||||
if (nextChild.getMax() > 1 || nextChild.getMax() == Child.MAX_UNLIMITED) {
|
||||
theEventWriter.writeStartArray(childName);
|
||||
inArray = true;
|
||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theIsSubElementWithinResource);
|
||||
} else if (nextChild instanceof RuntimeChildNarrativeDefinition && theIsSubElementWithinResource) {
|
||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theContainedResource);
|
||||
} else if (nextChild instanceof RuntimeChildNarrativeDefinition && theContainedResource) {
|
||||
// suppress narratives from contained resources
|
||||
} else {
|
||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, childName, theIsSubElementWithinResource);
|
||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, childName, theContainedResource);
|
||||
}
|
||||
currentChildName = childName;
|
||||
} else {
|
||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theIsSubElementWithinResource);
|
||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theContainedResource);
|
||||
}
|
||||
|
||||
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);
|
||||
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theNextValue, theEventWriter, resDef.getExtensions(), theIsSubElementWithinResource);
|
||||
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theNextValue, theEventWriter, resDef.getChildren(), theIsSubElementWithinResource);
|
||||
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theNextValue, theEventWriter, resDef.getExtensions(), theContainedResource);
|
||||
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;
|
||||
if (theResource instanceof IResource) {
|
||||
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) {
|
||||
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);
|
||||
IdDt resourceId = resource.getId();
|
||||
String versionIdPart = resourceId.getVersionIdPart();
|
||||
if (isBlank(versionIdPart)) {
|
||||
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) {
|
||||
theEventWriter.writeStartObject("meta");
|
||||
writeOptionalTagWithTextNode(theEventWriter, "versionId", resource.getId().getVersionIdPart());
|
||||
writeOptionalTagWithTextNode(theEventWriter, "lastUpdated", ResourceMetadataKeyEnum.UPDATED.get(resource));
|
||||
writeOptionalTagWithTextNode(theEventWriter, "versionId", versionIdPart);
|
||||
writeOptionalTagWithTextNode(theEventWriter, "lastUpdated", updated);
|
||||
|
||||
if (profiles != null && profiles.isEmpty() == false) {
|
||||
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) {
|
||||
String extUrl = UrlUtil.constructAbsoluteUrl(theParentExtensionUrl, theExtensionUrl);
|
||||
theState.enteringNewElementExtension(null, extUrl, theModifier);
|
||||
|
||||
for (int extIdx = 0; extIdx < theValues.size(); extIdx++) {
|
||||
JsonObject nextExt = theValues.getJsonObject(extIdx);
|
||||
for (String nextKey : nextExt.keySet()) {
|
||||
// if (nextKey.startsWith("value") && nextKey.length() > 5 &&
|
||||
// myContext.getRuntimeChildUndeclaredExtensionDefinition().getChildByName(nextKey) != null) {
|
||||
JsonValue jsonVal = nextExt.get(nextKey);
|
||||
if (jsonVal.getValueType() == ValueType.ARRAY) {
|
||||
/*
|
||||
* Extension children which are arrays are sub-extensions. Any other value type should be treated as
|
||||
* a value.
|
||||
*/
|
||||
JsonArray arrayValue = (JsonArray) jsonVal;
|
||||
parseExtensionInDstu2Style(theModifier, theState, extUrl, nextKey, arrayValue);
|
||||
} else {
|
||||
parseChildren(theState, nextKey, jsonVal, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
theState.endingElement();
|
||||
}
|
||||
// private void parseExtensionInDstu2Style(boolean theModifier, ParserState<?> theState, String theParentExtensionUrl, String theExtensionUrl, JsonArray theValues) {
|
||||
// String extUrl = UrlUtil.constructAbsoluteUrl(theParentExtensionUrl, theExtensionUrl);
|
||||
// theState.enteringNewElementExtension(null, extUrl, theModifier);
|
||||
//
|
||||
// for (int extIdx = 0; extIdx < theValues.size(); extIdx++) {
|
||||
// JsonObject nextExt = theValues.getJsonObject(extIdx);
|
||||
// for (String nextKey : nextExt.keySet()) {
|
||||
// // if (nextKey.startsWith("value") && nextKey.length() > 5 &&
|
||||
// // myContext.getRuntimeChildUndeclaredExtensionDefinition().getChildByName(nextKey) != null) {
|
||||
// JsonValue jsonVal = nextExt.get(nextKey);
|
||||
// if (jsonVal.getValueType() == ValueType.ARRAY) {
|
||||
// /*
|
||||
// * Extension children which are arrays are sub-extensions. Any other value type should be treated as a value.
|
||||
// */
|
||||
// JsonArray arrayValue = (JsonArray) jsonVal;
|
||||
// parseExtensionInDstu2Style(theModifier, theState, extUrl, nextKey, arrayValue);
|
||||
// } else {
|
||||
// parseChildren(theState, nextKey, jsonVal, null, null);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// theState.endingElement();
|
||||
// }
|
||||
|
||||
@Override
|
||||
public <T extends IBaseResource> T doParseResource(Class<T> theResourceType, Reader theReader) {
|
||||
|
@ -683,8 +683,6 @@ class ParserState<T> {
|
||||
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
||||
if ("entry".equals(theLocalPart) && verifyNamespace(XmlParser.ATOM_NS, theNamespaceURI)) {
|
||||
push(new AtomEntryState(myInstance, myResourceType));
|
||||
} else if (theLocalPart.equals("published")) {
|
||||
push(new AtomPrimitiveState(myInstance.getPublished()));
|
||||
} else if (theLocalPart.equals("title")) {
|
||||
push(new AtomPrimitiveState(myInstance.getTitle()));
|
||||
} else if ("id".equals(theLocalPart)) {
|
||||
@ -900,7 +898,7 @@ class ParserState<T> {
|
||||
if (myInstance instanceof IIdentifiableElement) {
|
||||
((IIdentifiableElement) myInstance).setElementSpecificId((theValue));
|
||||
} else {
|
||||
((IResource)myInstance).setId(new IdDt(theValue));
|
||||
((IResource) myInstance).setId(new IdDt(theValue));
|
||||
}
|
||||
} else if ("contentType".equals(theName)) {
|
||||
myInstance.setContentType(theValue);
|
||||
@ -1393,7 +1391,7 @@ class ParserState<T> {
|
||||
res.getId().setValue('#' + res.getId().getIdPart());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IBaseResource preResCurrentElement = getPreResourceState().getCurrentElement();
|
||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(preResCurrentElement);
|
||||
def.getChildByName("contained").getMutator().addValue(preResCurrentElement, res);
|
||||
@ -1496,6 +1494,7 @@ class ParserState<T> {
|
||||
private class ElementCompositeState extends BaseState {
|
||||
|
||||
private BaseRuntimeElementCompositeDefinition<?> myDefinition;
|
||||
|
||||
public BaseRuntimeElementCompositeDefinition<?> getDefinition() {
|
||||
return myDefinition;
|
||||
}
|
||||
@ -1623,8 +1622,8 @@ class ParserState<T> {
|
||||
ParserState<T>.PreResourceStateHapi state = new PreResourceStateHapi(myInstance, child.getMutator(), null);
|
||||
push(state);
|
||||
} else {
|
||||
ParserState<T>.PreResourceStateHl7Org state = new PreResourceStateHl7Org(myInstance, child.getMutator(), null);
|
||||
push(state);
|
||||
ParserState<T>.PreResourceStateHl7Org state = new PreResourceStateHl7Org(myInstance, child.getMutator(), null);
|
||||
push(state);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1729,10 +1728,9 @@ class ParserState<T> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1741,7 +1739,6 @@ class ParserState<T> {
|
||||
pop();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private class MetaElementState extends BaseState {
|
||||
@ -1761,8 +1758,8 @@ class ParserState<T> {
|
||||
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
||||
if (theLocalPart.equals("versionId")) {
|
||||
push(new MetaVersionElementState(getPreResourceState(), myMap));
|
||||
// } else if (theLocalPart.equals("profile")) {
|
||||
//
|
||||
// } else if (theLocalPart.equals("profile")) {
|
||||
//
|
||||
} else if (theLocalPart.equals("lastUpdated")) {
|
||||
InstantDt updated = new InstantDt();
|
||||
push(new PrimitiveState(getPreResourceState(), updated));
|
||||
@ -1774,7 +1771,7 @@ class ParserState<T> {
|
||||
securityLabels = new ArrayList<BaseCodingDt>();
|
||||
myMap.put(ResourceMetadataKeyEnum.SECURITY_LABELS, securityLabels);
|
||||
}
|
||||
BaseCodingDt securityLabel= myContext.getVersion().newCodingDt();
|
||||
BaseCodingDt securityLabel = myContext.getVersion().newCodingDt();
|
||||
BaseRuntimeElementCompositeDefinition<?> codinfDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(securityLabel.getClass());
|
||||
push(new SecurityLabelElementStateHapi(getPreResourceState(), codinfDef, securityLabel));
|
||||
securityLabels.add(securityLabel);
|
||||
@ -1903,33 +1900,30 @@ class ParserState<T> {
|
||||
if (myEntry == null) {
|
||||
myObject = (T) getCurrentElement();
|
||||
}
|
||||
|
||||
|
||||
IResource nextResource = (IResource) getCurrentElement();
|
||||
String version = ResourceMetadataKeyEnum.VERSION.get(nextResource);
|
||||
String resourceName = myContext.getResourceDefinition(nextResource).getName();
|
||||
String bundleIdPart = nextResource.getId().getIdPart();
|
||||
if (isNotBlank(bundleIdPart)) {
|
||||
// if (isNotBlank(entryBaseUrl)) {
|
||||
// nextResource.setId(new IdDt(entryBaseUrl, resourceName, bundleIdPart, version));
|
||||
// } else {
|
||||
nextResource.setId(new IdDt(null, resourceName, bundleIdPart, version));
|
||||
// }
|
||||
// if (isNotBlank(entryBaseUrl)) {
|
||||
// nextResource.setId(new IdDt(entryBaseUrl, resourceName, bundleIdPart, version));
|
||||
// } else {
|
||||
nextResource.setId(new IdDt(null, resourceName, bundleIdPart, version));
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
||||
super.enteringNewElement(theNamespaceURI, theLocalPart);
|
||||
if (myEntry != null) {
|
||||
myEntry.setResource((IResource) getCurrentElement());
|
||||
}
|
||||
if (myMutator != null) {
|
||||
myMutator.addValue(myTarget, getCurrentElement());
|
||||
}
|
||||
if (myMutator != null) {
|
||||
myMutator.addValue(myTarget, getCurrentElement());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1956,13 +1950,15 @@ class ParserState<T> {
|
||||
if (myTarget == null) {
|
||||
myObject = (T) getCurrentElement();
|
||||
}
|
||||
|
||||
|
||||
if (getCurrentElement() instanceof IDomainResource) {
|
||||
IDomainResource elem = (IDomainResource) getCurrentElement();
|
||||
String resourceName = myContext.getResourceDefinition(elem).getName();
|
||||
String versionId = elem.getMeta().getVersionId();
|
||||
if (StringUtils.isNotBlank(versionId)) {
|
||||
elem.getIdElement().setValue(resourceName + "/" + elem.getId().getIdPart() + "/_history/" + versionId);
|
||||
if (StringUtils.isBlank(elem.getId().getIdPart())) {
|
||||
// Resource has no ID
|
||||
} else if (StringUtils.isNotBlank(versionId)) {
|
||||
elem.getIdElement().setValue(resourceName + "/" + elem.getId().getIdPart() + "/_history/" + versionId);
|
||||
} else {
|
||||
elem.getIdElement().setValue(resourceName + "/" + elem.getId().getIdPart());
|
||||
}
|
||||
@ -2063,12 +2059,12 @@ class ParserState<T> {
|
||||
@Override
|
||||
public void wereBack() {
|
||||
final boolean bundle = "Bundle".equals(myContext.getResourceDefinition(myInstance).getName());
|
||||
|
||||
|
||||
FhirTerser terser = myContext.newTerser();
|
||||
terser.visit(myInstance, new IModelVisitor() {
|
||||
|
||||
@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) {
|
||||
BaseResourceReferenceDt nextRef = (BaseResourceReferenceDt) theElement;
|
||||
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;
|
||||
String ref = nextRef.getReference().getValue();
|
||||
if (isNotBlank(ref)) {
|
||||
@ -2099,8 +2095,8 @@ class ParserState<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) {
|
||||
acceptElement(theNextExt.getValue(), null, null);
|
||||
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) {
|
||||
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
|
||||
String value = getDt().getValueAsString();
|
||||
myHl7OrgDatatype.setValueAsString(value);
|
||||
|
||||
|
||||
super.doPop();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class XhtmlState extends BaseState {
|
||||
private int myDepth;
|
||||
private XhtmlDt myDt;
|
||||
@ -2583,7 +2578,7 @@ class ParserState<T> {
|
||||
protected void doPop() {
|
||||
pop();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void endingElement() throws DataFormatException {
|
||||
if (myJsonMode) {
|
||||
|
@ -271,7 +271,6 @@ public class XmlParser extends BaseParser implements IParser {
|
||||
}
|
||||
|
||||
writeOptionalTagWithTextNode(eventWriter, "updated", theBundle.getUpdated());
|
||||
writeOptionalTagWithTextNode(eventWriter, "published", theBundle.getPublished());
|
||||
|
||||
if (StringUtils.isNotBlank(theBundle.getAuthorName().getValue())) {
|
||||
eventWriter.writeStartElement("author");
|
||||
@ -804,6 +803,7 @@ public class XmlParser extends BaseParser implements IParser {
|
||||
if (updated != null) {
|
||||
writeOptionalTagWithValue(theEventWriter, "lastUpdated", updated.getValueAsString());
|
||||
}
|
||||
|
||||
for (IdDt profile : profiles) {
|
||||
theEventWriter.writeStartElement("profile");
|
||||
theEventWriter.writeAttribute("value", profile.getValue());
|
||||
|
@ -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.
|
||||
*/
|
||||
public Boolean getCreated() {
|
||||
|
@ -20,8 +20,7 @@ package ca.uhn.fhir.rest.client;
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
import java.io.IOException;
|
||||
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");
|
||||
}
|
||||
|
||||
IClientResponseHandler binding;
|
||||
IClientResponseHandler<? extends IBase> binding;
|
||||
if (myReturnBundleType != null) {
|
||||
binding = new ResourceResponseHandler(myReturnBundleType, null);
|
||||
} else {
|
||||
@ -1581,8 +1580,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
myBundle = theResources;
|
||||
}
|
||||
|
||||
public TransactionExecutable(List<IBaseResource> theResources) {
|
||||
myResources = theResources;
|
||||
public TransactionExecutable(List<? extends IBaseResource> theResources) {
|
||||
myResources = new ArrayList<IBaseResource>(theResources);
|
||||
}
|
||||
|
||||
public TransactionExecutable(IBaseBundle theBundle) {
|
||||
@ -1619,7 +1618,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
}
|
||||
|
||||
@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");
|
||||
return new TransactionExecutable<List<IBaseResource>>(theResources);
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public interface ITransaction {
|
||||
/**
|
||||
* 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
|
||||
|
@ -279,7 +279,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
||||
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;
|
||||
} else {
|
||||
Set<Include> includes = getRequestIncludesFromParams(params);
|
||||
@ -312,7 +312,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
||||
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;
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
@ -132,6 +132,11 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||
return RestfulOperationTypeEnum.SEARCH_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BundleTypeEnum getResponseBundleType() {
|
||||
return BundleTypeEnum.SEARCHSET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnTypeEnum getReturnType() {
|
||||
return ReturnTypeEnum.BUNDLE;
|
||||
@ -289,13 +294,9 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||
|
||||
}
|
||||
|
||||
public void setResourceType(Class<? extends IResource> resourceType) {
|
||||
this.myDeclaredResourceType = resourceType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getMethod().toString();
|
||||
protected boolean isAddContentLocationHeader() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<String> processWhitelistAndBlacklist(List<String> theQualifiedNames, Set<String> theQualifierWhitelist, Set<String> theQualifierBlacklist) {
|
||||
@ -313,6 +314,15 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||
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,
|
||||
SearchStyleEnum theSearchStyle) {
|
||||
SearchStyleEnum searchStyle = theSearchStyle;
|
||||
@ -473,9 +483,4 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BundleTypeEnum getResponseBundleType() {
|
||||
return BundleTypeEnum.SEARCHSET;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -203,8 +203,6 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
||||
addResourcesToBundle(new ArrayList<IBaseResource>(resourceList), theBundleType, theServerBase, theServer.getBundleInclusionRule(), theIncludes);
|
||||
addRootPropertiesToBundle(null, theServerBase, theCompleteUrl, theResult.size(), theBundleType);
|
||||
|
||||
myBundle.setPublished(theResult.getPublished());
|
||||
|
||||
if (theServer.getPagingProvider() != null) {
|
||||
int limit;
|
||||
limit = theLimit != null ? theLimit : theServer.getPagingProvider().getDefaultPageSize();
|
||||
@ -232,10 +230,6 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
||||
myBundle.getBundleId().setValue(UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
if (myBundle.getPublished().isEmpty()) {
|
||||
myBundle.getPublished().setToCurrentTimeInLocalTimeZone();
|
||||
}
|
||||
|
||||
if (myBundle.getLinkBase().isEmpty()) {
|
||||
myBundle.getLinkBase().setValue(theServerBase);
|
||||
}
|
||||
@ -269,7 +263,6 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
||||
|
||||
myBundle.getAuthorName().setValue(theAuthor);
|
||||
myBundle.getBundleId().setValue(UUID.randomUUID().toString());
|
||||
myBundle.getPublished().setToCurrentTimeInLocalTimeZone();
|
||||
myBundle.getLinkBase().setValue(theServerBase);
|
||||
myBundle.getLinkSelf().setValue(theCompleteUrl);
|
||||
myBundle.getType().setValueAsEnum(theBundleType);
|
||||
|
@ -30,10 +30,19 @@ import org.apache.commons.lang3.StringUtils;
|
||||
*/
|
||||
public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
||||
|
||||
private String myServletPath;
|
||||
|
||||
@Override
|
||||
public String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest) {
|
||||
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();
|
||||
String servletContextPath = "";
|
||||
if (theServletContext != null) {
|
||||
@ -48,7 +57,9 @@ public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
if (startOfPath == -1) {
|
||||
@ -56,9 +67,9 @@ public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
||||
}
|
||||
|
||||
int contextIndex;
|
||||
if (servletPath.length() == 0) {
|
||||
if (servletPath.length() == 0 || servletPath.equals("/")) {
|
||||
if (requestPath.length() == 0) {
|
||||
contextIndex = requestUrl.length();
|
||||
contextIndex = requestUrlLength;
|
||||
} else {
|
||||
contextIndex = requestUrl.indexOf(requestPath, startOfPath);
|
||||
}
|
||||
@ -68,8 +79,30 @@ public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
||||
|
||||
String fhirServerBase;
|
||||
int length = contextIndex + servletPath.length();
|
||||
if (length > requestUrlLength) {
|
||||
length = requestUrlLength;
|
||||
}
|
||||
fhirServerBase = requestUrl.substring(0, length);
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -490,7 +490,7 @@ public class RestfulServer extends HttpServlet {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,10 +76,10 @@ public class RestfulServerUtils {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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();
|
||||
IIdType fullId = theResource.getId().withServerBase(theServerBase, resName);
|
||||
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,
|
||||
boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, boolean theRespondGzip, String theServerBase) throws IOException {
|
||||
int stausCode = 200;
|
||||
RestfulServerUtils.streamResponseAsResource(theServer, theHttpResponse, theResource, theResponseEncoding, thePrettyPrint, theRequestIsBrowser, theNarrativeMode, stausCode, theRespondGzip,
|
||||
theServerBase);
|
||||
}
|
||||
// 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 {
|
||||
// int stausCode = 200;
|
||||
// RestfulServerUtils.streamResponseAsResource(theServer, theHttpResponse, theResource, theResponseEncoding, thePrettyPrint, theRequestIsBrowser, theNarrativeMode, stausCode, theRespondGzip,
|
||||
// theServerBase);
|
||||
// }
|
||||
|
||||
public static void validateResourceListNotNull(List<? extends IBaseResource> theResourceList) {
|
||||
if (theResourceList == null) {
|
||||
|
@ -129,7 +129,7 @@ public class ExceptionHandlingInterceptor extends InterceptorAdapter {
|
||||
boolean requestIsBrowser = RestfulServer.requestIsBrowser(theRequest);
|
||||
String fhirServerBase = ((Request) theRequestDetails).getFhirServerBase();
|
||||
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);
|
||||
// theRequestDetails.getServer().addHeadersToResponse(theResponse);
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
@ -61,7 +61,7 @@ public class FhirTerser {
|
||||
if (theElement instanceof ISupportsUndeclaredExtensions) {
|
||||
ISupportsUndeclaredExtensions containingElement = (ISupportsUndeclaredExtensions) theElement;
|
||||
for (ExtensionDt nextExt : containingElement.getUndeclaredExtensions()) {
|
||||
theCallback.acceptUndeclaredExtension(containingElement, theChildDefinition, theDefinition, nextExt);
|
||||
theCallback.acceptUndeclaredExtension(containingElement, null, theChildDefinition, theDefinition, nextExt);
|
||||
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) {
|
||||
final ArrayList<T> retVal = new ArrayList<T>();
|
||||
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
||||
visit(theResource, null, def, new IModelVisitor() {
|
||||
visit(theResource, null, null, def, new IModelVisitor() {
|
||||
@SuppressWarnings("unchecked")
|
||||
@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()) {
|
||||
return;
|
||||
}
|
||||
@ -105,7 +105,8 @@ public class FhirTerser {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@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())) {
|
||||
retVal.add((T) theNextExt);
|
||||
}
|
||||
@ -117,39 +118,34 @@ public class FhirTerser {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public List<ResourceReferenceInfo> getAllResourceReferences(final IBaseResource theResource) {
|
||||
final ArrayList<ResourceReferenceInfo> retVal = new ArrayList<ResourceReferenceInfo>();
|
||||
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
||||
visit(theResource, null, def, new IModelVisitor() {
|
||||
@Override
|
||||
public void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
||||
if (theElement == null || theElement.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String name = null;
|
||||
if (theChildDefinition != null) {
|
||||
name = theChildDefinition.getElementName();
|
||||
}
|
||||
if (BaseResourceReferenceDt.class.isAssignableFrom(theElement.getClass())) {
|
||||
retVal.add(new ResourceReferenceInfo(theResource, name, (BaseResourceReferenceDt) theElement));
|
||||
}
|
||||
}
|
||||
public <T extends IBase> List<ResourceReferenceInfo> getAllResourceReferences(final IBaseResource theResource) {
|
||||
final ArrayList<ResourceReferenceInfo> retVal = new ArrayList<ResourceReferenceInfo>();
|
||||
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
||||
visit(theResource, null, null, def, new IModelVisitor() {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void acceptElement(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
||||
if (theElement == null || theElement.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (BaseResourceReferenceDt.class.isAssignableFrom(theElement.getClass())) {
|
||||
retVal.add(new ResourceReferenceInfo(theResource, thePathToElement, (BaseResourceReferenceDt)theElement));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) {
|
||||
String name = null;
|
||||
if (theChildDefinition != null) {
|
||||
name = theChildDefinition.getElementName();
|
||||
}
|
||||
if (theNextExt.getValue() != null && BaseResourceReferenceDt.class.isAssignableFrom(theNextExt.getValue().getClass())) {
|
||||
retVal.add(new ResourceReferenceInfo(theResource, name, (BaseResourceReferenceDt) theNextExt.getValue()));
|
||||
}
|
||||
}
|
||||
});
|
||||
return retVal;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition,
|
||||
ExtensionDt theNextExt) {
|
||||
if (theNextExt.getValue() != null && BaseResourceReferenceDt.class.isAssignableFrom(theNextExt.getValue().getClass())) {
|
||||
retVal.add(new ResourceReferenceInfo(theResource, thePathToElement, (BaseResourceReferenceDt)theNextExt.getValue()));
|
||||
}
|
||||
}
|
||||
});
|
||||
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));
|
||||
|
||||
if (theSubList.size() == 1) {
|
||||
@ -222,8 +218,19 @@ public class FhirTerser {
|
||||
|
||||
}
|
||||
|
||||
private void visit(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, IModelVisitor theCallback) {
|
||||
theCallback.acceptElement(theElement, theChildDefinition, theDefinition);
|
||||
private List<String> addNameToList(List<String> theCurrentList, BaseRuntimeChildDefinition theChildDefinition) {
|
||||
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);
|
||||
|
||||
// if (theElement.isEmpty()) {
|
||||
@ -243,7 +250,7 @@ public class FhirTerser {
|
||||
IBaseResource theResource = resRefDt.getResource();
|
||||
if (theResource.getId() == null || theResource.getId().isEmpty() || theResource.getId().isLocal()) {
|
||||
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
||||
visit(theResource, null, def, theCallback);
|
||||
visit(theResource, pathToElement, null, def, theCallback);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -285,9 +292,9 @@ public class FhirTerser {
|
||||
|
||||
if (nextChild instanceof RuntimeChildDirectResource) {
|
||||
// Don't descend into embedded resources
|
||||
theCallback.acceptElement(nextValue, nextChild, childElementDef);
|
||||
theCallback.acceptElement(nextValue, null, nextChild, childElementDef);
|
||||
} else {
|
||||
visit(nextValue, nextChild, childElementDef, theCallback);
|
||||
visit(nextValue, pathToElement, nextChild, childElementDef, theCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -298,7 +305,7 @@ public class FhirTerser {
|
||||
BaseContainedDt value = (BaseContainedDt) theElement;
|
||||
for (IResource next : value.getContainedResources()) {
|
||||
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(next);
|
||||
visit(next, null, def, theCallback);
|
||||
visit(next, pathToElement, null, def, theCallback);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -309,7 +316,7 @@ public class FhirTerser {
|
||||
case CONTAINED_RESOURCE_LIST:
|
||||
if (theElement != null) {
|
||||
BaseRuntimeElementDefinition<?> def = myContext.getElementDefinition(theElement.getClass());
|
||||
visit(theElement, null, def, theCallback);
|
||||
visit(theElement, pathToElement, null, def, theCallback);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -454,7 +461,7 @@ public class FhirTerser {
|
||||
*/
|
||||
public void visit(IBaseResource theResource, IModelVisitor theVisitor) {
|
||||
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
||||
visit(theResource, null, def, theVisitor);
|
||||
visit(theResource, null, null, def, theVisitor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -28,6 +28,8 @@ import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @see FhirTerser#visit(IBaseResource, IModelVisitor)
|
||||
*/
|
||||
@ -39,7 +41,7 @@ public interface IModelVisitor {
|
||||
* @param theChildDefinition May be null if this is a root element
|
||||
* @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 theNextExt
|
||||
*/
|
||||
void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt);
|
||||
void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt);
|
||||
|
||||
|
||||
|
||||
|
@ -28,58 +28,71 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by Bill de Beaubien on 2/26/2015.
|
||||
*/
|
||||
public class ResourceReferenceInfo {
|
||||
private String myOwningResource;
|
||||
private String myName;
|
||||
private BaseResourceReferenceDt myResource;
|
||||
private String myOwningResource;
|
||||
private String myName;
|
||||
private BaseResourceReferenceDt myResource;
|
||||
|
||||
public ResourceReferenceInfo(IBaseResource theOwningResource, String theName, BaseResourceReferenceDt theResource) {
|
||||
myOwningResource = theOwningResource.getClass().getAnnotation(ResourceDef.class).name();
|
||||
myName = theName;
|
||||
myResource = theResource;
|
||||
}
|
||||
public ResourceReferenceInfo(IBaseResource theOwningResource, List<String> thePathToElement, BaseResourceReferenceDt theResource) {
|
||||
myOwningResource = theOwningResource.getClass().getAnnotation(ResourceDef.class).name();
|
||||
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
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
b.append("name", myName);
|
||||
b.append("resource", myResource.getReference());
|
||||
return b.build();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
b.append("name", myName);
|
||||
b.append("resource", myResource.getReference());
|
||||
return b.build();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
public BaseResourceReferenceDt getResourceReference() {
|
||||
return myResource;
|
||||
}
|
||||
public BaseResourceReferenceDt getResourceReference() {
|
||||
return myResource;
|
||||
}
|
||||
|
||||
public boolean matchesIncludeSet(Set<Include> theIncludes) {
|
||||
if (theIncludes == null)
|
||||
return false;
|
||||
for (Include include : theIncludes) {
|
||||
if (matchesInclude(include))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public boolean matchesIncludeSet(Set<Include> theIncludes) {
|
||||
if (theIncludes == null)
|
||||
return false;
|
||||
for (Include include : theIncludes) {
|
||||
if (matchesInclude(include))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean matchesInclude(Include theInclude) {
|
||||
if (theInclude.getValue().equals("*")) {
|
||||
return true;
|
||||
}
|
||||
if (theInclude.getValue().indexOf(':') != -1) {
|
||||
// DSTU2 style
|
||||
return (theInclude.getValue().equals(myOwningResource + ':' + myName));
|
||||
} else {
|
||||
// DSTU1 style
|
||||
return (theInclude.getValue().equals(myOwningResource + '.' + myName));
|
||||
}
|
||||
}
|
||||
public boolean matchesInclude(Include theInclude) {
|
||||
if (theInclude.getValue().equals("*")) {
|
||||
return true;
|
||||
}
|
||||
if (theInclude.getValue().indexOf(':') != -1) {
|
||||
// DSTU2 style
|
||||
return (theInclude.getValue().equals(myOwningResource + ':' + myName));
|
||||
} else {
|
||||
// DSTU1 style
|
||||
return (theInclude.getValue().equals(myOwningResource + '.' + myName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,7 @@ package ca.uhn.fhir.jpa.dao;
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
@ -444,12 +443,12 @@ public abstract class BaseFhirDao implements IDao {
|
||||
}
|
||||
|
||||
@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();
|
||||
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
||||
return template.execute(new TransactionCallback<List<IResource>>() {
|
||||
return template.execute(new TransactionCallback<List<IBaseResource>>() {
|
||||
@Override
|
||||
public List<IResource> doInTransaction(TransactionStatus theStatus) {
|
||||
public List<IBaseResource> doInTransaction(TransactionStatus theStatus) {
|
||||
List<BaseHasResource> resEntities = Lists.newArrayList();
|
||||
|
||||
List<HistoryTuple> tupleSubList = tuples.subList(theFromIndex, theToIndex);
|
||||
@ -471,7 +470,7 @@ public abstract class BaseFhirDao implements IDao {
|
||||
resEntities = resEntities.subList(0, limit);
|
||||
}
|
||||
|
||||
ArrayList<IResource> retVal = new ArrayList<IResource>();
|
||||
ArrayList<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||
for (BaseHasResource next : resEntities) {
|
||||
RuntimeResourceDefinition type;
|
||||
try {
|
||||
@ -514,7 +513,7 @@ public abstract class BaseFhirDao implements IDao {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected List<IResource> loadResourcesById(Set<IdDt> theIncludePids) {
|
||||
protected List<IBaseResource> loadResourcesById(Set<IdDt> theIncludePids) {
|
||||
Set<Long> pids = new HashSet<Long>();
|
||||
for (IdDt next : theIncludePids) {
|
||||
if (next.isIdPartValidLong()) {
|
||||
@ -528,6 +527,10 @@ public abstract class BaseFhirDao implements IDao {
|
||||
}
|
||||
}
|
||||
|
||||
if (pids.isEmpty()) {
|
||||
return new ArrayList<IBaseResource>();
|
||||
}
|
||||
|
||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<ResourceTable> cq = builder.createQuery(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);
|
||||
|
||||
ArrayList<IResource> retVal = new ArrayList<IResource>();
|
||||
ArrayList<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||
for (ResourceTable next : q.getResultList()) {
|
||||
IResource resource = (IResource) toResource(next);
|
||||
retVal.add(resource);
|
||||
|
@ -20,8 +20,7 @@ package ca.uhn.fhir.jpa.dao;
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
@ -660,12 +659,12 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||
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()) {
|
||||
ourLog.info("Loading {} included resources", includePids.size());
|
||||
resources = loadResourcesById(includePids);
|
||||
for (IResource next : resources) {
|
||||
ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put(next, BundleEntrySearchModeEnum.INCLUDE);
|
||||
for (IBaseResource next : resources) {
|
||||
ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put((IResource) next, BundleEntrySearchModeEnum.INCLUDE);
|
||||
}
|
||||
theListToPopulate.addAll(resources);
|
||||
}
|
||||
@ -1000,7 +999,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||
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() {
|
||||
return myResourceType;
|
||||
@ -1074,8 +1073,8 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IResource> getResources(int theFromIndex, int theToIndex) {
|
||||
ArrayList<IResource> retVal = new ArrayList<IResource>();
|
||||
public List<IBaseResource> getResources(int theFromIndex, int theToIndex) {
|
||||
List<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||
if (theFromIndex == 0 && current != null) {
|
||||
retVal.add(current);
|
||||
}
|
||||
@ -1128,7 +1127,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||
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()) {
|
||||
return;
|
||||
}
|
||||
@ -1520,15 +1519,15 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||
}
|
||||
|
||||
@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);
|
||||
return template.execute(new TransactionCallback<List<IResource>>() {
|
||||
return template.execute(new TransactionCallback<List<IBaseResource>>() {
|
||||
@Override
|
||||
public List<IResource> doInTransaction(TransactionStatus theStatus) {
|
||||
public List<IBaseResource> doInTransaction(TransactionStatus theStatus) {
|
||||
List<Long> pidsSubList = pids.subList(theFromIndex, theToIndex);
|
||||
|
||||
// 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);
|
||||
|
||||
/*
|
||||
@ -1538,18 +1537,18 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||
*/
|
||||
if (theParams.getIncludes() != null && theParams.getIncludes().isEmpty() == false) {
|
||||
Set<IdDt> previouslyLoadedPids = new HashSet<IdDt>();
|
||||
for (IResource next : retVal) {
|
||||
previouslyLoadedPids.add(next.getId().toUnqualifiedVersionless());
|
||||
for (IBaseResource next : retVal) {
|
||||
previouslyLoadedPids.add((IdDt) next.getId().toUnqualifiedVersionless());
|
||||
}
|
||||
|
||||
Set<IdDt> includePids = new HashSet<IdDt>();
|
||||
List<IResource> resources = retVal;
|
||||
List<IBaseResource> resources = retVal;
|
||||
do {
|
||||
includePids.clear();
|
||||
|
||||
FhirTerser t = getContext().newTerser();
|
||||
for (Include next : theParams.getIncludes()) {
|
||||
for (IResource nextResource : resources) {
|
||||
for (IBaseResource nextResource : resources) {
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(nextResource);
|
||||
List<Object> values = getIncludeValues(t, next, nextResource, def);
|
||||
|
||||
|
@ -24,6 +24,8 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
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> {
|
||||
|
||||
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;
|
||||
if ("*".equals(next.getValue())) {
|
||||
values = new ArrayList<Object>();
|
||||
|
@ -24,6 +24,8 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
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> {
|
||||
|
||||
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;
|
||||
if ("*".equals(theInclude.getValue())) {
|
||||
values = new ArrayList<Object>();
|
||||
|
@ -31,6 +31,7 @@ import java.util.Set;
|
||||
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -241,9 +242,9 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
|
||||
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");
|
||||
}
|
||||
List<IResource> resourcesToAdd = bundle.getResources(0, Math.min(bundle.size(), configuredMax));
|
||||
for (IResource next : resourcesToAdd) {
|
||||
searchBundle.addEntry().setResource(next);
|
||||
List<IBaseResource> resourcesToAdd = bundle.getResources(0, Math.min(bundle.size(), configuredMax));
|
||||
for (IBaseResource next : resourcesToAdd) {
|
||||
searchBundle.addEntry().setResource((IResource) next);
|
||||
}
|
||||
|
||||
response.addEntry().setResource(searchBundle);
|
||||
|
@ -39,9 +39,11 @@
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||
<property name="entityManagerFactory" ref="myEntityManagerFactory" />
|
||||
</bean>
|
||||
|
||||
<tx:annotation-driven transaction-manager="myTxManager" />
|
||||
|
||||
</beans>
|
@ -27,6 +27,7 @@ import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.hamcrest.core.StringContains;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
@ -453,8 +454,8 @@ public class FhirResourceDaoDstu2Test {
|
||||
|
||||
IBundleProvider history = ourPatientDao.history(null);
|
||||
assertEquals(4 + initialHistory, history.size());
|
||||
List<IResource> resources = history.getResources(0, 4);
|
||||
assertNotNull(resources.get(0).getResourceMetadata().get(ResourceMetadataKeyEnum.DELETED_AT));
|
||||
List<IBaseResource> resources = history.getResources(0, 4);
|
||||
assertNotNull(((IResource) resources.get(0)).getResourceMetadata().get(ResourceMetadataKeyEnum.DELETED_AT));
|
||||
|
||||
try {
|
||||
ourPatientDao.delete(id2);
|
||||
@ -534,9 +535,9 @@ public class FhirResourceDaoDstu2Test {
|
||||
IBundleProvider history = ourPatientDao.history(id, null);
|
||||
assertEquals(2, history.size());
|
||||
|
||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(0, 0).get(0)));
|
||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(0, 0).get(0)).getValue());
|
||||
assertNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(1, 1).get(0)));
|
||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(0, 0).get(0)));
|
||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(0, 0).get(0)).getValue());
|
||||
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));
|
||||
IBundleProvider resultsP = ourOrganizationDao.search(map);
|
||||
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(Organization.class, results.get(0).getClass());
|
||||
assertEquals(Patient.class, results.get(1).getClass());
|
||||
@ -2162,15 +2163,15 @@ public class FhirResourceDaoDstu2Test {
|
||||
|
||||
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("2", history.get(0).getId().getVersionIdPart());
|
||||
assertEquals(published, history.get(1).getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED));
|
||||
assertEquals(published, history.get(1).getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED));
|
||||
assertEquals(updated, history.get(1).getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED));
|
||||
assertEquals(published, ((IResource)history.get(1)).getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED));
|
||||
assertEquals(published, ((IResource)history.get(1)).getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED));
|
||||
assertEquals(updated, ((IResource)history.get(1)).getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED));
|
||||
assertEquals("001", ((Patient) history.get(1)).getIdentifierFirstRep().getValue());
|
||||
assertEquals(published2, history.get(0).getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED));
|
||||
assertEquals(updated2, history.get(0).getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED));
|
||||
assertEquals(published2, ((IResource)history.get(0)).getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED));
|
||||
assertEquals(updated2, ((IResource)history.get(0)).getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED));
|
||||
assertEquals("002", ((Patient) history.get(0)).getIdentifierFirstRep().getValue());
|
||||
|
||||
}
|
||||
@ -2313,8 +2314,8 @@ public class FhirResourceDaoDstu2Test {
|
||||
|
||||
private List<IdDt> toUnqualifiedVersionlessIds(IBundleProvider theFound) {
|
||||
List<IdDt> retVal = new ArrayList<IdDt>();
|
||||
for (IResource next : theFound.getResources(0, theFound.size())) {
|
||||
retVal.add(next.getId().toUnqualifiedVersionless());
|
||||
for (IBaseResource next : theFound.getResources(0, theFound.size())) {
|
||||
retVal.add((IdDt) next.getId().toUnqualifiedVersionless());
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
@ -2353,9 +2354,9 @@ public class FhirResourceDaoDstu2Test {
|
||||
|
||||
IBundleProvider value = ourDeviceDao.search(new SearchParameterMap());
|
||||
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());
|
||||
ourDeviceDao.delete(next.getId());
|
||||
ourDeviceDao.delete((IdDt) next.getId());
|
||||
}
|
||||
|
||||
value = ourDeviceDao.search(new SearchParameterMap());
|
||||
@ -2365,7 +2366,7 @@ public class FhirResourceDaoDstu2Test {
|
||||
}
|
||||
assertEquals(0, value.size());
|
||||
|
||||
List<IResource> res = value.getResources(0, 0);
|
||||
List<IBaseResource> res = value.getResources(0, 0);
|
||||
assertTrue(res.isEmpty());
|
||||
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
@ -93,7 +94,7 @@ public class FhirSystemDaoDstu1Test {
|
||||
IBundleProvider values = ourSystemDao.history(start);
|
||||
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(newpid2, res.get(1).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"));
|
||||
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();
|
||||
assertEquals(foundPatientId.getIdPart(), subject.getReference().getIdPart());
|
||||
|
||||
@ -371,7 +372,7 @@ public class FhirSystemDaoDstu1Test {
|
||||
*/
|
||||
|
||||
res = new ArrayList<IResource>();
|
||||
List<IResource> existing = results.getResources(0, 3);
|
||||
List<IBaseResource> existing = results.getResources(0, 3);
|
||||
|
||||
p1 = new Patient();
|
||||
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"));
|
||||
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());
|
||||
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import static org.junit.Assert.fail;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
@ -262,9 +263,9 @@ public class FhirSystemDaoDstu2Test {
|
||||
IBundleProvider history = ourPatientDao.history(id, null);
|
||||
assertEquals(2, history.size());
|
||||
|
||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(0, 0).get(0)));
|
||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(0, 0).get(0)).getValue());
|
||||
assertNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(1, 1).get(0)));
|
||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(0, 0).get(0)));
|
||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(0, 0).get(0)).getValue());
|
||||
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) {
|
||||
IBundleProvider all = systemDao.history(null);
|
||||
List<IResource> allRes = all.getResources(0, all.size());
|
||||
for (IResource iResource : allRes) {
|
||||
if (ResourceMetadataKeyEnum.DELETED_AT.get(iResource) == null) {
|
||||
List<IBaseResource> allRes = all.getResources(0, all.size());
|
||||
for (IBaseResource iResource : allRes) {
|
||||
if (ResourceMetadataKeyEnum.DELETED_AT.get((IResource) iResource) == null) {
|
||||
ourLog.info("Deleting: {}", iResource.getId());
|
||||
|
||||
Bundle b = new Bundle();
|
||||
|
@ -26,6 +26,7 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
@ -126,12 +127,7 @@ public class ResourceProviderDstu2Test {
|
||||
|
||||
CloseableHttpResponse response = ourHttpClient.execute(post);
|
||||
try {
|
||||
|
||||
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")));
|
||||
|
||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
@ -452,7 +448,7 @@ public class ResourceProviderDstu2Test {
|
||||
// NB this does not get used- The paging provider has its own limits built in
|
||||
ourDaoConfig.setHardSearchLimit(100);
|
||||
|
||||
List<IResource> resources = new ArrayList<IResource>();
|
||||
List<IBaseResource> resources = new ArrayList<IBaseResource>();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
Organization org = new Organization();
|
||||
org.setName("rpdstu2_testCountParam_01");
|
||||
|
@ -7,6 +7,7 @@ import java.util.List;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
@ -2,22 +2,25 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<!--
|
||||
Note: HAPI projects use the Sonatype OSS parent project to
|
||||
facilitate deployment to the global Maven repos.
|
||||
Note: HAPI projects use the "hapi-fhir" POM as their base to provide
|
||||
easy management.
|
||||
|
||||
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
|
||||
are using this file as a basis for your own project.
|
||||
-->
|
||||
<!--
|
||||
<parent>
|
||||
<groupId>org.sonatype.oss</groupId>
|
||||
<artifactId>oss-parent</artifactId>
|
||||
<version>7</version>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
-->
|
||||
|
||||
<groupId>ca.uhn.hapi.example</groupId>
|
||||
<artifactId>hapi-fhir-jpaserver-example</artifactId>
|
||||
<version>0.9-SNAPSHOT</version>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<name>HAPI FHIR JPA Server - Example</name>
|
||||
|
@ -4,12 +4,11 @@ import java.util.List;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
|
||||
import org.springframework.web.context.ContextLoaderListener;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
||||
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu1;
|
||||
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.IResourceProvider;
|
||||
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 {
|
||||
|
||||
@ -123,12 +122,12 @@ public class JpaServerDemo extends RestfulServer {
|
||||
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();
|
||||
loggingInterceptor.setLoggerName("fhir.access");
|
||||
loggingInterceptor.setMessageFormat("Path[${servletPath}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]");
|
||||
this.registerInterceptor(loggingInterceptor);
|
||||
List<IServerInterceptor> interceptorBeans = myAppCtx.getBean("myServerInterceptors", List.class);
|
||||
for (IServerInterceptor interceptor : interceptorBeans) {
|
||||
this.registerInterceptor(interceptor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -21,4 +21,18 @@
|
||||
</bean>
|
||||
<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>
|
@ -7,17 +7,16 @@ import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.web.context.ContextLoaderListener;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
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.JpaConformanceProviderDstu2;
|
||||
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu1;
|
||||
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
|
||||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||
import ca.uhn.fhir.rest.server.ETagSupportEnum;
|
||||
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.IResourceProvider;
|
||||
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 {
|
||||
|
||||
@ -164,13 +163,12 @@ public class TestRestfulServer extends RestfulServer {
|
||||
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();
|
||||
loggingInterceptor.setLoggerName("fhirtest.access");
|
||||
loggingInterceptor.setMessageFormat("Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]");
|
||||
this.registerInterceptor(loggingInterceptor);
|
||||
List<IServerInterceptor> interceptorBeans = myAppCtx.getBean("myServerInterceptors", List.class);
|
||||
for (IServerInterceptor interceptor : interceptorBeans) {
|
||||
this.registerInterceptor(interceptor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -21,4 +21,18 @@
|
||||
</bean>
|
||||
<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>
|
@ -1,10 +1,12 @@
|
||||
package ca.uhn.fhirtest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
@ -65,7 +67,8 @@ public class UhnFhirTestApp {
|
||||
ResourceMetadataKeyEnum.TAG_LIST.put(p1, list);
|
||||
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);
|
||||
|
||||
// for (int i = 0; i < 1000; i++) {
|
||||
|
@ -782,13 +782,13 @@ public class JsonParserTest {
|
||||
|
||||
private void parseAndEncode(String name) throws IOException {
|
||||
String msg = IOUtils.toString(XmlParser.class.getResourceAsStream(name));
|
||||
ourLog.info(msg);
|
||||
// ourLog.info(msg);
|
||||
|
||||
IParser p = ourCtx.newJsonParser();
|
||||
Profile res = p.parseResource(Profile.class, msg);
|
||||
|
||||
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(res);
|
||||
ourLog.info(encoded);
|
||||
// ourLog.info(encoded);
|
||||
|
||||
JSON expected = JSONSerializer.toJSON(msg.trim());
|
||||
JSON actual = JSONSerializer.toJSON(encoded.trim());
|
||||
@ -1219,7 +1219,6 @@ public class JsonParserTest {
|
||||
Bundle b = new Bundle();
|
||||
|
||||
InstantDt pub = InstantDt.withCurrentTime();
|
||||
b.setPublished(pub);
|
||||
Thread.sleep(2);
|
||||
|
||||
Patient p1 = new Patient();
|
||||
@ -1245,7 +1244,6 @@ public class JsonParserTest {
|
||||
ourLog.info(bundleString);
|
||||
|
||||
List<String> strings = new ArrayList<String>();
|
||||
strings.addAll(Arrays.asList("\"published\":\"" + pub.getValueAsString() + "\""));
|
||||
strings.addAll(Arrays.asList("\"id\":\"1\""));
|
||||
strings.addAll(Arrays.asList("this is the summary"));
|
||||
strings.addAll(Arrays.asList("\"id\":\"2\"", "\"rel\":\"alternate\"", "\"href\":\"http://foo/bar\""));
|
||||
|
@ -314,7 +314,6 @@ public class XmlParserTest {
|
||||
b.getCategories().addTag("http://hl7.org/fhir/tag", "http://hl7.org/fhir/tag/message", "Message");
|
||||
|
||||
InstantDt pub = InstantDt.withCurrentTime();
|
||||
b.setPublished(pub);
|
||||
Thread.sleep(2);
|
||||
|
||||
Patient p1 = new Patient();
|
||||
@ -340,7 +339,6 @@ public class XmlParserTest {
|
||||
ourLog.info(bundleString);
|
||||
|
||||
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.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>"));
|
||||
@ -380,7 +378,6 @@ public class XmlParserTest {
|
||||
b.getCategories().addTag("http://hl7.org/fhir/tag", "http://hl7.org/fhir/tag/message", "Message");
|
||||
|
||||
InstantDt pub = InstantDt.withCurrentTime();
|
||||
b.setPublished(pub);
|
||||
Thread.sleep(2);
|
||||
|
||||
Patient p1 = new Patient();
|
||||
@ -406,7 +403,6 @@ public class XmlParserTest {
|
||||
ourLog.info(bundleString);
|
||||
|
||||
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.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>"));
|
||||
|
@ -102,8 +102,7 @@ public class ClientTest {
|
||||
"<title/>\n" +
|
||||
"<id>d039f91a-cc3c-4013-988e-af4d8d0614bd</id>\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" +
|
||||
"</author>\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>"
|
||||
+ "<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>"+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>"
|
||||
+ "<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>"+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>"
|
||||
+ "<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>"+date1.getValueAsString()+"</updated>"
|
||||
@ -511,7 +507,7 @@ public class ClientTest {
|
||||
public void testHistoryWithParams() throws Exception {
|
||||
|
||||
//@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
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
@ -85,8 +85,7 @@ public class GenericClientTest {
|
||||
"<title/>\n" +
|
||||
"<id>d039f91a-cc3c-4013-988e-af4d8d0614bd</id>\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" +
|
||||
"</author>\n" +
|
||||
"<entry>\n" +
|
||||
@ -132,7 +131,7 @@ public class GenericClientTest {
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
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().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"));
|
||||
MethodOutcome resp = client.create().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).execute();
|
||||
assertTrue(resp.getCreated());
|
||||
|
||||
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
resp = client.create().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).execute();
|
||||
assertNull(resp.getCreated());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateWithStringAutoDetectsEncoding() throws Exception {
|
||||
|
||||
|
@ -114,8 +114,7 @@ public class IncludedResourceStitchingClientTest {
|
||||
" <link rel=\"self\" href=\"http://localhost:49782/Patient?_query=declaredExtInclude&_pretty=true\"/>\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" +
|
||||
" <published>2014-08-12T10:22:19.097-04:00</published>\n" +
|
||||
" <author>\n" +
|
||||
" <author>\n" +
|
||||
" <name>HAPI FHIR Server</name>\n" +
|
||||
" </author>\n" +
|
||||
" <entry>\n" +
|
||||
@ -192,8 +191,7 @@ public class IncludedResourceStitchingClientTest {
|
||||
" <link rel=\"self\" href=\"http://localhost:49627/Patient?_query=extInclude&_pretty=true\"/>\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" +
|
||||
" <published>2014-08-05T15:22:08.512-04:00</published>\n" +
|
||||
" <author>\n" +
|
||||
" <author>\n" +
|
||||
" <name>HAPI FHIR Server</name>\n" +
|
||||
" </author>\n" +
|
||||
" <entry>\n" +
|
||||
|
File diff suppressed because one or more lines are too long
@ -20,6 +20,7 @@ import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
||||
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.Patient;
|
||||
import ca.uhn.fhir.model.dstu.resource.Practitioner;
|
||||
@ -86,6 +87,23 @@ public class Dstu1BundleFactoryTest {
|
||||
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
|
||||
public void whenIncludeIsAsterisk_bundle_shouldContainAllReferencedResources() throws Exception {
|
||||
Bundle bundle = makeBundle(BundleInclusionRule.BASED_ON_INCLUDES, includes("*"));
|
||||
|
@ -1,30 +1,236 @@
|
||||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
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.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 ca.uhn.fhir.util.RandomServerPortProvider;
|
||||
|
||||
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
|
||||
* Simon Ling of Systems Made Simple
|
||||
* This is an incoming request from an instance of Tomcat on AWS, provided by Simon Ling of Systems Made Simple
|
||||
*/
|
||||
@Test
|
||||
public void testAwsUrl() {
|
||||
|
||||
|
||||
HttpServletRequest req = mock(HttpServletRequest.class);
|
||||
when(req.getRequestURI()).thenReturn("/FhirStorm/fhir/Patient/_search");
|
||||
when(req.getServletPath()).thenReturn("/fhir");
|
||||
when(req.getRequestURL()).thenReturn(new StringBuffer().append("http://fhirstorm.dyndns.org:8080/FhirStorm/fhir/Patient/_search"));
|
||||
when(req.getContextPath()).thenReturn("/FhirStorm");
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
<link rel="self" href="http://localhost:8888/fhir/context/Patient?_pretty=true&_include=Patient.managingOrganization&_pretty=true"/>
|
||||
<link rel="fhir-base" href="http://localhost:8888/fhir/context"/>
|
||||
<os:totalResults xmlns:os="http://a9.com/-/spec/opensearch/1.1/">2</os:totalResults>
|
||||
<published>2014-06-22T21:37:05-04:00</published>
|
||||
<author>
|
||||
<name>HAPI FHIR Server</name>
|
||||
</author>
|
||||
|
@ -105,7 +105,7 @@ public class FhirDstu2 implements IFhirVersion {
|
||||
public Class<? extends BaseContainedDt> getContainedType() {
|
||||
return ContainedDt.class;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BaseCodingDt newCodingDt() {
|
||||
return new CodingDt();
|
||||
|
@ -468,7 +468,7 @@ public class XmlParserDstu2Test {
|
||||
//@formatter:on
|
||||
|
||||
Patient p = ourCtx.newXmlParser().parseResource(Patient.class, res);
|
||||
assertEquals(htmlNoNs, p.getText().getDiv().getValueAsString());
|
||||
assertEquals(htmlNs, p.getText().getDiv().getValueAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,6 @@
|
||||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
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();
|
||||
String ref = patient.getManagingOrganization().getReference().getValue();
|
||||
assertEquals("Organization/555", ref);
|
||||
assertNull(status.getFirstHeader(Constants.HEADER_CONTENT_LOCATION));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1062,7 +1062,7 @@ public class XmlParserHl7OrgDstu2Test {
|
||||
Patient patient = ourCtx.newXmlParser().parseResource(Patient.class, msg);
|
||||
|
||||
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());
|
||||
|
||||
String encoded = ourCtx.newXmlParser().encodeResourceToString(patient);
|
||||
@ -1197,6 +1197,8 @@ public class XmlParserHl7OrgDstu2Test {
|
||||
Patient patient1 = ourCtx.newXmlParser().parseResource(Patient.class, msg);
|
||||
String encoded1 = ourCtx.newXmlParser().encodeResourceToString(patient1);
|
||||
|
||||
ourLog.info(encoded1);
|
||||
|
||||
Diff d = new Diff(new StringReader(msg), new StringReader(encoded1));
|
||||
assertTrue(d.toString(), d.identical());
|
||||
|
||||
|
127
hapi-fhir-testpage-overlay/.gitignore
vendored
127
hapi-fhir-testpage-overlay/.gitignore
vendored
@ -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/
|
||||
|
@ -1203,7 +1203,7 @@ public class Controller {
|
||||
|
||||
private String parseNarrative(HomeRequest theRequest, EncodingEnum theCtEnum, String theResultBody) {
|
||||
try {
|
||||
IResource resource = theCtEnum.newParser(getContext(theRequest)).parseResource(theResultBody);
|
||||
IResource resource = (IResource) theCtEnum.newParser(getContext(theRequest)).parseResource(theResultBody);
|
||||
String retVal = resource.getText().getDiv().getValueAsString();
|
||||
return StringUtils.defaultString(retVal);
|
||||
} catch (Exception e) {
|
||||
|
@ -49,7 +49,9 @@ public class HomeRequest {
|
||||
}
|
||||
|
||||
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("/")) {
|
||||
base = base.substring(0, base.length() - 1);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
@ -129,7 +130,7 @@ public class OverlayTestApp {
|
||||
client.create(p1);
|
||||
|
||||
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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -21,7 +21,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
@ -1,7 +1,6 @@
|
||||
package ca.uhn.example;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
@ -12,7 +11,7 @@ import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
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;
|
||||
|
||||
public class ExampleTest {
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
<groupId>ca.uhn.hapi.example</groupId>
|
||||
<artifactId>restful-server-example</artifactId>
|
||||
<version>0.8-SNAPSHOT</version>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<name>HAPI FHIR Sample RESTful Server</name>
|
||||
@ -40,7 +40,7 @@
|
||||
<!-- At least one "structures" JAR must also be included -->
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
|
@ -3,7 +3,6 @@ package ca.uhn.example.model;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.api.BaseElement;
|
||||
import ca.uhn.fhir.model.api.BaseIdentifiableElement;
|
||||
import ca.uhn.fhir.model.api.IElement;
|
||||
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.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.model.dstu.composite.ContactDt;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu2.composite.ContactPointDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
||||
import ca.uhn.fhir.model.primitive.BooleanDt;
|
||||
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
@ -115,7 +114,7 @@ public class MyOrganization extends Organization {
|
||||
@Description(shortDefinition = "Contains the actual contact details")
|
||||
@Extension(url = "http://foo#emergencyContactContact", isModifier = false, definedLocally = true)
|
||||
@Child(name = "contact")
|
||||
private ContactDt myContact;
|
||||
private ContactPointDt myContact;
|
||||
|
||||
/* *****************************
|
||||
* Getters and setters
|
||||
@ -132,14 +131,14 @@ public class MyOrganization extends Organization {
|
||||
myActive = theActive;
|
||||
}
|
||||
|
||||
public ContactDt getContact() {
|
||||
public ContactPointDt getContact() {
|
||||
if (myContact == null) {
|
||||
myContact = new ContactDt();
|
||||
myContact = new ContactPointDt();
|
||||
}
|
||||
return myContact;
|
||||
}
|
||||
|
||||
public void setContact(ContactDt theContact) {
|
||||
public void setContact(ContactPointDt theContact) {
|
||||
myContact = theContact;
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
package ca.uhn.example.provider;
|
||||
|
||||
import ca.uhn.example.model.MyOrganization;
|
||||
import ca.uhn.example.model.MyOrganization.EmergencyContact;
|
||||
import ca.uhn.fhir.model.dstu.composite.ContactDt;
|
||||
import ca.uhn.fhir.model.dstu.valueset.ContactUseEnum;
|
||||
import ca.uhn.fhir.model.dstu2.composite.ContactPointDt;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.ContactPointUseEnum;
|
||||
import ca.uhn.fhir.model.primitive.BooleanDt;
|
||||
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
@ -51,9 +50,9 @@ public class OrganizationResourceProvider implements IResourceProvider {
|
||||
|
||||
MyOrganization retVal = new MyOrganization();
|
||||
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.addTelecom().setUse(ContactUseEnum.WORK).setValue("1-888-123-4567");
|
||||
retVal.addTelecom().setUse(ContactPointUseEnum.WORK).setValue("1-888-123-4567");
|
||||
|
||||
// Populate the first, primitive extension
|
||||
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
|
||||
MyOrganization.EmergencyContact contact = new MyOrganization.EmergencyContact();
|
||||
contact.setActive(new BooleanDt(true));
|
||||
contact.setContact(new ContactDt());
|
||||
contact.setContact(new ContactPointDt());
|
||||
retVal.getEmergencyContact().add(contact);
|
||||
|
||||
return retVal;
|
||||
|
@ -7,11 +7,11 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
|
||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu.valueset.AdministrativeGenderCodesEnum;
|
||||
import ca.uhn.fhir.model.dstu.valueset.IssueSeverityEnum;
|
||||
import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
@ -59,7 +59,7 @@ public class PatientResourceProvider implements IResourceProvider {
|
||||
patient.getIdentifier().get(0).setValue("00002");
|
||||
patient.addName().addFamily("Test");
|
||||
patient.getName().get(0).addGiven("PatientOne");
|
||||
patient.setGender(AdministrativeGenderCodesEnum.F);
|
||||
patient.setGender(AdministrativeGenderEnum.FEMALE);
|
||||
|
||||
LinkedList<Patient> list = new LinkedList<Patient>();
|
||||
list.add(patient);
|
||||
|
@ -5,6 +5,7 @@ import java.util.List;
|
||||
|
||||
import ca.uhn.example.provider.OrganizationResourceProvider;
|
||||
import ca.uhn.example.provider.PatientResourceProvider;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||
import ca.uhn.fhir.narrative.INarrativeGenerator;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
@ -23,6 +24,7 @@ public class ExampleRestfulServlet extends RestfulServer {
|
||||
*/
|
||||
@Override
|
||||
public void initialize() {
|
||||
setFhirContext(FhirContext.forDstu2());// Support DSTU2
|
||||
|
||||
/*
|
||||
* Two resource providers are defined. Each one handles a specific
|
||||
|
@ -136,6 +136,16 @@
|
||||
configures the parser to preserve versions in resource reference links when
|
||||
encoding. By default, these are removed.
|
||||
</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 version="0.9" date="2015-Mar-14">
|
||||
<action type="add">
|
||||
|
@ -165,8 +165,10 @@
|
||||
|
||||
<h4>Search - Using HTTP POST</h4>
|
||||
<p>
|
||||
The FHIR specification allows the use of an HTTP POST to transmit a search to a server instead of using
|
||||
an HTTP GET. With this style of search, the search parameters are included in the request body instead
|
||||
The FHIR specification allows the use of an HTTP POST to transmit a search to a server instead of
|
||||
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 parameters.
|
||||
</p>
|
||||
@ -176,7 +178,7 @@
|
||||
case the client automatically switches to POST.
|
||||
</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
|
||||
for using this form in order to interoperate with servers which use it.
|
||||
</p>
|
||||
@ -211,18 +213,18 @@
|
||||
<param name="file"
|
||||
value="examples/src/main/java/example/GenericClientExample.java" />
|
||||
</macro>
|
||||
|
||||
|
||||
<h4>Conditional Creates</h4>
|
||||
<p>
|
||||
FHIR also specifies a type of update called "conditional create", where
|
||||
a set of search parameters are provided and a new resource is only
|
||||
created if no existing resource matches those parameters. See the
|
||||
FHIR specification for more information on conditional creation.
|
||||
created if no existing resource matches those parameters. See the
|
||||
FHIR specification for more information on conditional creation.
|
||||
</p>
|
||||
<macro name="snippet">
|
||||
<param name="id" value="updateConditional" />
|
||||
<param name="id" value="updateConditional"/>
|
||||
<param name="file"
|
||||
value="examples/src/main/java/example/GenericClientExample.java" />
|
||||
value="examples/src/main/java/example/GenericClientExample.java"/>
|
||||
</macro>
|
||||
</subsection>
|
||||
|
||||
@ -276,7 +278,7 @@
|
||||
</macro>
|
||||
<h4>Conditional Deletes</h4>
|
||||
<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
|
||||
a set of search criteria and a single resource is deleted if
|
||||
it matches that criteria. Note that this is not a mechanism
|
||||
@ -284,9 +286,9 @@
|
||||
on conditional deletes and how they are used.
|
||||
</p>
|
||||
<macro name="snippet">
|
||||
<param name="id" value="deleteConditional" />
|
||||
<param name="id" value="deleteConditional"/>
|
||||
<param name="file"
|
||||
value="examples/src/main/java/example/GenericClientExample.java" />
|
||||
value="examples/src/main/java/example/GenericClientExample.java"/>
|
||||
</macro>
|
||||
</subsection>
|
||||
|
||||
@ -305,19 +307,19 @@
|
||||
<param name="file"
|
||||
value="examples/src/main/java/example/GenericClientExample.java" />
|
||||
</macro>
|
||||
|
||||
|
||||
<h4>Conditional Updates</h4>
|
||||
<p>
|
||||
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
|
||||
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.
|
||||
</p>
|
||||
<macro name="snippet">
|
||||
<param name="id" value="updateConditional" />
|
||||
<param name="id" value="updateConditional"/>
|
||||
<param name="file"
|
||||
value="examples/src/main/java/example/GenericClientExample.java" />
|
||||
value="examples/src/main/java/example/GenericClientExample.java"/>
|
||||
</macro>
|
||||
|
||||
<h4>ETags and Resource Contention</h4>
|
||||
|
Loading…
x
Reference in New Issue
Block a user