Merge remote-tracking branch 'remotes/origin/master' into ks-20200120-near-search
This commit is contained in:
commit
f2e8037c90
|
@ -22,16 +22,25 @@ package ca.uhn.fhir.parser;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.*;
|
import ca.uhn.fhir.context.*;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeChildDefinition.IMutator;
|
import ca.uhn.fhir.context.BaseRuntimeChildDefinition.IMutator;
|
||||||
import ca.uhn.fhir.model.api.*;
|
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||||
|
import ca.uhn.fhir.model.api.IElement;
|
||||||
|
import ca.uhn.fhir.model.api.IIdentifiableElement;
|
||||||
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
|
||||||
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
|
import ca.uhn.fhir.model.api.Tag;
|
||||||
|
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.BaseResourceReferenceDt;
|
|
||||||
import ca.uhn.fhir.model.base.resource.ResourceMetadataMap;
|
import ca.uhn.fhir.model.base.resource.ResourceMetadataMap;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
import ca.uhn.fhir.model.primitive.XhtmlDt;
|
import ca.uhn.fhir.model.primitive.XhtmlDt;
|
||||||
import ca.uhn.fhir.parser.json.JsonLikeValue.ScalarType;
|
import ca.uhn.fhir.parser.json.JsonLikeValue.ScalarType;
|
||||||
import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType;
|
import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType;
|
||||||
import ca.uhn.fhir.util.*;
|
import ca.uhn.fhir.util.BundleUtil;
|
||||||
|
import ca.uhn.fhir.util.FhirTerser;
|
||||||
|
import ca.uhn.fhir.util.ReflectionUtil;
|
||||||
|
import ca.uhn.fhir.util.XmlUtil;
|
||||||
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.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
@ -39,9 +48,17 @@ import org.hl7.fhir.instance.model.api.*;
|
||||||
|
|
||||||
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 java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.*;
|
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
|
||||||
|
|
||||||
class ParserState<T> {
|
class ParserState<T> {
|
||||||
|
|
||||||
|
@ -54,6 +71,8 @@ class ParserState<T> {
|
||||||
private T myObject;
|
private T myObject;
|
||||||
private IBase myPreviousElement;
|
private IBase myPreviousElement;
|
||||||
private BaseState myState;
|
private BaseState myState;
|
||||||
|
private List<IBaseResource> myGlobalResources = new ArrayList<>();
|
||||||
|
private List<IBaseReference> myGlobalReferences = new ArrayList<>();
|
||||||
|
|
||||||
private ParserState(IParser theParser, FhirContext theContext, boolean theJsonMode, IParserErrorHandler theErrorHandler) {
|
private ParserState(IParser theParser, FhirContext theContext, boolean theJsonMode, IParserErrorHandler theErrorHandler) {
|
||||||
myParser = theParser;
|
myParser = theParser;
|
||||||
|
@ -130,7 +149,6 @@ class ParserState<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void string(String theData) {
|
public void string(String theData) {
|
||||||
myState.string(theData);
|
myState.string(theData);
|
||||||
}
|
}
|
||||||
|
@ -145,6 +163,60 @@ class ParserState<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IBase newInstance(RuntimeChildDeclaredExtensionDefinition theDefinition) {
|
||||||
|
return theDefinition.newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICompositeType newCompositeInstance(PreResourceState thePreResourceState, BaseRuntimeChildDefinition theChild, BaseRuntimeElementCompositeDefinition<?> theCompositeTarget) {
|
||||||
|
ICompositeType retVal = (ICompositeType) theCompositeTarget.newInstance(theChild.getInstanceConstructorArguments());
|
||||||
|
if (retVal instanceof IBaseReference) {
|
||||||
|
IBaseReference ref = (IBaseReference) retVal;
|
||||||
|
myGlobalReferences.add(ref);
|
||||||
|
thePreResourceState.getLocalReferences().add(ref);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICompositeType newCompositeTypeInstance(PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition<?> theCompositeTarget) {
|
||||||
|
ICompositeType retVal = (ICompositeType) theCompositeTarget.newInstance();
|
||||||
|
if (retVal instanceof IBaseReference) {
|
||||||
|
IBaseReference ref = (IBaseReference) retVal;
|
||||||
|
myGlobalReferences.add(ref);
|
||||||
|
thePreResourceState.getLocalReferences().add(ref);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPrimitiveType<?> newPrimitiveInstance(RuntimeChildDeclaredExtensionDefinition theDefinition, RuntimePrimitiveDatatypeDefinition thePrimitiveTarget) {
|
||||||
|
return thePrimitiveTarget.newInstance(theDefinition.getInstanceConstructorArguments());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPrimitiveType<?> getPrimitiveInstance(BaseRuntimeChildDefinition theChild, RuntimePrimitiveDatatypeDefinition thePrimitiveTarget) {
|
||||||
|
return thePrimitiveTarget.newInstance(theChild.getInstanceConstructorArguments());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBaseXhtml newInstance(RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition theXhtmlTarget) {
|
||||||
|
return theXhtmlTarget.newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public XhtmlDt newInstance(RuntimePrimitiveDatatypeNarrativeDefinition theXhtmlTarget) {
|
||||||
|
return theXhtmlTarget.newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPrimitiveType<?> newInstance(RuntimePrimitiveDatatypeDefinition thePrimitiveTarget) {
|
||||||
|
return thePrimitiveTarget.newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBaseResource newInstance(RuntimeResourceDefinition theDef) {
|
||||||
|
IBaseResource retVal = theDef.newInstance();
|
||||||
|
myGlobalResources.add(retVal);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBase newInstance(RuntimeResourceBlockDefinition theBlockTarget) {
|
||||||
|
return theBlockTarget.newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
private abstract class BaseState {
|
private abstract class BaseState {
|
||||||
|
|
||||||
private PreResourceState myPreResourceState;
|
private PreResourceState myPreResourceState;
|
||||||
|
@ -256,7 +328,7 @@ class ParserState<T> {
|
||||||
private class ContainedResourcesStateHapi extends PreResourceState {
|
private class ContainedResourcesStateHapi extends PreResourceState {
|
||||||
|
|
||||||
public ContainedResourcesStateHapi(PreResourceState thePreResourcesState) {
|
public ContainedResourcesStateHapi(PreResourceState thePreResourcesState) {
|
||||||
super(thePreResourcesState, ((IResource) thePreResourcesState.myInstance).getStructureFhirVersionEnum());
|
super(thePreResourcesState, thePreResourcesState.myInstance.getStructureFhirVersionEnum());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -290,7 +362,6 @@ class ParserState<T> {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<IResource> containedResources = (List<IResource>) preResCurrentElement.getContained().getContainedResources();
|
List<IResource> containedResources = (List<IResource>) preResCurrentElement.getContained().getContainedResources();
|
||||||
containedResources.add(res);
|
containedResources.add(res);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -374,7 +445,7 @@ class ParserState<T> {
|
||||||
switch (target.getChildType()) {
|
switch (target.getChildType()) {
|
||||||
case COMPOSITE_DATATYPE: {
|
case COMPOSITE_DATATYPE: {
|
||||||
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
||||||
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance(myDefinition.getInstanceConstructorArguments());
|
ICompositeType newChildInstance = newCompositeInstance(getPreResourceState(), myDefinition, compositeTarget);
|
||||||
myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
|
myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
|
||||||
ElementCompositeState newState = new ElementCompositeState(myPreResourceState, theLocalPart, compositeTarget, newChildInstance);
|
ElementCompositeState newState = new ElementCompositeState(myPreResourceState, theLocalPart, compositeTarget, newChildInstance);
|
||||||
push(newState);
|
push(newState);
|
||||||
|
@ -383,7 +454,7 @@ class ParserState<T> {
|
||||||
case ID_DATATYPE:
|
case ID_DATATYPE:
|
||||||
case PRIMITIVE_DATATYPE: {
|
case PRIMITIVE_DATATYPE: {
|
||||||
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
||||||
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance(myDefinition.getInstanceConstructorArguments());
|
IPrimitiveType<?> newChildInstance = newPrimitiveInstance(myDefinition, primitiveTarget);
|
||||||
myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
|
myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
|
||||||
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
|
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
|
||||||
push(newState);
|
push(newState);
|
||||||
|
@ -404,7 +475,7 @@ class ParserState<T> {
|
||||||
RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition.getChildExtensionForUrl(theUrlAttr);
|
RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition.getChildExtensionForUrl(theUrlAttr);
|
||||||
if (declaredExtension != null) {
|
if (declaredExtension != null) {
|
||||||
if (myChildInstance == null) {
|
if (myChildInstance == null) {
|
||||||
myChildInstance = myDefinition.newInstance();
|
myChildInstance = newInstance(myDefinition);
|
||||||
myDefinition.getMutator().addValue(myParentInstance, myChildInstance);
|
myDefinition.getMutator().addValue(myParentInstance, myChildInstance);
|
||||||
}
|
}
|
||||||
BaseState newState = new DeclaredExtensionState(getPreResourceState(), declaredExtension, myChildInstance);
|
BaseState newState = new DeclaredExtensionState(getPreResourceState(), declaredExtension, myChildInstance);
|
||||||
|
@ -414,6 +485,7 @@ class ParserState<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IBase getCurrentElement() {
|
protected IBase getCurrentElement() {
|
||||||
return myParentInstance;
|
return myParentInstance;
|
||||||
|
@ -501,7 +573,7 @@ class ParserState<T> {
|
||||||
switch (target.getChildType()) {
|
switch (target.getChildType()) {
|
||||||
case COMPOSITE_DATATYPE: {
|
case COMPOSITE_DATATYPE: {
|
||||||
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
||||||
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance(child.getInstanceConstructorArguments());
|
ICompositeType newChildInstance = newCompositeInstance(getPreResourceState(), child, compositeTarget);
|
||||||
child.getMutator().addValue(myInstance, newChildInstance);
|
child.getMutator().addValue(myInstance, newChildInstance);
|
||||||
ParserState<T>.ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), theChildName, compositeTarget, newChildInstance);
|
ParserState<T>.ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), theChildName, compositeTarget, newChildInstance);
|
||||||
push(newState);
|
push(newState);
|
||||||
|
@ -511,7 +583,7 @@ class ParserState<T> {
|
||||||
case PRIMITIVE_DATATYPE: {
|
case PRIMITIVE_DATATYPE: {
|
||||||
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
||||||
IPrimitiveType<?> newChildInstance;
|
IPrimitiveType<?> newChildInstance;
|
||||||
newChildInstance = primitiveTarget.newInstance(child.getInstanceConstructorArguments());
|
newChildInstance = getPrimitiveInstance(child, primitiveTarget);
|
||||||
child.getMutator().addValue(myInstance, newChildInstance);
|
child.getMutator().addValue(myInstance, newChildInstance);
|
||||||
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
|
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
|
||||||
push(newState);
|
push(newState);
|
||||||
|
@ -519,7 +591,7 @@ class ParserState<T> {
|
||||||
}
|
}
|
||||||
case RESOURCE_BLOCK: {
|
case RESOURCE_BLOCK: {
|
||||||
RuntimeResourceBlockDefinition blockTarget = (RuntimeResourceBlockDefinition) target;
|
RuntimeResourceBlockDefinition blockTarget = (RuntimeResourceBlockDefinition) target;
|
||||||
IBase newBlockInstance = blockTarget.newInstance();
|
IBase newBlockInstance = newInstance(blockTarget);
|
||||||
child.getMutator().addValue(myInstance, newBlockInstance);
|
child.getMutator().addValue(myInstance, newBlockInstance);
|
||||||
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), theChildName, blockTarget, newBlockInstance);
|
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), theChildName, blockTarget, newBlockInstance);
|
||||||
push(newState);
|
push(newState);
|
||||||
|
@ -527,7 +599,7 @@ class ParserState<T> {
|
||||||
}
|
}
|
||||||
case PRIMITIVE_XHTML: {
|
case PRIMITIVE_XHTML: {
|
||||||
RuntimePrimitiveDatatypeNarrativeDefinition xhtmlTarget = (RuntimePrimitiveDatatypeNarrativeDefinition) target;
|
RuntimePrimitiveDatatypeNarrativeDefinition xhtmlTarget = (RuntimePrimitiveDatatypeNarrativeDefinition) target;
|
||||||
XhtmlDt newDt = xhtmlTarget.newInstance();
|
XhtmlDt newDt = newInstance(xhtmlTarget);
|
||||||
child.getMutator().addValue(myInstance, newDt);
|
child.getMutator().addValue(myInstance, newDt);
|
||||||
XhtmlState state = new XhtmlState(getPreResourceState(), newDt, true);
|
XhtmlState state = new XhtmlState(getPreResourceState(), newDt, true);
|
||||||
push(state);
|
push(state);
|
||||||
|
@ -535,7 +607,7 @@ class ParserState<T> {
|
||||||
}
|
}
|
||||||
case PRIMITIVE_XHTML_HL7ORG: {
|
case PRIMITIVE_XHTML_HL7ORG: {
|
||||||
RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition xhtmlTarget = (RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition) target;
|
RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition xhtmlTarget = (RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition) target;
|
||||||
IBaseXhtml newDt = xhtmlTarget.newInstance();
|
IBaseXhtml newDt = newInstance(xhtmlTarget);
|
||||||
child.getMutator().addValue(myInstance, newDt);
|
child.getMutator().addValue(myInstance, newDt);
|
||||||
XhtmlStateHl7Org state = new XhtmlStateHl7Org(getPreResourceState(), newDt);
|
XhtmlStateHl7Org state = new XhtmlStateHl7Org(getPreResourceState(), newDt);
|
||||||
push(state);
|
push(state);
|
||||||
|
@ -669,7 +741,7 @@ class ParserState<T> {
|
||||||
switch (target.getChildType()) {
|
switch (target.getChildType()) {
|
||||||
case COMPOSITE_DATATYPE: {
|
case COMPOSITE_DATATYPE: {
|
||||||
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
||||||
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance();
|
ICompositeType newChildInstance = newCompositeTypeInstance(getPreResourceState(), compositeTarget);
|
||||||
myExtension.setValue(newChildInstance);
|
myExtension.setValue(newChildInstance);
|
||||||
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), theLocalPart, compositeTarget, newChildInstance);
|
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), theLocalPart, compositeTarget, newChildInstance);
|
||||||
push(newState);
|
push(newState);
|
||||||
|
@ -678,7 +750,7 @@ class ParserState<T> {
|
||||||
case ID_DATATYPE:
|
case ID_DATATYPE:
|
||||||
case PRIMITIVE_DATATYPE: {
|
case PRIMITIVE_DATATYPE: {
|
||||||
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
||||||
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance();
|
IPrimitiveType<?> newChildInstance = newInstance(primitiveTarget);
|
||||||
myExtension.setValue(newChildInstance);
|
myExtension.setValue(newChildInstance);
|
||||||
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
|
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
|
||||||
push(newState);
|
push(newState);
|
||||||
|
@ -847,10 +919,10 @@ class ParserState<T> {
|
||||||
private abstract class PreResourceState extends BaseState {
|
private abstract class PreResourceState extends BaseState {
|
||||||
|
|
||||||
private Map<String, IBaseResource> myContainedResources;
|
private Map<String, IBaseResource> myContainedResources;
|
||||||
|
private List<IBaseReference> myLocalReferences = new ArrayList<>();
|
||||||
private IBaseResource myInstance;
|
private IBaseResource myInstance;
|
||||||
private FhirVersionEnum myParentVersion;
|
private FhirVersionEnum myParentVersion;
|
||||||
private Class<? extends IBaseResource> myResourceType;
|
private Class<? extends IBaseResource> myResourceType;
|
||||||
|
|
||||||
PreResourceState(Class<? extends IBaseResource> theResourceType) {
|
PreResourceState(Class<? extends IBaseResource> theResourceType) {
|
||||||
super(null);
|
super(null);
|
||||||
myResourceType = theResourceType;
|
myResourceType = theResourceType;
|
||||||
|
@ -869,6 +941,10 @@ class ParserState<T> {
|
||||||
myContainedResources = thePreResourcesState.getContainedResources();
|
myContainedResources = thePreResourcesState.getContainedResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<IBaseReference> getLocalReferences() {
|
||||||
|
return myLocalReferences;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endingElement() throws DataFormatException {
|
public void endingElement() throws DataFormatException {
|
||||||
stitchBundleCrossReferences();
|
stitchBundleCrossReferences();
|
||||||
|
@ -905,10 +981,10 @@ class ParserState<T> {
|
||||||
if (!definition.getName().equals(theLocalPart) && definition.getName().equalsIgnoreCase(theLocalPart)) {
|
if (!definition.getName().equals(theLocalPart) && definition.getName().equalsIgnoreCase(theLocalPart)) {
|
||||||
throw new DataFormatException("Unknown resource type '" + theLocalPart + "': Resource names are case sensitive, found similar name: '" + definition.getName() + "'");
|
throw new DataFormatException("Unknown resource type '" + theLocalPart + "': Resource names are case sensitive, found similar name: '" + definition.getName() + "'");
|
||||||
}
|
}
|
||||||
myInstance = def.newInstance();
|
myInstance = newInstance(def);
|
||||||
|
|
||||||
if (myInstance instanceof IResource) {
|
if (myInstance instanceof IResource) {
|
||||||
push(new ResourceStateHapi(getRootPreResourceState(), def, (IResource) myInstance));
|
push(new ResourceStateHapi(getRootPreResourceState(), def, (IResource) myInstance, myContainedResources));
|
||||||
} else {
|
} else {
|
||||||
push(new ResourceStateHl7Org(getRootPreResourceState(), def, myInstance));
|
push(new ResourceStateHl7Org(getRootPreResourceState(), def, myInstance));
|
||||||
}
|
}
|
||||||
|
@ -996,8 +1072,7 @@ class ParserState<T> {
|
||||||
/*
|
/*
|
||||||
* Stitch together resource references
|
* Stitch together resource references
|
||||||
*/
|
*/
|
||||||
List<IBaseResource> resources = t.getAllPopulatedChildElementsOfType(myInstance, IBaseResource.class);
|
for (IBaseResource next : myGlobalResources) {
|
||||||
for (IBaseResource next : resources) {
|
|
||||||
IIdType id = next.getIdElement();
|
IIdType id = next.getIdElement();
|
||||||
if (id != null && id.isEmpty() == false) {
|
if (id != null && id.isEmpty() == false) {
|
||||||
String resName = myContext.getResourceDefinition(next).getName();
|
String resName = myContext.getResourceDefinition(next).getName();
|
||||||
|
@ -1006,15 +1081,12 @@ class ParserState<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IBaseResource next : resources) {
|
for (IBaseReference nextRef : myGlobalReferences) {
|
||||||
List<IBaseReference> refs = myContext.newTerser().getAllPopulatedChildElementsOfType(next, IBaseReference.class);
|
if (nextRef.isEmpty() == false && nextRef.getReferenceElement() != null) {
|
||||||
for (IBaseReference nextRef : refs) {
|
IIdType unqualifiedVersionless = nextRef.getReferenceElement().toUnqualifiedVersionless();
|
||||||
if (nextRef.isEmpty() == false && nextRef.getReferenceElement() != null) {
|
IBaseResource target = idToResource.get(unqualifiedVersionless.getValueAsString());
|
||||||
IIdType unqualifiedVersionless = nextRef.getReferenceElement().toUnqualifiedVersionless();
|
if (target != null) {
|
||||||
IBaseResource target = idToResource.get(unqualifiedVersionless.getValueAsString());
|
nextRef.setResource(target);
|
||||||
if (target != null) {
|
|
||||||
nextRef.setResource(target);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1035,43 +1107,21 @@ class ParserState<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void weaveContainedResources() {
|
void weaveContainedResources() {
|
||||||
FhirTerser terser = myContext.newTerser();
|
for (IBaseReference nextRef : myLocalReferences) {
|
||||||
terser.visit(myInstance, new IModelVisitor() {
|
String ref = nextRef.getReferenceElement().getValue();
|
||||||
|
if (isNotBlank(ref)) {
|
||||||
@Override
|
if (ref.startsWith("#")) {
|
||||||
public void acceptElement(IBaseResource theResource, IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition,
|
IBaseResource target = myContainedResources.get(ref);
|
||||||
BaseRuntimeElementDefinition<?> theDefinition) {
|
if (target != null) {
|
||||||
if (theElement instanceof BaseResourceReferenceDt) {
|
ourLog.debug("Resource contains local ref {}", ref);
|
||||||
BaseResourceReferenceDt nextRef = (BaseResourceReferenceDt) theElement;
|
nextRef.setResource(target);
|
||||||
String ref = nextRef.getReference().getValue();
|
} else {
|
||||||
if (isNotBlank(ref)) {
|
myErrorHandler.unknownReference(null, ref);
|
||||||
if (ref.startsWith("#")) {
|
|
||||||
IResource target = (IResource) myContainedResources.get(ref);
|
|
||||||
if (target != null) {
|
|
||||||
ourLog.debug("Resource contains local ref {} in field {}", ref, thePathToElement);
|
|
||||||
nextRef.setResource(target);
|
|
||||||
} else {
|
|
||||||
myErrorHandler.unknownReference(null, ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (theElement instanceof IBaseReference) {
|
|
||||||
IBaseReference nextRef = (IBaseReference) theElement;
|
|
||||||
String ref = nextRef.getReferenceElement().getValue();
|
|
||||||
if (isNotBlank(ref)) {
|
|
||||||
if (ref.startsWith("#")) {
|
|
||||||
IBaseResource target = myContainedResources.get(ref);
|
|
||||||
if (target != null) {
|
|
||||||
ourLog.debug("Resource contains local ref {} in field {}", ref, thePathToElement);
|
|
||||||
nextRef.setResource(target);
|
|
||||||
} else {
|
|
||||||
myErrorHandler.unknownReference(null, ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1284,7 +1334,7 @@ class ParserState<T> {
|
||||||
|
|
||||||
private IResource myInstance;
|
private IResource myInstance;
|
||||||
|
|
||||||
public ResourceStateHapi(PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition<?> theDef, IResource theInstance) {
|
public ResourceStateHapi(PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition<?> theDef, IResource theInstance, Map<String, IBaseResource> theContainedResources) {
|
||||||
super(thePreResourceState, theDef.getName(), theDef, theInstance);
|
super(thePreResourceState, theDef.getName(), theDef, theInstance);
|
||||||
myInstance = theInstance;
|
myInstance = theInstance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,9 +181,6 @@ public class XmlParser extends BaseParser {
|
||||||
heldComments.clear();
|
heldComments.clear();
|
||||||
}
|
}
|
||||||
parserState.endingElement();
|
parserState.endingElement();
|
||||||
// if (parserState.isComplete()) {
|
|
||||||
// return parserState.getObject();
|
|
||||||
// }
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case XMLStreamConstants.CHARACTERS: {
|
case XMLStreamConstants.CHARACTERS: {
|
||||||
|
@ -707,12 +704,12 @@ public class XmlParser extends BaseParser {
|
||||||
theEventWriter.writeStartElement(prefix, se.getName().getLocalPart(), namespaceURI);
|
theEventWriter.writeStartElement(prefix, se.getName().getLocalPart(), namespaceURI);
|
||||||
theEventWriter.writeNamespace(prefix, namespaceURI);
|
theEventWriter.writeNamespace(prefix, namespaceURI);
|
||||||
}
|
}
|
||||||
for (Iterator<Attribute> iter= se.getAttributes(); iter.hasNext(); ) {
|
// for (Iterator<Attribute> iter= se.getAttributes(); iter.hasNext(); ) {
|
||||||
Attribute next = iter.next();
|
// Attribute next = iter.next();
|
||||||
if ("lang".equals(next.getName().getLocalPart())) {
|
// if ("lang".equals(next.getName().getLocalPart())) {
|
||||||
theEventWriter.writeAttribute("", "", next.getName().getLocalPart(), next.getValue());
|
// theEventWriter.writeAttribute("", "", next.getName().getLocalPart(), next.getValue());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
firstElement = false;
|
firstElement = false;
|
||||||
} else {
|
} else {
|
||||||
if (isBlank(se.getName().getPrefix())) {
|
if (isBlank(se.getName().getPrefix())) {
|
||||||
|
@ -729,10 +726,10 @@ public class XmlParser extends BaseParser {
|
||||||
} else {
|
} else {
|
||||||
theEventWriter.writeStartElement(se.getName().getPrefix(), se.getName().getLocalPart(), se.getName().getNamespaceURI());
|
theEventWriter.writeStartElement(se.getName().getPrefix(), se.getName().getLocalPart(), se.getName().getNamespaceURI());
|
||||||
}
|
}
|
||||||
for (Iterator<?> attrIter = se.getAttributes(); attrIter.hasNext(); ) {
|
}
|
||||||
Attribute next = (Attribute) attrIter.next();
|
for (Iterator<?> attrIter = se.getAttributes(); attrIter.hasNext(); ) {
|
||||||
theEventWriter.writeAttribute(next.getName().getLocalPart(), next.getValue());
|
Attribute next = (Attribute) attrIter.next();
|
||||||
}
|
theEventWriter.writeAttribute(next.getName().getLocalPart(), next.getValue());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XMLStreamConstants.DTD:
|
case XMLStreamConstants.DTD:
|
||||||
|
|
|
@ -160,7 +160,7 @@ public class FhirTerser {
|
||||||
public <T extends IBase> List<T> getAllPopulatedChildElementsOfType(IBaseResource theResource, final Class<T> theType) {
|
public <T extends IBase> List<T> getAllPopulatedChildElementsOfType(IBaseResource theResource, final Class<T> theType) {
|
||||||
final ArrayList<T> retVal = new ArrayList<>();
|
final ArrayList<T> retVal = new ArrayList<>();
|
||||||
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
||||||
visit(new IdentityHashMap<>(), theResource, theResource, null, null, def, new IModelVisitor() {
|
visit(newMap(), theResource, theResource, null, null, def, new IModelVisitor() {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public void acceptElement(IBaseResource theOuterResource, IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
public void acceptElement(IBaseResource theOuterResource, IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
||||||
|
@ -179,7 +179,7 @@ public class FhirTerser {
|
||||||
public List<ResourceReferenceInfo> getAllResourceReferences(final IBaseResource theResource) {
|
public List<ResourceReferenceInfo> getAllResourceReferences(final IBaseResource theResource) {
|
||||||
final ArrayList<ResourceReferenceInfo> retVal = new ArrayList<>();
|
final ArrayList<ResourceReferenceInfo> retVal = new ArrayList<>();
|
||||||
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
||||||
visit(new IdentityHashMap<>(), theResource, theResource, null, null, def, new IModelVisitor() {
|
visit(newMap(), theResource, theResource, null, null, def, new IModelVisitor() {
|
||||||
@Override
|
@Override
|
||||||
public void acceptElement(IBaseResource theOuterResource, IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
public void acceptElement(IBaseResource theOuterResource, IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
||||||
if (theElement == null || theElement.isEmpty()) {
|
if (theElement == null || theElement.isEmpty()) {
|
||||||
|
@ -793,7 +793,11 @@ public class FhirTerser {
|
||||||
*/
|
*/
|
||||||
public void visit(IBaseResource theResource, IModelVisitor theVisitor) {
|
public void visit(IBaseResource theResource, IModelVisitor theVisitor) {
|
||||||
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
||||||
visit(new IdentityHashMap<>(), theResource, theResource, null, null, def, theVisitor);
|
visit(newMap(), theResource, theResource, null, null, def, theVisitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Object, Object> newMap() {
|
||||||
|
return new IdentityHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -814,7 +818,7 @@ public class FhirTerser {
|
||||||
visit(theResource, null, def, theVisitor, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
|
visit(theResource, null, def, theVisitor, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visit(IdentityHashMap<Object, Object> theStack, IBaseResource theResource, IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition,
|
private void visit(Map<Object, Object> theStack, IBaseResource theResource, IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition,
|
||||||
BaseRuntimeElementDefinition<?> theDefinition, IModelVisitor theCallback) {
|
BaseRuntimeElementDefinition<?> theDefinition, IModelVisitor theCallback) {
|
||||||
List<String> pathToElement = addNameToList(thePathToElement, theChildDefinition);
|
List<String> pathToElement = addNameToList(thePathToElement, theChildDefinition);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
(dependent HAPI modules listed in brackets):
|
(dependent HAPI modules listed in brackets):
|
||||||
<ul>
|
<ul>
|
||||||
<li>Jetty (CLI): 9.4.14.v20181114 -> 9.4.23.v20191118</li>
|
<li>Jetty (CLI): 9.4.14.v20181114 -> 9.4.23.v20191118</li>
|
||||||
|
<li>Spring (JPA, Testpage): 5.2.1 -> 5.2.3 (addresses CVE-2020-5398 and CVE-2020-5397)</li>
|
||||||
</ul>"
|
</ul>"
|
||||||
- item:
|
- item:
|
||||||
issue: "1583"
|
issue: "1583"
|
||||||
|
@ -64,6 +65,12 @@
|
||||||
issue: "1649"
|
issue: "1649"
|
||||||
type: "add"
|
type: "add"
|
||||||
title: "Support for LOINC 2.67 file format changes has been added to the JPA Server LOINC uploader. Thanks to Dan Vreeman for reporting!"
|
title: "Support for LOINC 2.67 file format changes has been added to the JPA Server LOINC uploader. Thanks to Dan Vreeman for reporting!"
|
||||||
|
- item:
|
||||||
|
issue: "1660"
|
||||||
|
type: "perf"
|
||||||
|
title: "A significant performance improvement was added to the Json and XML parsers when parsing large Bundle
|
||||||
|
resources. Throughput for parsing these resources has been improved by roughly 50%. Thanks to Rok Bertoncelj
|
||||||
|
and Bogdan Solga for providing analysis and insight that triggered this change."
|
||||||
- item:
|
- item:
|
||||||
issue: "1658"
|
issue: "1658"
|
||||||
type: "fix"
|
type: "fix"
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -655,7 +655,7 @@
|
||||||
<servicemix_saxon_version>9.5.1-5_1</servicemix_saxon_version>
|
<servicemix_saxon_version>9.5.1-5_1</servicemix_saxon_version>
|
||||||
<servicemix_xmlresolver_version>1.2_5</servicemix_xmlresolver_version>
|
<servicemix_xmlresolver_version>1.2_5</servicemix_xmlresolver_version>
|
||||||
<slf4j_version>1.7.28</slf4j_version>
|
<slf4j_version>1.7.28</slf4j_version>
|
||||||
<spring_version>5.2.1.RELEASE</spring_version>
|
<spring_version>5.2.3.RELEASE</spring_version>
|
||||||
<!-- FYI: Spring Data JPA 2.1.9 causes test failures due to unexpected cascading deletes -->
|
<!-- FYI: Spring Data JPA 2.1.9 causes test failures due to unexpected cascading deletes -->
|
||||||
<spring_data_version>2.2.0.RELEASE</spring_data_version>
|
<spring_data_version>2.2.0.RELEASE</spring_data_version>
|
||||||
<spring_boot_version>2.2.0.RELEASE</spring_boot_version>
|
<spring_boot_version>2.2.0.RELEASE</spring_boot_version>
|
||||||
|
|
Loading…
Reference in New Issue