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

This commit is contained in:
James Agnew 2015-12-14 10:56:33 -05:00
commit 9ef0498775
8 changed files with 279 additions and 151 deletions

1
.gitignore vendored
View File

@ -16,6 +16,7 @@ nohup.out
tmp.txt tmp.txt
*.hprof *.hprof
tmp.txt tmp.txt
ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString/
# Vagrant stuff. # Vagrant stuff.
.vagrant .vagrant

View File

@ -2,6 +2,8 @@ package ca.uhn.fhir.model.api;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import ch.qos.logback.core.db.dialect.MySQLDialect;
/* /*
* #%L * #%L
* HAPI FHIR - Core Library * HAPI FHIR - Core Library
@ -34,7 +36,7 @@ public class Include {
private boolean myRecurse; private boolean myRecurse;
private String myValue; private String myValue;
private boolean myImmutable; private final boolean myImmutable;
/** /**
* Constructor for <b>non-recursive</b> include * Constructor for <b>non-recursive</b> include
@ -44,10 +46,11 @@ public class Include {
*/ */
public Include(String theValue) { public Include(String theValue) {
myValue = theValue; myValue = theValue;
myImmutable = false;
} }
/** /**
* Constructor for <b>non-recursive</b> include * Constructor for an include
* *
* @param theValue * @param theValue
* The <code>_include</code> value, e.g. "Patient:name" * The <code>_include</code> value, e.g. "Patient:name"
@ -57,6 +60,21 @@ public class Include {
public Include(String theValue, boolean theRecurse) { public Include(String theValue, boolean theRecurse) {
myValue = theValue; myValue = theValue;
myRecurse = theRecurse; myRecurse = theRecurse;
myImmutable = false;
}
/**
* Constructor for an include
*
* @param theValue
* The <code>_include</code> value, e.g. "Patient:name"
* @param theRecurse
* Should the include recurse
*/
public Include(String theValue, boolean theRecurse, boolean theImmutable) {
myValue = theValue;
myRecurse = theRecurse;
myImmutable = theImmutable;
} }
/** /**
@ -132,9 +150,18 @@ public class Include {
myValue = theValue; myValue = theValue;
} }
/**
* Is this object {@link #toLocked() locked}?
*/
public boolean isLocked() {
return myImmutable;
}
/**
* Return a new
*/
public Include toLocked() { public Include toLocked() {
Include retVal = new Include(myValue, myRecurse); Include retVal = new Include(myValue, myRecurse, true);
retVal.myImmutable = true;
return retVal; return retVal;
} }
@ -145,4 +172,36 @@ public class Include {
builder.append("recurse", myRecurse); builder.append("recurse", myRecurse);
return builder.toString(); return builder.toString();
} }
/**
* Creates and returns a new copy of this Include with the given type. The
* following table shows what will be returned:
* <table>
* <tr><th>Initial Contents</th><th>theResourceType</th><th>Output</th></tr>
* <tr><td>Patient:careProvider</th><th>Organization</th><th>Patient:careProvider:Organization</th></tr>
* <tr><td>Patient:careProvider:Practitioner</th><th>Organization</th><th>Patient:careProvider:Organization</th></tr>
* <tr><td>Patient</th><th>(any)</th><th>{@link IllegalStateException}</th></tr>
* </table>
*
* @param theResourceType The resource type (e.g. "Organization")
* @return A new copy of the include. Note that if this include is {@link #toLocked() locked}, the returned include will be too
*/
public Include withType(String theResourceType) {
StringBuilder b = new StringBuilder();
b.append(myValue);
int firstColon = myValue.indexOf(':');
if (firstColon == -1 || firstColon == b.length() - 1) {
throw new IllegalStateException("This include does not contain a value in the format [ResourceType]:[paramName]");
}
int secondColon = myValue.indexOf(':', firstColon + 1);
if (secondColon != -1) {
b.delete(secondColon, b.length());
}
b.append(":");
b.append(theResourceType);
Include retVal = new Include(b.toString(), myRecurse, myImmutable);
return retVal;
}
} }

View File

