Merge branch 'master' of github.com:jamesagnew/hapi-fhir

This commit is contained in:
James Agnew 2016-06-29 09:56:12 -04:00
commit 1eb1dc7e36
16 changed files with 675 additions and 126 deletions

View File

@ -25,6 +25,18 @@
<artifactId>slf4j-simple</artifactId> <artifactId>slf4j-simple</artifactId>
<version>1.7.7</version> <version>1.7.7</version>
</dependency> </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.7</version>
</dependency>
<!-- Xiaomi phones depend on an old version of this... See #394 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.2</version><!--$NO-MVN-MAN-VER$-->
</dependency>
<!-- <!--
Woodstox note: The hapi-fhir-base-testmindeps-client project includes no Woodstox at all, so that we use the Woodstox note: The hapi-fhir-base-testmindeps-client project includes no Woodstox at all, so that we use the

View File

@ -27,6 +27,7 @@ import java.io.Reader;
import java.io.StringReader; import java.io.StringReader;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.Writer; import java.io.Writer;
import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -43,6 +44,7 @@ import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseCoding; import org.hl7.fhir.instance.model.api.IBaseCoding;
import org.hl7.fhir.instance.model.api.IBaseElement; import org.hl7.fhir.instance.model.api.IBaseElement;
import org.hl7.fhir.instance.model.api.IBaseExtension;
import org.hl7.fhir.instance.model.api.IBaseHasExtensions; import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
import org.hl7.fhir.instance.model.api.IBaseHasModifierExtensions; import org.hl7.fhir.instance.model.api.IBaseHasModifierExtensions;
import org.hl7.fhir.instance.model.api.IBaseMetaType; import org.hl7.fhir.instance.model.api.IBaseMetaType;
@ -65,7 +67,6 @@ import ca.uhn.fhir.context.RuntimeChildContainedResources;
import ca.uhn.fhir.context.RuntimeChildNarrativeDefinition; import ca.uhn.fhir.context.RuntimeChildNarrativeDefinition;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.IIdentifiableElement; import ca.uhn.fhir.model.api.IIdentifiableElement;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions; import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
@ -81,6 +82,7 @@ public abstract class BaseParser implements IParser {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseParser.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseParser.class);
private ContainedResources myContainedResources; private ContainedResources myContainedResources;
private FhirContext myContext; private FhirContext myContext;
private Set<String> myDontEncodeElements; private Set<String> myDontEncodeElements;
private boolean myDontEncodeElementsIncludesStars; private boolean myDontEncodeElementsIncludesStars;
@ -95,7 +97,6 @@ public abstract class BaseParser implements IParser {
private boolean myStripVersionsFromReferences = true; private boolean myStripVersionsFromReferences = true;
private boolean mySummaryMode; private boolean mySummaryMode;
private boolean mySuppressNarratives; private boolean mySuppressNarratives;
/** /**
* Constructor * Constructor
* *
@ -395,6 +396,51 @@ public abstract class BaseParser implements IParser {
return retVal; return retVal;
} }
@SuppressWarnings("unchecked")
ChildNameAndDef getChildNameAndDef(BaseRuntimeChildDefinition theChild, IBase theValue) {
Class<? extends IBase> type = theValue.getClass();
String childName = theChild.getChildNameByDatatype(type);
BaseRuntimeElementDefinition<?> childDef = theChild.getChildElementDefinitionByDatatype(type);
if (childDef == null) {
if (theValue instanceof IBaseExtension) {
return null;
}
/*
* For RI structures Enumeration class, this replaces the child def
* with the "code" one. This is messy, and presumably there is a better
* way..
*/
BaseRuntimeElementDefinition<?> elementDef = myContext.getElementDefinition(type);
if (elementDef.getName().equals("code")) {
Class<? extends IBase> type2 = myContext.getElementDefinition("code").getImplementingClass();
childDef = theChild.getChildElementDefinitionByDatatype(type2);
childName = theChild.getChildNameByDatatype(type2);
}
// See possibly the user has extended a built-in type without
// declaring it anywhere, as in XmlParserDstu3Test#testEncodeUndeclaredBlock
if (childDef == null) {
Class<?> nextSuperType = theValue.getClass();
while (IBase.class.isAssignableFrom(nextSuperType) && childDef == null) {
if (Modifier.isAbstract(nextSuperType.getModifiers()) == false) {
BaseRuntimeElementDefinition<?> def = myContext.getElementDefinition((Class<? extends IBase>) nextSuperType);
Class<?> nextChildType = def.getImplementingClass();
childDef = theChild.getChildElementDefinitionByDatatype((Class<? extends IBase>) nextChildType);
childName = theChild.getChildNameByDatatype((Class<? extends IBase>) nextChildType);
}
nextSuperType = nextSuperType.getSuperclass();
}
}
if (childDef == null) {
throwExceptionForUnknownChildType(theChild, type);
}
}
return new ChildNameAndDef(childName, childDef);
}
protected String getCompositeElementId(IBase theElement) { protected String getCompositeElementId(IBase theElement) {
String elementId = null; String elementId = null;
if (!(theElement instanceof IBaseResource)) { if (!(theElement instanceof IBaseResource)) {
@ -882,6 +928,26 @@ public abstract class BaseParser implements IParser {
return false; return false;
} }
class ChildNameAndDef {
private final BaseRuntimeElementDefinition<?> myChildDef;
private final String myChildName;
public ChildNameAndDef(String theChildName, BaseRuntimeElementDefinition<?> theChildDef) {
myChildName = theChildName;
myChildDef = theChildDef;
}
public BaseRuntimeElementDefinition<?> getChildDef() {
return myChildDef;
}
public String getChildName() {
return myChildName;
}
}
protected class CompositeChildElement { protected class CompositeChildElement {
private final BaseRuntimeChildDefinition myDef; private final BaseRuntimeChildDefinition myDef;
private final CompositeChildElement myParent; private final CompositeChildElement myParent;

View File

@ -612,13 +612,13 @@ public class JsonParser extends BaseParser implements IParser {
} }
} }
Class<? extends IBase> type = nextValue.getClass(); BaseParser.ChildNameAndDef childNameAndDef = super.getChildNameAndDef(nextChild, nextValue);
if (childNameAndDef == null) {
String childName = nextChild.getChildNameByDatatype(type); continue;
BaseRuntimeElementDefinition<?> childDef = nextChild.getChildElementDefinitionByDatatype(type);
if (childDef == null) {
super.throwExceptionForUnknownChildType(nextChild, type);
} }
String childName = childNameAndDef.getChildName();
BaseRuntimeElementDefinition<?> childDef = childNameAndDef.getChildDef();
boolean primitive = childDef.getChildType() == ChildTypeEnum.PRIMITIVE_DATATYPE; boolean primitive = childDef.getChildType() == ChildTypeEnum.PRIMITIVE_DATATYPE;
if ((childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES || childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCE_LIST) && theContainedResource) { if ((childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES || childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCE_LIST) && theContainedResource) {

View File

@ -236,12 +236,6 @@ public class XmlParser extends BaseParser implements IParser {
break; break;
} }
case XMLStreamConstants.ATTRIBUTE: {
Attribute elem = (Attribute) nextEvent;
String name = (elem.getName().getLocalPart());
parserState.attributeValue(name, elem.getValue());
break;
}
case XMLStreamConstants.END_DOCUMENT: case XMLStreamConstants.END_DOCUMENT:
case XMLStreamConstants.END_ELEMENT: { case XMLStreamConstants.END_ELEMENT: {
if (!heldComments.isEmpty()) { if (!heldComments.isEmpty()) {
@ -649,31 +643,14 @@ public class XmlParser extends BaseParser implements IParser {
continue; continue;
} }
Class<? extends IBase> type = nextValue.getClass(); BaseParser.ChildNameAndDef childNameAndDef = super.getChildNameAndDef(nextChild, nextValue);
String childName = nextChild.getChildNameByDatatype(type); if (childNameAndDef == null) {
String extensionUrl = nextChild.getExtensionUrl();
BaseRuntimeElementDefinition<?> childDef = nextChild.getChildElementDefinitionByDatatype(type);
if (childDef == null) {
if (nextValue instanceof IBaseExtension) {
continue; continue;
} }
/* String childName = childNameAndDef.getChildName();
* For RI structures Enumeration class, this replaces the child def BaseRuntimeElementDefinition<?> childDef = childNameAndDef.getChildDef();
* with the "code" one. This is messy, and presumably there is a better String extensionUrl = nextChild.getExtensionUrl();
* way..
*/
BaseRuntimeElementDefinition<?> elementDef = myContext.getElementDefinition(type);
if (elementDef.getName().equals("code")) {
Class type2 = myContext.getElementDefinition("code").getImplementingClass();
childDef = nextChild.getChildElementDefinitionByDatatype(type2);
childName = nextChild.getChildNameByDatatype(type2);
}
if (childDef == null) {
super.throwExceptionForUnknownChildType(nextChild, type);
}
}
if (nextValue instanceof IBaseExtension && myContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) { if (nextValue instanceof IBaseExtension && myContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) {
// This is called for the Query resource in DSTU1 only // This is called for the Query resource in DSTU1 only

View File

@ -61,6 +61,7 @@ public class XmlUtil {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlUtil.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlUtil.class);
private static volatile XMLOutputFactory ourOutputFactory; private static volatile XMLOutputFactory ourOutputFactory;
private static XMLOutputFactory ourFragmentOutputFactory; private static XMLOutputFactory ourFragmentOutputFactory;
private static Throwable ourNextException;
private static final Map<String, Integer> VALID_ENTITY_NAMES; private static final Map<String, Integer> VALID_ENTITY_NAMES;
private static final ExtendedEntityReplacingXmlResolver XML_RESOLVER = new ExtendedEntityReplacingXmlResolver(); private static final ExtendedEntityReplacingXmlResolver XML_RESOLVER = new ExtendedEntityReplacingXmlResolver();
@ -1519,6 +1520,8 @@ public class XmlUtil {
} }
public static XMLEventReader createXmlReader(Reader reader) throws FactoryConfigurationError, XMLStreamException { public static XMLEventReader createXmlReader(Reader reader) throws FactoryConfigurationError, XMLStreamException {
throwUnitTestExceptionIfConfiguredToDoSo();
XMLInputFactory inputFactory = getOrCreateInputFactory(); XMLInputFactory inputFactory = getOrCreateInputFactory();
// Now.. create the reader and return it // Now.. create the reader and return it
@ -1526,7 +1529,19 @@ public class XmlUtil {
return er; return er;
} }
private static void throwUnitTestExceptionIfConfiguredToDoSo() throws FactoryConfigurationError, XMLStreamException {
if (ourNextException != null) {
if (ourNextException instanceof FactoryConfigurationError) {
throw ((FactoryConfigurationError)ourNextException);
} else {
throw (XMLStreamException)ourNextException;
}
}
}
public static XMLStreamWriter createXmlStreamWriter(Writer theWriter) throws FactoryConfigurationError, XMLStreamException { public static XMLStreamWriter createXmlStreamWriter(Writer theWriter) throws FactoryConfigurationError, XMLStreamException {
throwUnitTestExceptionIfConfiguredToDoSo();
XMLOutputFactory outputFactory = getOrCreateOutputFactory(); XMLOutputFactory outputFactory = getOrCreateOutputFactory();
XMLStreamWriter retVal = outputFactory.createXMLStreamWriter(theWriter); XMLStreamWriter retVal = outputFactory.createXMLStreamWriter(theWriter);
return retVal; return retVal;
@ -1720,4 +1735,11 @@ public class XmlUtil {
} }
/**
* FOR UNIT TESTS ONLY - Throw this exception for the next operation
*/
static void setThrowExceptionForUnitTest(Throwable theException) {
ourNextException = theException;
}
} }

View File

@ -166,7 +166,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
public List<VersionIndependentConcept> findCodesAbove(String theSystem, String theCode) { public List<VersionIndependentConcept> findCodesAbove(String theSystem, String theCode) {
TermCodeSystem cs = getCodeSystem(theSystem); TermCodeSystem cs = getCodeSystem(theSystem);
if (cs == null) { if (cs == null) {
return Collections.emptyList(); return findCodesAboveUsingBuiltInSystems(theSystem, theCode);
} }
TermCodeSystemVersion csv = cs.getCurrentVersion(); TermCodeSystemVersion csv = cs.getCurrentVersion();
@ -198,7 +198,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
public List<VersionIndependentConcept> findCodesBelow(String theSystem, String theCode) { public List<VersionIndependentConcept> findCodesBelow(String theSystem, String theCode) {
TermCodeSystem cs = getCodeSystem(theSystem); TermCodeSystem cs = getCodeSystem(theSystem);
if (cs == null) { if (cs == null) {
return Collections.emptyList(); return findCodesBelowUsingBuiltInSystems(theSystem, theCode);
} }
TermCodeSystemVersion csv = cs.getCurrentVersion(); TermCodeSystemVersion csv = cs.getCurrentVersion();
@ -207,6 +207,24 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
return retVal; return retVal;
} }
/**
* Subclasses may override
* @param theSystem The code system
* @param theCode The code
*/
protected List<VersionIndependentConcept> findCodesBelowUsingBuiltInSystems(String theSystem, String theCode) {
return Collections.emptyList();
}
/**
* Subclasses may override
* @param theSystem The code system
* @param theCode The code
*/
protected List<VersionIndependentConcept> findCodesAboveUsingBuiltInSystems(String theSystem, String theCode) {
return Collections.emptyList();
}
private TermCodeSystemVersion findCurrentCodeSystemVersionForSystem(String theCodeSystem) { private TermCodeSystemVersion findCurrentCodeSystemVersionForSystem(String theCodeSystem) {
TermCodeSystem cs = getCodeSystem(theCodeSystem); TermCodeSystem cs = getCodeSystem(theCodeSystem);
if (cs == null || cs.getCurrentVersion() == null) { if (cs == null || cs.getCurrentVersion() == null) {

View File

@ -78,6 +78,9 @@ public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvc implements I
@Autowired @Autowired
private ValueSetExpander myValueSetExpander; private ValueSetExpander myValueSetExpander;
@Autowired
private IValidationSupport myValidationSupport;
private void addCodeIfNotAlreadyAdded(String system, ValueSetExpansionComponent retVal, Set<String> addedCodes, TermConcept nextConcept) { private void addCodeIfNotAlreadyAdded(String system, ValueSetExpansionComponent retVal, Set<String> addedCodes, TermConcept nextConcept) {
if (addedCodes.add(nextConcept.getCode())) { if (addedCodes.add(nextConcept.getCode())) {
ValueSetExpansionContainsComponent contains = retVal.addContains(); ValueSetExpansionContainsComponent contains = retVal.addContains();
@ -87,6 +90,71 @@ public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvc implements I
} }
} }
@Override
protected List<VersionIndependentConcept> findCodesBelowUsingBuiltInSystems(String theSystem, String theCode) {
ArrayList<VersionIndependentConcept> retVal = new ArrayList<VersionIndependentConcept>();
CodeSystem system = myValidationSupport.fetchCodeSystem(myContext, theSystem);
if (system != null) {
findCodesBelow(system, theSystem, theCode, retVal);
}
return retVal;
}
private void findCodesBelow(CodeSystem theSystem, String theSystemString, String theCode, List<VersionIndependentConcept> theListToPopulate) {
List<ConceptDefinitionComponent> conceptList = theSystem.getConcept();
findCodesBelow(theSystemString, theCode, theListToPopulate, conceptList);
}
private void findCodesBelow(String theSystemString, String theCode, List<VersionIndependentConcept> theListToPopulate, List<ConceptDefinitionComponent> conceptList) {
for (ConceptDefinitionComponent next : conceptList) {
if (theCode.equals(next.getCode())) {
addAllChildren(theSystemString, next, theListToPopulate);
} else {
findCodesBelow(theSystemString, theCode, theListToPopulate, next.getConcept());
}
}
}
private void findCodesAbove(CodeSystem theSystem, String theSystemString, String theCode, List<VersionIndependentConcept> theListToPopulate) {
List<ConceptDefinitionComponent> conceptList = theSystem.getConcept();
for (ConceptDefinitionComponent next : conceptList) {
addTreeIfItContainsCode(theSystemString, next, theCode, theListToPopulate);
}
}
private boolean addTreeIfItContainsCode(String theSystemString, ConceptDefinitionComponent theNext, String theCode, List<VersionIndependentConcept> theListToPopulate) {
boolean foundCodeInChild = false;
for (ConceptDefinitionComponent nextChild : theNext.getConcept()) {
foundCodeInChild |= addTreeIfItContainsCode(theSystemString, nextChild, theCode, theListToPopulate);
}
if (theCode.equals(theNext.getCode()) || foundCodeInChild) {
theListToPopulate.add(new VersionIndependentConcept(theSystemString, theNext.getCode()));
return true;
}
return false;
}
private void addAllChildren(String theSystemString, ConceptDefinitionComponent theCode, List<VersionIndependentConcept> theListToPopulate) {
if (isNotBlank(theCode.getCode())) {
theListToPopulate.add(new VersionIndependentConcept(theSystemString, theCode.getCode()));
}
for (ConceptDefinitionComponent nextChild : theCode.getConcept()) {
addAllChildren(theSystemString, nextChild, theListToPopulate);
}
}
@Override
protected List<VersionIndependentConcept> findCodesAboveUsingBuiltInSystems(String theSystem, String theCode) {
ArrayList<VersionIndependentConcept> retVal = new ArrayList<VersionIndependentConcept>();
CodeSystem system = myValidationSupport.fetchCodeSystem(myContext, theSystem);
if (system != null) {
findCodesAbove(system, theSystem, theCode, retVal);
}
return retVal;
}
private void addDisplayFilterExact(QueryBuilder qb, BooleanJunction<?> bool, ConceptSetFilterComponent nextFilter) { private void addDisplayFilterExact(QueryBuilder qb, BooleanJunction<?> bool, ConceptSetFilterComponent nextFilter) {
bool.must(qb.phrase().onField("myDisplay").sentence(nextFilter.getValue()).createQuery()); bool.must(qb.phrase().onField("myDisplay").sentence(nextFilter.getValue()).createQuery());
} }

View File

@ -51,6 +51,7 @@ import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept; import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink; import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test; import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
import ca.uhn.fhir.model.dstu2.resource.Bundle; import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry; import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
import ca.uhn.fhir.rest.method.IRequestOperationCallback; import ca.uhn.fhir.rest.method.IRequestOperationCallback;
@ -268,4 +269,12 @@ public abstract class BaseJpaTest {
return retVal; return retVal;
} }
public static Set<String> toCodes(List<VersionIndependentConcept> theConcepts) {
HashSet<String> retVal = new HashSet<String>();
for (VersionIndependentConcept next : theConcepts) {
retVal.add(next.getCode());
}
return retVal;
}
} }

View File

@ -12,6 +12,7 @@ import org.apache.commons.io.IOUtils;
import org.hibernate.search.jpa.FullTextEntityManager; import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.Search; import org.hibernate.search.jpa.Search;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport; import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.model.AllergyIntolerance;
import org.hl7.fhir.dstu3.model.Appointment; import org.hl7.fhir.dstu3.model.Appointment;
import org.hl7.fhir.dstu3.model.AuditEvent; import org.hl7.fhir.dstu3.model.AuditEvent;
import org.hl7.fhir.dstu3.model.Bundle; import org.hl7.fhir.dstu3.model.Bundle;
@ -91,6 +92,9 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
private static JpaValidationSupportChainDstu3 ourJpaValidationSupportChainDstu3; private static JpaValidationSupportChainDstu3 ourJpaValidationSupportChainDstu3;
private static IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept> ourValueSetDao; private static IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept> ourValueSetDao;
@Autowired
@Qualifier("myAllergyIntoleranceDaoDstu3")
protected IFhirResourceDao<AllergyIntolerance> myAllergyIntoleranceDao;
@Autowired @Autowired
protected ApplicationContext myAppCtx; protected ApplicationContext myAppCtx;
@Autowired @Autowired

View File

@ -11,6 +11,8 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.hl7.fhir.dstu3.model.AllergyIntolerance;
import org.hl7.fhir.dstu3.model.AllergyIntolerance.AllergyIntoleranceStatus;
import org.hl7.fhir.dstu3.model.AuditEvent; import org.hl7.fhir.dstu3.model.AuditEvent;
import org.hl7.fhir.dstu3.model.CodeSystem; import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode; import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode;
@ -531,6 +533,92 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
} }
@Test
public void testSearchCodeBelowBuiltInCodesystem() {
AllergyIntolerance ai1 = new AllergyIntolerance();
ai1.setStatus(AllergyIntoleranceStatus.ACTIVE);
String id1 = myAllergyIntoleranceDao.create(ai1, mySrd).getId().toUnqualifiedVersionless().getValue();
AllergyIntolerance ai2 = new AllergyIntolerance();
ai2.setStatus(AllergyIntoleranceStatus.CONFIRMED);
String id2 = myAllergyIntoleranceDao.create(ai2, mySrd).getId().toUnqualifiedVersionless().getValue();
AllergyIntolerance ai3 = new AllergyIntolerance();
ai3.setStatus(AllergyIntoleranceStatus.INACTIVE);
String id3 = myAllergyIntoleranceDao.create(ai3, mySrd).getId().toUnqualifiedVersionless().getValue();
SearchParameterMap params;
params = new SearchParameterMap();
params.add(AllergyIntolerance.SP_STATUS, new TokenParam("http://hl7.org/fhir/allergy-intolerance-status", AllergyIntoleranceStatus.ACTIVE.toCode()));
assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), containsInAnyOrder(id1));
params = new SearchParameterMap();
params.add(AllergyIntolerance.SP_STATUS, new TokenParam("http://hl7.org/fhir/allergy-intolerance-status", AllergyIntoleranceStatus.ACTIVE.toCode()).setModifier(TokenParamModifier.BELOW));
assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), containsInAnyOrder(id1, id2));
params = new SearchParameterMap();
params.add(AllergyIntolerance.SP_STATUS, new TokenParam("http://hl7.org/fhir/allergy-intolerance-status", AllergyIntoleranceStatus.CONFIRMED.toCode()).setModifier(TokenParamModifier.BELOW));
assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), containsInAnyOrder(id2));
params = new SearchParameterMap();
params.add(AllergyIntolerance.SP_STATUS, new TokenParam("http://hl7.org/fhir/allergy-intolerance-status", AllergyIntoleranceStatus.CONFIRMED.toCode()));
assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), containsInAnyOrder(id2));
params = new SearchParameterMap();
params.add(AllergyIntolerance.SP_STATUS, new TokenParam("http://hl7.org/fhir/allergy-intolerance-status", AllergyIntoleranceStatus.ENTEREDINERROR.toCode()));
assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), empty());
// Unknown code
params = new SearchParameterMap();
params.add(AllergyIntolerance.SP_STATUS, new TokenParam("http://hl7.org/fhir/allergy-intolerance-status", "fooooo"));
assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), empty());
// Unknown system
params = new SearchParameterMap();
params.add(AllergyIntolerance.SP_STATUS, new TokenParam("http://hl7.org/fhir/allergy-intolerance-status222222", "fooooo"));
assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), empty());
}
@Test
@Ignore
public void testSearchCodeBelowBuiltInCodesystemUnqualified() {
AllergyIntolerance ai1 = new AllergyIntolerance();
ai1.setStatus(AllergyIntoleranceStatus.ACTIVE);
String id1 = myAllergyIntoleranceDao.create(ai1, mySrd).getId().toUnqualifiedVersionless().getValue();
AllergyIntolerance ai2 = new AllergyIntolerance();
ai2.setStatus(AllergyIntoleranceStatus.CONFIRMED);
String id2 = myAllergyIntoleranceDao.create(ai2, mySrd).getId().toUnqualifiedVersionless().getValue();
AllergyIntolerance ai3 = new AllergyIntolerance();
ai3.setStatus(AllergyIntoleranceStatus.INACTIVE);
String id3 = myAllergyIntoleranceDao.create(ai3, mySrd).getId().toUnqualifiedVersionless().getValue();
SearchParameterMap params;
params = new SearchParameterMap();
params.add(AllergyIntolerance.SP_STATUS, new TokenParam(null, AllergyIntoleranceStatus.ACTIVE.toCode()));
assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), containsInAnyOrder(id1));
params = new SearchParameterMap();
params.add(AllergyIntolerance.SP_STATUS, new TokenParam(null, AllergyIntoleranceStatus.ACTIVE.toCode()).setModifier(TokenParamModifier.BELOW));
assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), containsInAnyOrder(id1, id2));
params = new SearchParameterMap();
params.add(AllergyIntolerance.SP_STATUS, new TokenParam(null, AllergyIntoleranceStatus.CONFIRMED.toCode()).setModifier(TokenParamModifier.BELOW));
assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), containsInAnyOrder(id2));
params = new SearchParameterMap();
params.add(AllergyIntolerance.SP_STATUS, new TokenParam(null, AllergyIntoleranceStatus.CONFIRMED.toCode()));
assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), containsInAnyOrder(id2));
params = new SearchParameterMap();
params.add(AllergyIntolerance.SP_STATUS, new TokenParam(null, AllergyIntoleranceStatus.ENTEREDINERROR.toCode()));
assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), empty());
}
@Test @Test
@Ignore @Ignore
public void testSearchCodeInEmptyValueSet() { public void testSearchCodeInEmptyValueSet() {

View File

@ -8,6 +8,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import java.util.List;
import java.util.Set; import java.util.Set;
import org.hl7.fhir.dstu3.model.CodeSystem; import org.hl7.fhir.dstu3.model.CodeSystem;
@ -102,6 +103,53 @@ public class TerminologySvcImplTest extends BaseJpaDstu3Test {
} }
@Test
public void testFindCodesBelowBuiltInCodeSystem() {
List<VersionIndependentConcept> concepts;
Set<String> codes;
concepts = myTermSvc.findCodesBelow("http://hl7.org/fhir/allergy-intolerance-status", "active");
codes = toCodes(concepts);
assertThat(codes, containsInAnyOrder("active", "confirmed", "unconfirmed"));
concepts = myTermSvc.findCodesBelow("http://hl7.org/fhir/allergy-intolerance-status", "confirmed");
codes = toCodes(concepts);
assertThat(codes, containsInAnyOrder("confirmed"));
// Unknown code
concepts = myTermSvc.findCodesBelow("http://hl7.org/fhir/allergy-intolerance-status", "FOO");
codes = toCodes(concepts);
assertThat(codes, empty());
// Unknown system
concepts = myTermSvc.findCodesBelow("http://hl7.org/fhir/allergy-intolerance-status2222", "FOO");
codes = toCodes(concepts);
assertThat(codes, empty());
}
@Test
public void testFindCodesAboveBuiltInCodeSystem() {
List<VersionIndependentConcept> concepts;
Set<String> codes;
concepts = myTermSvc.findCodesAbove("http://hl7.org/fhir/allergy-intolerance-status", "active");
codes = toCodes(concepts);
assertThat(codes, containsInAnyOrder("active"));
concepts = myTermSvc.findCodesAbove("http://hl7.org/fhir/allergy-intolerance-status", "confirmed");
codes = toCodes(concepts);
assertThat(codes, containsInAnyOrder("active", "confirmed"));
// Unknown code
concepts = myTermSvc.findCodesAbove("http://hl7.org/fhir/allergy-intolerance-status", "FOO");
codes = toCodes(concepts);
assertThat(codes, empty());
// Unknown system
concepts = myTermSvc.findCodesAbove("http://hl7.org/fhir/allergy-intolerance-status2222", "FOO");
codes = toCodes(concepts);
assertThat(codes, empty());
}
@Test @Test
public void testReindexTerminology() { public void testReindexTerminology() {

View File

@ -0,0 +1,48 @@
package ca.uhn.fhir.parser;
import org.hl7.fhir.dstu3.exceptions.FHIRException;
import org.hl7.fhir.dstu3.model.Identifier;
import org.hl7.fhir.dstu3.model.MessageHeader;
import org.hl7.fhir.dstu3.model.MessageHeader.MessageSourceComponent;
import ca.uhn.fhir.model.api.annotation.Block;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.api.annotation.Extension;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
@ResourceDef(name = "FooMessageHeader")
public class FooMessageHeader extends MessageHeader {
private static final long serialVersionUID = 1L;
@Block()
public static class FooMessageSourceComponent extends MessageHeader.MessageSourceComponent {
private static final long serialVersionUID = 1L;
@Child(name = "ext-messageheader-application-id", type = Identifier.class, modifier = true)
@Description(shortDefinition = "Message Header Application ID")
@Extension(url = "http://foo", definedLocally = false, isModifier = false)
private Identifier messageHeaderApplicationId;
/*
* Get messageHeaderApplicationId
*/
public Identifier getMessageHeaderApplicationId() throws FHIRException {
if (messageHeaderApplicationId == null) {
messageHeaderApplicationId = new Identifier();
}
return messageHeaderApplicationId;
}
/*
* Set messageHeaderApplicationId
*/
public void setmessageHeaderApplicationId(Identifier messageHeaderApplicationId) {
this.messageHeaderApplicationId = messageHeaderApplicationId;
}
}
}

View File

@ -111,6 +111,29 @@ public class JsonParserDstu3Test {
assertThat(output, containsString("\"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">VALUE</div>\"")); assertThat(output, containsString("\"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">VALUE</div>\""));
} }
@Test
public void testEncodeUndeclaredBlock() throws Exception {
FooMessageHeader.FooMessageSourceComponent source = new FooMessageHeader.FooMessageSourceComponent();
source.getMessageHeaderApplicationId().setValue("APPID");
source.setName("NAME");
FooMessageHeader header = new FooMessageHeader();
header.setSource(source);
Bundle bundle = new Bundle();
bundle.addEntry().setResource(header);
IParser p = ourCtx.newJsonParser();
p.setPrettyPrint(true);
String encode = p.encodeResourceToString(bundle);
ourLog.info(encode);
assertThat(encode, containsString("\"value\":\"APPID\""));
}
/** /**
* See #344 * See #344
*/ */

View File

@ -34,6 +34,7 @@ import org.custommonkey.xmlunit.XMLUnit;
import org.hamcrest.collection.IsEmptyCollection; import org.hamcrest.collection.IsEmptyCollection;
import org.hamcrest.core.StringContains; import org.hamcrest.core.StringContains;
import org.hamcrest.text.StringContainsInOrder; import org.hamcrest.text.StringContainsInOrder;
import org.hl7.fhir.dstu3.exceptions.FHIRException;
import org.hl7.fhir.dstu3.model.Address.AddressUse; import org.hl7.fhir.dstu3.model.Address.AddressUse;
import org.hl7.fhir.dstu3.model.Address.AddressUseEnumFactory; import org.hl7.fhir.dstu3.model.Address.AddressUseEnumFactory;
import org.hl7.fhir.dstu3.model.AllergyIntolerance; import org.hl7.fhir.dstu3.model.AllergyIntolerance;
@ -76,6 +77,7 @@ import org.hl7.fhir.dstu3.model.Location;
import org.hl7.fhir.dstu3.model.Medication; import org.hl7.fhir.dstu3.model.Medication;
import org.hl7.fhir.dstu3.model.MedicationOrder; import org.hl7.fhir.dstu3.model.MedicationOrder;
import org.hl7.fhir.dstu3.model.MedicationStatement; import org.hl7.fhir.dstu3.model.MedicationStatement;
import org.hl7.fhir.dstu3.model.MessageHeader.MessageSourceComponent;
import org.hl7.fhir.dstu3.model.Observation; import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.dstu3.model.Observation.ObservationRelationshipType; import org.hl7.fhir.dstu3.model.Observation.ObservationRelationshipType;
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus; import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
@ -119,87 +121,6 @@ public class XmlParserDstu3Test {
ourCtx.setNarrativeGenerator(null); ourCtx.setNarrativeGenerator(null);
} }
/**
* Make sure whitespace is preserved for pre tags
*/
@Test
public void testEncodeDivWithPreNonPrettyPrint() {
Patient p = new Patient();
p.getText().setDivAsString("<div>\n\n<p>A P TAG</p><p><pre>line1\nline2\nline3 <b>BOLD</b></pre></p></div>");
String output = ourCtx.newXmlParser().setPrettyPrint(false).encodeResourceToString(p);
ourLog.info(output);
//@formatter:off
assertThat(output, stringContainsInOrder(
"<text><div",
"<p>A P TAG</p><p>",
"<pre>line1\nline2\nline3 <b>BOLD</b></pre>"
));
//@formatter:on
}
@Test
public void testEncodeDivWithPrePrettyPrint() {
Patient p = new Patient();
p.getText().setDivAsString("<div>\n\n<p>A P TAG</p><p><pre>line1\nline2\nline3 <b>BOLD</b></pre></p></div>");
String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(output);
//@formatter:off
assertThat(output, stringContainsInOrder(
" <text>",
" <div",
" <pre>line1\nline2\nline3 <b>BOLD</b></pre>"
));
//@formatter:on
}
@Test
public void testEncodeContainedWithNonLocalId() throws Exception {
Patient p = new Patient();
p.setId("Patient1");
p.setBirthDate(new SimpleDateFormat("yyyy-mm-dd HH:mm:ss").parse("2016-04-15 10:15:30"));
ProcedureRequest pr = new ProcedureRequest();
pr.setId("1234567");
pr.setSubject(new Reference(p));
pr.setCode(new CodeableConcept().addCoding(new Coding("breastfeeding-readiness-assessment", "Breastfeeding Readiness Assessment", "Breastfeeding Readiness Assessment")));
// pr.setReason(new StringType("Single Live Birth"));
// pr.setScheduled(new DateType(new Date()));
pr.setEncounter(new Reference("Live Birth Encounter"));
pr.setPerformer(new Reference("Charge Nurse"));
pr.setStatus(ProcedureRequest.ProcedureRequestStatus.PROPOSED);
pr.setOrderedOn(new Date());
pr.setOrderer(new Reference("CDS System"));
pr.setPriority(ProcedureRequest.ProcedureRequestPriority.ROUTINE);
GuidanceResponse.GuidanceResponseStatus status = GuidanceResponse.GuidanceResponseStatus.SUCCESS;
//@formatter:off
GuidanceResponse gr = new GuidanceResponse()
.setRequestId("123")
.setModule(new Reference("Evaluate Operation"))
.setStatus(status);
//@formatter:on
gr.addAction(new GuidanceResponse.GuidanceResponseActionComponent().setTitle("Action").setResource(new Reference(pr)));
gr.getContained().add(p);
gr.getContained().add(pr);
IParser parser = ourCtx.newXmlParser();
parser.setPrettyPrint(true);
ourLog.info(parser.encodeResourceToString(gr));
}
@Test @Test
public void testBundleWithBinary() { public void testBundleWithBinary() {
//@formatter:off //@formatter:off
@ -231,6 +152,7 @@ public class XmlParserDstu3Test {
} }
@Test @Test
public void testContainedResourceInExtensionUndeclared() { public void testContainedResourceInExtensionUndeclared() {
Patient p = new Patient(); Patient p = new Patient();
@ -253,6 +175,7 @@ public class XmlParserDstu3Test {
assertEquals("ORG", o.getName()); assertEquals("ORG", o.getName());
} }
@Test @Test
public void testDuration() { public void testDuration() {
Encounter enc = new Encounter(); Encounter enc = new Encounter();
@ -1040,6 +963,85 @@ public class XmlParserDstu3Test {
} }
@Test
public void testEncodeContainedWithNonLocalId() throws Exception {
Patient p = new Patient();
p.setId("Patient1");
p.setBirthDate(new SimpleDateFormat("yyyy-mm-dd HH:mm:ss").parse("2016-04-15 10:15:30"));
ProcedureRequest pr = new ProcedureRequest();
pr.setId("1234567");
pr.setSubject(new Reference(p));
pr.setCode(new CodeableConcept().addCoding(new Coding("breastfeeding-readiness-assessment", "Breastfeeding Readiness Assessment", "Breastfeeding Readiness Assessment")));
// pr.setReason(new StringType("Single Live Birth"));
// pr.setScheduled(new DateType(new Date()));
pr.setEncounter(new Reference("Live Birth Encounter"));
pr.setPerformer(new Reference("Charge Nurse"));
pr.setStatus(ProcedureRequest.ProcedureRequestStatus.PROPOSED);
pr.setOrderedOn(new Date());
pr.setOrderer(new Reference("CDS System"));
pr.setPriority(ProcedureRequest.ProcedureRequestPriority.ROUTINE);
GuidanceResponse.GuidanceResponseStatus status = GuidanceResponse.GuidanceResponseStatus.SUCCESS;
//@formatter:off
GuidanceResponse gr = new GuidanceResponse()
.setRequestId("123")
.setModule(new Reference("Evaluate Operation"))
.setStatus(status);
//@formatter:on
gr.addAction(new GuidanceResponse.GuidanceResponseActionComponent().setTitle("Action").setResource(new Reference(pr)));
gr.getContained().add(p);
gr.getContained().add(pr);
IParser parser = ourCtx.newXmlParser();
parser.setPrettyPrint(true);
ourLog.info(parser.encodeResourceToString(gr));
}
/**
* Make sure whitespace is preserved for pre tags
*/
@Test
public void testEncodeDivWithPreNonPrettyPrint() {
Patient p = new Patient();
p.getText().setDivAsString("<div>\n\n<p>A P TAG</p><p><pre>line1\nline2\nline3 <b>BOLD</b></pre></p></div>");
String output = ourCtx.newXmlParser().setPrettyPrint(false).encodeResourceToString(p);
ourLog.info(output);
//@formatter:off
assertThat(output, stringContainsInOrder(
"<text><div",
"<p>A P TAG</p><p>",
"<pre>line1\nline2\nline3 <b>BOLD</b></pre>"
));
//@formatter:on
}
@Test
public void testEncodeDivWithPrePrettyPrint() {
Patient p = new Patient();
p.getText().setDivAsString("<div>\n\n<p>A P TAG</p><p><pre>line1\nline2\nline3 <b>BOLD</b></pre></p></div>");
String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(output);
//@formatter:off
assertThat(output, stringContainsInOrder(
" <text>",
" <div",
" <pre>line1\nline2\nline3 <b>BOLD</b></pre>"
));
//@formatter:on
}
@Test @Test
public void testEncodeDoesntIncludeUuidId() { public void testEncodeDoesntIncludeUuidId() {
Patient p = new Patient(); Patient p = new Patient();
@ -1396,6 +1398,27 @@ public class XmlParserDstu3Test {
assertThat(encoded, not(containsString("maritalStatus"))); assertThat(encoded, not(containsString("maritalStatus")));
} }
@Test
public void testEncodeUndeclaredBlock() throws Exception {
FooMessageHeader.FooMessageSourceComponent source = new FooMessageHeader.FooMessageSourceComponent();
source.getMessageHeaderApplicationId().setValue("APPID");
source.setName("NAME");
FooMessageHeader header = new FooMessageHeader();
header.setSource(source);
Bundle bundle = new Bundle();
bundle.addEntry().setResource(header);
IParser p = ourCtx.newXmlParser();
p.setPrettyPrint(true);
String encode = p.encodeResourceToString(bundle);
ourLog.info(encode);
assertThat(encode, containsString("<value value=\"APPID\"/>"));
}
@Test @Test
public void testEncodeUndeclaredExtensionWithEnumerationContent() { public void testEncodeUndeclaredExtensionWithEnumerationContent() {
IParser parser = ourCtx.newXmlParser(); IParser parser = ourCtx.newXmlParser();
@ -1607,6 +1630,54 @@ public class XmlParserDstu3Test {
assertThat(output, containsString("<text><status value=\"generated\"/><div xmlns=\"http://www.w3.org/1999/xhtml\"><div class=\"hapiHeaderText\"> John <b>SMITH </b>")); assertThat(output, containsString("<text><status value=\"generated\"/><div xmlns=\"http://www.w3.org/1999/xhtml\"><div class=\"hapiHeaderText\"> John <b>SMITH </b>"));
} }
@Test
public void testExceptionWithoutUrl() {
//@formatter:off
String input =
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" +
"<Patient xmlns=\"http://hl7.org/fhir\">" +
"<extension>" +
"<valueString value=\"FOO\">" +
"</extension>" +
"<address>" +
"<line value=\"FOO\"/>" +
"</address>" +
"</Patient>";
//@formatter:on
try {
ourCtx.newXmlParser().parseResource(Patient.class, input);
fail();
} catch (DataFormatException e) {
assertThat(e.toString(), containsString("Extension element has no 'url' attribute"));
}
}
@Test
public void testModifierExceptionWithoutUrl() {
//@formatter:off
String input =
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" +
"<Patient xmlns=\"http://hl7.org/fhir\">" +
"<modifierExtension>" +
"<valueString value=\"FOO\">" +
"</modifierExtension>" +
"<address>" +
"<line value=\"FOO\"/>" +
"</address>" +
"</Patient>";
//@formatter:on
try {
ourCtx.newXmlParser().parseResource(Patient.class, input);
fail();
} catch (DataFormatException e) {
assertThat(e.toString(), containsString("Extension element has no 'url' attribute"));
}
}
@Test @Test
public void testMoreExtensions() throws Exception { public void testMoreExtensions() throws Exception {
@ -2713,6 +2784,7 @@ public class XmlParserDstu3Test {
} }
} }
/** /**
* See #339 * See #339
* *

View File

@ -0,0 +1,90 @@
package ca.uhn.fhir.util;
import static org.junit.Assert.fail;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.stream.XMLStreamException;
import org.hl7.fhir.dstu3.model.Patient;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.parser.DataFormatException;
public class XmlUtilDstu3Test {
private static FhirContext ourCtx = FhirContext.forDstu3();
private Patient myPatient;
@After
public void after() {
XmlUtil.setThrowExceptionForUnitTest(null);
}
@Before
public void before() {
myPatient = new Patient();
myPatient.setId("1");
}
@Test
public void testParseMalformed() {
try {
ourCtx.newXmlParser().parseResource("AAAAA");
fail();
} catch (DataFormatException e) {
// good
}
}
public void testXmlFactoryThrowsXmlStreamException() {
XmlUtil.setThrowExceptionForUnitTest(new XMLStreamException("FOO"));
try {
ourCtx.newXmlParser().parseResource("AAAAA");
fail();
} catch (DataFormatException e) {
// good
}
try {
ourCtx.newXmlParser().encodeResourceToString(myPatient);
fail();
} catch (ConfigurationException e) {
// good
}
try {
ourCtx.newXmlParser().encodeBundleToString(new Bundle());
fail();
} catch (ConfigurationException e) {
// good
}
}
public void testXmlFactoryThrowsFactoryConfigurationError() {
XmlUtil.setThrowExceptionForUnitTest(new FactoryConfigurationError("FOO"));
try {
ourCtx.newXmlParser().parseResource("AAAAA");
fail();
} catch (DataFormatException e) {
// good
}
try {
ourCtx.newXmlParser().encodeResourceToString(myPatient);
fail();
} catch (ConfigurationException e) {
// good
}
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
}

View File

@ -391,6 +391,10 @@
causing issues on some Android phones which come with an older version causing issues on some Android phones which come with an older version
of this library bundled. Thanks to Paolo Perliti for reporting! of this library bundled. Thanks to Paolo Perliti for reporting!
</action> </action>
<action type="fix">
Parser is now better able to handle encoding fields which have been
populated with a class that extends the expected class
</action>
</release> </release>
<release version="1.5" date="2016-04-20"> <release version="1.5" date="2016-04-20">
<action type="fix" issue="339"> <action type="fix" issue="339">