Dramatically improve the performance of containResourcesForEncoding
We do this by avoiding the double processing of contained resources when looking for resources to contain
This commit is contained in:
parent
6475146bc9
commit
5120fe795e
|
@ -27,6 +27,7 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import ca.uhn.fhir.util.UrlUtil;
|
import ca.uhn.fhir.util.UrlUtil;
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
|
@ -235,7 +236,7 @@ public abstract class BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<IBaseReference> allReferences = myContext.newTerser().getAllPopulatedChildElementsOfType(theResource, IBaseReference.class);
|
List<IBaseReference> allReferences = getAllBaseReferences(theResource);
|
||||||
for (IBaseReference next : allReferences) {
|
for (IBaseReference next : allReferences) {
|
||||||
IBaseResource resource = next.getResource();
|
IBaseResource resource = next.getResource();
|
||||||
if (resource == null && next.getReferenceElement().isLocal()) {
|
if (resource == null && next.getReferenceElement().isLocal()) {
|
||||||
|
@ -280,6 +281,86 @@ public abstract class BaseParser implements IParser {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected List<IBaseReference> getAllBaseReferences(IBaseResource theResource){
|
||||||
|
final ArrayList<IBaseReference> retVal = new ArrayList<IBaseReference>();
|
||||||
|
findBaseReferences(retVal, theResource, myContext.getResourceDefinition(theResource));
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A customised traversal of the tree to find the 'top level' base references. Nested references are found via the recursive traversal
|
||||||
|
* of contained resources.
|
||||||
|
*/
|
||||||
|
protected void findBaseReferences(List<IBaseReference> allElements, IBase theElement, BaseRuntimeElementDefinition<?> theDefinition) {
|
||||||
|
if (theElement instanceof IBaseReference) {
|
||||||
|
allElements.add((IBaseReference) theElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseRuntimeElementDefinition<?> def = theDefinition;
|
||||||
|
if (def.getChildType() == ChildTypeEnum.CONTAINED_RESOURCE_LIST) {
|
||||||
|
def = myContext.getElementDefinition(theElement.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (def.getChildType()) {
|
||||||
|
case ID_DATATYPE:
|
||||||
|
case PRIMITIVE_XHTML_HL7ORG:
|
||||||
|
case PRIMITIVE_XHTML:
|
||||||
|
case PRIMITIVE_DATATYPE:
|
||||||
|
// These are primitive types
|
||||||
|
break;
|
||||||
|
case RESOURCE:
|
||||||
|
case RESOURCE_BLOCK:
|
||||||
|
case COMPOSITE_DATATYPE: {
|
||||||
|
BaseRuntimeElementCompositeDefinition<?> childDef = (BaseRuntimeElementCompositeDefinition<?>) def;
|
||||||
|
for (BaseRuntimeChildDefinition nextChild : childDef.getChildrenAndExtension()) {
|
||||||
|
|
||||||
|
List<?> values = nextChild.getAccessor().getValues(theElement);
|
||||||
|
if (values != null) {
|
||||||
|
for (Object nextValueObject : values) {
|
||||||
|
IBase nextValue;
|
||||||
|
try {
|
||||||
|
nextValue = (IBase) nextValueObject;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
String s = "Found instance of " + nextValueObject.getClass() + " - Did you set a field value to the incorrect type? Expected " + IBase.class.getName();
|
||||||
|
throw new ClassCastException(s);
|
||||||
|
}
|
||||||
|
if (nextValue == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (nextValue.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
BaseRuntimeElementDefinition<?> childElementDef;
|
||||||
|
childElementDef = nextChild.getChildElementDefinitionByDatatype(nextValue.getClass());
|
||||||
|
|
||||||
|
if (childElementDef == null) {
|
||||||
|
childElementDef = myContext.getElementDefinition(nextValue.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextChild instanceof RuntimeChildDirectResource) {
|
||||||
|
// Don't descend into embedded resources
|
||||||
|
if (nextValue instanceof IBaseReference) {
|
||||||
|
allElements.add((IBaseReference) nextValue);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
findBaseReferences(allElements, nextValue, childElementDef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONTAINED_RESOURCES:
|
||||||
|
// skip contained resources when looking for resources to contain
|
||||||
|
break;
|
||||||
|
case CONTAINED_RESOURCE_LIST:
|
||||||
|
case EXTENSION_DECLARED:
|
||||||
|
case UNDECL_EXT: {
|
||||||
|
throw new IllegalStateException("state should not happen: " + def.getChildType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String determineReferenceText(IBaseReference theRef, CompositeChildElement theCompositeChildElement) {
|
private String determineReferenceText(IBaseReference theRef, CompositeChildElement theCompositeChildElement) {
|
||||||
IIdType ref = theRef.getReferenceElement();
|
IIdType ref = theRef.getReferenceElement();
|
||||||
if (isBlank(ref.getIdPart())) {
|
if (isBlank(ref.getIdPart())) {
|
||||||
|
|
Loading…
Reference in New Issue