mirror of
https://github.com/hapifhir/hapi-fhir.git
synced 2025-03-09 14:33:32 +00:00
Merging cleanup from local branch with commit from #153
This commit is contained in:
parent
dfbfed2d35
commit
4f1d2a3c75
@ -147,7 +147,7 @@
|
|||||||
<include>javax.xml.stream:stax-api</include>
|
<include>javax.xml.stream:stax-api</include>
|
||||||
<include>javax.servlet:javax.servlet-api</include>
|
<include>javax.servlet:javax.servlet-api</include>
|
||||||
<include>org.codehaus.woodstox:stax2-api</include>
|
<include>org.codehaus.woodstox:stax2-api</include>
|
||||||
<include>org.slf4j:slf4j*</include>
|
<!-- <include>org.slf4j:slf4j*</include> -->
|
||||||
<include>org.apache.commons:*</include>
|
<include>org.apache.commons:*</include>
|
||||||
<include>org.apache.httpcomponents:*</include>
|
<include>org.apache.httpcomponents:*</include>
|
||||||
<include>org.glassfish:javax.json</include>
|
<include>org.glassfish:javax.json</include>
|
||||||
|
@ -49,14 +49,13 @@ import javax.json.stream.JsonGenerator;
|
|||||||
import javax.json.stream.JsonGeneratorFactory;
|
import javax.json.stream.JsonGeneratorFactory;
|
||||||
import javax.json.stream.JsonParsingException;
|
import javax.json.stream.JsonParsingException;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
|
||||||
import ca.uhn.fhir.model.primitive.*;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.hl7.fhir.instance.model.IBase;
|
import org.hl7.fhir.instance.model.IBase;
|
||||||
import org.hl7.fhir.instance.model.IBaseResource;
|
import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.IPrimitiveType;
|
import org.hl7.fhir.instance.model.IPrimitiveType;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseBinary;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseBooleanDatatype;
|
import org.hl7.fhir.instance.model.api.IBaseBooleanDatatype;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseDecimalDatatype;
|
import org.hl7.fhir.instance.model.api.IBaseDecimalDatatype;
|
||||||
@ -89,19 +88,25 @@ import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
|||||||
import ca.uhn.fhir.model.api.Tag;
|
import ca.uhn.fhir.model.api.Tag;
|
||||||
import ca.uhn.fhir.model.api.TagList;
|
import ca.uhn.fhir.model.api.TagList;
|
||||||
import ca.uhn.fhir.model.api.annotation.Child;
|
import ca.uhn.fhir.model.api.annotation.Child;
|
||||||
|
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
|
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
|
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseBinary;
|
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||||
import ca.uhn.fhir.model.primitive.DecimalDt;
|
import ca.uhn.fhir.model.primitive.DecimalDt;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
import ca.uhn.fhir.model.primitive.IntegerDt;
|
import ca.uhn.fhir.model.primitive.IntegerDt;
|
||||||
import ca.uhn.fhir.model.primitive.StringDt;
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.UriDt;
|
||||||
import ca.uhn.fhir.model.primitive.XhtmlDt;
|
import ca.uhn.fhir.model.primitive.XhtmlDt;
|
||||||
import ca.uhn.fhir.narrative.INarrativeGenerator;
|
import ca.uhn.fhir.narrative.INarrativeGenerator;
|
||||||
import ca.uhn.fhir.util.ElementUtil;
|
import ca.uhn.fhir.util.ElementUtil;
|
||||||
import ca.uhn.fhir.util.UrlUtil;
|
import ca.uhn.fhir.util.UrlUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is the FHIR JSON parser/encoder. Users should not interact with this class directly, but should use {@link FhirContext#newJsonParser()} to get an instance.
|
||||||
|
*/
|
||||||
public class JsonParser extends BaseParser implements IParser {
|
public class JsonParser extends BaseParser implements IParser {
|
||||||
|
|
||||||
private static final Set<String> BUNDLE_TEXTNODE_CHILDREN_DSTU1;
|
private static final Set<String> BUNDLE_TEXTNODE_CHILDREN_DSTU1;
|
||||||
@ -298,9 +303,9 @@ public class JsonParser extends BaseParser implements IParser {
|
|||||||
// IResource nextResource = nextEntry.getResource();
|
// IResource nextResource = nextEntry.getResource();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextEntry.getTransactionOperation().isEmpty() == false || nextEntry.getLinkSearch().isEmpty() == false) {
|
if (nextEntry.getTransactionMethod().isEmpty() == false || nextEntry.getLinkSearch().isEmpty() == false) {
|
||||||
theEventWriter.writeStartObject("transaction");
|
theEventWriter.writeStartObject("transaction");
|
||||||
writeOptionalTagWithTextNode(theEventWriter, "operation", nextEntry.getTransactionOperation().getValue());
|
writeOptionalTagWithTextNode(theEventWriter, "method", nextEntry.getTransactionMethod().getValue());
|
||||||
writeOptionalTagWithTextNode(theEventWriter, "url", nextEntry.getLinkSearch().getValue());
|
writeOptionalTagWithTextNode(theEventWriter, "url", nextEntry.getLinkSearch().getValue());
|
||||||
theEventWriter.writeEnd();
|
theEventWriter.writeEnd();
|
||||||
}
|
}
|
||||||
@ -343,7 +348,7 @@ public class JsonParser extends BaseParser implements IParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theWriter, IBase theNextValue,
|
private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theWriter, IBase theNextValue,
|
||||||
BaseRuntimeElementDefinition<?> theChildDef, String theChildName, boolean theIsSubElementWithinResource) throws IOException {
|
BaseRuntimeElementDefinition<?> theChildDef, String theChildName, boolean theContainedResource) throws IOException {
|
||||||
|
|
||||||
switch (theChildDef.getChildType()) {
|
switch (theChildDef.getChildType()) {
|
||||||
case PRIMITIVE_DATATYPE: {
|
case PRIMITIVE_DATATYPE: {
|
||||||
@ -391,7 +396,7 @@ public class JsonParser extends BaseParser implements IParser {
|
|||||||
if (theNextValue instanceof ExtensionDt) {
|
if (theNextValue instanceof ExtensionDt) {
|
||||||
theWriter.write("url", ((ExtensionDt) theNextValue).getUrlAsString());
|
theWriter.write("url", ((ExtensionDt) theNextValue).getUrlAsString());
|
||||||
}
|
}
|
||||||
encodeCompositeElementToStreamWriter(theResDef, theResource, theNextValue, theWriter, childCompositeDef, theIsSubElementWithinResource);
|
encodeCompositeElementToStreamWriter(theResDef, theResource, theNextValue, theWriter, childCompositeDef, theContainedResource);
|
||||||
theWriter.writeEnd();
|
theWriter.writeEnd();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -452,7 +457,7 @@ public class JsonParser extends BaseParser implements IParser {
|
|||||||
case RESOURCE:
|
case RESOURCE:
|
||||||
IBaseResource resource = (IBaseResource) theNextValue;
|
IBaseResource resource = (IBaseResource) theNextValue;
|
||||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(resource);
|
RuntimeResourceDefinition def = myContext.getResourceDefinition(resource);
|
||||||
encodeResourceToJsonStreamWriter(def, resource, theWriter, theChildName, true);
|
encodeResourceToJsonStreamWriter(def, resource, theWriter, theChildName, false);
|
||||||
break;
|
break;
|
||||||
case UNDECL_EXT:
|
case UNDECL_EXT:
|
||||||
default:
|
default:
|
||||||
@ -462,7 +467,7 @@ public class JsonParser extends BaseParser implements IParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theNextValue, JsonGenerator theEventWriter,
|
private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theNextValue, JsonGenerator theEventWriter,
|
||||||
List<? extends BaseRuntimeChildDefinition> theChildren, boolean theIsSubElementWithinResource) throws IOException {
|
List<? extends BaseRuntimeChildDefinition> theChildren, boolean theContainedResource) throws IOException {
|
||||||
for (BaseRuntimeChildDefinition nextChild : theChildren) {
|
for (BaseRuntimeChildDefinition nextChild : theChildren) {
|
||||||
if (nextChild.getElementName().equals("extension") || nextChild.getElementName().equals("modifierExtension")) {
|
if (nextChild.getElementName().equals("extension") || nextChild.getElementName().equals("modifierExtension")) {
|
||||||
continue;
|
continue;
|
||||||
@ -478,7 +483,7 @@ public class JsonParser extends BaseParser implements IParser {
|
|||||||
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
|
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
|
||||||
String childName = nextChild.getChildNameByDatatype(child.getDatatype());
|
String childName = nextChild.getChildNameByDatatype(child.getDatatype());
|
||||||
BaseRuntimeElementDefinition<?> type = child.getChildByName(childName);
|
BaseRuntimeElementDefinition<?> type = child.getChildByName(childName);
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, narr, type, childName, theIsSubElementWithinResource);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, narr, type, childName, theContainedResource);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -499,7 +504,7 @@ public class JsonParser extends BaseParser implements IParser {
|
|||||||
for (IBase nextValue : values) {
|
for (IBase nextValue : values) {
|
||||||
if (nextValue == null || nextValue.isEmpty()) {
|
if (nextValue == null || nextValue.isEmpty()) {
|
||||||
if (nextValue instanceof BaseContainedDt) {
|
if (nextValue instanceof BaseContainedDt) {
|
||||||
if (theIsSubElementWithinResource || getContainedResources().isEmpty()) {
|
if (theContainedResource || getContainedResources().isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -515,7 +520,7 @@ public class JsonParser extends BaseParser implements IParser {
|
|||||||
}
|
}
|
||||||
boolean primitive = childDef.getChildType() == ChildTypeEnum.PRIMITIVE_DATATYPE;
|
boolean primitive = childDef.getChildType() == ChildTypeEnum.PRIMITIVE_DATATYPE;
|
||||||
|
|
||||||
if (childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES && theIsSubElementWithinResource) {
|
if (childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES && theContainedResource) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,15 +542,15 @@ public class JsonParser extends BaseParser implements IParser {
|
|||||||
if (nextChild.getMax() > 1 || nextChild.getMax() == Child.MAX_UNLIMITED) {
|
if (nextChild.getMax() > 1 || nextChild.getMax() == Child.MAX_UNLIMITED) {
|
||||||
theEventWriter.writeStartArray(childName);
|
theEventWriter.writeStartArray(childName);
|
||||||
inArray = true;
|
inArray = true;
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theIsSubElementWithinResource);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theContainedResource);
|
||||||
} else if (nextChild instanceof RuntimeChildNarrativeDefinition && theIsSubElementWithinResource) {
|
} else if (nextChild instanceof RuntimeChildNarrativeDefinition && theContainedResource) {
|
||||||
// suppress narratives from contained resources
|
// suppress narratives from contained resources
|
||||||
} else {
|
} else {
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, childName, theIsSubElementWithinResource);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, childName, theContainedResource);
|
||||||
}
|
}
|
||||||
currentChildName = childName;
|
currentChildName = childName;
|
||||||
} else {
|
} else {
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theIsSubElementWithinResource);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theContainedResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primitive) {
|
if (primitive) {
|
||||||
@ -620,19 +625,19 @@ public class JsonParser extends BaseParser implements IParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void encodeCompositeElementToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theNextValue, JsonGenerator theEventWriter,
|
private void encodeCompositeElementToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theNextValue, JsonGenerator theEventWriter,
|
||||||
BaseRuntimeElementCompositeDefinition<?> resDef, boolean theIsSubElementWithinResource) throws IOException, DataFormatException {
|
BaseRuntimeElementCompositeDefinition<?> resDef, boolean theContainedResource) throws IOException, DataFormatException {
|
||||||
extractAndWriteExtensionsAsDirectChild(theNextValue, theEventWriter, resDef, theResDef, theResource, null);
|
extractAndWriteExtensionsAsDirectChild(theNextValue, theEventWriter, resDef, theResDef, theResource, null);
|
||||||
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theNextValue, theEventWriter, resDef.getExtensions(), theIsSubElementWithinResource);
|
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theNextValue, theEventWriter, resDef.getExtensions(), theContainedResource);
|
||||||
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theNextValue, theEventWriter, resDef.getChildren(), theIsSubElementWithinResource);
|
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theNextValue, theEventWriter, resDef.getChildren(), theContainedResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull,
|
private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull, boolean theContainedResource)
|
||||||
boolean theIsSubElementWithinResource) throws IOException {
|
throws IOException {
|
||||||
String resourceId = null;
|
String resourceId = null;
|
||||||
if (theResource instanceof IResource) {
|
if (theResource instanceof IResource) {
|
||||||
IResource res = (IResource) theResource;
|
IResource res = (IResource) theResource;
|
||||||
if (StringUtils.isNotBlank(res.getId().getIdPart())) {
|
if (StringUtils.isNotBlank(res.getId().getIdPart())) {
|
||||||
if (theIsSubElementWithinResource) {
|
if (theContainedResource) {
|
||||||
resourceId = res.getId().getIdPart();
|
resourceId = res.getId().getIdPart();
|
||||||
} else if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
} else if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
||||||
resourceId = res.getId().getIdPart();
|
resourceId = res.getId().getIdPart();
|
||||||
@ -640,17 +645,17 @@ public class JsonParser extends BaseParser implements IParser {
|
|||||||
}
|
}
|
||||||
} else if (theResource instanceof IAnyResource) {
|
} else if (theResource instanceof IAnyResource) {
|
||||||
IAnyResource res = (IAnyResource) theResource;
|
IAnyResource res = (IAnyResource) theResource;
|
||||||
if (theIsSubElementWithinResource && StringUtils.isNotBlank(res.getId())) {
|
if (theContainedResource && StringUtils.isNotBlank(res.getId())) {
|
||||||
resourceId = res.getId();
|
resourceId = res.getId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
encodeResourceToJsonStreamWriter(theResDef, theResource, theEventWriter, theObjectNameOrNull, theIsSubElementWithinResource, resourceId);
|
encodeResourceToJsonStreamWriter(theResDef, theResource, theEventWriter, theObjectNameOrNull, theContainedResource, resourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull,
|
private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull,
|
||||||
boolean theIsSubElementWithinResource, String theResourceId) throws IOException {
|
boolean theContainedResource, String theResourceId) throws IOException {
|
||||||
if (!theIsSubElementWithinResource) {
|
if (!theContainedResource) {
|
||||||
super.containResourcesForEncoding(theResource);
|
super.containResourcesForEncoding(theResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,54 +675,65 @@ public class JsonParser extends BaseParser implements IParser {
|
|||||||
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1) && theResource instanceof IResource) {
|
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1) && theResource instanceof IResource) {
|
||||||
IResource resource = (IResource) theResource;
|
IResource resource = (IResource) theResource;
|
||||||
// Object securityLabelRawObj =
|
// Object securityLabelRawObj =
|
||||||
List<BaseCodingDt> securityLabels = (List<BaseCodingDt>) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.SECURITY_LABELS);
|
|
||||||
if (!ElementUtil.isEmpty(resource.getId().getVersionIdPart(), ResourceMetadataKeyEnum.UPDATED.get(resource))
|
List<BaseCodingDt> securityLabels = extractMetadataListNotNull(resource, ResourceMetadataKeyEnum.SECURITY_LABELS);
|
||||||
|| (securityLabels != null && !securityLabels.isEmpty())) {
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ElementUtil.isEmpty(versionIdPart, updated, securityLabels, profiles) == false) {
|
||||||
theEventWriter.writeStartObject("meta");
|
theEventWriter.writeStartObject("meta");
|
||||||
writeOptionalTagWithTextNode(theEventWriter, "versionId", resource.getId().getVersionIdPart());
|
writeOptionalTagWithTextNode(theEventWriter, "versionId", versionIdPart);
|
||||||
writeOptionalTagWithTextNode(theEventWriter, "lastUpdated", ResourceMetadataKeyEnum.UPDATED.get(resource));
|
writeOptionalTagWithTextNode(theEventWriter, "lastUpdated", updated);
|
||||||
|
|
||||||
if (securityLabels != null) {
|
if (profiles != null && profiles.isEmpty() == false) {
|
||||||
if (!securityLabels.isEmpty()) {
|
theEventWriter.writeStartArray("profile");
|
||||||
|
for (IdDt profile : profiles) {
|
||||||
|
if (profile != null && isNotBlank(profile.getValue())) {
|
||||||
|
theEventWriter.write(profile.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
theEventWriter.writeEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (securityLabels.isEmpty() == false) {
|
||||||
theEventWriter.writeStartArray("security");
|
theEventWriter.writeStartArray("security");
|
||||||
|
|
||||||
for (BaseCodingDt securityLabel : securityLabels) {
|
for (BaseCodingDt securityLabel : securityLabels) {
|
||||||
theEventWriter.writeStartObject();
|
theEventWriter.writeStartObject();
|
||||||
|
BaseRuntimeElementCompositeDefinition<?> def = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(securityLabel.getClass());
|
||||||
UriDt system = securityLabel.getSystemElement();
|
encodeCompositeElementChildrenToStreamWriter(resDef, resource, securityLabel, theEventWriter, def.getChildren(), theContainedResource);
|
||||||
if (system != null && !system.isEmpty())
|
theEventWriter.writeEnd();
|
||||||
writeOptionalTagWithTextNode(theEventWriter, "system", system.getValueAsString());
|
|
||||||
|
|
||||||
CodeDt code = securityLabel.getCodeElement();
|
|
||||||
|
|
||||||
if (code != null && !code.isEmpty())
|
|
||||||
writeOptionalTagWithTextNode(theEventWriter, "code", code.getValueAsString());
|
|
||||||
|
|
||||||
StringDt display = securityLabel.getDisplayElement();
|
|
||||||
if (display != null && !display.isEmpty())
|
|
||||||
writeOptionalTagWithTextNode(theEventWriter, "display", display.getValueAsString());
|
|
||||||
|
|
||||||
/*todo: handle version
|
|
||||||
StringDt version = securityLabel.getVersion();
|
|
||||||
if (version != null && ! version.isEmpty())
|
|
||||||
writeOptionalTagWithTextNode(theEventWriter, "version", version.getValueAsString());
|
|
||||||
*/
|
|
||||||
theEventWriter.writeEnd(); //end the individual security label
|
|
||||||
}
|
}
|
||||||
theEventWriter.writeEnd(); //end security labels array
|
theEventWriter.writeEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tags != null && tags.isEmpty() == false) {
|
||||||
|
theEventWriter.writeStartArray("tag");
|
||||||
|
for (Tag tag : tags) {
|
||||||
|
theEventWriter.writeStartObject();
|
||||||
|
writeOptionalTagWithTextNode(theEventWriter, "system", tag.getScheme());
|
||||||
|
writeOptionalTagWithTextNode(theEventWriter, "code", tag.getTerm());
|
||||||
|
writeOptionalTagWithTextNode(theEventWriter, "display", tag.getLabel());
|
||||||
|
theEventWriter.writeEnd();
|
||||||
|
}
|
||||||
|
theEventWriter.writeEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
theEventWriter.writeEnd(); // end meta
|
theEventWriter.writeEnd(); // end meta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theResource instanceof BaseBinary) {
|
if (theResource instanceof IBaseBinary) {
|
||||||
BaseBinary bin = (BaseBinary) theResource;
|
IBaseBinary bin = (IBaseBinary) theResource;
|
||||||
theEventWriter.write("contentType", bin.getContentType());
|
theEventWriter.write("contentType", bin.getContentType());
|
||||||
theEventWriter.write("content", bin.getContentAsBase64());
|
theEventWriter.write("content", bin.getContentAsBase64());
|
||||||
} else {
|
} else {
|
||||||
encodeCompositeElementToStreamWriter(theResDef, theResource, theResource, theEventWriter, resDef, theIsSubElementWithinResource);
|
encodeCompositeElementToStreamWriter(theResDef, theResource, theResource, theEventWriter, resDef, theContainedResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
theEventWriter.writeEnd();
|
theEventWriter.writeEnd();
|
||||||
@ -1128,30 +1144,30 @@ public class JsonParser extends BaseParser implements IParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseExtensionInDstu2Style(boolean theModifier, ParserState<?> theState, String theParentExtensionUrl, String theExtensionUrl, JsonArray theValues) {
|
// private void parseExtensionInDstu2Style(boolean theModifier, ParserState<?> theState, String theParentExtensionUrl, String theExtensionUrl, JsonArray theValues) {
|
||||||
String extUrl = UrlUtil.constructAbsoluteUrl(theParentExtensionUrl, theExtensionUrl);
|
// String extUrl = UrlUtil.constructAbsoluteUrl(theParentExtensionUrl, theExtensionUrl);
|
||||||
theState.enteringNewElementExtension(null, extUrl, theModifier);
|
// theState.enteringNewElementExtension(null, extUrl, theModifier);
|
||||||
|
//
|
||||||
for (int extIdx = 0; extIdx < theValues.size(); extIdx++) {
|
// for (int extIdx = 0; extIdx < theValues.size(); extIdx++) {
|
||||||
JsonObject nextExt = theValues.getJsonObject(extIdx);
|
// JsonObject nextExt = theValues.getJsonObject(extIdx);
|
||||||
for (String nextKey : nextExt.keySet()) {
|
// for (String nextKey : nextExt.keySet()) {
|
||||||
// if (nextKey.startsWith("value") && nextKey.length() > 5 &&
|
// // if (nextKey.startsWith("value") && nextKey.length() > 5 &&
|
||||||
// myContext.getRuntimeChildUndeclaredExtensionDefinition().getChildByName(nextKey) != null) {
|
// // myContext.getRuntimeChildUndeclaredExtensionDefinition().getChildByName(nextKey) != null) {
|
||||||
JsonValue jsonVal = nextExt.get(nextKey);
|
// JsonValue jsonVal = nextExt.get(nextKey);
|
||||||
if (jsonVal.getValueType() == ValueType.ARRAY) {
|
// if (jsonVal.getValueType() == ValueType.ARRAY) {
|
||||||
/*
|
// /*
|
||||||
* Extension children which are arrays are sub-extensions. Any other value type should be treated as a value.
|
// * Extension children which are arrays are sub-extensions. Any other value type should be treated as a value.
|
||||||
*/
|
// */
|
||||||
JsonArray arrayValue = (JsonArray) jsonVal;
|
// JsonArray arrayValue = (JsonArray) jsonVal;
|
||||||
parseExtensionInDstu2Style(theModifier, theState, extUrl, nextKey, arrayValue);
|
// parseExtensionInDstu2Style(theModifier, theState, extUrl, nextKey, arrayValue);
|
||||||
} else {
|
// } else {
|
||||||
parseChildren(theState, nextKey, jsonVal, null, null);
|
// parseChildren(theState, nextKey, jsonVal, null, null);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
theState.endingElement();
|
// theState.endingElement();
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends IBaseResource> T doParseResource(Class<T> theResourceType, Reader theReader) {
|
public <T extends IBaseResource> T doParseResource(Class<T> theResourceType, Reader theReader) {
|
||||||
|
@ -20,17 +20,17 @@ package ca.uhn.fhir.parser;
|
|||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.*;
|
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
|
||||||
|
|
||||||
import javax.xml.namespace.QName;
|
import javax.xml.namespace.QName;
|
||||||
import javax.xml.stream.FactoryConfigurationError;
|
import javax.xml.stream.FactoryConfigurationError;
|
||||||
@ -46,13 +46,12 @@ import javax.xml.stream.events.Namespace;
|
|||||||
import javax.xml.stream.events.StartElement;
|
import javax.xml.stream.events.StartElement;
|
||||||
import javax.xml.stream.events.XMLEvent;
|
import javax.xml.stream.events.XMLEvent;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
|
||||||
import ca.uhn.fhir.model.primitive.*;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.hl7.fhir.instance.model.IBase;
|
import org.hl7.fhir.instance.model.IBase;
|
||||||
import org.hl7.fhir.instance.model.IBaseResource;
|
import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.IPrimitiveType;
|
import org.hl7.fhir.instance.model.IPrimitiveType;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseBinary;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseExtension;
|
import org.hl7.fhir.instance.model.api.IBaseExtension;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
|
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
|
||||||
@ -73,20 +72,22 @@ import ca.uhn.fhir.context.RuntimeChildUndeclaredExtensionDefinition;
|
|||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.api.BundleEntry;
|
import ca.uhn.fhir.model.api.BundleEntry;
|
||||||
import ca.uhn.fhir.model.api.ExtensionDt;
|
|
||||||
import ca.uhn.fhir.model.api.IElement;
|
|
||||||
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
|
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
|
||||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
import ca.uhn.fhir.model.api.Tag;
|
import ca.uhn.fhir.model.api.Tag;
|
||||||
import ca.uhn.fhir.model.api.TagList;
|
import ca.uhn.fhir.model.api.TagList;
|
||||||
|
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
|
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
|
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseBinary;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.XhtmlDt;
|
||||||
import ca.uhn.fhir.narrative.INarrativeGenerator;
|
import ca.uhn.fhir.narrative.INarrativeGenerator;
|
||||||
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
|
import ca.uhn.fhir.util.ElementUtil;
|
||||||
import ca.uhn.fhir.util.NonPrettyPrintWriterWrapper;
|
import ca.uhn.fhir.util.NonPrettyPrintWriterWrapper;
|
||||||
import ca.uhn.fhir.util.PrettyPrintWriterWrapper;
|
import ca.uhn.fhir.util.PrettyPrintWriterWrapper;
|
||||||
import ca.uhn.fhir.util.XmlUtil;
|
import ca.uhn.fhir.util.XmlUtil;
|
||||||
@ -245,12 +246,12 @@ public class XmlParser extends BaseParser implements IParser {
|
|||||||
writeTagWithTextNode(eventWriter, "title", theBundle.getTitle());
|
writeTagWithTextNode(eventWriter, "title", theBundle.getTitle());
|
||||||
writeTagWithTextNode(eventWriter, "id", theBundle.getBundleId());
|
writeTagWithTextNode(eventWriter, "id", theBundle.getBundleId());
|
||||||
|
|
||||||
writeAtomLink(eventWriter, "self", theBundle.getLinkSelf());
|
writeAtomLink(eventWriter, Constants.LINK_SELF, theBundle.getLinkSelf());
|
||||||
writeAtomLink(eventWriter, "first", theBundle.getLinkFirst());
|
writeAtomLink(eventWriter, Constants.LINK_FIRST, theBundle.getLinkFirst());
|
||||||
writeAtomLink(eventWriter, "previous", theBundle.getLinkPrevious());
|
writeAtomLink(eventWriter, Constants.LINK_PREVIOUS, theBundle.getLinkPrevious());
|
||||||
writeAtomLink(eventWriter, "next", theBundle.getLinkNext());
|
writeAtomLink(eventWriter, Constants.LINK_NEXT, theBundle.getLinkNext());
|
||||||
writeAtomLink(eventWriter, "last", theBundle.getLinkLast());
|
writeAtomLink(eventWriter, Constants.LINK_LAST, theBundle.getLinkLast());
|
||||||
writeAtomLink(eventWriter, "fhir-base", theBundle.getLinkBase());
|
writeAtomLink(eventWriter, Constants.LINK_FHIR_BASE, theBundle.getLinkBase());
|
||||||
|
|
||||||
if (theBundle.getTotalResults().getValue() != null) {
|
if (theBundle.getTotalResults().getValue() != null) {
|
||||||
eventWriter.writeStartElement("os", "totalResults", OPENSEARCH_NS);
|
eventWriter.writeStartElement("os", "totalResults", OPENSEARCH_NS);
|
||||||
@ -412,9 +413,9 @@ public class XmlParser extends BaseParser implements IParser {
|
|||||||
// IResource nextResource = nextEntry.getResource();
|
// IResource nextResource = nextEntry.getResource();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextEntry.getTransactionOperation().isEmpty() == false || nextEntry.getLinkSearch().isEmpty() == false) {
|
if (nextEntry.getTransactionMethod().isEmpty() == false || nextEntry.getLinkSearch().isEmpty() == false) {
|
||||||
theEventWriter.writeStartElement("transaction");
|
theEventWriter.writeStartElement("transaction");
|
||||||
writeOptionalTagWithValue(theEventWriter, "operation", nextEntry.getTransactionOperation().getValue());
|
writeOptionalTagWithValue(theEventWriter, "method", nextEntry.getTransactionMethod().getValue());
|
||||||
writeOptionalTagWithValue(theEventWriter, "url", nextEntry.getLinkSearch().getValue());
|
writeOptionalTagWithValue(theEventWriter, "url", nextEntry.getLinkSearch().getValue());
|
||||||
theEventWriter.writeEndElement();
|
theEventWriter.writeEndElement();
|
||||||
}
|
}
|
||||||
@ -733,69 +734,56 @@ public class XmlParser extends BaseParser implements IParser {
|
|||||||
// HL7.org Structures
|
// HL7.org Structures
|
||||||
encodeCompositeElementToStreamWriter(theResource, theResource, theEventWriter, resDef, theContainedResource);
|
encodeCompositeElementToStreamWriter(theResource, theResource, theEventWriter, resDef, theContainedResource);
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
||||||
|
|
||||||
// DSTU2+
|
// DSTU2+
|
||||||
|
|
||||||
|
|
||||||
IResource resource = (IResource) theResource;
|
IResource resource = (IResource) theResource;
|
||||||
writeOptionalTagWithValue(theEventWriter, "id", theResourceId);
|
writeOptionalTagWithValue(theEventWriter, "id", theResourceId);
|
||||||
|
|
||||||
|
|
||||||
InstantDt updated = (InstantDt) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED);
|
InstantDt updated = (InstantDt) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED);
|
||||||
//Object securityLabelRawObj = resource.getResourceMetadata().get(ResourceMetadataKeyEnum.SECURITY_LABELS);
|
|
||||||
List<BaseCodingDt> securityLabels = (List<BaseCodingDt>) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.SECURITY_LABELS);
|
|
||||||
IdDt resourceId = resource.getId();
|
IdDt resourceId = resource.getId();
|
||||||
if (resourceId != null && isNotBlank(resourceId.getVersionIdPart())
|
|
||||||
|| (updated != null && !updated.isEmpty())
|
|
||||||
|| (securityLabels != null && !securityLabels.isEmpty())) {
|
|
||||||
theEventWriter.writeStartElement("meta");
|
|
||||||
String versionIdPart = resourceId.getVersionIdPart();
|
String versionIdPart = resourceId.getVersionIdPart();
|
||||||
if (isBlank(versionIdPart)) {
|
if (isBlank(versionIdPart)) {
|
||||||
versionIdPart = ResourceMetadataKeyEnum.VERSION.get(resource);
|
versionIdPart = ResourceMetadataKeyEnum.VERSION.get(resource);
|
||||||
}
|
}
|
||||||
|
List<BaseCodingDt> securityLabels = extractMetadataListNotNull(resource, ResourceMetadataKeyEnum.SECURITY_LABELS);
|
||||||
|
List<IdDt> profiles = extractMetadataListNotNull(resource, ResourceMetadataKeyEnum.PROFILES);
|
||||||
|
TagList tags = ResourceMetadataKeyEnum.TAG_LIST.get(resource);
|
||||||
|
if (ElementUtil.isEmpty(versionIdPart, updated, securityLabels, profiles) == false) {
|
||||||
|
theEventWriter.writeStartElement("meta");
|
||||||
writeOptionalTagWithValue(theEventWriter, "versionId", versionIdPart);
|
writeOptionalTagWithValue(theEventWriter, "versionId", versionIdPart);
|
||||||
if (updated != null) {
|
if (updated != null) {
|
||||||
writeOptionalTagWithValue(theEventWriter, "lastUpdated", updated.getValueAsString());
|
writeOptionalTagWithValue(theEventWriter, "lastUpdated", updated.getValueAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (securityLabels != null) {
|
for (IdDt profile : profiles) {
|
||||||
|
theEventWriter.writeStartElement("profile");
|
||||||
if (!securityLabels.isEmpty()) {
|
theEventWriter.writeAttribute("value", profile.getValue());
|
||||||
|
theEventWriter.writeEndElement();
|
||||||
|
}
|
||||||
for (BaseCodingDt securityLabel : securityLabels) {
|
for (BaseCodingDt securityLabel : securityLabels) {
|
||||||
theEventWriter.writeStartElement("security");
|
theEventWriter.writeStartElement("security");
|
||||||
|
BaseRuntimeElementCompositeDefinition<?> def = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(securityLabel.getClass());
|
||||||
UriDt system = securityLabel.getSystemElement();
|
encodeCompositeElementChildrenToStreamWriter(resource, securityLabel, theEventWriter, def.getChildren(), theContainedResource);
|
||||||
if (system != null && !system.isEmpty())
|
|
||||||
writeOptionalTagWithValue(theEventWriter, "system", system.getValueAsString());
|
|
||||||
|
|
||||||
CodeDt code = securityLabel.getCodeElement();
|
|
||||||
if (code != null && !code.isEmpty())
|
|
||||||
writeOptionalTagWithValue(theEventWriter, "code", code.getValueAsString());
|
|
||||||
|
|
||||||
StringDt display = securityLabel.getDisplayElement();
|
|
||||||
if (display != null && !display.isEmpty())
|
|
||||||
writeOptionalTagWithValue(theEventWriter, "display", display.getValueAsString());
|
|
||||||
|
|
||||||
/*todo: handle version
|
|
||||||
StringDt version = securityLabel.getVersion();
|
|
||||||
if (version != null && ! version.isEmpty())
|
|
||||||
writeOptionalTagWithValue(theEventWriter, "version", version.getValueAsString());
|
|
||||||
*/
|
|
||||||
theEventWriter.writeEndElement();
|
theEventWriter.writeEndElement();
|
||||||
}
|
}
|
||||||
|
if (tags != null) {
|
||||||
|
for (Tag tag : tags) {
|
||||||
|
theEventWriter.writeStartElement("tag");
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "system", tag.getScheme());
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "code", tag.getTerm());
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "display", tag.getLabel());
|
||||||
|
theEventWriter.writeEndElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
theEventWriter.writeEndElement();
|
theEventWriter.writeEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theResource instanceof BaseBinary) {
|
if (theResource instanceof IBaseBinary) {
|
||||||
BaseBinary bin = (BaseBinary) theResource;
|
IBaseBinary bin = (IBaseBinary) theResource;
|
||||||
writeOptionalTagWithValue(theEventWriter, "contentType", bin.getContentType());
|
writeOptionalTagWithValue(theEventWriter, "contentType", bin.getContentType());
|
||||||
writeOptionalTagWithValue(theEventWriter, "content", bin.getContentAsBase64());
|
writeOptionalTagWithValue(theEventWriter, "content", bin.getContentAsBase64());
|
||||||
} else {
|
} else {
|
||||||
@ -809,8 +797,8 @@ public class XmlParser extends BaseParser implements IParser {
|
|||||||
theEventWriter.writeAttribute("id", theResourceId);
|
theEventWriter.writeAttribute("id", theResourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theResource instanceof BaseBinary) {
|
if (theResource instanceof IBaseBinary) {
|
||||||
BaseBinary bin = (BaseBinary) theResource;
|
IBaseBinary bin = (IBaseBinary) theResource;
|
||||||
if (bin.getContentType() != null) {
|
if (bin.getContentType() != null) {
|
||||||
theEventWriter.writeAttribute("contentType", bin.getContentType());
|
theEventWriter.writeAttribute("contentType", bin.getContentType());
|
||||||
}
|
}
|
||||||
|
@ -30,10 +30,19 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
*/
|
*/
|
||||||
public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
||||||
|
|
||||||
|
private String myServletPath;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest) {
|
public String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest) {
|
||||||
String requestFullPath = StringUtils.defaultString(theRequest.getRequestURI());
|
String requestFullPath = StringUtils.defaultString(theRequest.getRequestURI());
|
||||||
String servletPath = StringUtils.defaultString(theRequest.getServletPath());
|
|
||||||
|
String servletPath;
|
||||||
|
if (myServletPath != null) {
|
||||||
|
servletPath = myServletPath;
|
||||||
|
} else {
|
||||||
|
servletPath = StringUtils.defaultString(theRequest.getServletPath());
|
||||||
|
}
|
||||||
|
|
||||||
StringBuffer requestUrl = theRequest.getRequestURL();
|
StringBuffer requestUrl = theRequest.getRequestURL();
|
||||||
String servletContextPath = "";
|
String servletContextPath = "";
|
||||||
if (theServletContext != null) {
|
if (theServletContext != null) {
|
||||||
@ -48,7 +57,9 @@ public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int startOfPath = requestUrl.indexOf("//");
|
int startOfPath = requestUrl.indexOf("//");
|
||||||
if (startOfPath != -1 && (startOfPath + 2) < requestUrl.length()) {
|
int requestUrlLength = requestUrl.length();
|
||||||
|
|
||||||
|
if (startOfPath != -1 && (startOfPath + 2) < requestUrlLength) {
|
||||||
startOfPath = requestUrl.indexOf("/", startOfPath + 2);
|
startOfPath = requestUrl.indexOf("/", startOfPath + 2);
|
||||||
}
|
}
|
||||||
if (startOfPath == -1) {
|
if (startOfPath == -1) {
|
||||||
@ -56,9 +67,9 @@ public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int contextIndex;
|
int contextIndex;
|
||||||
if (servletPath.length() == 0) {
|
if (servletPath.length() == 0 || servletPath.equals("/")) {
|
||||||
if (requestPath.length() == 0) {
|
if (requestPath.length() == 0) {
|
||||||
contextIndex = requestUrl.length();
|
contextIndex = requestUrlLength;
|
||||||
} else {
|
} else {
|
||||||
contextIndex = requestUrl.indexOf(requestPath, startOfPath);
|
contextIndex = requestUrl.indexOf(requestPath, startOfPath);
|
||||||
}
|
}
|
||||||
@ -68,8 +79,30 @@ public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
|||||||
|
|
||||||
String fhirServerBase;
|
String fhirServerBase;
|
||||||
int length = contextIndex + servletPath.length();
|
int length = contextIndex + servletPath.length();
|
||||||
|
if (length > requestUrlLength) {
|
||||||
|
length = requestUrlLength;
|
||||||
|
}
|
||||||
fhirServerBase = requestUrl.substring(0, length);
|
fhirServerBase = requestUrl.substring(0, length);
|
||||||
return fhirServerBase;
|
return fhirServerBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set to a non-null value (default is <code>null</code>), this address strategy assumes that the FHIR endpoint is deployed to the given servlet path within the context. This is useful in some
|
||||||
|
* deployments where it isn't obvious to the servlet which part of the path is actually the root path to reach the servlet.
|
||||||
|
* <p>
|
||||||
|
* Example values could be:
|
||||||
|
* <ul>
|
||||||
|
* <li>null</li>
|
||||||
|
* <li>/</li>
|
||||||
|
* <li>/base</li>
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* <b>Wildcards are not supported!</b>
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public void setServletPath(String theServletPath) {
|
||||||
|
myServletPath = theServletPath;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,18 +7,16 @@ import javax.servlet.ServletContext;
|
|||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.web.context.ContextLoaderListener;
|
import org.springframework.web.context.ContextLoaderListener;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
||||||
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
|
|
||||||
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu1;
|
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu1;
|
||||||
|
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
|
||||||
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu1;
|
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu1;
|
||||||
|
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
|
||||||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||||
import ca.uhn.fhir.rest.server.ETagSupportEnum;
|
import ca.uhn.fhir.rest.server.ETagSupportEnum;
|
||||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||||
@ -26,7 +24,7 @@ import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
|
|||||||
import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy;
|
import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy;
|
||||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
|
|
||||||
public class TestRestfulServer extends RestfulServer {
|
public class TestRestfulServer extends RestfulServer {
|
||||||
|
|
||||||
@ -165,18 +163,12 @@ public class TestRestfulServer extends RestfulServer {
|
|||||||
setPagingProvider(new FifoMemoryPagingProvider(10));
|
setPagingProvider(new FifoMemoryPagingProvider(10));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do some fancy logging to create a nice access log that has details
|
* Load interceptors for the server from Spring (these are defined in hapi-fhir-server-config.xml
|
||||||
* about each incoming request.
|
|
||||||
*/
|
*/
|
||||||
List<IServerInterceptor> interceptorBeans = myAppCtx.getBean("myServerInterceptors", List.class);
|
List<IServerInterceptor> interceptorBeans = myAppCtx.getBean("myServerInterceptors", List.class);
|
||||||
for (IServerInterceptor interceptor : interceptorBeans)
|
for (IServerInterceptor interceptor : interceptorBeans) {
|
||||||
this.registerInterceptor(interceptor);
|
this.registerInterceptor(interceptor);
|
||||||
|
}
|
||||||
/*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);
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,11 @@
|
|||||||
<util:list id="myServerInterceptors">
|
<util:list id="myServerInterceptors">
|
||||||
<ref bean="myLoggingInterceptor"/>
|
<ref bean="myLoggingInterceptor"/>
|
||||||
</util:list>
|
</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">
|
<bean id="myLoggingInterceptor" class="ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor">
|
||||||
<property name="loggerName" value="fhirtest.access"/>
|
<property name="loggerName" value="fhirtest.access"/>
|
||||||
<property name="messageFormat"
|
<property name="messageFormat"
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package ca.uhn.fhir.rest.server;
|
package ca.uhn.fhir.rest.server;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -24,8 +25,6 @@ import org.junit.Before;
|
|||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.rest.server.ServerBaseTest.DummyProvider;
|
|
||||||
import ca.uhn.fhir.util.RandomServerPortProvider;
|
import ca.uhn.fhir.util.RandomServerPortProvider;
|
||||||
|
|
||||||
public class IncomingRequestAddressStrategyTest {
|
public class IncomingRequestAddressStrategyTest {
|
||||||
@ -99,9 +98,33 @@ public class IncomingRequestAddressStrategyTest {
|
|||||||
|
|
||||||
startServer(port, contextPath, 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);
|
httpGet("http://localhost:" + port);
|
||||||
assertEquals(null, ourLastBase);
|
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");
|
httpGet("http://localhost:" + port + "/ctx");
|
||||||
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
|
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
|
||||||
|
|
||||||
@ -113,6 +136,37 @@ public class IncomingRequestAddressStrategyTest {
|
|||||||
|
|
||||||
httpGet("http://localhost:" + port + "/ctx/Patient/123/_history/222");
|
httpGet("http://localhost:" + port + "/ctx/Patient/123/_history/222");
|
||||||
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
|
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
|
@Test
|
||||||
@ -168,6 +222,9 @@ public class IncomingRequestAddressStrategyTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest theReq, HttpServletResponse theResp) throws ServletException, IOException {
|
protected void doGet(HttpServletRequest theReq, HttpServletResponse theResp) throws ServletException, IOException {
|
||||||
|
|
||||||
|
// ourLog.info("Ctx: {}", theReq.)
|
||||||
|
|
||||||
ourLastBase = ourStrategy.determineServerBase(getServletContext(), theReq);
|
ourLastBase = ourStrategy.determineServerBase(getServletContext(), theReq);
|
||||||
theResp.setContentType("text/plain");
|
theResp.setContentType("text/plain");
|
||||||
theResp.getWriter().append("Success");
|
theResp.getWriter().append("Success");
|
||||||
|
@ -49,7 +49,9 @@ public class HomeRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (retVal.contains("${serverBase}")) {
|
if (retVal.contains("${serverBase}")) {
|
||||||
String base = new IncomingRequestAddressStrategy().determineServerBase(theRequest.getServletContext(), theRequest);
|
IncomingRequestAddressStrategy strategy = new IncomingRequestAddressStrategy();
|
||||||
|
strategy.setServletPath("");
|
||||||
|
String base = strategy.determineServerBase(theRequest.getServletContext(), theRequest);
|
||||||
if (base.endsWith("/")) {
|
if (base.endsWith("/")) {
|
||||||
base = base.substring(0, base.length() - 1);
|
base = base.substring(0, base.length() - 1);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user