More JPA work
This commit is contained in:
parent
ca5927880f
commit
54ab77d51a
|
@ -101,9 +101,14 @@ public class RuntimeChildResourceDefinition extends BaseRuntimeDeclaredChildDefi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
myResourceTypes = Collections.unmodifiableList(myResourceTypes);
|
||||||
myValidChildNames = Collections.unmodifiableSet(myValidChildNames);
|
myValidChildNames = Collections.unmodifiableSet(myValidChildNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Class<? extends IResource>> getResourceTypes() {
|
||||||
|
return myResourceTypes;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getClass().getSimpleName() + "[" + getElementName() + "]";
|
return getClass().getSimpleName() + "[" + getElementName() + "]";
|
||||||
|
|
|
@ -174,27 +174,6 @@ public class Organization extends BaseResource implements IResource {
|
||||||
*/
|
*/
|
||||||
public static final TokenParam IDENTIFIER = new TokenParam(SP_IDENTIFIER);
|
public static final TokenParam IDENTIFIER = new TokenParam(SP_IDENTIFIER);
|
||||||
|
|
||||||
/**
|
|
||||||
* Search parameter constant for <b>!accreditation</b>
|
|
||||||
* <p>
|
|
||||||
* Description: <b>Any accreditation code</b><br/>
|
|
||||||
* Type: <b>token</b><br/>
|
|
||||||
* Path: <b>Organization.accreditation.code</b><br/>
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
@SearchParamDefinition(name="!accreditation", path="Organization.accreditation.code", description="Any accreditation code", type="token")
|
|
||||||
public static final String SP_ACCREDITATION = "!accreditation";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <b>Fluent Client</b> search parameter constant for <b>!accreditation</b>
|
|
||||||
* <p>
|
|
||||||
* Description: <b>Any accreditation code</b><br/>
|
|
||||||
* Type: <b>token</b><br/>
|
|
||||||
* Path: <b>Organization.accreditation.code</b><br/>
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public static final TokenParam ACCREDITATION = new TokenParam(SP_ACCREDITATION);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search parameter constant for <b>partof</b>
|
* Search parameter constant for <b>partof</b>
|
||||||
* <p>
|
* <p>
|
||||||
|
|
|
@ -70,6 +70,7 @@ public class Request {
|
||||||
return myParameters;
|
return myParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public RequestType getRequestType() {
|
public RequestType getRequestType() {
|
||||||
return myRequestType;
|
return myRequestType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,7 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
}
|
}
|
||||||
BaseQueryParameter temp = (BaseQueryParameter) getParameters().get(i);
|
BaseQueryParameter temp = (BaseQueryParameter) getParameters().get(i);
|
||||||
methodParamsTemp.add(temp.getName());
|
methodParamsTemp.add(temp.getName());
|
||||||
if (temp.isRequired() && !theRequest.getParameters().containsKey(temp.getName())) {
|
if (temp.isRequired() && !theRequest.getParameters().containsKey(temp.getName())) {eee
|
||||||
ourLog.trace("Method {} doesn't match param '{}' is not present", getMethod().getName(), temp.getName());
|
ourLog.trace("Method {} doesn't match param '{}' is not present", getMethod().getName(), temp.getName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,40 @@
|
||||||
package ca.uhn.fhir.rest.param;
|
package ca.uhn.fhir.rest.param;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
|
||||||
public class ReferenceParam implements IQueryParameterType {
|
public class ReferenceParam implements IQueryParameterType {
|
||||||
|
|
||||||
private String myChain;
|
private String myChain;
|
||||||
|
private Class<? extends IResource> myType;
|
||||||
private String myValue;
|
private String myValue;
|
||||||
|
|
||||||
public ReferenceParam() {
|
public ReferenceParam() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReferenceParam(String theValue) {
|
public ReferenceParam(String theValue) {
|
||||||
setValueAsQueryToken(theValue);
|
setValueAsQueryToken(theValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReferenceParam(String theValue, String theChain) {
|
public ReferenceParam(String theChain, String theValue) {
|
||||||
setValueAsQueryToken(theValue);
|
setValueAsQueryToken(theValue);
|
||||||
setChain(theChain);
|
setChain(theChain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReferenceParam(Class<? extends IResource> theType, String theChain, String theValue) {
|
||||||
|
setType(theType);
|
||||||
|
setValueAsQueryToken(theValue);
|
||||||
|
setChain(theChain);
|
||||||
|
}
|
||||||
|
|
||||||
public String getChain() {
|
public String getChain() {
|
||||||
return myChain;
|
return myChain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Class<? extends IResource> getType() {
|
||||||
|
return myType;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValueAsQueryToken() {
|
public String getValueAsQueryToken() {
|
||||||
return myValue;
|
return myValue;
|
||||||
|
@ -32,6 +44,10 @@ public class ReferenceParam implements IQueryParameterType {
|
||||||
myChain = theChain;
|
myChain = theChain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setType(Class<? extends IResource> theType) {
|
||||||
|
myType = theType;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setValueAsQueryToken(String theParameter) {
|
public void setValueAsQueryToken(String theParameter) {
|
||||||
myValue=theParameter;
|
myValue=theParameter;
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package ca.uhn.fhir.rest.param;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
|
|
||||||
|
public class StringParameter extends StringDt {
|
||||||
|
|
||||||
|
private boolean myExact;
|
||||||
|
|
||||||
|
public StringParameter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringParameter(String theValue) {
|
||||||
|
setValue(theValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isExact() {
|
||||||
|
return myExact;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExact(boolean theExact) {
|
||||||
|
myExact = theExact;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,143 @@
|
||||||
|
package ca.uhn.fhir.rest.server;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHandler;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||||
|
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Search;
|
||||||
|
import ca.uhn.fhir.rest.param.StringParameter;
|
||||||
|
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by dsotnikov on 2/25/2014.
|
||||||
|
*/
|
||||||
|
public class StringParameterTest {
|
||||||
|
|
||||||
|
private static CloseableHttpClient ourClient;
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(StringParameterTest.class);
|
||||||
|
private static int ourPort;
|
||||||
|
private static Server ourServer;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchNormalMatch() throws Exception {
|
||||||
|
{
|
||||||
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?str=aaa");
|
||||||
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
assertEquals(1, new FhirContext().newXmlParser().parseBundle(responseContent).getEntries().size());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?str=AAA");
|
||||||
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
assertEquals(1, new FhirContext().newXmlParser().parseBundle(responseContent).getEntries().size());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?str=BBB");
|
||||||
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
assertEquals(0, new FhirContext().newXmlParser().parseBundle(responseContent).getEntries().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchExactMatch() throws Exception {
|
||||||
|
{
|
||||||
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?str:exact=aaa");
|
||||||
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
assertEquals(1, new FhirContext().newXmlParser().parseBundle(responseContent).getEntries().size());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?str:exact=AAA");
|
||||||
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
assertEquals(0, new FhirContext().newXmlParser().parseBundle(responseContent).getEntries().size());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?str:exact=BBB");
|
||||||
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
assertEquals(0, new FhirContext().newXmlParser().parseBundle(responseContent).getEntries().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() throws Exception {
|
||||||
|
ourServer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() throws Exception {
|
||||||
|
ourPort = RandomServerPortProvider.findFreePort();
|
||||||
|
ourServer = new Server(ourPort);
|
||||||
|
|
||||||
|
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||||
|
|
||||||
|
ServletHandler proxyHandler = new ServletHandler();
|
||||||
|
RestfulServer servlet = new RestfulServer();
|
||||||
|
servlet.setResourceProviders(patientProvider);
|
||||||
|
ServletHolder servletHolder = new ServletHolder(servlet);
|
||||||
|
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
||||||
|
ourServer.setHandler(proxyHandler);
|
||||||
|
ourServer.start();
|
||||||
|
|
||||||
|
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||||
|
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||||
|
builder.setConnectionManager(connectionManager);
|
||||||
|
ourClient = builder.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by dsotnikov on 2/25/2014.
|
||||||
|
*/
|
||||||
|
public static class DummyPatientResourceProvider implements IResourceProvider {
|
||||||
|
|
||||||
|
@Search
|
||||||
|
public List<Patient> findPatient(@RequiredParam(name = "str") StringParameter theParam) {
|
||||||
|
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||||
|
|
||||||
|
if (theParam.isExact() && theParam.getValue().equals("aaa")) {
|
||||||
|
retVal.add(new Patient());
|
||||||
|
}
|
||||||
|
if (!theParam.isExact() && theParam.getValue().toLowerCase().equals("aaa")) {
|
||||||
|
retVal.add(new Patient());
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends IResource> getResourceType() {
|
||||||
|
return Patient.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
encoding/<project>=UTF-8
|
|
@ -0,0 +1,2 @@
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
line.separator=\n
|
|
@ -1,7 +1,8 @@
|
||||||
package ca.uhn.fhir.jpa.dao;
|
package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.*;
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
|
||||||
|
import java.text.Normalizer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -70,6 +71,7 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||||
import ca.uhn.fhir.rest.param.QualifiedDateParam;
|
import ca.uhn.fhir.rest.param.QualifiedDateParam;
|
||||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||||
|
import ca.uhn.fhir.rest.param.StringParameter;
|
||||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
@ -78,239 +80,22 @@ import ca.uhn.fhir.util.FhirTerser;
|
||||||
|
|
||||||
public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>> implements IFhirResourceDao<T> {
|
public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>> implements IFhirResourceDao<T> {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDao.class);
|
||||||
private FhirContext myCtx;
|
private FhirContext myCtx;
|
||||||
|
|
||||||
@PersistenceContext(name = "FHIR_UT", type = PersistenceContextType.TRANSACTION, unitName = "FHIR_UT")
|
@PersistenceContext(name = "FHIR_UT", type = PersistenceContextType.TRANSACTION, unitName = "FHIR_UT")
|
||||||
private EntityManager myEntityManager;
|
private EntityManager myEntityManager;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private PlatformTransactionManager myPlatformTransactionManager;
|
private PlatformTransactionManager myPlatformTransactionManager;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private List<IFhirResourceDao<?>> myResourceDaos;
|
private List<IFhirResourceDao<?>> myResourceDaos;
|
||||||
private String myResourceName;
|
private String myResourceName;
|
||||||
private Class<T> myResourceType;
|
private Class<T> myResourceType;
|
||||||
private Map<Class<? extends IResource>, Class<? extends BaseResourceTable<?>>> myResourceTypeToDao;
|
private Map<Class<? extends IResource>, IFhirResourceDao<?>> myResourceTypeToDao;
|
||||||
|
|
||||||
private Class<X> myTableType;
|
private Class<X> myTableType;
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
|
|
||||||
@Override
|
|
||||||
public MethodOutcome create(T theResource) {
|
|
||||||
|
|
||||||
final X entity = toEntity(theResource);
|
|
||||||
|
|
||||||
entity.setPublished(new Date());
|
|
||||||
entity.setUpdated(entity.getPublished());
|
|
||||||
|
|
||||||
final List<ResourceIndexedSearchParamString> stringParams = extractSearchParamStrings(entity, theResource);
|
|
||||||
final List<ResourceIndexedSearchParamToken> tokenParams = extractSearchParamTokens(entity, theResource);
|
|
||||||
final List<ResourceIndexedSearchParamNumber> numberParams = extractSearchParamNumber(entity, theResource);
|
|
||||||
final List<ResourceIndexedSearchParamDate> dateParams = extractSearchParamDates(entity, theResource);
|
|
||||||
final List<ResourceLink> links = extractResourceLinks(entity, theResource);
|
|
||||||
|
|
||||||
ourLog.info("Saving links: {}",links);
|
|
||||||
|
|
||||||
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
|
||||||
template.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
|
|
||||||
template.setReadOnly(false);
|
|
||||||
template.execute(new TransactionCallback<X>() {
|
|
||||||
@Override
|
|
||||||
public X doInTransaction(TransactionStatus theStatus) {
|
|
||||||
myEntityManager.persist(entity);
|
|
||||||
for (ResourceIndexedSearchParamString next : stringParams) {
|
|
||||||
myEntityManager.persist(next);
|
|
||||||
}
|
|
||||||
for (ResourceIndexedSearchParamToken next : tokenParams) {
|
|
||||||
myEntityManager.persist(next);
|
|
||||||
}
|
|
||||||
for (ResourceIndexedSearchParamNumber next : numberParams) {
|
|
||||||
myEntityManager.persist(next);
|
|
||||||
}
|
|
||||||
for (ResourceIndexedSearchParamDate next : dateParams) {
|
|
||||||
myEntityManager.persist(next);
|
|
||||||
}
|
|
||||||
for (ResourceLink next : links) {
|
|
||||||
myEntityManager.persist(next);
|
|
||||||
}
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
MethodOutcome outcome = toMethodOutcome(entity);
|
|
||||||
return outcome;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Class<T> getResourceType() {
|
|
||||||
return myResourceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<X> getTableType() {
|
|
||||||
return myTableType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.REQUIRED)
|
|
||||||
@Override
|
|
||||||
public List<T> history(IdDt theId) {
|
|
||||||
ArrayList<T> retVal = new ArrayList<T>();
|
|
||||||
|
|
||||||
String resourceType = myCtx.getResourceDefinition(myResourceType).getName();
|
|
||||||
TypedQuery<ResourceHistoryTable> q = myEntityManager.createQuery(ResourceHistoryTable.Q_GETALL, ResourceHistoryTable.class);
|
|
||||||
q.setParameter("PID", theId.asLong());
|
|
||||||
q.setParameter("RESTYPE", resourceType);
|
|
||||||
|
|
||||||
// TypedQuery<ResourceHistoryTable> query =
|
|
||||||
// myEntityManager.createQuery(criteriaQuery);
|
|
||||||
List<ResourceHistoryTable> results = q.getResultList();
|
|
||||||
for (ResourceHistoryTable next : results) {
|
|
||||||
retVal.add(toResource(next));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
retVal.add(read(theId));
|
|
||||||
} catch (ResourceNotFoundException e) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retVal.isEmpty()) {
|
|
||||||
throw new ResourceNotFoundException(theId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void postConstruct() throws Exception {
|
|
||||||
myResourceType = myTableType.newInstance().getResourceType();
|
|
||||||
myCtx = new FhirContext(myResourceType);
|
|
||||||
myResourceName = myCtx.getResourceDefinition(myResourceType).getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.REQUIRED)
|
|
||||||
@Override
|
|
||||||
public T read(IdDt theId) {
|
|
||||||
X entity = readEntity(theId);
|
|
||||||
|
|
||||||
T retVal = toResource(entity);
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<T> search(Map<String, IQueryParameterType> theParams) {
|
|
||||||
Map<String, List<List<IQueryParameterType>>> map = new HashMap<String, List<List<IQueryParameterType>>>();
|
|
||||||
for (Entry<String, IQueryParameterType> nextEntry : theParams.entrySet()) {
|
|
||||||
map.put(nextEntry.getKey(), new ArrayList<List<IQueryParameterType>>());
|
|
||||||
map.get(nextEntry.getKey()).add(Collections.singletonList(nextEntry.getValue()));
|
|
||||||
}
|
|
||||||
return searchWithAndOr(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<T> search(String theSpName, IQueryParameterType theValue) {
|
|
||||||
return search(Collections.singletonMap(theSpName, theValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<T> searchWithAndOr(Map<String, List<List<IQueryParameterType>>> theParams) {
|
|
||||||
Map<String, List<List<IQueryParameterType>>> params = theParams;
|
|
||||||
if (params == null) {
|
|
||||||
params = Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
RuntimeResourceDefinition resourceDef = myCtx.getResourceDefinition(myResourceType);
|
|
||||||
|
|
||||||
Set<Long> pids = new HashSet<Long>();
|
|
||||||
|
|
||||||
for (Entry<String, List<List<IQueryParameterType>>> nextParamEntry : params.entrySet()) {
|
|
||||||
String nextParamName = nextParamEntry.getKey();
|
|
||||||
RuntimeSearchParam nextParamDef = resourceDef.getSearchParam(nextParamName);
|
|
||||||
if (nextParamDef != null) {
|
|
||||||
if (nextParamDef.getParamType() == SearchParamTypeEnum.TOKEN) {
|
|
||||||
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
|
||||||
pids = addPredicateToken(pids, nextAnd);
|
|
||||||
if (pids.isEmpty()) {
|
|
||||||
return new ArrayList<T>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (nextParamDef.getParamType() == SearchParamTypeEnum.STRING) {
|
|
||||||
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
|
||||||
pids = addPredicateString(pids, nextAnd);
|
|
||||||
if (pids.isEmpty()) {
|
|
||||||
return new ArrayList<T>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (nextParamDef.getParamType() == SearchParamTypeEnum.QUANTITY) {
|
|
||||||
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
|
||||||
pids = addPredicateQuantity(pids, nextAnd);
|
|
||||||
if (pids.isEmpty()) {
|
|
||||||
return new ArrayList<T>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (nextParamDef.getParamType() == SearchParamTypeEnum.DATE) {
|
|
||||||
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
|
||||||
pids = addPredicateDate(pids, nextAnd);
|
|
||||||
if (pids.isEmpty()) {
|
|
||||||
return new ArrayList<T>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (nextParamDef.getParamType() == SearchParamTypeEnum.REFERENCE) {
|
|
||||||
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
|
||||||
pids = addPredicateReference(nextParamName, pids, nextAnd);
|
|
||||||
if (pids.isEmpty()) {
|
|
||||||
return new ArrayList<T>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Don't know how to handle parameter of type: " + nextParamDef.getParamType());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute the query and make sure we return distinct results
|
|
||||||
{
|
|
||||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
|
||||||
CriteriaQuery<X> cq = builder.createQuery(myTableType);
|
|
||||||
Root<X> from = cq.from(myTableType);
|
|
||||||
if (!params.isEmpty()) {
|
|
||||||
cq.where(from.get("myId").in(pids));
|
|
||||||
}
|
|
||||||
TypedQuery<X> q = myEntityManager.createQuery(cq);
|
|
||||||
|
|
||||||
List<T> retVal = new ArrayList<>();
|
|
||||||
for (X next : q.getResultList()) {
|
|
||||||
T resource = toResource(next);
|
|
||||||
retVal.add(resource);
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Required
|
|
||||||
public void setTableType(Class<X> theTableType) {
|
|
||||||
myTableType = theTableType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.SUPPORTS)
|
|
||||||
@Override
|
|
||||||
public MethodOutcome update(final T theResource, final IdDt theId) {
|
|
||||||
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
|
||||||
X savedEntity = template.execute(new TransactionCallback<X>() {
|
|
||||||
@Override
|
|
||||||
public X doInTransaction(TransactionStatus theStatus) {
|
|
||||||
final X entity = readEntity(theId);
|
|
||||||
final ResourceHistoryTable existing = entity.toHistory(myCtx);
|
|
||||||
|
|
||||||
populateResourceIntoEntity(theResource, entity);
|
|
||||||
myEntityManager.persist(existing);
|
|
||||||
|
|
||||||
entity.setUpdated(new Date());
|
|
||||||
myEntityManager.persist(entity);
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return toMethodOutcome(savedEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<Long> addPredicateDate(Set<Long> thePids, List<IQueryParameterType> theOrParams) {
|
private Set<Long> addPredicateDate(Set<Long> thePids, List<IQueryParameterType> theOrParams) {
|
||||||
if (theOrParams == null || theOrParams.isEmpty()) {
|
if (theOrParams == null || theOrParams.isEmpty()) {
|
||||||
return thePids;
|
return thePids;
|
||||||
|
@ -453,42 +238,73 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
||||||
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
||||||
return new HashSet<Long>(q.getResultList());
|
return new HashSet<Long>(q.getResultList());
|
||||||
}
|
}
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDao.class);
|
|
||||||
|
|
||||||
private Set<Long> addPredicateReference(String theParamName, Set<Long> thePids, List<IQueryParameterType> theOrParams) {
|
private Set<Long> addPredicateReference(String theParamName, Set<Long> thePids, List<IQueryParameterType> theOrParams) {
|
||||||
assert theParamName.contains(".")==false;
|
assert theParamName.contains(".") == false;
|
||||||
|
|
||||||
|
Set<Long> pidsToRetain = thePids;
|
||||||
if (theOrParams == null || theOrParams.isEmpty()) {
|
if (theOrParams == null || theOrParams.isEmpty()) {
|
||||||
return thePids;
|
return pidsToRetain;
|
||||||
}
|
}
|
||||||
|
|
||||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||||
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
||||||
Root<ResourceLink> from = cq.from(ResourceLink.class);
|
Root<ResourceLink> from = cq.from(ResourceLink.class);
|
||||||
cq.select(from.get("mySourceResourcePid").as(Long.class));
|
cq.select(from.get("mySourceResourcePid").as(Long.class));
|
||||||
|
|
||||||
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
||||||
|
|
||||||
for (IQueryParameterType nextOr : theOrParams) {
|
for (IQueryParameterType nextOr : theOrParams) {
|
||||||
IQueryParameterType params = nextOr;
|
IQueryParameterType params = nextOr;
|
||||||
|
|
||||||
if (params instanceof ReferenceParam) {
|
if (params instanceof ReferenceParam) {
|
||||||
ReferenceParam ref = (ReferenceParam) params;
|
ReferenceParam ref = (ReferenceParam) params;
|
||||||
|
|
||||||
if (isBlank(ref.getChain())) {
|
if (isBlank(ref.getChain())) {
|
||||||
Long targetPid=Long.valueOf(ref.getValueAsQueryToken());
|
Long targetPid = Long.valueOf(ref.getValueAsQueryToken());
|
||||||
ourLog.info("Searching for resource link with target PID: {}", targetPid);
|
ourLog.info("Searching for resource link with target PID: {}", targetPid);
|
||||||
Predicate eq = builder.equal(from.get("myTargetResourcePid"), targetPid);
|
Predicate eq = builder.equal(from.get("myTargetResourcePid"), targetPid);
|
||||||
codePredicates.add(eq);
|
codePredicates.add(eq);
|
||||||
} else {
|
} else {
|
||||||
// todo: handle chain with resource type
|
// TODO: handle chain with resource type
|
||||||
BaseRuntimeChildDefinition def = myCtx.newTerser().getDefinition(myResourceType, ref.getValueAsQueryToken());
|
String chain = myCtx.getResourceDefinition(myResourceType).getSearchParam(theParamName).getPath();
|
||||||
|
BaseRuntimeChildDefinition def = myCtx.newTerser().getDefinition(myResourceType, chain);
|
||||||
if (!(def instanceof RuntimeChildResourceDefinition)) {
|
if (!(def instanceof RuntimeChildResourceDefinition)) {
|
||||||
throw new ConfigurationException("Property "+ref.getValueAsQueryToken()+" of type "+myResourceName+" is not a resource");
|
throw new ConfigurationException("Property " + chain + " of type " + myResourceName + " is not a resource: " + def.getClass());
|
||||||
|
}
|
||||||
|
List<Class<? extends IResource>> resourceTypes;
|
||||||
|
if (ref.getType() == null) {
|
||||||
|
RuntimeChildResourceDefinition resDef = (RuntimeChildResourceDefinition) def;
|
||||||
|
resourceTypes = resDef.getResourceTypes();
|
||||||
|
} else {
|
||||||
|
resourceTypes = new ArrayList<>();
|
||||||
|
resourceTypes.add(ref.getType());
|
||||||
|
}
|
||||||
|
for (Class<? extends IResource> nextType : resourceTypes) {
|
||||||
|
RuntimeResourceDefinition typeDef = myCtx.getResourceDefinition(nextType);
|
||||||
|
RuntimeSearchParam param = typeDef.getSearchParam(ref.getChain());
|
||||||
|
if (param == null) {
|
||||||
|
ourLog.debug("Type {} doesn't have search param {}", nextType.getSimpleName(), param);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
IFhirResourceDao<?> dao = getResourceTypeToDao().get(nextType);
|
||||||
|
if (dao == null) {
|
||||||
|
ourLog.debug("Don't have a DAO for type {}", nextType.getSimpleName(), param);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
IQueryParameterType chainValue = toParameterType(param.getParamType(), ref.getValueAsQueryToken());
|
||||||
|
Set<Long> pids = dao.searchForIds(ref.getChain(), chainValue);
|
||||||
|
if (pids.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Predicate eq = from.get("myTargetResourcePid").in(pids);
|
||||||
|
codePredicates.add(eq);
|
||||||
|
|
||||||
}
|
}
|
||||||
RuntimeChildResourceDefinition resDef = (RuntimeChildResourceDefinition) def;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Invalid token type: " + params.getClass());
|
throw new IllegalArgumentException("Invalid token type: " + params.getClass());
|
||||||
}
|
}
|
||||||
|
@ -497,9 +313,9 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
|
|
||||||
Predicate masterCodePredicate = builder.or(codePredicates.toArray(new Predicate[0]));
|
Predicate masterCodePredicate = builder.or(codePredicates.toArray(new Predicate[0]));
|
||||||
|
|
||||||
Predicate type = builder.equal(from.get("mySourcePath"), myResourceName+"."+theParamName);
|
Predicate type = builder.equal(from.get("mySourcePath"), myResourceName + "." + theParamName);
|
||||||
if (thePids.size() > 0) {
|
if (pidsToRetain.size() > 0) {
|
||||||
Predicate inPids = (from.get("mySourceResourcePid").in(thePids));
|
Predicate inPids = (from.get("mySourceResourcePid").in(pidsToRetain));
|
||||||
cq.where(builder.and(type, inPids, masterCodePredicate));
|
cq.where(builder.and(type, inPids, masterCodePredicate));
|
||||||
} else {
|
} else {
|
||||||
cq.where(builder.and(type, masterCodePredicate));
|
cq.where(builder.and(type, masterCodePredicate));
|
||||||
|
@ -531,7 +347,11 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
throw new IllegalArgumentException("Invalid token type: " + params.getClass());
|
throw new IllegalArgumentException("Invalid token type: " + params.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
Predicate singleCode = builder.equal(from.get("myValue"), string);
|
Predicate singleCode = builder.equal(from.get("myValueNormalized"), normalizeString(string));
|
||||||
|
if (params instanceof StringParameter && ((StringParameter) params).isExact()) {
|
||||||
|
Predicate exactCode = builder.equal(from.get("myValueExact"), string);
|
||||||
|
singleCode = builder.and(singleCode, exactCode);
|
||||||
|
}
|
||||||
codePredicates.add(singleCode);
|
codePredicates.add(singleCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,6 +422,53 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
return new HashSet<Long>(q.getResultList());
|
return new HashSet<Long>(q.getResultList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
|
||||||
|
@Override
|
||||||
|
public MethodOutcome create(T theResource) {
|
||||||
|
|
||||||
|
final X entity = toEntity(theResource);
|
||||||
|
|
||||||
|
entity.setPublished(new Date());
|
||||||
|
entity.setUpdated(entity.getPublished());
|
||||||
|
|
||||||
|
final List<ResourceIndexedSearchParamString> stringParams = extractSearchParamStrings(entity, theResource);
|
||||||
|
final List<ResourceIndexedSearchParamToken> tokenParams = extractSearchParamTokens(entity, theResource);
|
||||||
|
final List<ResourceIndexedSearchParamNumber> numberParams = extractSearchParamNumber(entity, theResource);
|
||||||
|
final List<ResourceIndexedSearchParamDate> dateParams = extractSearchParamDates(entity, theResource);
|
||||||
|
final List<ResourceLink> links = extractResourceLinks(entity, theResource);
|
||||||
|
|
||||||
|
ourLog.info("Saving links: {}", links);
|
||||||
|
|
||||||
|
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
||||||
|
template.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
|
||||||
|
template.setReadOnly(false);
|
||||||
|
template.execute(new TransactionCallback<X>() {
|
||||||
|
@Override
|
||||||
|
public X doInTransaction(TransactionStatus theStatus) {
|
||||||
|
myEntityManager.persist(entity);
|
||||||
|
for (ResourceIndexedSearchParamString next : stringParams) {
|
||||||
|
myEntityManager.persist(next);
|
||||||
|
}
|
||||||
|
for (ResourceIndexedSearchParamToken next : tokenParams) {
|
||||||
|
myEntityManager.persist(next);
|
||||||
|
}
|
||||||
|
for (ResourceIndexedSearchParamNumber next : numberParams) {
|
||||||
|
myEntityManager.persist(next);
|
||||||
|
}
|
||||||
|
for (ResourceIndexedSearchParamDate next : dateParams) {
|
||||||
|
myEntityManager.persist(next);
|
||||||
|
}
|
||||||
|
for (ResourceLink next : links) {
|
||||||
|
myEntityManager.persist(next);
|
||||||
|
}
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MethodOutcome outcome = toMethodOutcome(entity);
|
||||||
|
return outcome;
|
||||||
|
}
|
||||||
|
|
||||||
private List<ResourceLink> extractResourceLinks(X theEntity, T theResource) {
|
private List<ResourceLink> extractResourceLinks(X theEntity, T theResource) {
|
||||||
ArrayList<ResourceLink> retVal = new ArrayList<ResourceLink>();
|
ArrayList<ResourceLink> retVal = new ArrayList<ResourceLink>();
|
||||||
|
|
||||||
|
@ -621,6 +488,10 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
|
|
||||||
List<Object> values = t.getValues(theResource, nextPath);
|
List<Object> values = t.getValues(theResource, nextPath);
|
||||||
for (Object nextObject : values) {
|
for (Object nextObject : values) {
|
||||||
|
if (nextObject == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ResourceLink nextEntity;
|
ResourceLink nextEntity;
|
||||||
if (nextObject instanceof ResourceReferenceDt) {
|
if (nextObject instanceof ResourceReferenceDt) {
|
||||||
ResourceReferenceDt nextValue = (ResourceReferenceDt) nextObject;
|
ResourceReferenceDt nextValue = (ResourceReferenceDt) nextObject;
|
||||||
|
@ -634,16 +505,20 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myResourceTypeToDao == null) {
|
Map<Class<? extends IResource>, IFhirResourceDao<?>> resourceTypeToDao = getResourceTypeToDao();
|
||||||
myResourceTypeToDao = new HashMap<>();
|
Class<? extends BaseResourceTable<?>> tableType = resourceTypeToDao.get(type).getTableType();
|
||||||
for (IFhirResourceDao<?> next : myResourceDaos) {
|
Long valueOf;
|
||||||
myResourceTypeToDao.put(next.getResourceType(), next.getTableType());
|
try {
|
||||||
}
|
valueOf = Long.valueOf(id);
|
||||||
|
} catch (Exception e) {
|
||||||
|
String resName = myCtx.getResourceDefinition(type).getName();
|
||||||
|
throw new InvalidRequestException("Resource ID " + resName + "/" + id + " is invalid (must be numeric), specified in path: " + nextPath);
|
||||||
|
}
|
||||||
|
BaseResourceTable<?> target = myEntityManager.find(tableType, valueOf);
|
||||||
|
if (target == null) {
|
||||||
|
String resName = myCtx.getResourceDefinition(type).getName();
|
||||||
|
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
Class<? extends BaseResourceTable<?>> tableType = myResourceTypeToDao.get(type);
|
|
||||||
BaseResourceTable<?> target = myEntityManager.find(tableType, Long.valueOf(id));
|
|
||||||
|
|
||||||
nextEntity = new ResourceLink(nextPath, theEntity, target);
|
nextEntity = new ResourceLink(nextPath, theEntity, target);
|
||||||
} else {
|
} else {
|
||||||
if (!multiType) {
|
if (!multiType) {
|
||||||
|
@ -733,7 +608,8 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
|
|
||||||
if (nextObject instanceof QuantityDt) {
|
if (nextObject instanceof QuantityDt) {
|
||||||
QuantityDt nextValue = (QuantityDt) nextObject;
|
QuantityDt nextValue = (QuantityDt) nextObject;
|
||||||
ResourceIndexedSearchParamNumber nextEntity = new ResourceIndexedSearchParamNumber(resourceName, nextValue.getValue().getValue(), nextValue.getSystem().getValueAsString(), nextValue.getUnits().getValue());
|
ResourceIndexedSearchParamNumber nextEntity = new ResourceIndexedSearchParamNumber(resourceName, nextValue.getValue().getValue(), nextValue.getSystem().getValueAsString(),
|
||||||
|
nextValue.getUnits().getValue());
|
||||||
nextEntity.setResource(theEntity, def.getName());
|
nextEntity.setResource(theEntity, def.getName());
|
||||||
retVal.add(nextEntity);
|
retVal.add(nextEntity);
|
||||||
} else {
|
} else {
|
||||||
|
@ -778,7 +654,7 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
|
|
||||||
if (nextObject instanceof IPrimitiveDatatype<?>) {
|
if (nextObject instanceof IPrimitiveDatatype<?>) {
|
||||||
IPrimitiveDatatype<?> nextValue = (IPrimitiveDatatype<?>) nextObject;
|
IPrimitiveDatatype<?> nextValue = (IPrimitiveDatatype<?>) nextObject;
|
||||||
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(resourceName, nextValue.getValueAsString());
|
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(resourceName, normalizeString(nextValue.getValueAsString()), nextValue.getValueAsString());
|
||||||
nextEntity.setResource(theEntity, def.getName());
|
nextEntity.setResource(theEntity, def.getName());
|
||||||
retVal.add(nextEntity);
|
retVal.add(nextEntity);
|
||||||
} else if (nextObject instanceof HumanNameDt) {
|
} else if (nextObject instanceof HumanNameDt) {
|
||||||
|
@ -789,7 +665,7 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
if (nextName.isEmpty()) {
|
if (nextName.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(resourceName, nextName.getValueAsString());
|
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(resourceName, normalizeString(nextName.getValueAsString()), nextName.getValueAsString());
|
||||||
nextEntity.setResource(theEntity, def.getName());
|
nextEntity.setResource(theEntity, def.getName());
|
||||||
retVal.add(nextEntity);
|
retVal.add(nextEntity);
|
||||||
}
|
}
|
||||||
|
@ -804,6 +680,19 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String normalizeString(String theString) {
|
||||||
|
char[] out = new char[theString.length()];
|
||||||
|
theString = Normalizer.normalize(theString, Normalizer.Form.NFD);
|
||||||
|
int j = 0;
|
||||||
|
for (int i = 0, n = theString.length(); i < n; ++i) {
|
||||||
|
char c = theString.charAt(i);
|
||||||
|
if (c <= '\u007F') {
|
||||||
|
out[j++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new String(out).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
private List<ResourceIndexedSearchParamToken> extractSearchParamTokens(X theEntity, T theResource) {
|
private List<ResourceIndexedSearchParamToken> extractSearchParamTokens(X theEntity, T theResource) {
|
||||||
ArrayList<ResourceIndexedSearchParamToken> retVal = new ArrayList<ResourceIndexedSearchParamToken>();
|
ArrayList<ResourceIndexedSearchParamToken> retVal = new ArrayList<ResourceIndexedSearchParamToken>();
|
||||||
|
|
||||||
|
@ -815,6 +704,9 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
String nextPath = nextSpDef.getPath();
|
String nextPath = nextSpDef.getPath();
|
||||||
|
if (nextPath.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
boolean multiType = false;
|
boolean multiType = false;
|
||||||
if (nextPath.endsWith("[x]")) {
|
if (nextPath.endsWith("[x]")) {
|
||||||
|
@ -864,6 +756,57 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Class<T> getResourceType() {
|
||||||
|
return myResourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Class<? extends IResource>, IFhirResourceDao<?>> getResourceTypeToDao() {
|
||||||
|
if (myResourceTypeToDao == null) {
|
||||||
|
myResourceTypeToDao = new HashMap<>();
|
||||||
|
for (IFhirResourceDao<?> next : myResourceDaos) {
|
||||||
|
myResourceTypeToDao.put(next.getResourceType(), next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<Class<? extends IResource>, IFhirResourceDao<?>> resourceTypeToDao = myResourceTypeToDao;
|
||||||
|
return resourceTypeToDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<X> getTableType() {
|
||||||
|
return myTableType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(propagation = Propagation.REQUIRED)
|
||||||
|
@Override
|
||||||
|
public List<T> history(IdDt theId) {
|
||||||
|
ArrayList<T> retVal = new ArrayList<T>();
|
||||||
|
|
||||||
|
String resourceType = myCtx.getResourceDefinition(myResourceType).getName();
|
||||||
|
TypedQuery<ResourceHistoryTable> q = myEntityManager.createQuery(ResourceHistoryTable.Q_GETALL, ResourceHistoryTable.class);
|
||||||
|
q.setParameter("PID", theId.asLong());
|
||||||
|
q.setParameter("RESTYPE", resourceType);
|
||||||
|
|
||||||
|
// TypedQuery<ResourceHistoryTable> query =
|
||||||
|
// myEntityManager.createQuery(criteriaQuery);
|
||||||
|
List<ResourceHistoryTable> results = q.getResultList();
|
||||||
|
for (ResourceHistoryTable next : results) {
|
||||||
|
retVal.add(toResource(next));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
retVal.add(read(theId));
|
||||||
|
} catch (ResourceNotFoundException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retVal.isEmpty()) {
|
||||||
|
throw new ResourceNotFoundException(theId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
private void populateResourceIntoEntity(T theResource, X retVal) {
|
private void populateResourceIntoEntity(T theResource, X retVal) {
|
||||||
retVal.setResource(myCtx.newJsonParser().encodeResourceToString(theResource));
|
retVal.setResource(myCtx.newJsonParser().encodeResourceToString(theResource));
|
||||||
retVal.setEncoding(EncodingEnum.JSON);
|
retVal.setEncoding(EncodingEnum.JSON);
|
||||||
|
@ -877,6 +820,22 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void postConstruct() throws Exception {
|
||||||
|
myResourceType = myTableType.newInstance().getResourceType();
|
||||||
|
myCtx = new FhirContext(myResourceType);
|
||||||
|
myResourceName = myCtx.getResourceDefinition(myResourceType).getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(propagation = Propagation.REQUIRED)
|
||||||
|
@Override
|
||||||
|
public T read(IdDt theId) {
|
||||||
|
X entity = readEntity(theId);
|
||||||
|
|
||||||
|
T retVal = toResource(entity);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
private X readEntity(IdDt theId) {
|
private X readEntity(IdDt theId) {
|
||||||
X entity = (X) myEntityManager.find(myTableType, theId.asLong());
|
X entity = (X) myEntityManager.find(myTableType, theId.asLong());
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
|
@ -885,6 +844,132 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<T> search(Map<String, IQueryParameterType> theParams) {
|
||||||
|
Map<String, List<List<IQueryParameterType>>> map = new HashMap<String, List<List<IQueryParameterType>>>();
|
||||||
|
for (Entry<String, IQueryParameterType> nextEntry : theParams.entrySet()) {
|
||||||
|
map.put(nextEntry.getKey(), new ArrayList<List<IQueryParameterType>>());
|
||||||
|
map.get(nextEntry.getKey()).add(Collections.singletonList(nextEntry.getValue()));
|
||||||
|
}
|
||||||
|
return searchWithAndOr(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<T> search(String theParameterName, IQueryParameterType theValue) {
|
||||||
|
return search(Collections.singletonMap(theParameterName, theValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Long> searchForIds(Map<String, IQueryParameterType> theParams) {
|
||||||
|
Map<String, List<List<IQueryParameterType>>> map = new HashMap<String, List<List<IQueryParameterType>>>();
|
||||||
|
for (Entry<String, IQueryParameterType> nextEntry : theParams.entrySet()) {
|
||||||
|
map.put(nextEntry.getKey(), new ArrayList<List<IQueryParameterType>>());
|
||||||
|
map.get(nextEntry.getKey()).add(Collections.singletonList(nextEntry.getValue()));
|
||||||
|
}
|
||||||
|
return searchForIdsWithAndOr(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Long> searchForIdsWithAndOr(Map<String, List<List<IQueryParameterType>>> theParams) {
|
||||||
|
Map<String, List<List<IQueryParameterType>>> params = theParams;
|
||||||
|
if (params == null) {
|
||||||
|
params = Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
RuntimeResourceDefinition resourceDef = myCtx.getResourceDefinition(myResourceType);
|
||||||
|
|
||||||
|
Set<Long> pids = new HashSet<Long>();
|
||||||
|
|
||||||
|
for (Entry<String, List<List<IQueryParameterType>>> nextParamEntry : params.entrySet()) {
|
||||||
|
String nextParamName = nextParamEntry.getKey();
|
||||||
|
RuntimeSearchParam nextParamDef = resourceDef.getSearchParam(nextParamName);
|
||||||
|
if (nextParamDef != null) {
|
||||||
|
if (nextParamDef.getParamType() == SearchParamTypeEnum.TOKEN) {
|
||||||
|
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
||||||
|
pids = addPredicateToken(pids, nextAnd);
|
||||||
|
if (pids.isEmpty()) {
|
||||||
|
return new HashSet<Long>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (nextParamDef.getParamType() == SearchParamTypeEnum.STRING) {
|
||||||
|
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
||||||
|
pids = addPredicateString(pids, nextAnd);
|
||||||
|
if (pids.isEmpty()) {
|
||||||
|
return new HashSet<Long>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (nextParamDef.getParamType() == SearchParamTypeEnum.QUANTITY) {
|
||||||
|
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
||||||
|
pids = addPredicateQuantity(pids, nextAnd);
|
||||||
|
if (pids.isEmpty()) {
|
||||||
|
return new HashSet<Long>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (nextParamDef.getParamType() == SearchParamTypeEnum.DATE) {
|
||||||
|
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
||||||
|
pids = addPredicateDate(pids, nextAnd);
|
||||||
|
if (pids.isEmpty()) {
|
||||||
|
return new HashSet<Long>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (nextParamDef.getParamType() == SearchParamTypeEnum.REFERENCE) {
|
||||||
|
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
||||||
|
pids = addPredicateReference(nextParamName, pids, nextAnd);
|
||||||
|
if (pids.isEmpty()) {
|
||||||
|
return new HashSet<Long>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Don't know how to handle parameter of type: " + nextParamDef.getParamType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pids;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Long> searchForIds(String theParameterName, IQueryParameterType theValue) {
|
||||||
|
return searchForIds(Collections.singletonMap(theParameterName, theValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<T> searchWithAndOr(Map<String, List<List<IQueryParameterType>>> theParams) {
|
||||||
|
|
||||||
|
Set<Long> pids;
|
||||||
|
if (theParams.isEmpty()) {
|
||||||
|
pids = null;
|
||||||
|
} else {
|
||||||
|
pids = searchForIdsWithAndOr(theParams);
|
||||||
|
if (pids.isEmpty()) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the query and make sure we return distinct results
|
||||||
|
{
|
||||||
|
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<X> cq = builder.createQuery(myTableType);
|
||||||
|
Root<X> from = cq.from(myTableType);
|
||||||
|
if (!theParams.isEmpty()) {
|
||||||
|
cq.where(from.get("myId").in(pids));
|
||||||
|
}
|
||||||
|
TypedQuery<X> q = myEntityManager.createQuery(cq);
|
||||||
|
|
||||||
|
List<T> retVal = new ArrayList<>();
|
||||||
|
for (X next : q.getResultList()) {
|
||||||
|
T resource = toResource(next);
|
||||||
|
retVal.add(resource);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setTableType(Class<X> theTableType) {
|
||||||
|
myTableType = theTableType;
|
||||||
|
}
|
||||||
|
|
||||||
private X toEntity(T theResource) {
|
private X toEntity(T theResource) {
|
||||||
X retVal;
|
X retVal;
|
||||||
try {
|
try {
|
||||||
|
@ -905,6 +990,33 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
return outcome;
|
return outcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IQueryParameterType toParameterType(SearchParamTypeEnum theParamType, String theValueAsQueryToken) {
|
||||||
|
switch (theParamType) {
|
||||||
|
case DATE:
|
||||||
|
return new QualifiedDateParam(theValueAsQueryToken);
|
||||||
|
case NUMBER:
|
||||||
|
QuantityDt qt = new QuantityDt();
|
||||||
|
qt.setValueAsQueryToken(theValueAsQueryToken);
|
||||||
|
return qt;
|
||||||
|
case QUANTITY:
|
||||||
|
qt = new QuantityDt();
|
||||||
|
qt.setValueAsQueryToken(theValueAsQueryToken);
|
||||||
|
return qt;
|
||||||
|
case STRING:
|
||||||
|
StringDt st = new StringDt();
|
||||||
|
st.setValueAsQueryToken(theValueAsQueryToken);
|
||||||
|
return st;
|
||||||
|
case TOKEN:
|
||||||
|
IdentifierDt id = new IdentifierDt();
|
||||||
|
id.setValueAsQueryToken(theValueAsQueryToken);
|
||||||
|
return id;
|
||||||
|
case COMPOSITE:
|
||||||
|
case REFERENCE:
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Don't know how to convert param type: " + theParamType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private T toResource(BaseHasResource theEntity) {
|
private T toResource(BaseHasResource theEntity) {
|
||||||
String resourceText = theEntity.getResource();
|
String resourceText = theEntity.getResource();
|
||||||
IParser parser = theEntity.getEncoding().newParser(myCtx);
|
IParser parser = theEntity.getEncoding().newParser(myCtx);
|
||||||
|
@ -923,4 +1035,26 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional(propagation = Propagation.SUPPORTS)
|
||||||
|
@Override
|
||||||
|
public MethodOutcome update(final T theResource, final IdDt theId) {
|
||||||
|
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
||||||
|
X savedEntity = template.execute(new TransactionCallback<X>() {
|
||||||
|
@Override
|
||||||
|
public X doInTransaction(TransactionStatus theStatus) {
|
||||||
|
final X entity = readEntity(theId);
|
||||||
|
final ResourceHistoryTable existing = entity.toHistory(myCtx);
|
||||||
|
|
||||||
|
populateResourceIntoEntity(theResource, entity);
|
||||||
|
myEntityManager.persist(existing);
|
||||||
|
|
||||||
|
entity.setUpdated(new Date());
|
||||||
|
myEntityManager.persist(entity);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return toMethodOutcome(savedEntity);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.entity.BaseResourceTable;
|
import ca.uhn.fhir.jpa.entity.BaseResourceTable;
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
|
@ -28,12 +29,18 @@ public interface IFhirResourceDao<T extends IResource> {
|
||||||
|
|
||||||
List<T> search(Map<String, IQueryParameterType> theParams);
|
List<T> search(Map<String, IQueryParameterType> theParams);
|
||||||
|
|
||||||
List<T> search(String theSpName, IQueryParameterType theValue);
|
List<T> search(String theParameterName, IQueryParameterType theValue);
|
||||||
|
|
||||||
List<T> searchWithAndOr(Map<String, List<List<IQueryParameterType>>> theMap);
|
List<T> searchWithAndOr(Map<String, List<List<IQueryParameterType>>> theMap);
|
||||||
|
|
||||||
Class<T> getResourceType();
|
Class<T> getResourceType();
|
||||||
|
|
||||||
Class<? extends BaseResourceTable<T>> getTableType();
|
Class<? extends BaseResourceTable<T>> getTableType();
|
||||||
|
|
||||||
|
Set<Long> searchForIds(String theParameterName, IQueryParameterType theValue);
|
||||||
|
|
||||||
|
Set<Long> searchForIds(Map<String, IQueryParameterType> theParams);
|
||||||
|
|
||||||
|
Set<Long> searchForIdsWithAndOr(Map<String, List<List<IQueryParameterType>>> theMap);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package ca.uhn.fhir.jpa.entity;
|
||||||
|
|
||||||
|
import javax.persistence.DiscriminatorValue;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.Device;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@DiscriminatorValue("DEVICE")
|
||||||
|
public class DeviceResourceTable extends BaseResourceTable<Device> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Device> getResourceType() {
|
||||||
|
return Device.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package ca.uhn.fhir.jpa.entity;
|
||||||
|
|
||||||
|
import javax.persistence.DiscriminatorValue;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@DiscriminatorValue("DIAGNOSTICREPORT")
|
||||||
|
public class DiagnosticReportResourceTable extends BaseResourceTable<DiagnosticReport> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<DiagnosticReport> getResourceType() {
|
||||||
|
return DiagnosticReport.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package ca.uhn.fhir.jpa.entity;
|
||||||
|
|
||||||
|
import javax.persistence.DiscriminatorValue;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.Location;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@DiscriminatorValue("LOCATION")
|
||||||
|
public class LocationResourceTable extends BaseResourceTable<Location> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Location> getResourceType() {
|
||||||
|
return Location.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package ca.uhn.fhir.jpa.entity;
|
||||||
|
|
||||||
|
import javax.persistence.DiscriminatorValue;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@DiscriminatorValue("ORGANIZATION")
|
||||||
|
public class OrganizationResourceTable extends BaseResourceTable<Organization> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Organization> getResourceType() {
|
||||||
|
return Organization.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -20,31 +20,46 @@ public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchP
|
||||||
@Column(name = "RESOURCE_PID", insertable=false, updatable=false)
|
@Column(name = "RESOURCE_PID", insertable=false, updatable=false)
|
||||||
private Long myResourcePid;
|
private Long myResourcePid;
|
||||||
|
|
||||||
@Column(name = "SP_VALUE", length = 100, nullable = true)
|
@Column(name = "SP_VALUE_NORMALIZED", length = 100, nullable = true)
|
||||||
public String myValue;
|
public String myValueNormalized;
|
||||||
|
|
||||||
|
@Column(name="SP_VALUE_EXACT",length=100,nullable=true)
|
||||||
|
public String myValueExact;
|
||||||
|
|
||||||
public ResourceIndexedSearchParamString() {
|
public ResourceIndexedSearchParamString() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceIndexedSearchParamString(String theName, String theValue) {
|
public ResourceIndexedSearchParamString(String theName, String theValueNormalized, String theValueExact) {
|
||||||
setName(theName);
|
setName(theName);
|
||||||
setValue(theValue);
|
setValueNormalized(theValueNormalized);
|
||||||
|
setValueExact(theValueExact);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseResourceTable<?> getResource() {
|
public BaseResourceTable<?> getResource() {
|
||||||
return myResource;
|
return myResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return myValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setResource(BaseResourceTable<?> theResource) {
|
protected void setResource(BaseResourceTable<?> theResource) {
|
||||||
myResource = theResource;
|
myResource = theResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValue(String theValue) {
|
public String getValueNormalized() {
|
||||||
myValue = theValue;
|
return myValueNormalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setValueNormalized(String theValueNormalized) {
|
||||||
|
myValueNormalized = theValueNormalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValueExact() {
|
||||||
|
return myValueExact;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValueExact(String theValueExact) {
|
||||||
|
myValueExact = theValueExact;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "RES_LINK")
|
@Table(name = "RES_LINK")
|
||||||
public class ResourceLink implements Serializable {
|
public class ResourceLink implements Serializable {
|
||||||
|
@ -95,6 +97,7 @@ public class ResourceLink implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTargetResource(BaseResourceTable<?> theTargetResource) {
|
public void setTargetResource(BaseResourceTable<?> theTargetResource) {
|
||||||
|
Validate.notNull(theTargetResource);
|
||||||
myTargetResource = theTargetResource;
|
myTargetResource = theTargetResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
package ca.uhn.fhir.jpa.dao;
|
package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -8,6 +14,7 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.hamcrest.core.StringContains;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -19,7 +26,11 @@ import ca.uhn.fhir.model.api.TagList;
|
||||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||||
import ca.uhn.fhir.model.dstu.composite.QuantityDt;
|
import ca.uhn.fhir.model.dstu.composite.QuantityDt;
|
||||||
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.Device;
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.Location;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.AdministrativeGenderCodesEnum;
|
import ca.uhn.fhir.model.dstu.valueset.AdministrativeGenderCodesEnum;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
||||||
|
@ -28,30 +39,24 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
import ca.uhn.fhir.model.primitive.StringDt;
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
|
||||||
import ca.uhn.fhir.rest.param.QualifiedDateParam;
|
import ca.uhn.fhir.rest.param.QualifiedDateParam;
|
||||||
|
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||||
|
import ca.uhn.fhir.rest.param.StringParameter;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
|
||||||
public class FhirResourceDaoTest {
|
public class FhirResourceDaoTest {
|
||||||
|
|
||||||
private static ClassPathXmlApplicationContext ourCtx;
|
private static ClassPathXmlApplicationContext ourCtx;
|
||||||
private static IFhirResourceDao<Patient> ourPatientDao;
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoTest.class);
|
||||||
private static IFhirResourceDao<Observation> ourObservationDao;
|
private static IFhirResourceDao<Observation> ourObservationDao;
|
||||||
|
private static IFhirResourceDao<Patient> ourPatientDao;
|
||||||
|
private static IFhirResourceDao<Device> ourDeviceDao;
|
||||||
|
private static IFhirResourceDao<DiagnosticReport> ourDiagnosticReportDao;
|
||||||
|
private static IFhirResourceDao<Organization> ourOrganizationDao;
|
||||||
|
private static IFhirResourceDao<Location> ourLocationDao;
|
||||||
|
|
||||||
private static Date ourTestStarted;
|
private static Date ourTestStarted;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@BeforeClass
|
|
||||||
public static void beforeClass() {
|
|
||||||
ourTestStarted = new Date();
|
|
||||||
ourCtx = new ClassPathXmlApplicationContext("fhir-spring-test-config.xml");
|
|
||||||
ourPatientDao = ourCtx.getBean("myPatientDao", IFhirResourceDao.class);
|
|
||||||
ourObservationDao = ourCtx.getBean("myObservationDao", IFhirResourceDao.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
public static void afterClass() {
|
|
||||||
ourCtx.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPersistAndReadResource() {
|
public void testPersistAndReadResource() {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
@ -70,8 +75,7 @@ public class FhirResourceDaoTest {
|
||||||
assertTrue(published.before(now));
|
assertTrue(published.before(now));
|
||||||
assertTrue(updated.before(now));
|
assertTrue(updated.before(now));
|
||||||
}
|
}
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoTest.class);
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPersistResourceLink() {
|
public void testPersistResourceLink() {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
@ -92,7 +96,12 @@ public class FhirResourceDaoTest {
|
||||||
obs02.setSubject(new ResourceReferenceDt(Patient.class, patientId02));
|
obs02.setSubject(new ResourceReferenceDt(Patient.class, patientId02));
|
||||||
IdDt obsId02 = ourObservationDao.create(obs02).getId();
|
IdDt obsId02 = ourObservationDao.create(obs02).getId();
|
||||||
|
|
||||||
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}]",new Object[] {patientId01,patientId02,obsId01,obsId02});
|
// Create another type, that shouldn't be returned
|
||||||
|
DiagnosticReport dr01 = new DiagnosticReport();
|
||||||
|
dr01.setSubject(new ResourceReferenceDt(Patient.class, patientId01));
|
||||||
|
IdDt drId01 = ourDiagnosticReportDao.create(dr01).getId();
|
||||||
|
|
||||||
|
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]",new Object[] {patientId01,patientId02,obsId01,obsId02,drId01});
|
||||||
|
|
||||||
List<Observation> result = ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam(patientId01.getValue()));
|
List<Observation> result = ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam(patientId01.getValue()));
|
||||||
assertEquals(1,result.size());
|
assertEquals(1,result.size());
|
||||||
|
@ -107,39 +116,21 @@ public class FhirResourceDaoTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchResourceLinkWithChain() {
|
public void testPersistSearchParamDate() {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier("urn:system", "testSearchResourceLinkWithChain");
|
patient.addIdentifier("urn:system", "001");
|
||||||
IdDt patientId01 = ourPatientDao.create(patient).getId();
|
patient.setBirthDate(new DateTimeDt("2001-01-01"));
|
||||||
|
|
||||||
Patient patient02 = new Patient();
|
ourPatientDao.create(patient);
|
||||||
patient02.addIdentifier("urn:system", "testSearchResourceLinkWithChain");
|
|
||||||
IdDt patientId02 = ourPatientDao.create(patient02).getId();
|
List<Patient> found = ourPatientDao.search("birthdate", new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN, "2000-01-01"));
|
||||||
|
assertEquals(1,found.size());
|
||||||
|
|
||||||
Observation obs01 = new Observation();
|
|
||||||
obs01.setApplies(new DateTimeDt(new Date()));
|
|
||||||
obs01.setSubject(new ResourceReferenceDt(Patient.class, patientId01));
|
|
||||||
IdDt obsId01 = ourObservationDao.create(obs01).getId();
|
|
||||||
|
|
||||||
Observation obs02 = new Observation();
|
|
||||||
obs02.setApplies(new DateTimeDt(new Date()));
|
|
||||||
obs02.setSubject(new ResourceReferenceDt(Patient.class, patientId02));
|
|
||||||
IdDt obsId02 = ourObservationDao.create(obs02).getId();
|
|
||||||
|
|
||||||
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}]",new Object[] {patientId01,patientId02,obsId01,obsId02});
|
|
||||||
|
|
||||||
List<Observation> result = ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam(patientId01.getValue()));
|
|
||||||
assertEquals(1,result.size());
|
|
||||||
assertEquals(obsId01,result.get(0).getId());
|
|
||||||
|
|
||||||
result = ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam(patientId02.getValue(), Patient.SP_IDENTIFIER));
|
|
||||||
assertEquals(1,result.size());
|
|
||||||
assertEquals(obsId02,result.get(0).getId());
|
|
||||||
|
|
||||||
result = ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam("999999999999", Patient.SP_IDENTIFIER));
|
|
||||||
assertEquals(0,result.size());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -158,7 +149,6 @@ public class FhirResourceDaoTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPersistSearchParamQuantity() {
|
public void testPersistSearchParamQuantity() {
|
||||||
Observation obs = new Observation();
|
Observation obs = new Observation();
|
||||||
|
@ -174,21 +164,7 @@ public class FhirResourceDaoTest {
|
||||||
assertEquals(0,found.size());
|
assertEquals(0,found.size());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPersistSearchParamDate() {
|
|
||||||
Patient patient = new Patient();
|
|
||||||
patient.addIdentifier("urn:system", "001");
|
|
||||||
patient.setBirthDate(new DateTimeDt("2001-01-01"));
|
|
||||||
|
|
||||||
ourPatientDao.create(patient);
|
|
||||||
|
|
||||||
List<Patient> found = ourPatientDao.search("birthdate", new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN, "2000-01-01"));
|
|
||||||
assertEquals(1,found.size());
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPersistSearchParams() {
|
public void testPersistSearchParams() {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
@ -236,6 +212,212 @@ public class FhirResourceDaoTest {
|
||||||
assertEquals(0, found.size());
|
assertEquals(0, found.size());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchAll() {
|
||||||
|
{
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addIdentifier("urn:system", "001");
|
||||||
|
patient.addName().addFamily("Tester").addGiven("Joe");
|
||||||
|
ourPatientDao.create(patient);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addIdentifier("urn:system", "002");
|
||||||
|
patient.addName().addFamily("Tester").addGiven("John");
|
||||||
|
ourPatientDao.create(patient);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, IQueryParameterType> params = new HashMap<>();
|
||||||
|
List<Patient> patients = ourPatientDao.search(params);
|
||||||
|
assertEquals(2, patients.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchNameParam() {
|
||||||
|
IdDt id1;
|
||||||
|
{
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addIdentifier("urn:system", "001");
|
||||||
|
patient.addName().addFamily("testSearchNameParam01Fam").addGiven("testSearchNameParam01Giv");
|
||||||
|
id1=ourPatientDao.create(patient).getId();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addIdentifier("urn:system", "002");
|
||||||
|
patient.addName().addFamily("testSearchNameParam02Fam").addGiven("testSearchNameParam02Giv");
|
||||||
|
ourPatientDao.create(patient);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, IQueryParameterType> params = new HashMap<>();
|
||||||
|
params.put(Patient.SP_FAMILY, new StringDt("testSearchNameParam01Fam"));
|
||||||
|
List<Patient> patients = ourPatientDao.search(params);
|
||||||
|
assertEquals(1, patients.size());
|
||||||
|
assertEquals(id1, patients.get(0).getId());
|
||||||
|
|
||||||
|
params = new HashMap<>();
|
||||||
|
params.put(Patient.SP_FAMILY, new StringDt("testSearchNameParam01Giv"));
|
||||||
|
patients = ourPatientDao.search(params);
|
||||||
|
assertEquals(1, patients.size());
|
||||||
|
assertEquals(id1, patients.get(0).getId());
|
||||||
|
|
||||||
|
params = new HashMap<>();
|
||||||
|
params.put(Patient.SP_FAMILY, new StringDt("testSearchNameParam01Foo"));
|
||||||
|
patients = ourPatientDao.search(params);
|
||||||
|
assertEquals(0, patients.size());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchResourceLinkWithChain() {
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addIdentifier("urn:system", "testSearchResourceLinkWithChainXX");
|
||||||
|
patient.addIdentifier("urn:system", "testSearchResourceLinkWithChain01");
|
||||||
|
IdDt patientId01 = ourPatientDao.create(patient).getId();
|
||||||
|
|
||||||
|
Patient patient02 = new Patient();
|
||||||
|
patient02.addIdentifier("urn:system", "testSearchResourceLinkWithChainXX");
|
||||||
|
patient02.addIdentifier("urn:system", "testSearchResourceLinkWithChain02");
|
||||||
|
IdDt patientId02 = ourPatientDao.create(patient02).getId();
|
||||||
|
|
||||||
|
Observation obs01 = new Observation();
|
||||||
|
obs01.setApplies(new DateTimeDt(new Date()));
|
||||||
|
obs01.setSubject(new ResourceReferenceDt(Patient.class, patientId01));
|
||||||
|
IdDt obsId01 = ourObservationDao.create(obs01).getId();
|
||||||
|
|
||||||
|
Observation obs02 = new Observation();
|
||||||
|
obs02.setApplies(new DateTimeDt(new Date()));
|
||||||
|
obs02.setSubject(new ResourceReferenceDt(Patient.class, patientId02));
|
||||||
|
IdDt obsId02 = ourObservationDao.create(obs02).getId();
|
||||||
|
|
||||||
|
// Create another type, that shouldn't be returned
|
||||||
|
DiagnosticReport dr01 = new DiagnosticReport();
|
||||||
|
dr01.setSubject(new ResourceReferenceDt(Patient.class, patientId01));
|
||||||
|
IdDt drId01 = ourDiagnosticReportDao.create(dr01).getId();
|
||||||
|
|
||||||
|
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]",new Object[] {patientId01,patientId02,obsId01,obsId02,drId01});
|
||||||
|
|
||||||
|
List<Observation> result = ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam(Patient.SP_IDENTIFIER, "testSearchResourceLinkWithChain01"));
|
||||||
|
assertEquals(1,result.size());
|
||||||
|
assertEquals(obsId01,result.get(0).getId());
|
||||||
|
|
||||||
|
result = ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam(Patient.SP_IDENTIFIER, "999999999999"));
|
||||||
|
assertEquals(0,result.size());
|
||||||
|
|
||||||
|
result = ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam(Patient.SP_IDENTIFIER, "testSearchResourceLinkWithChainXX"));
|
||||||
|
assertEquals(2,result.size());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateWithInvalidReferenceFailsGracefully() {
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addName().addFamily("testSearchResourceLinkWithChainWithMultipleTypes01");
|
||||||
|
patient.setManagingOrganization(new ResourceReferenceDt(Organization.class, "99999999"));
|
||||||
|
try {
|
||||||
|
ourPatientDao.create(patient).getId();
|
||||||
|
fail();
|
||||||
|
}catch (InvalidRequestException e) {
|
||||||
|
assertThat(e.getMessage(), StringContains.containsString("99999 not found"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchResourceLinkWithChainWithMultipleTypes() {
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addName().addFamily("testSearchResourceLinkWithChainWithMultipleTypes01");
|
||||||
|
patient.addName().addFamily("testSearchResourceLinkWithChainWithMultipleTypesXX");
|
||||||
|
IdDt patientId01 = ourPatientDao.create(patient).getId();
|
||||||
|
|
||||||
|
Location loc01 = new Location();
|
||||||
|
loc01.getName().setValue("testSearchResourceLinkWithChainWithMultipleTypes01");
|
||||||
|
IdDt locId01 = ourLocationDao.create(loc01).getId();
|
||||||
|
|
||||||
|
Observation obs01 = new Observation();
|
||||||
|
obs01.setApplies(new DateTimeDt(new Date()));
|
||||||
|
obs01.setSubject(new ResourceReferenceDt(Patient.class, patientId01));
|
||||||
|
IdDt obsId01 = ourObservationDao.create(obs01).getId();
|
||||||
|
|
||||||
|
Observation obs02 = new Observation();
|
||||||
|
obs02.setApplies(new DateTimeDt(new Date()));
|
||||||
|
obs02.setSubject(new ResourceReferenceDt(Location.class, locId01));
|
||||||
|
IdDt obsId02 = ourObservationDao.create(obs02).getId();
|
||||||
|
|
||||||
|
ourLog.info("P1[{}] L1[{}] Obs1[{}] Obs2[{}]",new Object[] {patientId01,locId01,obsId01,obsId02});
|
||||||
|
|
||||||
|
List<Observation> result = ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam(Patient.SP_NAME, "testSearchResourceLinkWithChainWithMultipleTypes01"));
|
||||||
|
assertEquals(2,result.size());
|
||||||
|
|
||||||
|
result = ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam(Patient.SP_NAME, "testSearchResourceLinkWithChainWithMultipleTypesXX"));
|
||||||
|
assertEquals(1,result.size());
|
||||||
|
|
||||||
|
result = ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam(Patient.SP_NAME, "testSearchResourceLinkWithChainWithMultipleTypesYY"));
|
||||||
|
assertEquals(0,result.size());
|
||||||
|
|
||||||
|
result = ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam(Patient.class, Patient.SP_NAME, "testSearchResourceLinkWithChainWithMultipleTypes01"));
|
||||||
|
assertEquals(1,result.size());
|
||||||
|
assertEquals(obsId01, result.get(0).getId());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchStringParam() {
|
||||||
|
{
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addIdentifier("urn:system", "001");
|
||||||
|
patient.addName().addFamily("Tester_testSearchStringParam").addGiven("Joe");
|
||||||
|
ourPatientDao.create(patient);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addIdentifier("urn:system", "002");
|
||||||
|
patient.addName().addFamily("Tester_testSearchStringParam").addGiven("John");
|
||||||
|
ourPatientDao.create(patient);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, IQueryParameterType> params = new HashMap<>();
|
||||||
|
params.put(Patient.SP_FAMILY, new StringDt("Tester_testSearchStringParam"));
|
||||||
|
List<Patient> patients = ourPatientDao.search(params);
|
||||||
|
assertEquals(2, patients.size());
|
||||||
|
|
||||||
|
params.put(Patient.SP_FAMILY, new StringDt("FOO_testSearchStringParam"));
|
||||||
|
patients = ourPatientDao.search(params);
|
||||||
|
assertEquals(0, patients.size());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchStringParamWithNonNormalized() {
|
||||||
|
{
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addIdentifier("urn:system", "001");
|
||||||
|
patient.addName().addGiven("testSearchStringParamWithNonNormalized_höra");
|
||||||
|
ourPatientDao.create(patient);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addIdentifier("urn:system", "002");
|
||||||
|
patient.addName().addGiven("testSearchStringParamWithNonNormalized_HORA");
|
||||||
|
ourPatientDao.create(patient);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, IQueryParameterType> params = new HashMap<>();
|
||||||
|
params.put(Patient.SP_FAMILY, new StringDt("testSearchStringParamWithNonNormalized_hora"));
|
||||||
|
List<Patient> patients = ourPatientDao.search(params);
|
||||||
|
assertEquals(2, patients.size());
|
||||||
|
|
||||||
|
StringParameter parameter = new StringParameter("testSearchStringParamWithNonNormalized_hora");
|
||||||
|
parameter.setExact(true);
|
||||||
|
params.put(Patient.SP_FAMILY, parameter);
|
||||||
|
patients = ourPatientDao.search(params);
|
||||||
|
assertEquals(0, patients.size());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTagsWithCreateAndReadAndSearch() {
|
public void testTagsWithCreateAndReadAndSearch() {
|
||||||
|
@ -274,87 +456,6 @@ public class FhirResourceDaoTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSearchAll() {
|
|
||||||
{
|
|
||||||
Patient patient = new Patient();
|
|
||||||
patient.addIdentifier("urn:system", "001");
|
|
||||||
patient.addName().addFamily("Tester").addGiven("Joe");
|
|
||||||
ourPatientDao.create(patient);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Patient patient = new Patient();
|
|
||||||
patient.addIdentifier("urn:system", "002");
|
|
||||||
patient.addName().addFamily("Tester").addGiven("John");
|
|
||||||
ourPatientDao.create(patient);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, IQueryParameterType> params = new HashMap<>();
|
|
||||||
List<Patient> patients = ourPatientDao.search(params);
|
|
||||||
assertEquals(2, patients.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSearchStringParam() {
|
|
||||||
{
|
|
||||||
Patient patient = new Patient();
|
|
||||||
patient.addIdentifier("urn:system", "001");
|
|
||||||
patient.addName().addFamily("Tester_testSearchStringParam").addGiven("Joe");
|
|
||||||
ourPatientDao.create(patient);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Patient patient = new Patient();
|
|
||||||
patient.addIdentifier("urn:system", "002");
|
|
||||||
patient.addName().addFamily("Tester_testSearchStringParam").addGiven("John");
|
|
||||||
ourPatientDao.create(patient);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, IQueryParameterType> params = new HashMap<>();
|
|
||||||
params.put(Patient.SP_FAMILY, new StringDt("Tester_testSearchStringParam"));
|
|
||||||
List<Patient> patients = ourPatientDao.search(params);
|
|
||||||
assertEquals(2, patients.size());
|
|
||||||
|
|
||||||
params.put(Patient.SP_FAMILY, new StringDt("FOO_testSearchStringParam"));
|
|
||||||
patients = ourPatientDao.search(params);
|
|
||||||
assertEquals(0, patients.size());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSearchNameParam() {
|
|
||||||
IdDt id1;
|
|
||||||
{
|
|
||||||
Patient patient = new Patient();
|
|
||||||
patient.addIdentifier("urn:system", "001");
|
|
||||||
patient.addName().addFamily("testSearchNameParam01Fam").addGiven("testSearchNameParam01Giv");
|
|
||||||
id1=ourPatientDao.create(patient).getId();
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Patient patient = new Patient();
|
|
||||||
patient.addIdentifier("urn:system", "002");
|
|
||||||
patient.addName().addFamily("testSearchNameParam02Fam").addGiven("testSearchNameParam02Giv");
|
|
||||||
ourPatientDao.create(patient);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, IQueryParameterType> params = new HashMap<>();
|
|
||||||
params.put(Patient.SP_FAMILY, new StringDt("testSearchNameParam01Fam"));
|
|
||||||
List<Patient> patients = ourPatientDao.search(params);
|
|
||||||
assertEquals(1, patients.size());
|
|
||||||
assertEquals(id1, patients.get(0).getId());
|
|
||||||
|
|
||||||
params = new HashMap<>();
|
|
||||||
params.put(Patient.SP_FAMILY, new StringDt("testSearchNameParam01Giv"));
|
|
||||||
patients = ourPatientDao.search(params);
|
|
||||||
assertEquals(1, patients.size());
|
|
||||||
assertEquals(id1, patients.get(0).getId());
|
|
||||||
|
|
||||||
params = new HashMap<>();
|
|
||||||
params.put(Patient.SP_FAMILY, new StringDt("testSearchNameParam01Foo"));
|
|
||||||
patients = ourPatientDao.search(params);
|
|
||||||
assertEquals(0, patients.size());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateAndGetHistoryResource() throws InterruptedException {
|
public void testUpdateAndGetHistoryResource() throws InterruptedException {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
@ -404,4 +505,22 @@ public class FhirResourceDaoTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() {
|
||||||
|
ourCtx.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() {
|
||||||
|
ourTestStarted = new Date();
|
||||||
|
ourCtx = new ClassPathXmlApplicationContext("fhir-spring-test-config.xml");
|
||||||
|
ourPatientDao = ourCtx.getBean("myPatientDao", IFhirResourceDao.class);
|
||||||
|
ourObservationDao = ourCtx.getBean("myObservationDao", IFhirResourceDao.class);
|
||||||
|
ourDiagnosticReportDao = ourCtx.getBean("myDiagnosticReportDao", IFhirResourceDao.class);
|
||||||
|
ourDeviceDao = ourCtx.getBean("myDeviceDao", IFhirResourceDao.class);
|
||||||
|
ourOrganizationDao = ourCtx.getBean("myOrganizationDao", IFhirResourceDao.class);
|
||||||
|
ourLocationDao = ourCtx.getBean("myLocationDao", IFhirResourceDao.class);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,21 @@
|
||||||
<bean id="myPatientDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
<bean id="myPatientDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||||
<property name="tableType" value="ca.uhn.fhir.jpa.entity.PatientResourceTable"/>
|
<property name="tableType" value="ca.uhn.fhir.jpa.entity.PatientResourceTable"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="myObservationDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
<bean id="myObservationDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||||
<property name="tableType" value="ca.uhn.fhir.jpa.entity.ObservationResourceTable"/>
|
<property name="tableType" value="ca.uhn.fhir.jpa.entity.ObservationResourceTable"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
<bean id="myDiagnosticReportDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||||
|
<property name="tableType" value="ca.uhn.fhir.jpa.entity.DiagnosticReportResourceTable"/>
|
||||||
|
</bean>
|
||||||
|
<bean id="myDeviceDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||||
|
<property name="tableType" value="ca.uhn.fhir.jpa.entity.DeviceResourceTable"/>
|
||||||
|
</bean>
|
||||||
|
<bean id="myLocationDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||||
|
<property name="tableType" value="ca.uhn.fhir.jpa.entity.LocationResourceTable"/>
|
||||||
|
</bean>
|
||||||
|
<bean id="myOrganizationDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||||
|
<property name="tableType" value="ca.uhn.fhir.jpa.entity.OrganizationResourceTable"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="myPersistenceDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" lazy-init="true">
|
<bean id="myPersistenceDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" lazy-init="true">
|
||||||
<property name="url" value="jdbc:derby:memory:myUnitTestDB;create=true" />
|
<property name="url" value="jdbc:derby:memory:myUnitTestDB;create=true" />
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry excluding="**/*.java" kind="src" output="target/test-classes" path="src/test/resources"/>
|
<classpathentry excluding="**/*.java" kind="src" output="target/test-classes" path="src/test/resources"/>
|
||||||
<classpathentry kind="src" path="target/generated/valuesets"/>
|
|
||||||
<classpathentry including="**/*.java" kind="src" path="src/main/java"/>
|
<classpathentry including="**/*.java" kind="src" path="src/main/java"/>
|
||||||
<classpathentry excluding="**/*.java" kind="src" path="src/main/resources"/>
|
<classpathentry excluding="**/*.java" kind="src" path="src/main/resources"/>
|
||||||
<classpathentry kind="var" path="M2_REPO/javax/json/javax.json-api/1.0/javax.json-api-1.0.jar" sourcepath="M2_REPO/javax/json/javax.json-api/1.0/javax.json-api-1.0-sources.jar"/>
|
<classpathentry kind="var" path="M2_REPO/javax/json/javax.json-api/1.0/javax.json-api-1.0.jar" sourcepath="M2_REPO/javax/json/javax.json-api/1.0/javax.json-api-1.0-sources.jar"/>
|
||||||
|
|
|
@ -165,7 +165,7 @@ public abstract class BaseStructureSpreadsheetParser extends BaseStructureParser
|
||||||
sp.setType(cellValue(nextRow, colType));
|
sp.setType(cellValue(nextRow, colType));
|
||||||
sp.setPath(cellValue(nextRow, colPath));
|
sp.setPath(cellValue(nextRow, colPath));
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(sp.getName())) {
|
if (StringUtils.isNotBlank(sp.getName()) && !sp.getName().startsWith("!")) {
|
||||||
theResource.getSearchParameters().add(sp);
|
theResource.getSearchParameters().add(sp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,10 @@ public class SearchParameter {
|
||||||
private String myPath;
|
private String myPath;
|
||||||
private String myType;
|
private String myType;
|
||||||
|
|
||||||
|
public SearchParameter() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return StringUtils.defaultString(myDescription);
|
return StringUtils.defaultString(myDescription);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue