commit
1f534985e8
|
@ -386,7 +386,7 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return isBlank(getValue());
|
return super.isBaseEmpty() && isBlank(getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -47,6 +47,8 @@ import ca.uhn.fhir.parser.json.JsonLikeValue.ScalarType;
|
||||||
import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType;
|
import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType;
|
||||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
import ca.uhn.fhir.util.ElementUtil;
|
import ca.uhn.fhir.util.ElementUtil;
|
||||||
|
import static ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum.ID_DATATYPE;
|
||||||
|
import static ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum.PRIMITIVE_DATATYPE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is the FHIR JSON parser/encoder. Users should not interact with this class directly, but should use
|
* This class is the FHIR JSON parser/encoder. Users should not interact with this class directly, but should use
|
||||||
|
@ -612,9 +614,23 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
||||||
write(theEventWriter, "resourceType", resDef.getName());
|
write(theEventWriter, "resourceType", resDef.getName());
|
||||||
if (theResourceId != null && theResourceId.hasIdPart()) {
|
if (theResourceId != null && theResourceId.hasIdPart()) {
|
||||||
write(theEventWriter, "id", theResourceId.getIdPart());
|
write(theEventWriter, "id", theResourceId.getIdPart());
|
||||||
if (theResourceId.hasFormatComment()) {
|
final List<HeldExtension> extensions = new ArrayList<HeldExtension>(0);
|
||||||
|
final List<HeldExtension> modifierExtensions = new ArrayList<HeldExtension>(0);
|
||||||
|
// Undeclared extensions
|
||||||
|
extractUndeclaredExtensions(theResourceId, extensions, modifierExtensions, null, null);
|
||||||
|
boolean haveExtension = false;
|
||||||
|
if (!extensions.isEmpty()) {
|
||||||
|
haveExtension = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theResourceId.hasFormatComment() || haveExtension) {
|
||||||
beginObject(theEventWriter, "_id");
|
beginObject(theEventWriter, "_id");
|
||||||
|
if (theResourceId.hasFormatComment()) {
|
||||||
writeCommentsPreAndPost(theResourceId, theEventWriter);
|
writeCommentsPreAndPost(theResourceId, theEventWriter);
|
||||||
|
}
|
||||||
|
if (haveExtension) {
|
||||||
|
writeExtensionsAsDirectChild(theResource, theEventWriter, theResDef, extensions, modifierExtensions);
|
||||||
|
}
|
||||||
theEventWriter.endObject();
|
theEventWriter.endObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1014,6 +1030,9 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseExtension(ParserState<?> theState, JsonLikeArray theValues, boolean theIsModifier) {
|
private void parseExtension(ParserState<?> theState, JsonLikeArray theValues, boolean theIsModifier) {
|
||||||
|
int allUnderscoreNames = 0;
|
||||||
|
int handledUnderscoreNames = 0;
|
||||||
|
|
||||||
for (int i = 0; i < theValues.size(); i++) {
|
for (int i = 0; i < theValues.size(); i++) {
|
||||||
JsonLikeObject nextExtObj = JsonLikeValue.asObject(theValues.get(i));
|
JsonLikeObject nextExtObj = JsonLikeValue.asObject(theValues.get(i));
|
||||||
JsonLikeValue jsonElement = nextExtObj.get("url");
|
JsonLikeValue jsonElement = nextExtObj.get("url");
|
||||||
|
@ -1040,9 +1059,43 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
||||||
} else if ("modifierExtension".equals(next)) {
|
} else if ("modifierExtension".equals(next)) {
|
||||||
JsonLikeArray jsonVal = JsonLikeValue.asArray(nextExtObj.get(next));
|
JsonLikeArray jsonVal = JsonLikeValue.asArray(nextExtObj.get(next));
|
||||||
parseExtension(theState, jsonVal, true);
|
parseExtension(theState, jsonVal, true);
|
||||||
|
} else if (next.charAt(0) == '_') {
|
||||||
|
allUnderscoreNames++;
|
||||||
|
continue;
|
||||||
} else {
|
} else {
|
||||||
JsonLikeValue jsonVal = nextExtObj.get(next);
|
JsonLikeValue jsonVal = nextExtObj.get(next);
|
||||||
parseChildren(theState, next, jsonVal, null, null, false);
|
String alternateName = '_' + next;
|
||||||
|
JsonLikeValue alternateVal = nextExtObj.get(alternateName);
|
||||||
|
if (alternateVal != null) {
|
||||||
|
handledUnderscoreNames++;
|
||||||
|
}
|
||||||
|
parseChildren(theState, next, jsonVal, alternateVal, alternateName, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This happens if an element has an extension but no actual value. I.e.
|
||||||
|
* if a resource has a "_status" element but no corresponding "status"
|
||||||
|
* element. This could be used to handle a null value with an extension
|
||||||
|
* for example.
|
||||||
|
*/
|
||||||
|
if (allUnderscoreNames > handledUnderscoreNames) {
|
||||||
|
for (String alternateName : nextExtObj.keySet()) {
|
||||||
|
if (alternateName.startsWith("_") && alternateName.length() > 1) {
|
||||||
|
JsonLikeValue nextValue = nextExtObj.get(alternateName);
|
||||||
|
if (nextValue != null) {
|
||||||
|
if (nextValue.isObject()) {
|
||||||
|
String nextName = alternateName.substring(1);
|
||||||
|
if (nextExtObj.get(nextName) == null) {
|
||||||
|
theState.enteringNewElement(null, nextName);
|
||||||
|
parseAlternates(nextValue, theState, alternateName, alternateName);
|
||||||
|
theState.endingElement();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
getErrorHandler().incorrectJsonType(null, alternateName, ValueType.OBJECT, null, nextValue.getJsonType(), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
theState.endingElement();
|
theState.endingElement();
|
||||||
|
@ -1314,6 +1367,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
||||||
} else {
|
} else {
|
||||||
String childName = myDef.getChildNameByDatatype(myValue.getClass());
|
String childName = myDef.getChildNameByDatatype(myValue.getClass());
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, myValue, def, childName, false, myParent, false);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, myValue, def, childName, false, myParent, false);
|
||||||
|
managePrimitiveExtension(myValue, theResDef, theResource, theEventWriter, def, childName);
|
||||||
}
|
}
|
||||||
|
|
||||||
theEventWriter.endObject();
|
theEventWriter.endObject();
|
||||||
|
@ -1368,6 +1422,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
||||||
throw new ConfigurationException("Unable to encode extension, unregognized child element type: " + value.getClass().getCanonicalName());
|
throw new ConfigurationException("Unable to encode extension, unregognized child element type: " + value.getClass().getCanonicalName());
|
||||||
}
|
}
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, value, childDef, childName, true, myParent, false);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, value, childDef, childName, true, myParent, false);
|
||||||
|
managePrimitiveExtension(value, theResDef, theResource, theEventWriter, childDef, childName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// theEventWriter.name(myUndeclaredExtension.get);
|
// theEventWriter.name(myUndeclaredExtension.get);
|
||||||
|
@ -1375,6 +1430,26 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
||||||
theEventWriter.endObject();
|
theEventWriter.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void managePrimitiveExtension(final IBase theValue, final RuntimeResourceDefinition theResDef, final IBaseResource theResource, final JsonLikeWriter theEventWriter, final BaseRuntimeElementDefinition<?> def, final String childName) throws IOException {
|
||||||
|
if (def.getChildType().equals(ID_DATATYPE) || def.getChildType().equals(PRIMITIVE_DATATYPE)) {
|
||||||
|
final List<HeldExtension> extensions = new ArrayList<HeldExtension>(0);
|
||||||
|
final List<HeldExtension> modifierExtensions = new ArrayList<HeldExtension>(0);
|
||||||
|
// Undeclared extensions
|
||||||
|
extractUndeclaredExtensions(theValue, extensions, modifierExtensions, myParent, null);
|
||||||
|
// Declared extensions
|
||||||
|
if (def != null) {
|
||||||
|
extractDeclaredExtensions(theValue, def, extensions, modifierExtensions, myParent);
|
||||||
|
}
|
||||||
|
boolean haveContent = false;
|
||||||
|
if (!extensions.isEmpty() || !modifierExtensions.isEmpty()) {
|
||||||
|
haveContent = true;
|
||||||
|
}
|
||||||
|
if (haveContent) {
|
||||||
|
beginObject(theEventWriter, '_' + childName);
|
||||||
|
writeExtensionsAsDirectChild(theResource, theEventWriter, theResDef, extensions, modifierExtensions);
|
||||||
|
theEventWriter.endObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -422,6 +422,7 @@ class ParserState<T> {
|
||||||
push(newState);
|
push(newState);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
case ID_DATATYPE:
|
||||||
case PRIMITIVE_DATATYPE: {
|
case PRIMITIVE_DATATYPE: {
|
||||||
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
||||||
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance(myDefinition.getInstanceConstructorArguments());
|
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance(myDefinition.getInstanceConstructorArguments());
|
||||||
|
@ -1158,10 +1159,16 @@ class ParserState<T> {
|
||||||
// if (isNotBlank(entryBaseUrl)) {
|
// if (isNotBlank(entryBaseUrl)) {
|
||||||
// nextResource.setId(new IdDt(entryBaseUrl, resourceName, bundleIdPart, version));
|
// nextResource.setId(new IdDt(entryBaseUrl, resourceName, bundleIdPart, version));
|
||||||
// } else {
|
// } else {
|
||||||
|
IdDt previousId = nextResource.getId();
|
||||||
nextResource.setId(new IdDt(null, resourceName, bundleIdPart, version));
|
nextResource.setId(new IdDt(null, resourceName, bundleIdPart, version));
|
||||||
|
// Copy extensions
|
||||||
|
if (!previousId.getAllUndeclaredExtensions().isEmpty()) {
|
||||||
|
for (final ExtensionDt ext : previousId.getAllUndeclaredExtensions()) {
|
||||||
|
nextResource.getId().addUndeclaredExtension(ext);
|
||||||
|
}
|
||||||
|
}
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,10 +229,14 @@ public class XmlParser extends BaseParser /* implements IParser */ {
|
||||||
case ID_DATATYPE: {
|
case ID_DATATYPE: {
|
||||||
IIdType value = IIdType.class.cast(theElement);
|
IIdType value = IIdType.class.cast(theElement);
|
||||||
String encodedValue = "id".equals(childName) ? value.getIdPart() : value.getValue();
|
String encodedValue = "id".equals(childName) ? value.getIdPart() : value.getValue();
|
||||||
|
if (StringUtils.isNotBlank(encodedValue) || super.hasExtensions(value)) {
|
||||||
theEventWriter.writeStartElement(childName);
|
theEventWriter.writeStartElement(childName);
|
||||||
|
if (StringUtils.isNotBlank(encodedValue)) {
|
||||||
theEventWriter.writeAttribute("value", encodedValue);
|
theEventWriter.writeAttribute("value", encodedValue);
|
||||||
|
}
|
||||||
encodeExtensionsIfPresent(theResource, theEventWriter, theElement, theIncludedResource);
|
encodeExtensionsIfPresent(theResource, theEventWriter, theElement, theIncludedResource);
|
||||||
theEventWriter.writeEndElement();
|
theEventWriter.writeEndElement();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PRIMITIVE_DATATYPE: {
|
case PRIMITIVE_DATATYPE: {
|
||||||
|
@ -354,8 +358,7 @@ public class XmlParser extends BaseParser /* implements IParser */ {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextChild instanceof RuntimeChildContainedResources) {
|
if (nextChild instanceof RuntimeChildContainedResources) {
|
||||||
encodeChildElementToStreamWriter(theResource, theEventWriter, null, nextChild.getChildNameByDatatype(null), nextChild.getChildElementDefinitionByDatatype(null), null, theContainedResource,
|
encodeChildElementToStreamWriter(theResource, theEventWriter, null, nextChild.getChildNameByDatatype(null), nextChild.getChildElementDefinitionByDatatype(null), null, theContainedResource, nextChildElem);
|
||||||
nextChildElem);
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
List<? extends IBase> values = nextChild.getAccessor().getValues(theElement);
|
List<? extends IBase> values = nextChild.getAccessor().getValues(theElement);
|
||||||
|
@ -398,8 +401,7 @@ public class XmlParser extends BaseParser /* implements IParser */ {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeExtension(IBaseResource theResource, XMLStreamWriter theEventWriter, boolean theContainedResource, CompositeChildElement nextChildElem, BaseRuntimeChildDefinition nextChild,
|
private void encodeExtension(IBaseResource theResource, XMLStreamWriter theEventWriter, boolean theContainedResource, CompositeChildElement nextChildElem, BaseRuntimeChildDefinition nextChild, IBase nextValue, String childName, String extensionUrl, BaseRuntimeElementDefinition<?> childDef)
|
||||||
IBase nextValue, String childName, String extensionUrl, BaseRuntimeElementDefinition<?> childDef)
|
|
||||||
throws XMLStreamException {
|
throws XMLStreamException {
|
||||||
BaseRuntimeDeclaredChildDefinition extDef = (BaseRuntimeDeclaredChildDefinition) nextChild;
|
BaseRuntimeDeclaredChildDefinition extDef = (BaseRuntimeDeclaredChildDefinition) nextChild;
|
||||||
if (extDef.isModifier()) {
|
if (extDef.isModifier()) {
|
||||||
|
@ -434,8 +436,7 @@ public class XmlParser extends BaseParser /* implements IParser */ {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeResourceToXmlStreamWriter(IBaseResource theResource, XMLStreamWriter theEventWriter, boolean theIncludedResource, boolean theSubResource)
|
private void encodeResourceToXmlStreamWriter(IBaseResource theResource, XMLStreamWriter theEventWriter, boolean theIncludedResource, boolean theSubResource) throws XMLStreamException, DataFormatException {
|
||||||
throws XMLStreamException, DataFormatException {
|
|
||||||
IIdType resourceId = null;
|
IIdType resourceId = null;
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(theResource.getIdElement().getIdPart())) {
|
if (StringUtils.isNotBlank(theResource.getIdElement().getIdPart())) {
|
||||||
|
@ -470,11 +471,13 @@ public class XmlParser extends BaseParser /* implements IParser */ {
|
||||||
theEventWriter.writeDefaultNamespace(FHIR_NS);
|
theEventWriter.writeDefaultNamespace(FHIR_NS);
|
||||||
|
|
||||||
if (theResource instanceof IAnyResource) {
|
if (theResource instanceof IAnyResource) {
|
||||||
|
|
||||||
// HL7.org Structures
|
// HL7.org Structures
|
||||||
if (theResourceId != null) {
|
if (theResourceId != null) {
|
||||||
writeCommentsPre(theEventWriter, theResourceId);
|
writeCommentsPre(theEventWriter, theResourceId);
|
||||||
writeOptionalTagWithValue(theEventWriter, "id", theResourceId.getIdPart());
|
theEventWriter.writeStartElement("id");
|
||||||
|
theEventWriter.writeAttribute("value", theResourceId.getIdPart());
|
||||||
|
encodeExtensionsIfPresent(theResource, theEventWriter, theResourceId, false);
|
||||||
|
theEventWriter.writeEndElement();
|
||||||
writeCommentsPost(theEventWriter, theResourceId);
|
writeCommentsPost(theEventWriter, theResourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,8 +489,13 @@ public class XmlParser extends BaseParser /* implements IParser */ {
|
||||||
|
|
||||||
IResource resource = (IResource) theResource;
|
IResource resource = (IResource) theResource;
|
||||||
if (theResourceId != null) {
|
if (theResourceId != null) {
|
||||||
writeCommentsPre(theEventWriter, theResourceId);
|
/* writeCommentsPre(theEventWriter, theResourceId);
|
||||||
writeOptionalTagWithValue(theEventWriter, "id", theResourceId.getIdPart());
|
writeOptionalTagWithValue(theEventWriter, "id", theResourceId.getIdPart());
|
||||||
|
writeCommentsPost(theEventWriter, theResourceId);*/
|
||||||
|
theEventWriter.writeStartElement("id");
|
||||||
|
theEventWriter.writeAttribute("value", theResourceId.getIdPart());
|
||||||
|
encodeExtensionsIfPresent(theResource, theEventWriter, theResourceId, false);
|
||||||
|
theEventWriter.writeEndElement();
|
||||||
writeCommentsPost(theEventWriter, theResourceId);
|
writeCommentsPost(theEventWriter, theResourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package ca.uhn.fhir.parser;
|
package ca.uhn.fhir.parser;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||||
|
import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.model.primitive.StringDt;
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Sébastien Rivière 12/04/2017
|
* Created by Sébastien Rivière 12/04/2017
|
||||||
|
@ -16,7 +17,7 @@ import ca.uhn.fhir.util.TestUtil;
|
||||||
public class ElementWithExtensionDstu2Test {
|
public class ElementWithExtensionDstu2Test {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ca.uhn.fhir.parser.ElementWithExtensionDstu2Test.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ca.uhn.fhir.parser.ElementWithExtensionDstu2Test.class);
|
||||||
private static FhirContext ctx = FhirContext.forDstu2();
|
private final FhirContext ctx = FhirContext.forDstu2();
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void afterClassClearContext() {
|
public static void afterClassClearContext() {
|
||||||
|
@ -24,13 +25,42 @@ public class ElementWithExtensionDstu2Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testExtensionOnPrimitiveExtensionJson() throws Exception {
|
public void testExtensionOnPrimitiveExtensionJson() throws Exception {
|
||||||
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
|
patient.setId("1");
|
||||||
|
final HumanNameDt name = patient.getNameFirstRep();
|
||||||
|
name.addFamily(new StringDt("family"));
|
||||||
|
name.getFamilyFirstRep().addUndeclaredExtension(new ExtensionDt(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK")));
|
||||||
|
|
||||||
|
final StringDt stringExt = new StringDt();
|
||||||
|
stringExt.setValue("myStringExt");
|
||||||
|
stringExt.addUndeclaredExtension(new ExtensionDt(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK")));
|
||||||
|
final ExtensionDt ext = new ExtensionDt();
|
||||||
|
ext.setValue(stringExt);
|
||||||
|
ext.setUrl("/myExt");
|
||||||
|
patient.addUndeclaredExtension(ext);
|
||||||
|
|
||||||
|
|
||||||
|
patient.setPetName(new StringDt("myPet"));
|
||||||
|
patient.getPetName().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||||
|
|
||||||
|
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||||
|
final String json = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
ourLog.info(json);
|
||||||
|
|
||||||
|
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||||
|
assertEquals(1, patient.getName().get(0).getFamilyFirstRep().getUndeclaredExtensions().size());
|
||||||
|
assertEquals(1, ((StringDt) patient.getUndeclaredExtensionsByUrl("/myExt").get(0).getValue()).getUndeclaredExtensions().size());
|
||||||
|
assertEquals(1, patient.getPetName().getUndeclaredExtensions().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExtensionOnPrimitiveExtensionWithNullValueJson() throws Exception {
|
||||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
patient.setId("1");
|
patient.setId("1");
|
||||||
patient.getPetName().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
patient.getPetName().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||||
parser.setServerBaseUrl("http://foo");
|
|
||||||
final String json = parser.encodeResourceToString(patient);
|
final String json = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
ourLog.info(json);
|
ourLog.info(json);
|
||||||
|
@ -39,13 +69,44 @@ public class ElementWithExtensionDstu2Test {
|
||||||
assertEquals(1, patient.getPetName().getUndeclaredExtensions().size());
|
assertEquals(1, patient.getPetName().getUndeclaredExtensions().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExtensionOnPrimitiveExtensionXml() throws Exception {
|
public void testExtensionOnPrimitiveExtensionXml() throws Exception {
|
||||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
patient.setId("1");
|
patient.setId("1");
|
||||||
|
|
||||||
|
final HumanNameDt name = patient.getNameFirstRep();
|
||||||
|
name.addFamily(new StringDt("family"));
|
||||||
|
name.getFamilyFirstRep().addUndeclaredExtension(new ExtensionDt(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK")));
|
||||||
|
|
||||||
|
final StringDt stringExt = new StringDt();
|
||||||
|
stringExt.setValue("myStringExt");
|
||||||
|
stringExt.addUndeclaredExtension(new ExtensionDt(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK")));
|
||||||
|
final ExtensionDt ext = new ExtensionDt();
|
||||||
|
ext.setValue(stringExt);
|
||||||
|
ext.setUrl("/myExt");
|
||||||
|
patient.addUndeclaredExtension(ext);
|
||||||
|
|
||||||
|
|
||||||
|
patient.setPetName(new StringDt("myPet"));
|
||||||
|
patient.getPetName().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||||
|
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||||
|
final String xml = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
ourLog.info(xml);
|
||||||
|
|
||||||
|
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||||
|
assertEquals(1, patient.getName().get(0).getFamilyFirstRep().getUndeclaredExtensions().size());
|
||||||
|
assertEquals(1, ((StringDt) patient.getUndeclaredExtensionsByUrl("/myExt").get(0).getValue()).getUndeclaredExtensions().size());
|
||||||
|
assertEquals(1, patient.getPetName().getUndeclaredExtensions().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExtensionOnPrimitiveExtensionWithNullValueXml() throws Exception {
|
||||||
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
|
patient.setId("1");
|
||||||
patient.getPetName().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
patient.getPetName().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||||
parser.setServerBaseUrl("http://foo");
|
|
||||||
final String xml = parser.encodeResourceToString(patient);
|
final String xml = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
ourLog.info(xml);
|
ourLog.info(xml);
|
||||||
|
@ -55,13 +116,11 @@ public class ElementWithExtensionDstu2Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testExtensionOnIDDatatypeJson() throws Exception {
|
public void testExtensionOnIDDatatypeJson() throws Exception {
|
||||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
patient.setId("1");
|
patient.setId("1");
|
||||||
patient.getId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
patient.getId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||||
parser.setServerBaseUrl("http://foo");
|
|
||||||
final String json = parser.encodeResourceToString(patient);
|
final String json = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
ourLog.info(json);
|
ourLog.info(json);
|
||||||
|
@ -70,14 +129,14 @@ public class ElementWithExtensionDstu2Test {
|
||||||
assertEquals(1, patient.getId().getUndeclaredExtensions().size());
|
assertEquals(1, patient.getId().getUndeclaredExtensions().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testExtensionOnIDDatatypeXml() throws Exception {
|
public void testExtensionOnIDDatatypeXml() throws Exception {
|
||||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
patient.setId("1");
|
patient.setId("1");
|
||||||
patient.getId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
patient.getId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||||
parser.setServerBaseUrl("http://foo");
|
|
||||||
final String xml = parser.encodeResourceToString(patient);
|
final String xml = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
ourLog.info(xml);
|
ourLog.info(xml);
|
||||||
|
@ -87,13 +146,26 @@ public class ElementWithExtensionDstu2Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testExtensionOnIDDatatypeExtensionJson() throws Exception {
|
public void testExtensionOnIDDatatypeExtensionJson() throws Exception {
|
||||||
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
|
patient.setId("1");
|
||||||
|
patient.setCustomId(new IdDt("3"));
|
||||||
|
patient.getCustomId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||||
|
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||||
|
final String json = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
ourLog.info(json);
|
||||||
|
|
||||||
|
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||||
|
assertEquals(1, patient.getCustomId().getUndeclaredExtensions().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExtensionOnIDDatatypeExtensionNullValueJson() throws Exception {
|
||||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
patient.setId("1");
|
patient.setId("1");
|
||||||
patient.getCustomId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
patient.getCustomId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||||
parser.setServerBaseUrl("http://foo");
|
|
||||||
final String json = parser.encodeResourceToString(patient);
|
final String json = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
ourLog.info(json);
|
ourLog.info(json);
|
||||||
|
@ -103,13 +175,26 @@ public class ElementWithExtensionDstu2Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testExtensionOnIDDatatypeExtensionXml() throws Exception {
|
public void testExtensionOnIDDatatypeExtensionXml() throws Exception {
|
||||||
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
|
patient.setId("1");
|
||||||
|
patient.setCustomId(new IdDt("4"));
|
||||||
|
patient.getCustomId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||||
|
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||||
|
final String xml = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
ourLog.info(xml);
|
||||||
|
|
||||||
|
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||||
|
assertEquals(1, patient.getCustomId().getUndeclaredExtensions().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExtensionOnIDDatatypeExtensionNullValueXml() throws Exception {
|
||||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
patient.setId("1");
|
patient.setId("1");
|
||||||
patient.getCustomId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
patient.getCustomId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||||
parser.setServerBaseUrl("http://foo");
|
|
||||||
final String xml = parser.encodeResourceToString(patient);
|
final String xml = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
ourLog.info(xml);
|
ourLog.info(xml);
|
||||||
|
|
|
@ -436,7 +436,7 @@ public final class IdType extends UriType implements IPrimitiveType<String>, IId
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return isBlank(getValue());
|
return super.isEmpty() && isBlank(getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.apache.commons.io.FileUtils;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.hl7.fhir.dstu3.model.Bundle;
|
|
||||||
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
|
|
||||||
import org.hl7.fhir.dstu3.model.DomainResource;
|
|
||||||
import org.hl7.fhir.dstu3.model.Narrative;
|
|
||||||
import org.hl7.fhir.dstu3.model.Resource;
|
|
||||||
import org.junit.AfterClass;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
|
||||||
|
|
||||||
public class MinimizeResources {
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(MinimizeResources.class);
|
|
||||||
|
|
||||||
private static FhirContext ourCtx = FhirContext.forDstu3();
|
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
public static void afterClassClearContext() {
|
|
||||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
|
|
||||||
|
|
||||||
Collection<File> xml = FileUtils.listFiles(new File("../hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/profile"), new String[] {"xml"}, false);
|
|
||||||
for (File next : xml) {
|
|
||||||
ourLog.info("Checking: {}", next.getAbsoluteFile());
|
|
||||||
|
|
||||||
String inputFile = IOUtils.toString(new FileReader(next));
|
|
||||||
Bundle bundle = (Bundle) ourCtx.newXmlParser().parseResource(inputFile);
|
|
||||||
for (BundleEntryComponent nextEntry : bundle.getEntry()) {
|
|
||||||
Resource resource;
|
|
||||||
resource = nextEntry.getResource();
|
|
||||||
if (resource instanceof DomainResource) {
|
|
||||||
((DomainResource) resource).setText(new Narrative());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
String output = ourCtx.newXmlParser().setPrettyPrint(false).encodeResourceToString(bundle);
|
|
||||||
if (!output.equals(inputFile)) {
|
|
||||||
ourLog.info("Rewriting {}", next.getAbsolutePath());
|
|
||||||
|
|
||||||
FileWriter writer = new FileWriter(next, false);
|
|
||||||
writer.append(output);
|
|
||||||
writer.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,14 +1,14 @@
|
||||||
package ca.uhn.fhir.parser;
|
package ca.uhn.fhir.parser;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
import org.hl7.fhir.dstu3.model.StringType;
|
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
import org.hl7.fhir.dstu3.model.*;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Sébastien Rivière 12/04/2017
|
* Created by Sébastien Rivière 12/04/2017
|
||||||
|
@ -16,7 +16,7 @@ import ca.uhn.fhir.util.TestUtil;
|
||||||
public class ElementWithExtensionDstu3Test {
|
public class ElementWithExtensionDstu3Test {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ca.uhn.fhir.parser.ElementWithExtensionDstu3Test.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ca.uhn.fhir.parser.ElementWithExtensionDstu3Test.class);
|
||||||
private static final FhirContext ctx = FhirContext.forDstu3();
|
private final FhirContext ctx = FhirContext.forDstu3();
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void afterClassClearContext() {
|
public static void afterClassClearContext() {
|
||||||
|
@ -24,11 +24,43 @@ public class ElementWithExtensionDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testNullFlavorPrimitiveExtensionJson() throws Exception {
|
public void testNullFlavorPrimitiveExtensionJson() throws Exception {
|
||||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
patient.setId("1");
|
patient.setId("1");
|
||||||
|
final HumanName name = patient.getNameFirstRep();
|
||||||
|
name.setFamily("family");
|
||||||
|
name.getFamilyElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
|
||||||
|
patient.setPetName(new StringType("myPet"));
|
||||||
|
patient.getExtensionsByUrl("/petname");
|
||||||
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
|
||||||
|
final StringType stringExt = new StringType();
|
||||||
|
stringExt.setValue("myStringExt");
|
||||||
|
stringExt.addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
final Extension ext = new Extension();
|
||||||
|
ext.setValue(stringExt);
|
||||||
|
ext.setUrl("/myExt");
|
||||||
|
patient.addExtension(ext);
|
||||||
|
|
||||||
|
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||||
|
final String json = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
ourLog.info(json);
|
||||||
|
|
||||||
|
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||||
|
assertEquals(1, patient.getName().get(0).getFamilyElement().getExtension().size());
|
||||||
|
assertEquals(1, patient.getExtensionsByUrl("/myExt").get(0).getValue().getExtension().size());
|
||||||
|
assertEquals(1, patient.getPetName().getExtension().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullFlavorPrimitiveExtensionNullValueJson() throws Exception {
|
||||||
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
|
patient.setId("1");
|
||||||
|
patient.getExtensionsByUrl("/petname");
|
||||||
|
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
|
||||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||||
final String json = parser.encodeResourceToString(patient);
|
final String json = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
@ -39,11 +71,45 @@ public class ElementWithExtensionDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testNullFlavorPrimitiveExtensionXml() throws Exception {
|
public void testNullFlavorPrimitiveExtensionXml() throws Exception {
|
||||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
patient.setId("1");
|
patient.setId("1");
|
||||||
|
final HumanName name = patient.getNameFirstRep();
|
||||||
|
name.setFamily("family");
|
||||||
|
name.getFamilyElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
|
||||||
|
patient.setPetName(new StringType("myPet"));
|
||||||
|
patient.getExtensionsByUrl("/petname");
|
||||||
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
|
||||||
|
final StringType stringExt = new StringType();
|
||||||
|
stringExt.setValue("myStringExt");
|
||||||
|
stringExt.addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
final Extension ext = new Extension();
|
||||||
|
ext.setValue(stringExt);
|
||||||
|
ext.setUrl("/myExt");
|
||||||
|
patient.addExtension(ext);
|
||||||
|
|
||||||
|
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||||
|
final String xml = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
ourLog.info(xml);
|
||||||
|
|
||||||
|
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||||
|
assertEquals(1, patient.getName().get(0).getFamilyElement().getExtension().size());
|
||||||
|
assertEquals(1, patient.getExtensionsByUrl("/myExt").get(0).getValue().getExtension().size());
|
||||||
|
assertEquals(1, patient.getPetName().getExtension().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullFlavorPrimitiveExtensionNullValueXml() throws Exception {
|
||||||
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
|
patient.setId("1");
|
||||||
|
|
||||||
|
patient.getExtensionsByUrl("/petname");
|
||||||
|
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
|
||||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||||
final String xml = parser.encodeResourceToString(patient);
|
final String xml = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
@ -53,8 +119,8 @@ public class ElementWithExtensionDstu3Test {
|
||||||
assertEquals(1, patient.getPetName().getExtension().size());
|
assertEquals(1, patient.getPetName().getExtension().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testNullFlavorIDDatatypeJson() throws Exception {
|
public void testNullFlavorIDDatatypeJson() throws Exception {
|
||||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
patient.setId("1");
|
patient.setId("1");
|
||||||
|
@ -69,7 +135,6 @@ public class ElementWithExtensionDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testNullFlavorIDDatatypeXml() throws Exception {
|
public void testNullFlavorIDDatatypeXml() throws Exception {
|
||||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
patient.setId("1");
|
patient.setId("1");
|
||||||
|
@ -84,10 +149,10 @@ public class ElementWithExtensionDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testNullFlavorExtensionIDDatatypeJson() throws Exception {
|
public void testNullFlavorExtensionIDDatatypeJson() throws Exception {
|
||||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
patient.setId("1");
|
patient.setId("1");
|
||||||
|
patient.setCustomId(new IdType(("4")));
|
||||||
patient.getCustomId().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
patient.getCustomId().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||||
final String json = parser.encodeResourceToString(patient);
|
final String json = parser.encodeResourceToString(patient);
|
||||||
|
@ -99,12 +164,13 @@ public class ElementWithExtensionDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testNullFlavorExtensionIDDatatypeXml() throws Exception {
|
public void testNullFlavorExtensionIDDatatypeXml() throws Exception {
|
||||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
patient.setId("1");
|
patient.setId("1");
|
||||||
patient.getCustomId().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
|
||||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||||
|
patient.setCustomId(new IdType(("4")));
|
||||||
|
patient.getCustomId().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
|
||||||
final String xml = parser.encodeResourceToString(patient);
|
final String xml = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
ourLog.info(xml);
|
ourLog.info(xml);
|
||||||
|
@ -112,5 +178,48 @@ public class ElementWithExtensionDstu3Test {
|
||||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||||
assertEquals(1, patient.getCustomId().getExtension().size());
|
assertEquals(1, patient.getCustomId().getExtension().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExtensionOnResourceIdXml(){
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.setActive(true);
|
||||||
|
p.getIdElement().setValue("123");
|
||||||
|
p.getIdElement().addExtension().setUrl("http://foo").setValue(new StringType("FOO"));
|
||||||
|
|
||||||
|
IParser parser = ctx.newXmlParser();
|
||||||
|
String encoded = parser.encodeResourceToString(p);
|
||||||
|
assertThat(encoded, containsString("http://foo"));
|
||||||
|
assertThat(encoded, containsString("FOO"));
|
||||||
|
|
||||||
|
p = (Patient) parser.parseResource(encoded);
|
||||||
|
assertEquals("Patient/123", p.getId());
|
||||||
|
Extension ex = p.getIdElement().getExtension().get(0);
|
||||||
|
assertEquals("http://foo", ex.getUrl());
|
||||||
|
assertEquals("FOO", ex.getValueAsPrimitive().getValueAsString());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExtensionOnResourceIdJson(){
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.setActive(true);
|
||||||
|
p.getIdElement().setValue("123");
|
||||||
|
p.getIdElement().addExtension().setUrl("http://foo").setValue(new StringType("FOO"));
|
||||||
|
|
||||||
|
IParser parser = ctx.newJsonParser();
|
||||||
|
String encoded = parser.encodeResourceToString(p);
|
||||||
|
assertThat(encoded, containsString("http://foo"));
|
||||||
|
assertThat(encoded, containsString("FOO"));
|
||||||
|
|
||||||
|
p = (Patient) parser.parseResource(encoded);
|
||||||
|
assertEquals("Patient/123", p.getId());
|
||||||
|
Extension ex = p.getIdElement().getExtension().get(0);
|
||||||
|
assertEquals("http://foo", ex.getUrl());
|
||||||
|
assertEquals("FOO", ex.getValueAsPrimitive().getValueAsString());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class MyPatientWithCustomUrlExtension extends Patient {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return super.isEmpty() && myPetName.isEmpty();
|
return super.isEmpty() && getCustomId().isEmpty() && getPetName().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IdType getCustomId() {
|
public IdType getCustomId() {
|
||||||
|
|
|
@ -0,0 +1,224 @@
|
||||||
|
package ca.uhn.fhir.parser;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
import org.hl7.fhir.r4.model.*;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Sébastien Rivière 12/04/2017
|
||||||
|
*/
|
||||||
|
public class ElementWithExtensionR4Test {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ElementWithExtensionR4Test.class);
|
||||||
|
private static FhirContext ourCtx = FhirContext.forR4();
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClassClearContext() {
|
||||||
|
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullFlavorPrimitiveExtensionJson() throws Exception {
|
||||||
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
|
patient.setId("1");
|
||||||
|
final HumanName name = patient.getNameFirstRep();
|
||||||
|
name.setFamily("family");
|
||||||
|
name.getFamilyElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
|
||||||
|
patient.setPetName(new StringType("myPet"));
|
||||||
|
patient.getExtensionsByUrl("/petname");
|
||||||
|
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
|
||||||
|
final StringType stringExt = new StringType();
|
||||||
|
stringExt.setValue("myStringExt");
|
||||||
|
stringExt.addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
final Extension ext = new Extension();
|
||||||
|
ext.setValue(stringExt);
|
||||||
|
ext.setUrl("/myExt");
|
||||||
|
patient.addExtension(ext);
|
||||||
|
|
||||||
|
final IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||||
|
final String json = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
ourLog.info(json);
|
||||||
|
|
||||||
|
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||||
|
assertEquals(1, patient.getName().get(0).getFamilyElement().getExtension().size());
|
||||||
|
assertEquals(1, patient.getExtensionsByUrl("/myExt").get(0).getValue().getExtension().size());
|
||||||
|
assertEquals(1, patient.getPetName().getExtension().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullFlavorPrimitiveExtensionNullValueJson() throws Exception {
|
||||||
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
|
patient.setId("1");
|
||||||
|
patient.getExtensionsByUrl("/petname");
|
||||||
|
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
|
||||||
|
final IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||||
|
final String json = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
ourLog.info(json);
|
||||||
|
|
||||||
|
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||||
|
assertEquals(1, patient.getPetName().getExtension().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullFlavorPrimitiveExtensionXml() throws Exception {
|
||||||
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
|
patient.setId("1");
|
||||||
|
final HumanName name = patient.getNameFirstRep();
|
||||||
|
name.setFamily("family");
|
||||||
|
name.getFamilyElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
|
||||||
|
patient.setPetName(new StringType("myPet"));
|
||||||
|
patient.getExtensionsByUrl("/petname");
|
||||||
|
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
|
||||||
|
final StringType stringExt = new StringType();
|
||||||
|
stringExt.setValue("myStringExt");
|
||||||
|
stringExt.addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
final Extension ext = new Extension();
|
||||||
|
ext.setValue(stringExt);
|
||||||
|
ext.setUrl("/myExt");
|
||||||
|
patient.addExtension(ext);
|
||||||
|
|
||||||
|
final IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||||
|
final String xml = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
ourLog.info(xml);
|
||||||
|
|
||||||
|
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||||
|
assertEquals(1, patient.getName().get(0).getFamilyElement().getExtension().size());
|
||||||
|
assertEquals(1, patient.getExtensionsByUrl("/myExt").get(0).getValue().getExtension().size());
|
||||||
|
assertEquals(1, patient.getPetName().getExtension().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullFlavorPrimitiveExtensionNullValueXml() throws Exception {
|
||||||
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
|
patient.setId("1");
|
||||||
|
|
||||||
|
patient.getExtensionsByUrl("/petname");
|
||||||
|
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
|
||||||
|
final IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||||
|
final String xml = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
ourLog.info(xml);
|
||||||
|
|
||||||
|
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||||
|
assertEquals(1, patient.getPetName().getExtension().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullFlavorIDDatatypeJson() throws Exception {
|
||||||
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
|
patient.setId("1");
|
||||||
|
patient.getIdElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
final IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||||
|
final String json = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
ourLog.info(json);
|
||||||
|
|
||||||
|
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||||
|
assertEquals(1, patient.getIdElement().getExtension().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullFlavorIDDatatypeXml() throws Exception {
|
||||||
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
|
patient.setId("1");
|
||||||
|
patient.getIdElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
final IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||||
|
final String xml = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
ourLog.info(xml);
|
||||||
|
|
||||||
|
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||||
|
assertEquals(1, patient.getIdElement().getExtension().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullFlavorExtensionIDDatatypeJson() throws Exception {
|
||||||
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
|
patient.setId("1");
|
||||||
|
patient.setCustomId(new IdType(("4")));
|
||||||
|
patient.getCustomId().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
final IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||||
|
final String json = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
ourLog.info(json);
|
||||||
|
|
||||||
|
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||||
|
assertEquals(1, patient.getCustomId().getExtension().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullFlavorExtensionIDDatatypeXml() throws Exception {
|
||||||
|
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||||
|
patient.setId("1");
|
||||||
|
final IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||||
|
patient.setCustomId(new IdType(("4")));
|
||||||
|
patient.getCustomId().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||||
|
|
||||||
|
final String xml = parser.encodeResourceToString(patient);
|
||||||
|
|
||||||
|
ourLog.info(xml);
|
||||||
|
|
||||||
|
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||||
|
assertEquals(1, patient.getCustomId().getExtension().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExtensionOnResourceIdXml(){
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.setActive(true);
|
||||||
|
p.getIdElement().setValue("123");
|
||||||
|
p.getIdElement().addExtension().setUrl("http://foo").setValue(new StringType("FOO"));
|
||||||
|
|
||||||
|
IParser parser = ourCtx.newXmlParser();
|
||||||
|
String encoded = parser.encodeResourceToString(p);
|
||||||
|
assertThat(encoded, containsString("http://foo"));
|
||||||
|
assertThat(encoded, containsString("FOO"));
|
||||||
|
|
||||||
|
p = (Patient) parser.parseResource(encoded);
|
||||||
|
assertEquals("Patient/123", p.getId());
|
||||||
|
Extension ex = p.getIdElement().getExtension().get(0);
|
||||||
|
assertEquals("http://foo", ex.getUrl());
|
||||||
|
assertEquals("FOO", ex.getValueAsPrimitive().getValueAsString());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExtensionOnResourceIdJson(){
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.setActive(true);
|
||||||
|
p.getIdElement().setValue("123");
|
||||||
|
p.getIdElement().addExtension().setUrl("http://foo").setValue(new StringType("FOO"));
|
||||||
|
|
||||||
|
IParser parser = ourCtx.newJsonParser();
|
||||||
|
String encoded = parser.encodeResourceToString(p);
|
||||||
|
assertThat(encoded, containsString("http://foo"));
|
||||||
|
assertThat(encoded, containsString("FOO"));
|
||||||
|
|
||||||
|
p = (Patient) parser.parseResource(encoded);
|
||||||
|
assertEquals("Patient/123", p.getId());
|
||||||
|
Extension ex = p.getIdElement().getExtension().get(0);
|
||||||
|
assertEquals("http://foo", ex.getUrl());
|
||||||
|
assertEquals("FOO", ex.getValueAsPrimitive().getValueAsString());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
package ca.uhn.fhir.parser;
|
||||||
|
|
||||||
|
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;
|
||||||
|
import org.hl7.fhir.r4.model.IdType;
|
||||||
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
import org.hl7.fhir.r4.model.StringType;
|
||||||
|
|
||||||
|
@ResourceDef()
|
||||||
|
public class MyPatientWithCustomUrlExtension extends Patient {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Child(name = "petName")
|
||||||
|
@Extension(url = "/petname", definedLocally = false, isModifier = false)
|
||||||
|
@Description(shortDefinition = "The name of the patient's favourite pet")
|
||||||
|
private StringType myPetName;
|
||||||
|
|
||||||
|
@Child(name = "customid")
|
||||||
|
@Extension(url = "/customid", definedLocally = false, isModifier = false)
|
||||||
|
@Description(shortDefinition = "The customid of the patient's ")
|
||||||
|
private IdType myCustomId;
|
||||||
|
|
||||||
|
public StringType getPetName() {
|
||||||
|
if (myPetName == null) {
|
||||||
|
myPetName = new StringType();
|
||||||
|
}
|
||||||
|
return myPetName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPetName(final StringType thePetName) {
|
||||||
|
myPetName = thePetName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return super.isEmpty() && getCustomId().isEmpty() && getPetName().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdType getCustomId() {
|
||||||
|
if (myCustomId == null) {
|
||||||
|
myCustomId = new IdType();
|
||||||
|
}
|
||||||
|
return myCustomId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCustomId(final IdType myCustomId) {
|
||||||
|
this.myCustomId = myCustomId;
|
||||||
|
}
|
||||||
|
}
|
|
@ -279,6 +279,10 @@
|
||||||
Previously my.org was treated as the resource type and Foo was treated as the ID. Thanks
|
Previously my.org was treated as the resource type and Foo was treated as the ID. Thanks
|
||||||
to GitHub user @CarthageKing for the pull request!
|
to GitHub user @CarthageKing for the pull request!
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix" issue="695">
|
||||||
|
Extensions on ID datatypes were not parsed or serialized correctly. Thanks to
|
||||||
|
Stephen Rivière for the pull request!
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="2.5" date="2017-06-08">
|
<release version="2.5" date="2017-06-08">
|
||||||
<action type="fix">
|
<action type="fix">
|
||||||
|
|
Loading…
Reference in New Issue