Merge remote-tracking branch 'remotes/origin/master' into ks-20200120-near-search

This commit is contained in:
Ken Stevens 2020-01-22 15:06:52 -05:00
commit f2e8037c90
5 changed files with 143 additions and 85 deletions

View File

@ -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,9 +1081,7 @@ class ParserState<T> {
} }
} }
for (IBaseResource next : resources) { for (IBaseReference nextRef : myGlobalReferences) {
List<IBaseReference> refs = myContext.newTerser().getAllPopulatedChildElementsOfType(next, IBaseReference.class);
for (IBaseReference nextRef : refs) {
if (nextRef.isEmpty() == false && nextRef.getReferenceElement() != null) { if (nextRef.isEmpty() == false && nextRef.getReferenceElement() != null) {
IIdType unqualifiedVersionless = nextRef.getReferenceElement().toUnqualifiedVersionless(); IIdType unqualifiedVersionless = nextRef.getReferenceElement().toUnqualifiedVersionless();
IBaseResource target = idToResource.get(unqualifiedVersionless.getValueAsString()); IBaseResource target = idToResource.get(unqualifiedVersionless.getValueAsString());
@ -1017,7 +1090,6 @@ class ParserState<T> {
} }
} }
} }
}
/* /*
* Set resource IDs based on Bundle.entry.request.url * Set resource IDs based on Bundle.entry.request.url
@ -1035,34 +1107,13 @@ class ParserState<T> {
} }
void weaveContainedResources() { void weaveContainedResources() {
FhirTerser terser = myContext.newTerser(); for (IBaseReference nextRef : myLocalReferences) {
terser.visit(myInstance, new IModelVisitor() {
@Override
public void acceptElement(IBaseResource theResource, IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition,
BaseRuntimeElementDefinition<?> theDefinition) {
if (theElement instanceof BaseResourceReferenceDt) {
BaseResourceReferenceDt nextRef = (BaseResourceReferenceDt) theElement;
String ref = nextRef.getReference().getValue();
if (isNotBlank(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(); String ref = nextRef.getReferenceElement().getValue();
if (isNotBlank(ref)) { if (isNotBlank(ref)) {
if (ref.startsWith("#")) { if (ref.startsWith("#")) {
IBaseResource target = myContainedResources.get(ref); IBaseResource target = myContainedResources.get(ref);
if (target != null) { if (target != null) {
ourLog.debug("Resource contains local ref {} in field {}", ref, thePathToElement); ourLog.debug("Resource contains local ref {}", ref);
nextRef.setResource(target); nextRef.setResource(target);
} else { } else {
myErrorHandler.unknownReference(null, ref); myErrorHandler.unknownReference(null, ref);
@ -1070,8 +1121,7 @@ class ParserState<T> {
} }
} }
} }
}
});
} }
@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;
} }

View File

@ -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,11 +726,11 @@ 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(); ) { for (Iterator<?> attrIter = se.getAttributes(); attrIter.hasNext(); ) {
Attribute next = (Attribute) attrIter.next(); Attribute next = (Attribute) attrIter.next();
theEventWriter.writeAttribute(next.getName().getLocalPart(), next.getValue()); theEventWriter.writeAttribute(next.getName().getLocalPart(), next.getValue());
} }
}
break; break;
case XMLStreamConstants.DTD: case XMLStreamConstants.DTD:
case XMLStreamConstants.END_DOCUMENT: case XMLStreamConstants.END_DOCUMENT:

View File

@ -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);

View File

@ -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 -&gt; 9.4.23.v20191118</li> <li>Jetty (CLI): 9.4.14.v20181114 -&gt; 9.4.23.v20191118</li>
<li>Spring (JPA, Testpage): 5.2.1 -&gt; 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"

View File

@ -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>