@ -1322,7 +1322,7 @@ public class SearchBuilder {
* *
* @param theLastUpdated * @param theLastUpdated
*/ */
private HashSet<Long> loadReverseIncludes(Collection<Long> theMatches, Set<Include> theRevIncludes, boolean theReverseMode, EverythingModeEnum theEverythingModeEnum, DateRangeParam theLastUpdated) { private HashSet<Long> loadReverseIncludes(Collection<Long> theMatches, Set<Include> theRevIncludes, boolean theReverseMode, DateRangeParam theLastUpdated) {
if (theMatches.size() == 0) { if (theMatches.size() == 0) {
return new HashSet<Long>(); return new HashSet<Long>();
} }
@ -1595,7 +1595,7 @@ public class SearchBuilder {
final Set<Long> revIncludedPids; final Set<Long> revIncludedPids;
if (theParams.getEverythingMode() == null) { if (theParams.getEverythingMode() == null) {
if (theParams.getRevIncludes() != null && theParams.getRevIncludes().isEmpty() == false) { if (theParams.getRevIncludes() != null && theParams.getRevIncludes().isEmpty() == false) {
revIncludedPids = loadReverseIncludes(pids, theParams.getRevIncludes(), true, null, lu); revIncludedPids = loadReverseIncludes(pids, theParams.getRevIncludes(), true, lu);
} else { } else {
revIncludedPids = new HashSet<Long>(); revIncludedPids = new HashSet<Long>();
} }
@ -1623,7 +1623,7 @@ public class SearchBuilder {
// Load includes // Load includes
pidsSubList = new ArrayList<Long>(pidsSubList); pidsSubList = new ArrayList<Long>(pidsSubList);
revIncludedPids.addAll(loadReverseIncludes(pidsSubList, theParams.getIncludes(), false, null, theParams.getLastUpdated())); revIncludedPids.addAll(loadReverseIncludes(pidsSubList, theParams.getIncludes(), false, theParams.getLastUpdated()));
// Execute the query and make sure we return distinct results // Execute the query and make sure we return distinct results
List<IBaseResource> resources = new ArrayList<IBaseResource>(); List<IBaseResource> resources = new ArrayList<IBaseResource>();

View File

@ -4,7 +4,9 @@ import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import java.util.List; import java.util.List;
@ -14,9 +16,8 @@ import javax.servlet.http.HttpServletRequest;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.Test; import org.junit.Test;
import ca.uhn.fhir.jpa.dao.FhirSearchDao;
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.jpa.dao.FhirSearchDao.Suggestion; import ca.uhn.fhir.jpa.dao.FhirSearchDao.Suggestion;
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.model.dstu2.resource.Device; import ca.uhn.fhir.model.dstu2.resource.Device;
import ca.uhn.fhir.model.dstu2.resource.Media; import ca.uhn.fhir.model.dstu2.resource.Media;
import ca.uhn.fhir.model.dstu2.resource.Observation; import ca.uhn.fhir.model.dstu2.resource.Observation;

View File

@ -1430,25 +1430,36 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
{ {
Organization org = new Organization(); Organization org = new Organization();
org.getNameElement().setValue(methodName + "_O1Parent"); org.getNameElement().setValue(methodName + "_O1Parent");
parentOrgId = myOrganizationDao.create(org).getId(); parentOrgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
} }
IIdType orgId;
IIdType patientId;
{ {
Organization org = new Organization(); Organization org = new Organization();
org.getNameElement().setValue(methodName + "_O1"); org.getNameElement().setValue(methodName + "_O1");
org.setPartOf(new ResourceReferenceDt(parentOrgId)); org.setPartOf(new ResourceReferenceDt(parentOrgId));
IIdType orgId = myOrganizationDao.create(org).getId(); orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
Patient patient = new Patient(); Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001"); patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().addFamily("Tester_" + methodName + "_P1").addGiven("Joe"); patient.addName().addFamily("Tester_" + methodName + "_P1").addGiven("Joe");
patient.getManagingOrganization().setReference(orgId); patient.getManagingOrganization().setReference(orgId);
myPatientDao.create(patient); patient.addCareProvider().setReference(orgId);
patientId = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
} }
IIdType practId2;
{
Practitioner pract = new Practitioner();
pract.getName().addFamily(methodName + "_PRACT1");
practId2 = myPractitionerDao.create(pract).getId().toUnqualifiedVersionless();
}
IIdType patientId2;
{ {
Patient patient = new Patient(); Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("002"); patient.addIdentifier().setSystem("urn:system").setValue("002");
patient.addName().addFamily("Tester_" + methodName + "_P2").addGiven("John"); patient.addName().addFamily("Tester_" + methodName + "_P2").addGiven("John");
myPatientDao.create(patient); patient.addCareProvider().setReference(practId2);
patientId2 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
} }
{ {
@ -1527,6 +1538,20 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
assertEquals(1, patients.size()); assertEquals(1, patients.size());
assertEquals(Patient.class, patients.get(0).getClass()); assertEquals(Patient.class, patients.get(0).getClass());
} }
{
// Untyped include
SearchParameterMap params = new SearchParameterMap();
params.addInclude(Patient.INCLUDE_CAREPROVIDER);
List<IIdType> ids = toUnqualifiedVersionlessIds(myPatientDao.search(params));
assertThat(ids, containsInAnyOrder(orgId, patientId, patientId2, practId2));
}
{
// // Typed include
// SearchParameterMap params = new SearchParameterMap();
// params.addInclude(Patient.INCLUDE_CAREPROVIDER.withType("Practitioner"));
// List<IIdType> ids = toUnqualifiedVersionlessIds(myPatientDao.search(params));
// assertThat(ids, containsInAnyOrder(patientId, patientId2, practId2));
}
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")

View File

@ -1,7 +1,10 @@
package ca.uhn.fhir.rest.server; package ca.uhn.fhir.rest.server;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.*; import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -51,56 +54,21 @@ import ca.uhn.fhir.util.PortUtil;
public class IncludeTest { public class IncludeTest {
private static CloseableHttpClient ourClient; private static CloseableHttpClient ourClient;
private static FhirContext ourCtx;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(IncludeTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(IncludeTest.class);
private static int ourPort; private static int ourPort;
private static Server ourServer; private static Server ourServer;
private static FhirContext ourCtx;
@Test @Test
public void testNoIncludes() throws Exception { public void testBadInclude() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello"); HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello&_include=foo&_include=baz");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
assertEquals(1, bundle.size());
Patient p = bundle.getResources(Patient.class).get(0);
assertEquals(0, p.getName().size());
assertEquals("Hello", p.getId().getIdPart());
}
@Test
public void testOneInclude() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello&_include=foo");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
assertEquals(1, bundle.size());
Patient p = bundle.getResources(Patient.class).get(0);
assertEquals(1, p.getName().size());
assertEquals("Hello", p.getId().getIdPart());
assertEquals("foo", p.getName().get(0).getFamilyFirstRep().getValue());
}
// @Test
public void testMixedContainedAndNonContained() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/DiagnosticReport?_query=stitchedInclude&_pretty=true");
HttpResponse status = ourClient.execute(httpGet); HttpResponse status = ourClient.execute(httpGet);
assertEquals(400, status.getStatusLine().getStatusCode());
String responseContent = IOUtils.toString(status.getEntity().getContent()); String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent()); IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info(responseContent); ourLog.info(responseContent);
assertThat(responseContent, containsString("Invalid _include parameter value"));
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
assertEquals(4, bundle.size());
} }
@Test @Test
@ -128,6 +96,32 @@ public class IncludeTest {
} }
@Test
public void testIIncludedResourcesNonContainedInDeclaredExtension() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=declaredExtInclude&_pretty=true");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
ourLog.info(responseContent);
assertEquals(4, bundle.size());
assertEquals(new IdDt("Patient/p1"), bundle.toListOfResources().get(0).getId().toUnqualifiedVersionless());
assertEquals(new IdDt("Patient/p2"), bundle.toListOfResources().get(1).getId().toUnqualifiedVersionless());
assertEquals(new IdDt("Organization/o1"), bundle.toListOfResources().get(2).getId().toUnqualifiedVersionless());
assertEquals(new IdDt("Organization/o2"), bundle.toListOfResources().get(3).getId().toUnqualifiedVersionless());
Patient p1 = (Patient) bundle.toListOfResources().get(0);
assertEquals(0, p1.getContained().getContainedResources().size());
Patient p2 = (Patient) bundle.toListOfResources().get(1);
assertEquals(0, p2.getContained().getContainedResources().size());
}
@Test @Test
public void testIIncludedResourcesNonContainedInExtension() throws Exception { public void testIIncludedResourcesNonContainedInExtension() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=extInclude&_pretty=true"); HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=extInclude&_pretty=true");
@ -179,29 +173,79 @@ public class IncludeTest {
} }
@Test @Test
public void testIIncludedResourcesNonContainedInDeclaredExtension() throws Exception { public void testIncludeWithType() {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=declaredExtInclude&_pretty=true"); assertEquals("Patient:careProvider:Practitioner", new Include("Patient:careProvider", true).withType("Practitioner").getValue());
assertEquals(true, new Include("Patient:careProvider", true).withType("Practitioner").isRecurse());
assertEquals(false, new Include("Patient:careProvider:Organization", true).withType("Practitioner").isLocked());
assertEquals("Patient:careProvider:Practitioner", new Include("Patient:careProvider:Organization", true).withType("Practitioner").getValue());
assertEquals(true, new Include("Patient:careProvider:Organization", true).toLocked().withType("Practitioner").isLocked());
try {
new Include("").withType("Patient");
fail();
} catch (IllegalStateException e) {
// good
}
try {
new Include("Patient").withType("Patient");
fail();
} catch (IllegalStateException e) {
// good
}
try {
new Include("Patient:").withType("Patient");
fail();
} catch (IllegalStateException e) {
// good
}
}
// @Test
public void testMixedContainedAndNonContained() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/DiagnosticReport?_query=stitchedInclude&_pretty=true");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info(responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
assertEquals(4, bundle.size());
}
@Test
public void testNoIncludes() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello");
HttpResponse status = ourClient.execute(httpGet); HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent()); String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent()); IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode()); assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent); Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
assertEquals(1, bundle.size());
ourLog.info(responseContent); Patient p = bundle.getResources(Patient.class).get(0);
assertEquals(0, p.getName().size());
assertEquals("Hello", p.getId().getIdPart());
}
assertEquals(4, bundle.size()); @Test
assertEquals(new IdDt("Patient/p1"), bundle.toListOfResources().get(0).getId().toUnqualifiedVersionless()); public void testOneInclude() throws Exception {
assertEquals(new IdDt("Patient/p2"), bundle.toListOfResources().get(1).getId().toUnqualifiedVersionless()); HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello&_include=foo");
assertEquals(new IdDt("Organization/o1"), bundle.toListOfResources().get(2).getId().toUnqualifiedVersionless()); HttpResponse status = ourClient.execute(httpGet);
assertEquals(new IdDt("Organization/o2"), bundle.toListOfResources().get(3).getId().toUnqualifiedVersionless()); String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
Patient p1 = (Patient) bundle.toListOfResources().get(0); assertEquals(200, status.getStatusLine().getStatusCode());
assertEquals(0, p1.getContained().getContainedResources().size()); Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
assertEquals(1, bundle.size());
Patient p2 = (Patient) bundle.toListOfResources().get(1);
assertEquals(0, p2.getContained().getContainedResources().size());
Patient p = bundle.getResources(Patient.class).get(0);
assertEquals(1, p.getName().size());
assertEquals("Hello", p.getId().getIdPart());
assertEquals("foo", p.getName().get(0).getFamilyFirstRep().getValue());
} }
@Test @Test
@ -226,18 +270,6 @@ public class IncludeTest {
} }
@Test
public void testBadInclude() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello&_include=foo&_include=baz");
HttpResponse status = ourClient.execute(httpGet);
assertEquals(400, status.getStatusLine().getStatusCode());
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info(responseContent);
assertThat(responseContent, containsString("Invalid _include parameter value"));
}
@AfterClass @AfterClass
public static void afterClass() throws Exception { public static void afterClass() throws Exception {
ourServer.stop(); ourServer.stop();
@ -268,27 +300,20 @@ public class IncludeTest {
} }
@ResourceDef(name = "Patient") public static void main(String[] args) {
public static class ExtPatient extends Patient {
@Child(name = "secondOrg")
@Extension(url = "http://foo#secondOrg", definedLocally = false, isModifier = false)
private ResourceReferenceDt mySecondOrg;
@Override Organization org = new Organization();
public boolean isEmpty() { org.setId("Organization/65546");
return super.isEmpty() && ElementUtil.isEmpty(mySecondOrg); org.getName().setValue("Contained Test Organization");
}
public ResourceReferenceDt getSecondOrg() { Patient patient = new Patient();
if (mySecondOrg == null) { patient.setId("Patient/1333");
mySecondOrg = new ResourceReferenceDt(); patient.addIdentifier("urn:mrns", "253345");
} patient.getManagingOrganization().setResource(patient);
return mySecondOrg;
}
public void setSecondOrg(ResourceReferenceDt theSecondOrg) { System.out.println(FhirContext.forDstu1().newXmlParser().setPrettyPrint(true).encodeResourceToString(patient));
mySecondOrg = theSecondOrg;
} patient.getManagingOrganization().getReference();
} }
@ -345,11 +370,10 @@ public class IncludeTest {
*/ */
public static class DummyPatientResourceProvider implements IResourceProvider { public static class DummyPatientResourceProvider implements IResourceProvider {
@Search(queryName = "normalInclude") @Search(queryName = "containedInclude")
public List<Patient> normalInclude() { public List<Patient> containedInclude() {
Organization o1 = new Organization(); Organization o1 = new Organization();
o1.getName().setValue("o1"); o1.getName().setValue("o1");
o1.setId("o1");
Patient p1 = new Patient(); Patient p1 = new Patient();
p1.setId("p1"); p1.setId("p1");
@ -364,25 +388,6 @@ public class IncludeTest {
return Arrays.asList(p1, p2); return Arrays.asList(p1, p2);
} }
@Search(queryName = "extInclude")
public List<Patient> extInclude() {
Organization o1 = new Organization();
o1.getName().setValue("o1");
o1.setId("o1");
Patient p1 = new Patient();
p1.setId("p1");
p1.addIdentifier().setLabel("p1");
p1.addUndeclaredExtension(false, "http://foo", new ResourceReferenceDt(o1));
Patient p2 = new Patient();
p2.setId("p2");
p2.addIdentifier().setLabel("p2");
p2.addUndeclaredExtension(false, "http://foo", new ResourceReferenceDt(o1));
return Arrays.asList(p1, p2);
}
@Search(queryName = "declaredExtInclude") @Search(queryName = "declaredExtInclude")
public List<ExtPatient> declaredExtInclude() { public List<ExtPatient> declaredExtInclude() {
Organization o1 = new Organization(); Organization o1 = new Organization();
@ -407,20 +412,21 @@ public class IncludeTest {
return Arrays.asList(p1, p2); return Arrays.asList(p1, p2);
} }
@Search(queryName = "containedInclude") @Search(queryName = "extInclude")
public List<Patient> containedInclude() { public List<Patient> extInclude() {
Organization o1 = new Organization(); Organization o1 = new Organization();
o1.getName().setValue("o1"); o1.getName().setValue("o1");
o1.setId("o1");
Patient p1 = new Patient(); Patient p1 = new Patient();
p1.setId("p1"); p1.setId("p1");
p1.addIdentifier().setLabel("p1"); p1.addIdentifier().setLabel("p1");
p1.getManagingOrganization().setResource(o1); p1.addUndeclaredExtension(false, "http://foo", new ResourceReferenceDt(o1));
Patient p2 = new Patient(); Patient p2 = new Patient();
p2.setId("p2"); p2.setId("p2");
p2.addIdentifier().setLabel("p2"); p2.addIdentifier().setLabel("p2");
p2.getManagingOrganization().setResource(o1); p2.addUndeclaredExtension(false, "http://foo", new ResourceReferenceDt(o1));
return Arrays.asList(p1, p2); return Arrays.asList(p1, p2);
} }
@ -449,22 +455,48 @@ public class IncludeTest {
return Patient.class; return Patient.class;
} }
@Search(queryName = "normalInclude")
public List<Patient> normalInclude() {
Organization o1 = new Organization();
o1.getName().setValue("o1");
o1.setId("o1");
Patient p1 = new Patient();
p1.setId("p1");
p1.addIdentifier().setLabel("p1");
p1.getManagingOrganization().setResource(o1);
Patient p2 = new Patient();
p2.setId("p2");
p2.addIdentifier().setLabel("p2");
p2.getManagingOrganization().setResource(o1);
return Arrays.asList(p1, p2);
} }
public static void main(String[] args) { }
Organization org = new Organization(); @ResourceDef(name = "Patient")
org.setId("Organization/65546"); public static class ExtPatient extends Patient {
org.getName().setValue("Contained Test Organization"); @Child(name = "secondOrg")
@Extension(url = "http://foo#secondOrg", definedLocally = false, isModifier = false)
private ResourceReferenceDt mySecondOrg;
Patient patient = new Patient(); public ResourceReferenceDt getSecondOrg() {
patient.setId("Patient/1333"); if (mySecondOrg == null) {
patient.addIdentifier("urn:mrns", "253345"); mySecondOrg = new ResourceReferenceDt();
patient.getManagingOrganization().setResource(patient); }
return mySecondOrg;
}
System.out.println(FhirContext.forDstu1().newXmlParser().setPrettyPrint(true).encodeResourceToString(patient)); @Override
public boolean isEmpty() {
return super.isEmpty() && ElementUtil.isEmpty(mySecondOrg);
}
patient.getManagingOrganization().getReference(); public void setSecondOrg(ResourceReferenceDt theSecondOrg) {
mySecondOrg = theSecondOrg;
}
} }

30
pom.xml
View File

@ -240,7 +240,7 @@
<jetty_version>9.2.14.v20151106</jetty_version> <jetty_version>9.2.14.v20151106</jetty_version>
<!-- Note on Hibernate versions: Hibernate 4.3+ uses JPA 2.1, which is too new for a number of platforms including JBoss EAP 6.x and Glassfish 3.0. Upgrade this version with caution! Also note that if <!-- Note on Hibernate versions: Hibernate 4.3+ uses JPA 2.1, which is too new for a number of platforms including JBoss EAP 6.x and Glassfish 3.0. Upgrade this version with caution! Also note that if
you change this, you may get a failure in hibernate4-maven-plugin. See the note in hapi-fhir-jpaserver-base/pom.xml's configuration for that plugin... --> you change this, you may get a failure in hibernate4-maven-plugin. See the note in hapi-fhir-jpaserver-base/pom.xml's configuration for that plugin... -->
<hibernate_version>5.0.3.Final</hibernate_version> <hibernate_version>5.0.5.Final</hibernate_version>
<hibernate_validator_version>5.2.2.Final</hibernate_validator_version> <hibernate_validator_version>5.2.2.Final</hibernate_validator_version>
<maven_assembly_plugin_version>2.5.3</maven_assembly_plugin_version> <maven_assembly_plugin_version>2.5.3</maven_assembly_plugin_version>
<maven_failsafe_plugin_version>2.18.1</maven_failsafe_plugin_version> <maven_failsafe_plugin_version>2.18.1</maven_failsafe_plugin_version>
@ -251,7 +251,7 @@
<mitreid-connect-version>1.1.8</mitreid-connect-version> <mitreid-connect-version>1.1.8</mitreid-connect-version>
<phloc_schematron_version>2.7.1</phloc_schematron_version> <phloc_schematron_version>2.7.1</phloc_schematron_version>
<phloc_commons_version>4.3.6</phloc_commons_version> <phloc_commons_version>4.3.6</phloc_commons_version>
<spring_version>4.2.2.RELEASE</spring_version> <spring_version>4.2.3.RELEASE</spring_version>
<thymeleaf-version>2.1.4.RELEASE</thymeleaf-version> <thymeleaf-version>2.1.4.RELEASE</thymeleaf-version>
<ebay_cors_filter_version>1.0.1</ebay_cors_filter_version> <ebay_cors_filter_version>1.0.1</ebay_cors_filter_version>
<xmlunit_version>1.6</xmlunit_version> <xmlunit_version>1.6</xmlunit_version>
@ -277,7 +277,7 @@
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>18.0</version> <version>19.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.phloc</groupId> <groupId>com.phloc</groupId>
@ -392,12 +392,12 @@
<dependency> <dependency>
<groupId>org.apache.lucene</groupId> <groupId>org.apache.lucene</groupId>
<artifactId>lucene-highlighter</artifactId> <artifactId>lucene-highlighter</artifactId>
<version>5.3.0</version> <version>5.3.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.lucene</groupId> <groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-phonetic</artifactId> <artifactId>lucene-analyzers-phonetic</artifactId>
<version>5.3.0</version> <version>5.3.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.maven.doxia</groupId> <groupId>org.apache.maven.doxia</groupId>
@ -407,17 +407,17 @@
<dependency> <dependency>
<groupId>org.apache.maven.scm</groupId> <groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-api</artifactId> <artifactId>maven-scm-api</artifactId>
<version>1.9</version> <version>1.9.4</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.maven.scm</groupId> <groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-manager-plexus</artifactId> <artifactId>maven-scm-manager-plexus</artifactId>
<version>1.9</version> <version>1.9.4</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.maven.scm</groupId> <groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-gitexe</artifactId> <artifactId>maven-scm-provider-gitexe</artifactId>
<version>1.9</version> <version>1.9.4</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.maven.wagon</groupId> <groupId>org.apache.maven.wagon</groupId>
@ -552,7 +552,7 @@
<dependency> <dependency>
<groupId>org.hibernate</groupId> <groupId>org.hibernate</groupId>
<artifactId>hibernate-search-orm</artifactId> <artifactId>hibernate-search-orm</artifactId>
<version>5.5.0.Final</version> <version>5.5.1.Final</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.javassist</groupId> <groupId>org.javassist</groupId>
@ -562,17 +562,17 @@
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-android</artifactId> <artifactId>slf4j-android</artifactId>
<version>1.7.12</version> <version>1.7.13</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
<version>1.7.12</version> <version>1.7.13</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId> <artifactId>jcl-over-slf4j</artifactId>
<version>1.7.12</version> <version>1.7.13</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
@ -663,7 +663,7 @@
<plugin> <plugin>
<groupId>org.apache.felix</groupId> <groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId> <artifactId>maven-bundle-plugin</artifactId>
<version>3.0.0</version> <version>3.0.1</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
@ -931,12 +931,12 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId> <artifactId>maven-checkstyle-plugin</artifactId>
<version>2.15</version> <version>2.17</version>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.puppycrawl.tools</groupId> <groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId> <artifactId>checkstyle</artifactId>
<version>6.11.2</version> <version>6.13</version>
</dependency> </dependency>
</dependencies> </dependencies>
<configuration> <configuration>

View File

@ -7,6 +7,16 @@
</properties> </properties>
<body> <body>
<release version="1.4" date="TBD"> <release version="1.4" date="TBD">
<action type="add">
Bump the version of a few dependencies to the
latest versions (dependent HAPI modules listed in brackets):
<![CDATA[
<ul>
<li>Hibernate (JPA, Web Tester): 5.0.3 -&gt; 5.0.5</li>
<li>Springframework (JPA, Web Tester): 4.2.2 -&gt; 4.2.3</li>
</ul>
]]>
</action>
<action type="fix"> <action type="fix">
Remove a dependency on a Java 1.7 class Remove a dependency on a Java 1.7 class
(ReflectiveOperationException) in several spots in the (ReflectiveOperationException) in several spots in the