Merge pull request #688 from CarthageKing/bugfix-issue659

Correctly serialize baseurl/FooResource references
This commit is contained in:
James Agnew 2017-08-12 14:51:46 -04:00 committed by GitHub
commit 6efafe62f1
18 changed files with 407 additions and 17 deletions

View File

@ -305,11 +305,16 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
b.append(myResourceType);
}
if (b.length() > 0) {
if (b.length() > 0 && isNotBlank(myUnqualifiedId)) {
b.append('/');
}
if (isNotBlank(myUnqualifiedId)) {
b.append(myUnqualifiedId);
} else if (isNotBlank(myUnqualifiedVersionId)) {
b.append('/');
}
b.append(myUnqualifiedId);
if (isNotBlank(myUnqualifiedVersionId)) {
b.append('/');
b.append(Constants.PARAM_HISTORY);
@ -527,7 +532,21 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
if (typeIndex == -1) {
myResourceType = theValue.substring(0, idIndex);
} else {
myResourceType = theValue.substring(typeIndex + 1, idIndex);
if (typeIndex > 0 && '/' == theValue.charAt(typeIndex - 1)) {
typeIndex = theValue.indexOf('/', typeIndex + 1);
}
if (typeIndex >= idIndex) {
// e.g. http://example.org/foo
// 'foo' was the id but we're making that the resource type. Nullify the id part because we don't have an id.
// Also set null value to the super.setValue() and enable myHaveComponentParts so it forces getValue() to properly
// recreate the url
myResourceType = myUnqualifiedId;
myUnqualifiedId = null;
super.setValue(null);
myHaveComponentParts = true;
} else {
myResourceType = theValue.substring(typeIndex + 1, idIndex);
}
if (typeIndex > 4) {
myBaseUrl = theValue.substring(0, typeIndex);

View File

@ -197,8 +197,16 @@ public class ResourceLink implements Serializable {
public void setTargetResourceUrl(IIdType theTargetResourceUrl) {
Validate.isTrue(theTargetResourceUrl.hasBaseUrl());
Validate.isTrue(theTargetResourceUrl.hasResourceType());
Validate.isTrue(theTargetResourceUrl.hasIdPart());
if (theTargetResourceUrl.hasIdPart()) {
// do nothing
} else {
// Must have set an url like http://example.org/something
// We treat 'something' as the resource type because of fix for #659. Prior to #659 fix, 'something' was
// treated as the id and 'example.org' was treated as the resource type
// TODO: log a warning?
}
myTargetResourceType = theTargetResourceUrl.getResourceType();
myTargetResourceUrl = theTargetResourceUrl.getValue();
}

View File

@ -84,7 +84,38 @@ public class IdDtTest {
assertEquals("foo/_history/2", id.withVersion("2").getValue());
}
@Test
public void testBaseUrlFoo1() {
IdDt id = new IdDt("http://my.org/foo");
assertEquals("http://my.org/foo", id.getValueAsString());
assertEquals(null, id.getIdPart());
assertEquals("foo", id.toUnqualified().getValueAsString());
assertEquals("foo", id.toUnqualifiedVersionless().getValueAsString());
assertEquals(null, id.getVersionIdPart());
assertEquals("foo", id.getResourceType());
assertEquals("http://my.org", id.getBaseUrl());
assertEquals("Patient", id.withResourceType("Patient").getValue());
assertEquals("http://foo/Patient", id.withServerBase("http://foo", "Patient").getValue());
assertEquals("http://my.org/foo//_history/2", id.withVersion("2").getValue());
}
@Test
public void testBaseUrlFoo2() {
IdDt id = new IdDt("http://my.org/a/b/c/foo");
assertEquals("http://my.org/a/b/c/foo", id.getValueAsString());
assertEquals("foo", id.getIdPart());
assertEquals("c/foo", id.toUnqualified().getValueAsString());
assertEquals("c/foo", id.toUnqualifiedVersionless().getValueAsString());
assertEquals(null, id.getVersionIdPart());
assertEquals("c", id.getResourceType());
assertEquals("http://my.org/a/b", id.getBaseUrl());
assertEquals("Patient/foo", id.withResourceType("Patient").getValue());
assertEquals("http://foo/Patient/foo", id.withServerBase("http://foo", "Patient").getValue());
assertEquals("http://my.org/a/b/c/foo/_history/2", id.withVersion("2").getValue());
}
@Test
public void testDetectIsIdPartValid() {
assertTrue(new IdDt("0").isIdPartValid());

View File

@ -358,11 +358,16 @@ public final class IdType extends UriType implements IPrimitiveType<String>, IId
b.append(myResourceType);
}
if (b.length() > 0) {
if (b.length() > 0 && isNotBlank(myUnqualifiedId)) {
b.append('/');
}
if (isNotBlank(myUnqualifiedId)) {
b.append(myUnqualifiedId);
} else if (isNotBlank(myUnqualifiedVersionId)) {
b.append('/');
}
b.append(myUnqualifiedId);
if (isNotBlank(myUnqualifiedVersionId)) {
b.append('/');
b.append("_history");
@ -554,7 +559,21 @@ public final class IdType extends UriType implements IPrimitiveType<String>, IId
if (typeIndex == -1) {
myResourceType = theValue.substring(0, idIndex);
} else {
myResourceType = theValue.substring(typeIndex + 1, idIndex);
if (typeIndex > 0 && '/' == theValue.charAt(typeIndex - 1)) {
typeIndex = theValue.indexOf('/', typeIndex + 1);
}
if (typeIndex >= idIndex) {
// e.g. http://example.org/foo
// 'foo' was the id but we're making that the resource type. Nullify the id part because we don't have an id.
// Also set null value to the super.setValue() and enable myHaveComponentParts so it forces getValue() to properly
// recreate the url
myResourceType = myUnqualifiedId;
myUnqualifiedId = null;
super.setValue(null);
myHaveComponentParts = true;
} else {
myResourceType = theValue.substring(typeIndex + 1, idIndex);
}
if (typeIndex > 4) {
myBaseUrl = theValue.substring(0, typeIndex);

View File

@ -92,6 +92,37 @@ public class IdTypeDstu2_1Test {
assertEquals("foo/_history/2", id.withVersion("2").getValue());
}
@Test
public void testBaseUrlFoo1() {
IdType id = new IdType("http://my.org/foo");
assertEquals("http://my.org/foo", id.getValueAsString());
assertEquals(null, id.getIdPart());
assertEquals("foo", id.toUnqualified().getValueAsString());
assertEquals("foo", id.toUnqualifiedVersionless().getValueAsString());
assertEquals(null, id.getVersionIdPart());
assertEquals("foo", id.getResourceType());
assertEquals("http://my.org", id.getBaseUrl());
assertEquals("Patient", id.withResourceType("Patient").getValue());
assertEquals("http://foo/Patient", id.withServerBase("http://foo", "Patient").getValue());
assertEquals("http://my.org/foo//_history/2", id.withVersion("2").getValue());
}
@Test
public void testBaseUrlFoo2() {
IdType id = new IdType("http://my.org/a/b/c/foo");
assertEquals("http://my.org/a/b/c/foo", id.getValueAsString());
assertEquals("foo", id.getIdPart());
assertEquals("c/foo", id.toUnqualified().getValueAsString());
assertEquals("c/foo", id.toUnqualifiedVersionless().getValueAsString());
assertEquals(null, id.getVersionIdPart());
assertEquals("c", id.getResourceType());
assertEquals("http://my.org/a/b", id.getBaseUrl());
assertEquals("Patient/foo", id.withResourceType("Patient").getValue());
assertEquals("http://foo/Patient/foo", id.withServerBase("http://foo", "Patient").getValue());
assertEquals("http://my.org/a/b/c/foo/_history/2", id.withVersion("2").getValue());
}
@Test
public void testDetectLocal() {

View File

@ -1876,6 +1876,26 @@ public class JsonParserDstu2_1Test {
Assert.assertThat(message, containsString("contained"));
}
@Test
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
String refVal = "http://my.org/FooBar";
Patient fhirPat = new Patient();
fhirPat.addExtension().setUrl("x1").setValue(new Reference(refVal));
IParser parser = ourCtx.newJsonParser();
String output = parser.encodeResourceToString(fhirPat);
System.out.println("output: " + output);
// Deserialize then check that valueReference value is still correct
fhirPat = parser.parseResource(Patient.class, output);
List<Extension> extlst = fhirPat.getExtensionsByUrl("x1");
Assert.assertEquals(1, extlst.size());
Assert.assertEquals(refVal, ((Reference) extlst.get(0).getValue()).getReference());
}
@AfterClass

View File

@ -100,6 +100,7 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
@ -2738,6 +2739,26 @@ public class XmlParserDstu2_1Test {
}
@Test
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
String refVal = "http://my.org/FooBar";
Patient fhirPat = new Patient();
fhirPat.addExtension().setUrl("x1").setValue(new Reference(refVal));
IParser parser = ourCtx.newXmlParser();
String output = parser.encodeResourceToString(fhirPat);
System.out.println("output: " + output);
// Deserialize then check that valueReference value is still correct
fhirPat = parser.parseResource(Patient.class, output);
List<Extension> extlst = fhirPat.getExtensionsByUrl("x1");
Assert.assertEquals(1, extlst.size());
Assert.assertEquals(refVal, ((Reference) extlst.get(0).getValue()).getReference());
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();

View File

@ -142,7 +142,7 @@ public class BaseResourceReferenceDtTest {
new ResourceReferenceDt("http://foo/123123").loadResource(client);
fail();
} catch (DataFormatException e) {
assertEquals("Unknown resource name \"foo\" (this name is not known in FHIR version \"DSTU2\")", e.getMessage());
assertEquals("Unknown resource name \"123123\" (this name is not known in FHIR version \"DSTU2\")", e.getMessage());
}
try {

View File

@ -2043,4 +2043,24 @@ public class JsonParserDstu2Test {
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@Test
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
String refVal = "http://my.org/FooBar";
Patient fhirPat = new Patient();
fhirPat.addUndeclaredExtension(false, "x1").setValue(new ResourceReferenceDt(refVal));
IParser parser = ourCtx.newJsonParser();
String output = parser.encodeResourceToString(fhirPat);
System.out.println("output: " + output);
// Deserialize then check that valueReference value is still correct
fhirPat = parser.parseResource(Patient.class, output);
List<ExtensionDt> extlst = fhirPat.getUndeclaredExtensionsByUrl("x1");
Assert.assertEquals(1, extlst.size());
Assert.assertEquals(refVal, ((ResourceReferenceDt) extlst.get(0).getValue()).getReference().getValue());
}
}

View File

@ -33,6 +33,7 @@ import org.hamcrest.text.StringContainsInOrder;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
@ -2853,6 +2854,26 @@ public class XmlParserDstu2Test {
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@Test
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
String refVal = "http://my.org/FooBar";
Patient fhirPat = new Patient();
fhirPat.addUndeclaredExtension(false, "x1").setValue(new ResourceReferenceDt(refVal));
IParser parser = ourCtx.newXmlParser();
String output = parser.encodeResourceToString(fhirPat);
System.out.println("output: " + output);
// Deserialize then check that valueReference value is still correct
fhirPat = parser.parseResource(Patient.class, output);
List<ExtensionDt> extlst = fhirPat.getUndeclaredExtensionsByUrl("x1");
Assert.assertEquals(1, extlst.size());
Assert.assertEquals(refVal, ((ResourceReferenceDt) extlst.get(0).getValue()).getReference().getValue());
}
@AfterClass
public static void afterClassClearContext() {

View File

@ -357,11 +357,16 @@ public final class IdType extends UriType implements IPrimitiveType<String>, IId
b.append(myResourceType);
}
if (b.length() > 0) {
if (b.length() > 0 && isNotBlank(myUnqualifiedId)) {
b.append('/');
}
if (isNotBlank(myUnqualifiedId)) {
b.append(myUnqualifiedId);
} else if (isNotBlank(myUnqualifiedVersionId)) {
b.append('/');
}
b.append(myUnqualifiedId);
if (isNotBlank(myUnqualifiedVersionId)) {
b.append('/');
b.append("_history");
@ -553,7 +558,21 @@ public final class IdType extends UriType implements IPrimitiveType<String>, IId
if (typeIndex == -1) {
myResourceType = theValue.substring(0, idIndex);
} else {
myResourceType = theValue.substring(typeIndex + 1, idIndex);
if (typeIndex > 0 && '/' == theValue.charAt(typeIndex - 1)) {
typeIndex = theValue.indexOf('/', typeIndex + 1);
}
if (typeIndex >= idIndex) {
// e.g. http://example.org/foo
// 'foo' was the id but we're making that the resource type. Nullify the id part because we don't have an id.
// Also set null value to the super.setValue() and enable myHaveComponentParts so it forces getValue() to properly
// recreate the url
myResourceType = myUnqualifiedId;
myUnqualifiedId = null;
super.setValue(null);
myHaveComponentParts = true;
} else {
myResourceType = theValue.substring(typeIndex + 1, idIndex);
}
if (typeIndex > 4) {
myBaseUrl = theValue.substring(0, typeIndex);

View File

@ -92,6 +92,38 @@ public class IdTypeDstu3Test {
assertEquals("foo/_history/2", id.withVersion("2").getValue());
}
@Test
public void testBaseUrlFoo1() {
IdType id = new IdType("http://my.org/foo");
assertEquals("http://my.org/foo", id.getValueAsString());
assertEquals(null, id.getIdPart());
assertEquals("foo", id.toUnqualified().getValueAsString());
assertEquals("foo", id.toUnqualifiedVersionless().getValueAsString());
assertEquals(null, id.getVersionIdPart());
assertEquals("foo", id.getResourceType());
assertEquals("http://my.org", id.getBaseUrl());
assertEquals("Patient", id.withResourceType("Patient").getValue());
assertEquals("http://foo/Patient", id.withServerBase("http://foo", "Patient").getValue());
assertEquals("http://my.org/foo//_history/2", id.withVersion("2").getValue());
}
@Test
public void testBaseUrlFoo2() {
IdType id = new IdType("http://my.org/a/b/c/foo");
assertEquals("http://my.org/a/b/c/foo", id.getValueAsString());
assertEquals("foo", id.getIdPart());
assertEquals("c/foo", id.toUnqualified().getValueAsString());
assertEquals("c/foo", id.toUnqualifiedVersionless().getValueAsString());
assertEquals(null, id.getVersionIdPart());
assertEquals("c", id.getResourceType());
assertEquals("http://my.org/a/b", id.getBaseUrl());
assertEquals("Patient/foo", id.withResourceType("Patient").getValue());
assertEquals("http://foo/Patient/foo", id.withServerBase("http://foo", "Patient").getValue());
assertEquals("http://my.org/a/b/c/foo/_history/2", id.withVersion("2").getValue());
}
@Test
public void testDetectLocal() {
IdType id;

View File

@ -2430,6 +2430,26 @@ public class JsonParserDstu3Test {
assertTrue(result.isSuccessful());
}
@Test
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
String refVal = "http://my.org/FooBar";
Patient fhirPat = new Patient();
fhirPat.addExtension().setUrl("x1").setValue(new Reference(refVal));
IParser parser = ourCtx.newJsonParser();
String output = parser.encodeResourceToString(fhirPat);
System.out.println("output: " + output);
// Deserialize then check that valueReference value is still correct
fhirPat = parser.parseResource(Patient.class, output);
List<Extension> extlst = fhirPat.getExtensionsByUrl("x1");
Assert.assertEquals(1, extlst.size());
Assert.assertEquals(refVal, ((Reference) extlst.get(0).getValue()).getReference());
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();

View File

@ -3323,6 +3323,26 @@ public class XmlParserDstu3Test {
}
@Test
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
String refVal = "http://my.org/FooBar";
Patient fhirPat = new Patient();
fhirPat.addExtension().setUrl("x1").setValue(new Reference(refVal));
IParser parser = ourCtx.newXmlParser();
String output = parser.encodeResourceToString(fhirPat);
System.out.println("output: " + output);
// Deserialize then check that valueReference value is still correct
fhirPat = parser.parseResource(Patient.class, output);
List<Extension> extlst = fhirPat.getExtensionsByUrl("x1");
Assert.assertEquals(1, extlst.size());
Assert.assertEquals(refVal, ((Reference) extlst.get(0).getValue()).getReference());
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();

View File

@ -384,11 +384,16 @@ public final class IdType extends UriType implements IPrimitiveType<String>, IId
b.append(myResourceType);
}
if (b.length() > 0) {
if (b.length() > 0 && isNotBlank(myUnqualifiedId)) {
b.append('/');
}
if (isNotBlank(myUnqualifiedId)) {
b.append(myUnqualifiedId);
} else if (isNotBlank(myUnqualifiedVersionId)) {
b.append('/');
}
b.append(myUnqualifiedId);
if (isNotBlank(myUnqualifiedVersionId)) {
b.append('/');
b.append("_history");
@ -571,7 +576,21 @@ public final class IdType extends UriType implements IPrimitiveType<String>, IId
if (typeIndex == -1) {
myResourceType = theValue.substring(0, idIndex);
} else {
myResourceType = theValue.substring(typeIndex + 1, idIndex);
if (typeIndex > 0 && '/' == theValue.charAt(typeIndex - 1)) {
typeIndex = theValue.indexOf('/', typeIndex + 1);
}
if (typeIndex >= idIndex) {
// e.g. http://example.org/foo
// 'foo' was the id but we're making that the resource type. Nullify the id part because we don't have an id.
// Also set null value to the super.setValue() and enable myHaveComponentParts so it forces getValue() to properly
// recreate the url
myResourceType = myUnqualifiedId;
myUnqualifiedId = null;
super.setValue(null);
myHaveComponentParts = true;
} else {
myResourceType = theValue.substring(typeIndex + 1, idIndex);
}
if (typeIndex > 4) {
myBaseUrl = theValue.substring(0, typeIndex);

View File

@ -83,7 +83,55 @@ public class IdTypeTest {
assertEquals("Patient/cid:Patient-72/_history/1", id2.getIdPart());
}
@Test
public void testNormal() {
IdType id = new IdType("foo");
assertEquals("foo", id.getValueAsString());
assertEquals("foo", id.getIdPart());
assertEquals("foo", id.toUnqualified().getValueAsString());
assertEquals("foo", id.toUnqualifiedVersionless().getValueAsString());
assertEquals(null, id.getVersionIdPart());
assertEquals(null, id.getResourceType());
assertEquals(null, id.getBaseUrl());
assertEquals("Patient/foo", id.withResourceType("Patient").getValue());
assertEquals("http://foo/Patient/foo", id.withServerBase("http://foo", "Patient").getValue());
assertEquals("foo/_history/2", id.withVersion("2").getValue());
}
@Test
public void testBaseUrlFoo1() {
IdType id = new IdType("http://my.org/foo");
assertEquals("http://my.org/foo", id.getValueAsString());
assertEquals(null, id.getIdPart());
assertEquals("foo", id.toUnqualified().getValueAsString());
assertEquals("foo", id.toUnqualifiedVersionless().getValueAsString());
assertEquals(null, id.getVersionIdPart());
assertEquals("foo", id.getResourceType());
assertEquals("http://my.org", id.getBaseUrl());
assertEquals("Patient", id.withResourceType("Patient").getValue());
assertEquals("http://foo/Patient", id.withServerBase("http://foo", "Patient").getValue());
assertEquals("http://my.org/foo//_history/2", id.withVersion("2").getValue());
}
@Test
public void testBaseUrlFoo2() {
IdType id = new IdType("http://my.org/a/b/c/foo");
assertEquals("http://my.org/a/b/c/foo", id.getValueAsString());
assertEquals("foo", id.getIdPart());
assertEquals("c/foo", id.toUnqualified().getValueAsString());
assertEquals("c/foo", id.toUnqualifiedVersionless().getValueAsString());
assertEquals(null, id.getVersionIdPart());
assertEquals("c", id.getResourceType());
assertEquals("http://my.org/a/b", id.getBaseUrl());
assertEquals("Patient/foo", id.withResourceType("Patient").getValue());
assertEquals("http://foo/Patient/foo", id.withServerBase("http://foo", "Patient").getValue());
assertEquals("http://my.org/a/b/c/foo/_history/2", id.withVersion("2").getValue());
}
@Test
public void testDetermineBase() {

View File

@ -63,6 +63,7 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.xml.sax.SAXException;
@ -1383,6 +1384,26 @@ public class JsonParserHl7OrgDstu2Test {
}
@Test
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
String refVal = "http://my.org/FooBar";
Patient fhirPat = new Patient();
fhirPat.addExtension().setUrl("x1").setValue(new Reference(refVal));
IParser parser = ourCtx.newJsonParser();
String output = parser.encodeResourceToString(fhirPat);
System.out.println("output: " + output);
// Deserialize then check that valueReference value is still correct
fhirPat = parser.parseResource(Patient.class, output);
List<Extension> extlst = fhirPat.getExtension();
Assert.assertEquals(1, extlst.size());
Assert.assertEquals(refVal, ((Reference) extlst.get(0).getValue()).getReference());
}
@ResourceDef(name = "Patient")
public static class MyPatientWithOneDeclaredAddressExtension extends Patient {

View File

@ -65,6 +65,7 @@ import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.INarrative;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.junit.After;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
@ -1790,6 +1791,26 @@ public class XmlParserHl7OrgDstu2Test {
}
@Test
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
String refVal = "http://my.org/FooBar";
Patient fhirPat = new Patient();
fhirPat.addExtension().setUrl("x1").setValue(new Reference(refVal));
IParser parser = ourCtx.newXmlParser();
String output = parser.encodeResourceToString(fhirPat);
System.out.println("output: " + output);
// Deserialize then check that valueReference value is still correct
fhirPat = parser.parseResource(Patient.class, output);
List<Extension> extlst = fhirPat.getExtension();
Assert.assertEquals(1, extlst.size());
Assert.assertEquals(refVal, ((Reference) extlst.get(0).getValue()).getReference());
}
@BeforeClass
public static void beforeClass() {
XMLUnit.setIgnoreAttributeOrder(true);