Fix #402 - Don't overwrite narrative sections
This commit is contained in:
parent
731be21c9f
commit
eaaf2768c3
|
@ -66,13 +66,17 @@ public abstract class BaseRuntimeChildDefinition {
|
|||
}
|
||||
|
||||
public interface IAccessor {
|
||||
List<IBase> getValues(Object theTarget);
|
||||
List<IBase> getValues(IBase theTarget);
|
||||
|
||||
default IBase getFirstValueOrNull(IBase theTarget) {
|
||||
return getValues(theTarget).stream().findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IMutator {
|
||||
void addValue(Object theTarget, IBase theValue);
|
||||
void addValue(IBase theTarget, IBase theValue);
|
||||
|
||||
void setValue(Object theTarget, IBase theValue);
|
||||
void setValue(IBase theTarget, IBase theValue);
|
||||
}
|
||||
|
||||
BaseRuntimeElementDefinition<?> findResourceReferenceDefinition(Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
|
||||
|
|
|
@ -20,34 +20,33 @@ package ca.uhn.fhir.context;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.util.ValidateUtil;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.util.ValidateUtil;
|
||||
|
||||
public abstract class BaseRuntimeDeclaredChildDefinition extends BaseRuntimeChildDefinition {
|
||||
private final IAccessor myAccessor;
|
||||
private String myBindingValueSet;
|
||||
private final String myElementName;
|
||||
private final Field myField;
|
||||
private final String myFormalDefinition;
|
||||
private final int myMax;
|
||||
private final int myMin;
|
||||
private boolean myModifier;
|
||||
|
||||
private final IMutator myMutator;
|
||||
private final String myShortDefinition;
|
||||
private String myBindingValueSet;
|
||||
private boolean myModifier;
|
||||
private boolean mySummary;
|
||||
|
||||
BaseRuntimeDeclaredChildDefinition(Field theField, Child theChildAnnotation, Description theDescriptionAnnotation, String theElementName) throws ConfigurationException {
|
||||
super();
|
||||
Validate.notNull(theField, "No field speficied");
|
||||
Validate.notNull(theField, "No field specified");
|
||||
ValidateUtil.isGreaterThanOrEqualTo(theChildAnnotation.min(), 0, "Min must be >= 0");
|
||||
Validate.isTrue(theChildAnnotation.max() == -1 || theChildAnnotation.max() >= theChildAnnotation.min(), "Max must be >= Min (unless it is -1 / unlimited)");
|
||||
Validate.notBlank(theElementName, "Element name must not be blank");
|
||||
|
@ -87,6 +86,10 @@ public abstract class BaseRuntimeDeclaredChildDefinition extends BaseRuntimeChil
|
|||
return myBindingValueSet;
|
||||
}
|
||||
|
||||
void setBindingValueSet(String theBindingValueSet) {
|
||||
myBindingValueSet = theBindingValueSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return myElementName;
|
||||
|
@ -119,107 +122,99 @@ public abstract class BaseRuntimeDeclaredChildDefinition extends BaseRuntimeChil
|
|||
return myShortDefinition;
|
||||
}
|
||||
|
||||
public BaseRuntimeElementDefinition<?> getSingleChildOrThrow() {
|
||||
if (getValidChildNames().size() != 1) {
|
||||
throw new IllegalStateException("This child has " + getValidChildNames().size() + " children, expected 1. This is a HAPI bug. Found: " + getValidChildNames());
|
||||
}
|
||||
return getChildByName(getValidChildNames().iterator().next());
|
||||
}
|
||||
|
||||
public boolean isModifier() {
|
||||
return myModifier;
|
||||
}
|
||||
|
||||
protected void setModifier(boolean theModifier) {
|
||||
myModifier = theModifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSummary() {
|
||||
return mySummary;
|
||||
}
|
||||
|
||||
void setBindingValueSet(String theBindingValueSet) {
|
||||
myBindingValueSet = theBindingValueSet;
|
||||
}
|
||||
|
||||
protected void setModifier(boolean theModifier) {
|
||||
myModifier = theModifier;
|
||||
}
|
||||
|
||||
private final class FieldListAccessor implements IAccessor {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<IBase> getValues(Object theTarget) {
|
||||
List<IBase> retVal;
|
||||
try {
|
||||
retVal = (List<IBase>) myField.get(theTarget);
|
||||
} catch (Exception e) {
|
||||
throw new ConfigurationException("Failed to get value", e);
|
||||
}
|
||||
|
||||
public List<IBase> getValues(IBase theTarget) {
|
||||
List<IBase> retVal = (List<IBase>) getFieldValue(theTarget, myField);
|
||||
if (retVal == null) {
|
||||
retVal = Collections.emptyList();
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected final class FieldListMutator implements IMutator {
|
||||
@Override
|
||||
public void addValue(Object theTarget, IBase theValue) {
|
||||
public void addValue(IBase theTarget, IBase theValue) {
|
||||
addValue(theTarget, theValue, false);
|
||||
}
|
||||
|
||||
private void addValue(Object theTarget, IBase theValue, boolean theClear) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<IBase> existingList = (List<IBase>) myField.get(theTarget);
|
||||
if (existingList == null) {
|
||||
existingList = new ArrayList<IBase>(2);
|
||||
myField.set(theTarget, existingList);
|
||||
}
|
||||
if (theClear) {
|
||||
existingList.clear();
|
||||
}
|
||||
existingList.add(theValue);
|
||||
} catch (Exception e) {
|
||||
throw new ConfigurationException("Failed to set value", e);
|
||||
private void addValue(IBase theTarget, IBase theValue, boolean theClear) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<IBase> existingList = (List<IBase>) getFieldValue(theTarget, myField);
|
||||
if (existingList == null) {
|
||||
existingList = new ArrayList<>(2);
|
||||
setFieldValue(theTarget, existingList, myField);
|
||||
}
|
||||
if (theClear) {
|
||||
existingList.clear();
|
||||
}
|
||||
existingList.add(theValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Object theTarget, IBase theValue) {
|
||||
public void setValue(IBase theTarget, IBase theValue) {
|
||||
addValue(theTarget, theValue, true);
|
||||
}
|
||||
}
|
||||
|
||||
private final class FieldPlainAccessor implements IAccessor {
|
||||
@Override
|
||||
public List<IBase> getValues(Object theTarget) {
|
||||
try {
|
||||
Object values = myField.get(theTarget);
|
||||
if (values == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<IBase> retVal = Collections.singletonList((IBase) values);
|
||||
return retVal;
|
||||
} catch (Exception e) {
|
||||
throw new ConfigurationException("Failed to get value", e);
|
||||
public List<IBase> getValues(IBase theTarget) {
|
||||
Object values = getFieldValue(theTarget, myField);
|
||||
if (values == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.singletonList((IBase) values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBase getFirstValueOrNull(IBase theTarget) {
|
||||
return (IBase) getFieldValue(theTarget, myField);
|
||||
}
|
||||
}
|
||||
|
||||
protected final class FieldPlainMutator implements IMutator {
|
||||
@Override
|
||||
public void addValue(Object theTarget, IBase theValue) {
|
||||
try {
|
||||
myField.set(theTarget, theValue);
|
||||
} catch (Exception e) {
|
||||
throw new ConfigurationException("Failed to set value", e);
|
||||
}
|
||||
public void addValue(IBase theTarget, IBase theValue) {
|
||||
setFieldValue(theTarget, theValue, myField);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Object theTarget, IBase theValue) {
|
||||
public void setValue(IBase theTarget, IBase theValue) {
|
||||
addValue(theTarget, theValue);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setFieldValue(IBase theTarget, Object theValue, Field theField) {
|
||||
try {
|
||||
theField.set(theTarget, theValue);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ConfigurationException("Failed to set value", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Object getFieldValue(IBase theTarget, Field theField) {
|
||||
try {
|
||||
return theField.get(theTarget);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ConfigurationException("Failed to get value", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildD
|
|||
public IAccessor getAccessor() {
|
||||
return new IAccessor() {
|
||||
@Override
|
||||
public List<IBase> getValues(Object theTarget) {
|
||||
public List<IBase> getValues(IBase theTarget) {
|
||||
ExtensionDt target = (ExtensionDt) theTarget;
|
||||
if (target.getValue() != null) {
|
||||
return Collections.singletonList((IBase) target.getValue());
|
||||
|
@ -76,6 +76,7 @@ public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildD
|
|||
ArrayList<IBase> retVal = new ArrayList<IBase>(target.getUndeclaredExtensions());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -113,7 +114,7 @@ public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildD
|
|||
public IMutator getMutator() {
|
||||
return new IMutator() {
|
||||
@Override
|
||||
public void addValue(Object theTarget, IBase theValue) {
|
||||
public void addValue(IBase theTarget, IBase theValue) {
|
||||
ExtensionDt target = (ExtensionDt) theTarget;
|
||||
if (theValue instanceof IDatatype) {
|
||||
target.setValue((IDatatype) theTarget);
|
||||
|
@ -123,7 +124,7 @@ public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildD
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Object theTarget, IBase theValue) {
|
||||
public void setValue(IBase theTarget, IBase theValue) {
|
||||
ExtensionDt target = (ExtensionDt) theTarget;
|
||||
if (theValue instanceof IDatatype) {
|
||||
target.setValue((IDatatype) theTarget);
|
||||
|
|
|
@ -19,17 +19,6 @@ package ca.uhn.fhir.parser;
|
|||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.xml.stream.events.StartElement;
|
||||
import javax.xml.stream.events.XMLEvent;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
|
||||
import ca.uhn.fhir.context.*;
|
||||
import ca.uhn.fhir.context.BaseRuntimeChildDefinition.IMutator;
|
||||
|
@ -37,21 +26,32 @@ import ca.uhn.fhir.model.api.*;
|
|||
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.primitive.*;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.primitive.XhtmlDt;
|
||||
import ca.uhn.fhir.parser.json.JsonLikeValue.ScalarType;
|
||||
import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType;
|
||||
import ca.uhn.fhir.util.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
|
||||
import javax.xml.stream.events.StartElement;
|
||||
import javax.xml.stream.events.XMLEvent;
|
||||
import java.util.*;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
class ParserState<T> {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ParserState.class);
|
||||
|
||||
private List<String> myComments = new ArrayList<String>(2);
|
||||
private final FhirContext myContext;
|
||||
private final IParserErrorHandler myErrorHandler;
|
||||
private final boolean myJsonMode;
|
||||
private T myObject;
|
||||
private final IParser myParser;
|
||||
private List<String> myComments = new ArrayList<String>(2);
|
||||
private T myObject;
|
||||
private IBase myPreviousElement;
|
||||
private BaseState myState;
|
||||
|
||||
|
@ -152,38 +152,6 @@ class ParserState<T> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param theResourceType
|
||||
* May be null
|
||||
*/
|
||||
static <T extends IBaseResource> ParserState<T> getPreResourceInstance(IParser theParser, Class<T> theResourceType, FhirContext theContext, boolean theJsonMode, IParserErrorHandler theErrorHandler)
|
||||
throws DataFormatException {
|
||||
ParserState<T> retVal = new ParserState<T>(theParser, theContext, theJsonMode, theErrorHandler);
|
||||
if (theResourceType == null) {
|
||||
if (theContext.getVersion().getVersion().isRi()) {
|
||||
retVal.push(retVal.new PreResourceStateHl7Org(theResourceType));
|
||||
} else {
|
||||
retVal.push(retVal.new PreResourceStateHapi(theResourceType));
|
||||
}
|
||||
} else {
|
||||
if (IResource.class.isAssignableFrom(theResourceType)) {
|
||||
retVal.push(retVal.new PreResourceStateHapi(theResourceType));
|
||||
} else {
|
||||
retVal.push(retVal.new PreResourceStateHl7Org(theResourceType));
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static ParserState<TagList> getPreTagListInstance(IParser theParser, FhirContext theContext, boolean theJsonMode, IParserErrorHandler theErrorHandler) {
|
||||
ParserState<TagList> retVal = new ParserState<TagList>(theParser, theContext, theJsonMode, theErrorHandler);
|
||||
retVal.push(retVal.new PreTagListState());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private abstract class BaseState {
|
||||
|
||||
private PreResourceState myPreResourceState;
|
||||
|
@ -195,8 +163,7 @@ class ParserState<T> {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param theValue
|
||||
* The attribute value
|
||||
* @param theValue The attribute value
|
||||
*/
|
||||
public void attributeValue(String theName, String theValue) throws DataFormatException {
|
||||
myErrorHandler.unknownAttribute(null, theName);
|
||||
|
@ -211,8 +178,7 @@ class ParserState<T> {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param theNamespaceUri
|
||||
* The XML namespace (if XML) or null
|
||||
* @param theNamespaceUri The XML namespace (if XML) or null
|
||||
*/
|
||||
public void enteringNewElement(String theNamespaceUri, String theLocalPart) throws DataFormatException {
|
||||
myErrorHandler.unknownElement(null, theLocalPart);
|
||||
|
@ -275,8 +241,7 @@ class ParserState<T> {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param theData
|
||||
* The string value
|
||||
* @param theData The string value
|
||||
*/
|
||||
public void string(String theData) {
|
||||
// ignore by default
|
||||
|
@ -287,8 +252,7 @@ class ParserState<T> {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param theNextEvent
|
||||
* The XML event
|
||||
* @param theNextEvent The XML event
|
||||
*/
|
||||
public void xmlEvent(XMLEvent theNextEvent) {
|
||||
// ignore
|
||||
|
@ -414,30 +378,30 @@ class ParserState<T> {
|
|||
}
|
||||
|
||||
switch (target.getChildType()) {
|
||||
case COMPOSITE_DATATYPE: {
|
||||
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
||||
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance(myDefinition.getInstanceConstructorArguments());
|
||||
myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
|
||||
ElementCompositeState newState = new ElementCompositeState(myPreResourceState, theLocalPart, compositeTarget, newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
case ID_DATATYPE:
|
||||
case PRIMITIVE_DATATYPE: {
|
||||
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
||||
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance(myDefinition.getInstanceConstructorArguments());
|
||||
myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
|
||||
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
case PRIMITIVE_XHTML:
|
||||
case RESOURCE:
|
||||
case RESOURCE_BLOCK:
|
||||
case UNDECL_EXT:
|
||||
case EXTENSION_DECLARED:
|
||||
default:
|
||||
break;
|
||||
case COMPOSITE_DATATYPE: {
|
||||
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
||||
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance(myDefinition.getInstanceConstructorArguments());
|
||||
myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
|
||||
ElementCompositeState newState = new ElementCompositeState(myPreResourceState, theLocalPart, compositeTarget, newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
case ID_DATATYPE:
|
||||
case PRIMITIVE_DATATYPE: {
|
||||
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
||||
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance(myDefinition.getInstanceConstructorArguments());
|
||||
myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
|
||||
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
case PRIMITIVE_XHTML:
|
||||
case RESOURCE:
|
||||
case RESOURCE_BLOCK:
|
||||
case UNDECL_EXT:
|
||||
case EXTENSION_DECLARED:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,81 +509,81 @@ class ParserState<T> {
|
|||
}
|
||||
|
||||
switch (target.getChildType()) {
|
||||
case COMPOSITE_DATATYPE: {
|
||||
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
||||
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance(child.getInstanceConstructorArguments());
|
||||
child.getMutator().addValue(myInstance, newChildInstance);
|
||||
ParserState<T>.ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), theChildName, compositeTarget, newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
case ID_DATATYPE:
|
||||
case PRIMITIVE_DATATYPE: {
|
||||
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
||||
IPrimitiveType<?> newChildInstance;
|
||||
newChildInstance = primitiveTarget.newInstance(child.getInstanceConstructorArguments());
|
||||
child.getMutator().addValue(myInstance, newChildInstance);
|
||||
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
case RESOURCE_BLOCK: {
|
||||
RuntimeResourceBlockDefinition blockTarget = (RuntimeResourceBlockDefinition) target;
|
||||
IBase newBlockInstance = blockTarget.newInstance();
|
||||
child.getMutator().addValue(myInstance, newBlockInstance);
|
||||
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), theChildName, blockTarget, newBlockInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
case PRIMITIVE_XHTML: {
|
||||
RuntimePrimitiveDatatypeNarrativeDefinition xhtmlTarget = (RuntimePrimitiveDatatypeNarrativeDefinition) target;
|
||||
XhtmlDt newDt = xhtmlTarget.newInstance();
|
||||
child.getMutator().addValue(myInstance, newDt);
|
||||
XhtmlState state = new XhtmlState(getPreResourceState(), newDt, true);
|
||||
push(state);
|
||||
return;
|
||||
}
|
||||
case PRIMITIVE_XHTML_HL7ORG: {
|
||||
RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition xhtmlTarget = (RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition) target;
|
||||
IBaseXhtml newDt = xhtmlTarget.newInstance();
|
||||
child.getMutator().addValue(myInstance, newDt);
|
||||
XhtmlStateHl7Org state = new XhtmlStateHl7Org(getPreResourceState(), newDt);
|
||||
push(state);
|
||||
return;
|
||||
}
|
||||
case CONTAINED_RESOURCES: {
|
||||
List<? extends IBase> values = child.getAccessor().getValues(myInstance);
|
||||
Object newDt;
|
||||
if (values == null || values.isEmpty() || values.get(0) == null) {
|
||||
newDt = newContainedDt((IResource) getPreResourceState().myInstance);
|
||||
child.getMutator().addValue(myInstance, (IBase) newDt);
|
||||
} else {
|
||||
newDt = values.get(0);
|
||||
case COMPOSITE_DATATYPE: {
|
||||
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
||||
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance(child.getInstanceConstructorArguments());
|
||||
child.getMutator().addValue(myInstance, newChildInstance);
|
||||
ParserState<T>.ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), theChildName, compositeTarget, newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
ContainedResourcesStateHapi state = new ContainedResourcesStateHapi(getPreResourceState());
|
||||
push(state);
|
||||
return;
|
||||
}
|
||||
case CONTAINED_RESOURCE_LIST: {
|
||||
ContainedResourcesStateHl7Org state = new ContainedResourcesStateHl7Org(getPreResourceState());
|
||||
push(state);
|
||||
return;
|
||||
}
|
||||
case RESOURCE: {
|
||||
if (myInstance instanceof IAnyResource || myInstance instanceof IBaseBackboneElement || myInstance instanceof IBaseElement) {
|
||||
ParserState<T>.PreResourceStateHl7Org state = new PreResourceStateHl7Org(myInstance, child.getMutator(), null);
|
||||
push(state);
|
||||
} else {
|
||||
ParserState<T>.PreResourceStateHapi state = new PreResourceStateHapi(myInstance, child.getMutator(), null);
|
||||
push(state);
|
||||
case ID_DATATYPE:
|
||||
case PRIMITIVE_DATATYPE: {
|
||||
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
||||
IPrimitiveType<?> newChildInstance;
|
||||
newChildInstance = primitiveTarget.newInstance(child.getInstanceConstructorArguments());
|
||||
child.getMutator().addValue(myInstance, newChildInstance);
|
||||
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
case RESOURCE_BLOCK: {
|
||||
RuntimeResourceBlockDefinition blockTarget = (RuntimeResourceBlockDefinition) target;
|
||||
IBase newBlockInstance = blockTarget.newInstance();
|
||||
child.getMutator().addValue(myInstance, newBlockInstance);
|
||||
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), theChildName, blockTarget, newBlockInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
case PRIMITIVE_XHTML: {
|
||||
RuntimePrimitiveDatatypeNarrativeDefinition xhtmlTarget = (RuntimePrimitiveDatatypeNarrativeDefinition) target;
|
||||
XhtmlDt newDt = xhtmlTarget.newInstance();
|
||||
child.getMutator().addValue(myInstance, newDt);
|
||||
XhtmlState state = new XhtmlState(getPreResourceState(), newDt, true);
|
||||
push(state);
|
||||
return;
|
||||
}
|
||||
case PRIMITIVE_XHTML_HL7ORG: {
|
||||
RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition xhtmlTarget = (RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition) target;
|
||||
IBaseXhtml newDt = xhtmlTarget.newInstance();
|
||||
child.getMutator().addValue(myInstance, newDt);
|
||||
XhtmlStateHl7Org state = new XhtmlStateHl7Org(getPreResourceState(), newDt);
|
||||
push(state);
|
||||
return;
|
||||
}
|
||||
case CONTAINED_RESOURCES: {
|
||||
List<? extends IBase> values = child.getAccessor().getValues(myInstance);
|
||||
Object newDt;
|
||||
if (values == null || values.isEmpty() || values.get(0) == null) {
|
||||
newDt = newContainedDt((IResource) getPreResourceState().myInstance);
|
||||
child.getMutator().addValue(myInstance, (IBase) newDt);
|
||||
} else {
|
||||
newDt = values.get(0);
|
||||
}
|
||||
ContainedResourcesStateHapi state = new ContainedResourcesStateHapi(getPreResourceState());
|
||||
push(state);
|
||||
return;
|
||||
}
|
||||
case CONTAINED_RESOURCE_LIST: {
|
||||
ContainedResourcesStateHl7Org state = new ContainedResourcesStateHl7Org(getPreResourceState());
|
||||
push(state);
|
||||
return;
|
||||
}
|
||||
case RESOURCE: {
|
||||
if (myInstance instanceof IAnyResource || myInstance instanceof IBaseBackboneElement || myInstance instanceof IBaseElement) {
|
||||
ParserState<T>.PreResourceStateHl7Org state = new PreResourceStateHl7Org(myInstance, child.getMutator(), null);
|
||||
push(state);
|
||||
} else {
|
||||
ParserState<T>.PreResourceStateHapi state = new PreResourceStateHapi(myInstance, child.getMutator(), null);
|
||||
push(state);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case UNDECL_EXT:
|
||||
case EXTENSION_DECLARED: {
|
||||
// Throw an exception because this shouldn't happen here
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case UNDECL_EXT:
|
||||
case EXTENSION_DECLARED: {
|
||||
// Throw an exception because this shouldn't happen here
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
throw new DataFormatException("Illegal resource position: " + target.getChildType());
|
||||
|
@ -716,32 +680,32 @@ class ParserState<T> {
|
|||
|
||||
if (target != null) {
|
||||
switch (target.getChildType()) {
|
||||
case COMPOSITE_DATATYPE: {
|
||||
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
||||
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance();
|
||||
myExtension.setValue(newChildInstance);
|
||||
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), theLocalPart, compositeTarget, newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
case ID_DATATYPE:
|
||||
case PRIMITIVE_DATATYPE: {
|
||||
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
||||
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance();
|
||||
myExtension.setValue(newChildInstance);
|
||||
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
case CONTAINED_RESOURCES:
|
||||
case CONTAINED_RESOURCE_LIST:
|
||||
case EXTENSION_DECLARED:
|
||||
case PRIMITIVE_XHTML:
|
||||
case PRIMITIVE_XHTML_HL7ORG:
|
||||
case RESOURCE:
|
||||
case RESOURCE_BLOCK:
|
||||
case UNDECL_EXT:
|
||||
break;
|
||||
case COMPOSITE_DATATYPE: {
|
||||
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
||||
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance();
|
||||
myExtension.setValue(newChildInstance);
|
||||
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), theLocalPart, compositeTarget, newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
case ID_DATATYPE:
|
||||
case PRIMITIVE_DATATYPE: {
|
||||
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
||||
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance();
|
||||
myExtension.setValue(newChildInstance);
|
||||
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
case CONTAINED_RESOURCES:
|
||||
case CONTAINED_RESOURCE_LIST:
|
||||
case EXTENSION_DECLARED:
|
||||
case PRIMITIVE_XHTML:
|
||||
case PRIMITIVE_XHTML_HL7ORG:
|
||||
case RESOURCE:
|
||||
case RESOURCE_BLOCK:
|
||||
case UNDECL_EXT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -890,7 +854,6 @@ class ParserState<T> {
|
|||
|
||||
}
|
||||
|
||||
|
||||
private abstract class PreResourceState extends BaseState {
|
||||
|
||||
private Map<String, IBaseResource> myContainedResources;
|
||||
|
@ -1008,14 +971,14 @@ class ParserState<T> {
|
|||
|
||||
if (wantedProfileType != null && !wantedProfileType.equals(myInstance.getClass())) {
|
||||
if (myResourceType == null || myResourceType.isAssignableFrom(wantedProfileType)) {
|
||||
ourLog.debug("Converting resource of type {} to type defined for profile \"{}\": {}", new Object[] { myInstance.getClass().getName(), usedProfile, wantedProfileType });
|
||||
ourLog.debug("Converting resource of type {} to type defined for profile \"{}\": {}", new Object[]{myInstance.getClass().getName(), usedProfile, wantedProfileType});
|
||||
|
||||
/*
|
||||
* This isn't the most efficient thing really.. If we want a specific
|
||||
* type we just re-parse into that type. The problem is that we don't know
|
||||
* until we've parsed the resource which type we want to use because the
|
||||
* profile declarations are in the text of the resource itself.
|
||||
*
|
||||
*
|
||||
* At some point it would be good to write code which can present a view
|
||||
* of one type backed by another type and use that.
|
||||
*/
|
||||
|
@ -1094,7 +1057,7 @@ class ParserState<T> {
|
|||
|
||||
@Override
|
||||
public void acceptElement(IBaseResource theResource, IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition,
|
||||
BaseRuntimeElementDefinition<?> theDefinition) {
|
||||
BaseRuntimeElementDefinition<?> theDefinition) {
|
||||
if (theElement instanceof BaseResourceReferenceDt) {
|
||||
BaseResourceReferenceDt nextRef = (BaseResourceReferenceDt) theElement;
|
||||
String ref = nextRef.getReference().getValue();
|
||||
|
@ -1137,7 +1100,7 @@ class ParserState<T> {
|
|||
|
||||
private class PreResourceStateHapi extends PreResourceState {
|
||||
private IMutator myMutator;
|
||||
private Object myTarget;
|
||||
private IBase myTarget;
|
||||
|
||||
|
||||
public PreResourceStateHapi(Class<? extends IBaseResource> theResourceType) {
|
||||
|
@ -1145,7 +1108,7 @@ class ParserState<T> {
|
|||
assert theResourceType == null || IResource.class.isAssignableFrom(theResourceType);
|
||||
}
|
||||
|
||||
public PreResourceStateHapi(Object theTarget, IMutator theMutator, Class<? extends IBaseResource> theResourceType) {
|
||||
public PreResourceStateHapi(IBase theTarget, IMutator theMutator, Class<? extends IBaseResource> theResourceType) {
|
||||
super(theResourceType);
|
||||
myTarget = theTarget;
|
||||
myMutator = theMutator;
|
||||
|
@ -1175,18 +1138,18 @@ class ParserState<T> {
|
|||
String resourceName = myContext.getResourceDefinition(nextResource).getName();
|
||||
String bundleIdPart = nextResource.getId().getIdPart();
|
||||
if (isNotBlank(bundleIdPart)) {
|
||||
// if (isNotBlank(entryBaseUrl)) {
|
||||
// nextResource.setId(new IdDt(entryBaseUrl, resourceName, bundleIdPart, version));
|
||||
// } else {
|
||||
IdDt previousId = nextResource.getId();
|
||||
nextResource.setId(new IdDt(null, resourceName, bundleIdPart, version));
|
||||
// Copy extensions
|
||||
if (!previousId.getAllUndeclaredExtensions().isEmpty()) {
|
||||
for (final ExtensionDt ext : previousId.getAllUndeclaredExtensions()) {
|
||||
nextResource.getId().addUndeclaredExtension(ext);
|
||||
}
|
||||
}
|
||||
// }
|
||||
// if (isNotBlank(entryBaseUrl)) {
|
||||
// nextResource.setId(new IdDt(entryBaseUrl, resourceName, bundleIdPart, version));
|
||||
// } else {
|
||||
IdDt previousId = nextResource.getId();
|
||||
nextResource.setId(new IdDt(null, resourceName, bundleIdPart, version));
|
||||
// Copy extensions
|
||||
if (!previousId.getAllUndeclaredExtensions().isEmpty()) {
|
||||
for (final ExtensionDt ext : previousId.getAllUndeclaredExtensions()) {
|
||||
nextResource.getId().addUndeclaredExtension(ext);
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1195,13 +1158,13 @@ class ParserState<T> {
|
|||
private class PreResourceStateHl7Org extends PreResourceState {
|
||||
|
||||
private IMutator myMutator;
|
||||
private Object myTarget;
|
||||
private IBase myTarget;
|
||||
|
||||
public PreResourceStateHl7Org(Class<? extends IBaseResource> theResourceType) {
|
||||
super(theResourceType);
|
||||
}
|
||||
|
||||
public PreResourceStateHl7Org(Object theTarget, IMutator theMutator, Class<? extends IBaseResource> theResourceType) {
|
||||
public PreResourceStateHl7Org(IBase theTarget, IMutator theMutator, Class<? extends IBaseResource> theResourceType) {
|
||||
super(theResourceType);
|
||||
myMutator = theMutator;
|
||||
myTarget = theTarget;
|
||||
|
@ -1463,21 +1426,21 @@ class ParserState<T> {
|
|||
String value = defaultIfBlank(theValue, null);
|
||||
|
||||
switch (mySubState) {
|
||||
case TERM:
|
||||
myTerm = (value);
|
||||
break;
|
||||
case LABEL:
|
||||
myLabel = (value);
|
||||
break;
|
||||
case SCHEME:
|
||||
myScheme = (value);
|
||||
break;
|
||||
case NONE:
|
||||
// This handles JSON encoding, which is a bit weird
|
||||
enteringNewElement(null, theName);
|
||||
attributeValue(null, value);
|
||||
endingElement();
|
||||
break;
|
||||
case TERM:
|
||||
myTerm = (value);
|
||||
break;
|
||||
case LABEL:
|
||||
myLabel = (value);
|
||||
break;
|
||||
case SCHEME:
|
||||
myScheme = (value);
|
||||
break;
|
||||
case NONE:
|
||||
// This handles JSON encoding, which is a bit weird
|
||||
enteringNewElement(null, theName);
|
||||
attributeValue(null, value);
|
||||
endingElement();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1604,4 +1567,32 @@ class ParserState<T> {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param theResourceType May be null
|
||||
*/
|
||||
static <T extends IBaseResource> ParserState<T> getPreResourceInstance(IParser theParser, Class<T> theResourceType, FhirContext theContext, boolean theJsonMode, IParserErrorHandler theErrorHandler)
|
||||
throws DataFormatException {
|
||||
ParserState<T> retVal = new ParserState<T>(theParser, theContext, theJsonMode, theErrorHandler);
|
||||
if (theResourceType == null) {
|
||||
if (theContext.getVersion().getVersion().isRi()) {
|
||||
retVal.push(retVal.new PreResourceStateHl7Org(theResourceType));
|
||||
} else {
|
||||
retVal.push(retVal.new PreResourceStateHapi(theResourceType));
|
||||
}
|
||||
} else {
|
||||
if (IResource.class.isAssignableFrom(theResourceType)) {
|
||||
retVal.push(retVal.new PreResourceStateHapi(theResourceType));
|
||||
} else {
|
||||
retVal.push(retVal.new PreResourceStateHl7Org(theResourceType));
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static ParserState<TagList> getPreTagListInstance(IParser theParser, FhirContext theContext, boolean theJsonMode, IParserErrorHandler theErrorHandler) {
|
||||
ParserState<TagList> retVal = new ParserState<TagList>(theParser, theContext, theJsonMode, theErrorHandler);
|
||||
retVal.push(retVal.new PreTagListState());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -354,17 +354,10 @@ public class XmlParser extends BaseParser {
|
|||
}
|
||||
|
||||
if (nextChild instanceof RuntimeChildNarrativeDefinition) {
|
||||
INarrative narr = (INarrative) nextChild.getAccessor().getFirstValueOrNull(theElement);
|
||||
|
||||
INarrativeGenerator gen = myContext.getNarrativeGenerator();
|
||||
INarrative narr;
|
||||
if (theResource instanceof IResource) {
|
||||
narr = ((IResource) theResource).getText();
|
||||
} else if (theResource instanceof IDomainResource) {
|
||||
narr = ((IDomainResource) theResource).getText();
|
||||
} else {
|
||||
narr = null;
|
||||
}
|
||||
// FIXME potential null access on narr see line 623
|
||||
if (gen != null && narr.isEmpty()) {
|
||||
if (gen != null && (narr == null || narr.isEmpty())) {
|
||||
gen.populateResourceNarrative(myContext, theResource);
|
||||
}
|
||||
if (narr != null && narr.isEmpty() == false) {
|
||||
|
|
|
@ -216,12 +216,12 @@ public class FhirTerser {
|
|||
}
|
||||
|
||||
public Object getSingleValueOrNull(IBase theTarget, String thePath) {
|
||||
Class<Object> wantedType = Object.class;
|
||||
Class<IBase> wantedType = IBase.class;
|
||||
|
||||
return getSingleValueOrNull(theTarget, thePath, wantedType);
|
||||
}
|
||||
|
||||
public <T> T getSingleValueOrNull(IBase theTarget, String thePath, Class<T> theWantedType) {
|
||||
public <T extends IBase> T getSingleValueOrNull(IBase theTarget, String thePath, Class<T> theWantedType) {
|
||||
Validate.notNull(theTarget, "theTarget must not be null");
|
||||
Validate.notBlank(thePath, "thePath must not be empty");
|
||||
|
||||
|
@ -241,12 +241,12 @@ public class FhirTerser {
|
|||
return retVal.get(0);
|
||||
}
|
||||
|
||||
private <T> List<T> getValues(BaseRuntimeElementCompositeDefinition<?> theCurrentDef, Object theCurrentObj, List<String> theSubList, Class<T> theWantedClass) {
|
||||
private <T extends IBase> List<T> getValues(BaseRuntimeElementCompositeDefinition<?> theCurrentDef, IBase theCurrentObj, List<String> theSubList, Class<T> theWantedClass) {
|
||||
return getValues(theCurrentDef, theCurrentObj, theSubList, theWantedClass, false, false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> List<T> getValues(BaseRuntimeElementCompositeDefinition<?> theCurrentDef, Object theCurrentObj, List<String> theSubList, Class<T> theWantedClass, boolean theCreate, boolean theAddExtension) {
|
||||
private <T extends IBase> List<T> getValues(BaseRuntimeElementCompositeDefinition<?> theCurrentDef, IBase theCurrentObj, List<String> theSubList, Class<T> theWantedClass, boolean theCreate, boolean theAddExtension) {
|
||||
String name = theSubList.get(0);
|
||||
List<T> retVal = new ArrayList<>();
|
||||
|
||||
|
@ -325,7 +325,7 @@ public class FhirTerser {
|
|||
List<T> values = retVal;
|
||||
retVal = new ArrayList<>();
|
||||
for (T nextElement : values) {
|
||||
BaseRuntimeElementCompositeDefinition<?> nextChildDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition((Class<? extends IBase>) nextElement.getClass());
|
||||
BaseRuntimeElementCompositeDefinition<?> nextChildDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(nextElement.getClass());
|
||||
List<T> foundValues = getValues(nextChildDef, nextElement, theSubList.subList(1, theSubList.size()), theWantedClass, theCreate, theAddExtension);
|
||||
retVal.addAll(foundValues);
|
||||
}
|
||||
|
@ -410,7 +410,7 @@ public class FhirTerser {
|
|||
List<T> values = retVal;
|
||||
retVal = new ArrayList<>();
|
||||
for (T nextElement : values) {
|
||||
BaseRuntimeElementCompositeDefinition<?> nextChildDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition((Class<? extends IBase>) nextElement.getClass());
|
||||
BaseRuntimeElementCompositeDefinition<?> nextChildDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(nextElement.getClass());
|
||||
List<T> foundValues = getValues(nextChildDef, nextElement, theSubList.subList(1, theSubList.size()), theWantedClass, theCreate, theAddExtension);
|
||||
retVal.addAll(foundValues);
|
||||
}
|
||||
|
@ -476,9 +476,10 @@ public class FhirTerser {
|
|||
* @return A list of values of type {@link Object}.
|
||||
*/
|
||||
public List<Object> getValues(IBaseResource theResource, String thePath) {
|
||||
Class<Object> wantedClass = Object.class;
|
||||
Class<IBase> wantedClass = IBase.class;
|
||||
|
||||
return getValues(theResource, thePath, wantedClass);
|
||||
List values = getValues(theResource, thePath, wantedClass);
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -491,9 +492,10 @@ public class FhirTerser {
|
|||
* @return A list of values of type {@link Object}.
|
||||
*/
|
||||
public List<Object> getValues(IBaseResource theResource, String thePath, boolean theCreate) {
|
||||
Class<Object> wantedClass = Object.class;
|
||||
Class<IBase> wantedClass = IBase.class;
|
||||
|
||||
return getValues(theResource, thePath, wantedClass, theCreate);
|
||||
List retVal = getValues(theResource, thePath, wantedClass, theCreate);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -507,9 +509,10 @@ public class FhirTerser {
|
|||
* @return A list of values of type {@link Object}.
|
||||
*/
|
||||
public List<Object> getValues(IBaseResource theResource, String thePath, boolean theCreate, boolean theAddExtension) {
|
||||
Class<Object> wantedClass = Object.class;
|
||||
Class<IBase> wantedClass = IBase.class;
|
||||
|
||||
return getValues(theResource, thePath, wantedClass, theCreate, theAddExtension);
|
||||
List retVal = getValues(theResource, thePath, wantedClass, theCreate, theAddExtension);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -522,7 +525,7 @@ public class FhirTerser {
|
|||
* @param <T> Type declared by <code>theWantedClass</code>
|
||||
* @return A list of values of type <code>theWantedClass</code>.
|
||||
*/
|
||||
public <T> List<T> getValues(IBaseResource theResource, String thePath, Class<T> theWantedClass) {
|
||||
public <T extends IBase> List<T> getValues(IBaseResource theResource, String thePath, Class<T> theWantedClass) {
|
||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
|
||||
List<String> parts = parsePath(def, thePath);
|
||||
return getValues(def, theResource, parts, theWantedClass);
|
||||
|
@ -539,7 +542,7 @@ public class FhirTerser {
|
|||
* @param <T> Type declared by <code>theWantedClass</code>
|
||||
* @return A list of values of type <code>theWantedClass</code>.
|
||||
*/
|
||||
public <T> List<T> getValues(IBaseResource theResource, String thePath, Class<T> theWantedClass, boolean theCreate) {
|
||||
public <T extends IBase> List<T> getValues(IBaseResource theResource, String thePath, Class<T> theWantedClass, boolean theCreate) {
|
||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
|
||||
List<String> parts = parsePath(def, thePath);
|
||||
return getValues(def, theResource, parts, theWantedClass, theCreate, false);
|
||||
|
@ -557,7 +560,7 @@ public class FhirTerser {
|
|||
* @param <T> Type declared by <code>theWantedClass</code>
|
||||
* @return A list of values of type <code>theWantedClass</code>.
|
||||
*/
|
||||
public <T> List<T> getValues(IBaseResource theResource, String thePath, Class<T> theWantedClass, boolean theCreate, boolean theAddExtension) {
|
||||
public <T extends IBase> List<T> getValues(IBaseResource theResource, String thePath, Class<T> theWantedClass, boolean theCreate, boolean theAddExtension) {
|
||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
|
||||
List<String> parts = parsePath(def, thePath);
|
||||
return getValues(def, theResource, parts, theWantedClass, theCreate, theAddExtension);
|
||||
|
|
|
@ -319,6 +319,29 @@ public class JsonParserDstu3Test {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* See #402
|
||||
*/
|
||||
@Test
|
||||
public void testEncodeCompositionDoesntOverwriteNarrative() {
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
ctx.setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
|
||||
|
||||
Composition composition = new Composition();
|
||||
composition.getText().setDivAsString("<div>root</div>");
|
||||
composition.addSection().getText().setDivAsString("<div>section0</div>");
|
||||
composition.addSection().getText().setDivAsString("<div>section1</div>");
|
||||
|
||||
String output = ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(composition);
|
||||
ourLog.info(output);
|
||||
|
||||
assertThat(output, containsString("<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">root</div>"));
|
||||
assertThat(output, containsString("<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">section0</div>"));
|
||||
assertThat(output, containsString("<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">section1</div>"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEncodeAndParseMetaProfileAndTags() {
|
||||
Patient p = new Patient();
|
||||
|
|
|
@ -1070,6 +1070,28 @@ public class XmlParserDstu3Test {
|
|||
assertEquals("grandparent", gp.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* See #402
|
||||
*/
|
||||
@Test
|
||||
public void testEncodeCompositionDoesntOverwriteNarrative() {
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
ctx.setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
|
||||
|
||||
Composition composition = new Composition();
|
||||
composition.getText().setDivAsString("<div>root</div>");
|
||||
composition.addSection().getText().setDivAsString("<div>section0</div>");
|
||||
composition.addSection().getText().setDivAsString("<div>section1</div>");
|
||||
|
||||
String output = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(composition);
|
||||
ourLog.info(output);
|
||||
|
||||
assertThat(output, containsString("<div xmlns=\"http://www.w3.org/1999/xhtml\">root</div>"));
|
||||
assertThat(output, containsString("<div xmlns=\"http://www.w3.org/1999/xhtml\">section0</div>"));
|
||||
assertThat(output, containsString("<div xmlns=\"http://www.w3.org/1999/xhtml\">section1</div>"));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* See #326
|
||||
*/
|
||||
|
|
|
@ -287,6 +287,10 @@
|
|||
conditional creates can now be authorized even if they are happening inside a FHIR
|
||||
transaction.
|
||||
</action>
|
||||
<action type="fix" issue="402">
|
||||
When encoding a Composition resource in XML, the section narrative blocks were incorrectly
|
||||
replaced by the main resource narrative. Thanks to Mirjam Baltus for reporting!
|
||||
</action>
|
||||
</release>
|
||||
<release version="4.0.3" date="2019-09-03" description="Igloo (Point Release)">
|
||||
<action type="fix">
|
||||
|
|
Loading…
Reference in New Issue