Lots more JPA work, and getting sorting in`
This commit is contained in:
parent
27dab8a442
commit
5675237f40
|
@ -166,4 +166,26 @@ public class Bundle extends BaseBundle /*implements IElement*/ {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of entries in this bundle
|
||||
*/
|
||||
public int size() {
|
||||
return getEntries().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing all resources of the given type from this bundle
|
||||
*/
|
||||
public <T extends IResource> List<T> getResources(Class<T> theClass) {
|
||||
ArrayList<T> retVal = new ArrayList<T>();
|
||||
for (BundleEntry next : getEntries()) {
|
||||
if (next.getResource()!=null && theClass.isAssignableFrom(next.getResource().getClass())) {
|
||||
@SuppressWarnings("unchecked")
|
||||
T resource = (T) next.getResource();
|
||||
retVal.add(resource);
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public interface IQueryParameterAnd {
|
|||
* for information on the <b>token</b> format
|
||||
* </p>
|
||||
*/
|
||||
public List<QualifiedParamList> getValuesAsQueryTokens();
|
||||
public List<IQueryParameterOr> getValuesAsQueryTokens();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -20,32 +20,33 @@ package ca.uhn.fhir.model.api;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
|
||||
public interface IQueryParameterOr {
|
||||
|
||||
/**
|
||||
* Sets the value of this type using the <b>token</b> format. This
|
||||
* format is used in HTTP queries as a parameter format.
|
||||
* Sets the value of this type using the <b>token</b> format. This format is used in HTTP queries as a parameter
|
||||
* format.
|
||||
* <p>
|
||||
* See FHIR specification
|
||||
* <a href="http://www.hl7.org/implement/standards/fhir/search.html#ptypes">2.2.2 Search SearchParameter Types</a>
|
||||
* for information on the <b>token</b> format
|
||||
* See FHIR specification <a href="http://www.hl7.org/implement/standards/fhir/search.html#ptypes">2.2.2 Search
|
||||
* SearchParameter Types</a> for information on the <b>token</b> format
|
||||
* </p>
|
||||
*/
|
||||
public void setValuesAsQueryTokens(QualifiedParamList theParameters);
|
||||
|
||||
// public void setValuesAsQueryTokens(List<IQueryParameterType> theParameters);
|
||||
|
||||
/**
|
||||
* Returns the value of this type using the <b>token</b> format. This
|
||||
* format is used in HTTP queries as a parameter format.
|
||||
* Returns the value of this type using the <b>token</b> format. This format is used in HTTP queries as a parameter
|
||||
* format.
|
||||
*
|
||||
* <p>
|
||||
* See FHIR specification
|
||||
* <a href="http://www.hl7.org/implement/standards/fhir/search.html#ptypes">2.2.2 Search SearchParameter Types</a>
|
||||
* for information on the <b>token</b> format
|
||||
* See FHIR specification <a href="http://www.hl7.org/implement/standards/fhir/search.html#ptypes">2.2.2 Search
|
||||
* SearchParameter Types</a> for information on the <b>token</b> format
|
||||
* </p>
|
||||
*/
|
||||
public QualifiedParamList getValuesAsQueryTokens();
|
||||
public List<IQueryParameterType> getValuesAsQueryTokens();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -175,8 +175,7 @@ public class ResourceReferenceDt
|
|||
* </p>
|
||||
*/
|
||||
public ResourceReferenceDt setReference( String theString) {
|
||||
myReference = new StringDt(theString);
|
||||
return this;
|
||||
return setReference(new StringDt(theString));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ package ca.uhn.fhir.parser;
|
|||
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.ObjectInputStream.GetField;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -39,6 +40,7 @@ import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
|||
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
|
||||
import ca.uhn.fhir.context.RuntimeChildResourceDefinition;
|
||||
import ca.uhn.fhir.context.RuntimeElemContainedResources;
|
||||
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition;
|
||||
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeNarrativeDefinition;
|
||||
|
@ -663,7 +665,7 @@ class ParserState<T> {
|
|||
case RESOURCE_REF: {
|
||||
ResourceReferenceDt newChildInstance = new ResourceReferenceDt();
|
||||
myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
|
||||
ResourceReferenceState newState = new ResourceReferenceState(getPreResourceState(), newChildInstance);
|
||||
ResourceReferenceState newState = new ResourceReferenceState(getPreResourceState(), (RuntimeResourceReferenceDefinition)target, newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
|
@ -767,7 +769,7 @@ class ParserState<T> {
|
|||
ResourceReferenceDt newChildInstance = new ResourceReferenceDt();
|
||||
getPreResourceState().getResourceReferences().add(newChildInstance);
|
||||
child.getMutator().addValue(myInstance, newChildInstance);
|
||||
ResourceReferenceState newState = new ResourceReferenceState(getPreResourceState(), newChildInstance);
|
||||
ResourceReferenceState newState = new ResourceReferenceState(getPreResourceState(), resourceRefTarget, newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
|
@ -873,7 +875,7 @@ class ParserState<T> {
|
|||
case RESOURCE_REF: {
|
||||
ResourceReferenceDt newChildInstance = new ResourceReferenceDt();
|
||||
myExtension.setValue(newChildInstance);
|
||||
ResourceReferenceState newState = new ResourceReferenceState(getPreResourceState(), newChildInstance);
|
||||
ResourceReferenceState newState = new ResourceReferenceState(getPreResourceState(), null, newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
|
@ -1125,7 +1127,7 @@ class ParserState<T> {
|
|||
private ResourceReferenceDt myInstance;
|
||||
private ResourceReferenceSubState mySubState;
|
||||
|
||||
public ResourceReferenceState(PreResourceState thePreResourceState, ResourceReferenceDt theInstance) {
|
||||
public ResourceReferenceState(PreResourceState thePreResourceState, RuntimeResourceReferenceDefinition theTarget, ResourceReferenceDt theInstance) {
|
||||
super(thePreResourceState);
|
||||
myInstance = theInstance;
|
||||
mySubState = ResourceReferenceSubState.INITIAL;
|
||||
|
@ -1144,6 +1146,25 @@ class ParserState<T> {
|
|||
case INITIAL:
|
||||
throw new DataFormatException("Unexpected attribute: " + theValue);
|
||||
case REFERENCE:
|
||||
int lastSlash = theValue.lastIndexOf('/');
|
||||
if (lastSlash==-1) {
|
||||
myInstance.setResourceId(theValue);
|
||||
} else if (lastSlash==0) {
|
||||
myInstance.setResourceId(theValue.substring(1));
|
||||
}else {
|
||||
int secondLastSlash=theValue.lastIndexOf('/', lastSlash-1);
|
||||
String resourceTypeName;
|
||||
if (secondLastSlash==-1) {
|
||||
resourceTypeName=theValue.substring(0,lastSlash);
|
||||
}else {
|
||||
resourceTypeName=theValue.substring(secondLastSlash+1,lastSlash);
|
||||
}
|
||||
myInstance.setResourceId(theValue.substring(lastSlash+1));
|
||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(resourceTypeName);
|
||||
if(def!=null) {
|
||||
myInstance.setResourceType(def.getImplementingClass());
|
||||
}
|
||||
}
|
||||
myInstance.setReference(theValue);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -21,35 +21,23 @@ package ca.uhn.fhir.rest.api;
|
|||
*/
|
||||
|
||||
/**
|
||||
* Represents values for <a
|
||||
* href="http://hl7.org/implement/standards/fhir/search.html#sort">sorting</a>
|
||||
* resources returned by a server.
|
||||
* Represents values for <a href="http://hl7.org/implement/standards/fhir/search.html#sort">sorting</a> resources
|
||||
* returned by a server.
|
||||
*/
|
||||
public class SortSpec {
|
||||
|
||||
private String myFieldName;
|
||||
private SortSpec myChain;
|
||||
private String myFieldName;
|
||||
private SortOrderEnum myOrder;
|
||||
|
||||
/**
|
||||
* Gets the chained sort specification, or <code>null</code> if none. If
|
||||
* multiple sort parameters are chained (indicating a sub-sort), the second
|
||||
* level sort is chained via this property.
|
||||
* Gets the chained sort specification, or <code>null</code> if none. If multiple sort parameters are chained
|
||||
* (indicating a sub-sort), the second level sort is chained via this property.
|
||||
*/
|
||||
public SortSpec getChain() {
|
||||
return myChain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the chained sort specification, or <code>null</code> if none. If
|
||||
* multiple sort parameters are chained (indicating a sub-sort), the second
|
||||
* level sort is chained via this property.
|
||||
*/
|
||||
public void setChain(SortSpec theChain) {
|
||||
myChain = theChain;
|
||||
}
|
||||
|
||||
private SortOrderEnum myOrder;
|
||||
|
||||
/**
|
||||
* Returns the actual name of the field to sort by
|
||||
*/
|
||||
|
@ -58,16 +46,22 @@ public class SortSpec {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the sort order specified by this parameter, or <code>null</code>
|
||||
* if none is explicitly defined (which means {@link SortOrderEnum#ASC}
|
||||
* according to the <a
|
||||
* href="http://hl7.org/implement/standards/fhir/search.html#sort">FHIR
|
||||
* specification</a>)
|
||||
* Returns the sort order specified by this parameter, or <code>null</code> if none is explicitly defined (which
|
||||
* means {@link SortOrderEnum#ASC} according to the <a
|
||||
* href="http://hl7.org/implement/standards/fhir/search.html#sort">FHIR specification</a>)
|
||||
*/
|
||||
public SortOrderEnum getOrder() {
|
||||
return myOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the chained sort specification, or <code>null</code> if none. If multiple sort parameters are chained
|
||||
* (indicating a sub-sort), the second level sort is chained via this property.
|
||||
*/
|
||||
public void setChain(SortSpec theChain) {
|
||||
myChain = theChain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the actual name of the field to sort by
|
||||
*/
|
||||
|
@ -76,11 +70,9 @@ public class SortSpec {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the sort order specified by this parameter, or <code>null</code> if
|
||||
* none is explicitly defined (which means {@link SortOrderEnum#ASC}
|
||||
* according to the <a
|
||||
* href="http://hl7.org/implement/standards/fhir/search.html#sort">FHIR
|
||||
* specification</a>)
|
||||
* Sets the sort order specified by this parameter, or <code>null</code> if none is explicitly defined (which means
|
||||
* {@link SortOrderEnum#ASC} according to the <a
|
||||
* href="http://hl7.org/implement/standards/fhir/search.html#sort">FHIR specification</a>)
|
||||
*/
|
||||
public void setOrder(SortOrderEnum theOrder) {
|
||||
myOrder = theOrder;
|
||||
|
|
|
@ -154,16 +154,25 @@ public abstract class BaseClient {
|
|||
}
|
||||
|
||||
if (response.getStatusLine().getStatusCode() < 200 || response.getStatusLine().getStatusCode() > 299) {
|
||||
BaseServerResponseException exception = BaseServerResponseException.newInstance(response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase());
|
||||
|
||||
String body=null;
|
||||
try {
|
||||
String body = IOUtils.toString(reader);
|
||||
exception.setResponseBody(body);
|
||||
body = IOUtils.toString(reader);
|
||||
} catch (Exception e) {
|
||||
ourLog.debug("Failed to read input stream", e);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(reader);
|
||||
}
|
||||
|
||||
String message = "HTTP " + response.getStatusLine().getStatusCode()+" " +response.getStatusLine().getReasonPhrase();
|
||||
if (Constants.CT_TEXT.equals(mimeType)) {
|
||||
message = message+": " + body;
|
||||
}
|
||||
|
||||
BaseServerResponseException exception = BaseServerResponseException.newInstance(response.getStatusLine().getStatusCode(), message);
|
||||
|
||||
if(body!=null) {
|
||||
exception.setResponseBody(body);
|
||||
}
|
||||
|
||||
throw exception;
|
||||
}
|
||||
|
|
|
@ -431,6 +431,12 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
params.get(parameterName).add(parameterValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery prettyPrint() {
|
||||
setPrettyPrint(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class QueryInternal implements IUntypedQuery {
|
||||
|
|
|
@ -45,5 +45,7 @@ public interface IQuery {
|
|||
* can be useful for debugging, but is generally not desirable in a production situation.
|
||||
*/
|
||||
IQuery andLogRequestAndResponse(boolean theLogRequestAndResponse);
|
||||
|
||||
IQuery prettyPrint();
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR Library
|
||||
|
@ -38,6 +40,14 @@ public class ReferenceParam implements IParam {
|
|||
return new ReferenceChainCriterion(getParamName(), theICriterion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the referenced resource if the resource has the given ID (this can be
|
||||
* the logical ID or the absolute URL of the resource)
|
||||
*/
|
||||
public ICriterion hasId(IdDt theId) {
|
||||
return new StringCriterion(getParamName(), theId.getValueAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the referenced resource if the resource has the given ID (this can be
|
||||
* the logical ID or the absolute URL of the resource)
|
||||
|
@ -48,8 +58,8 @@ public class ReferenceParam implements IParam {
|
|||
|
||||
private static class ReferenceChainCriterion implements ICriterion, ICriterionInternal {
|
||||
|
||||
private ICriterionInternal myWrappedCriterion;
|
||||
private String myParamName;
|
||||
private ICriterionInternal myWrappedCriterion;
|
||||
|
||||
public ReferenceChainCriterion(String theParamName, ICriterion theWrappedCriterion) {
|
||||
myParamName = theParamName;
|
||||
|
@ -57,13 +67,13 @@ public class ReferenceParam implements IParam {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getParameterValue() {
|
||||
return myWrappedCriterion.getParameterValue();
|
||||
public String getParameterName() {
|
||||
return myParamName + "." + myWrappedCriterion.getParameterName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameterName() {
|
||||
return myParamName + "." + myWrappedCriterion.getParameterName();
|
||||
public String getParameterValue() {
|
||||
return myWrappedCriterion.getParameterValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,10 @@ package ca.uhn.fhir.rest.method;
|
|||
import java.util.ArrayList;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
|
||||
public class QualifiedParamList extends ArrayList<String> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -37,6 +41,15 @@ public class QualifiedParamList extends ArrayList<String> {
|
|||
super(theCapacity);
|
||||
}
|
||||
|
||||
public QualifiedParamList(FhirContext theContext, IQueryParameterOr theNextOr) {
|
||||
for (IQueryParameterType next : theNextOr.getValuesAsQueryTokens()) {
|
||||
if (myQualifier==null) {
|
||||
myQualifier=next.getQueryParameterQualifier(theContext);
|
||||
}
|
||||
add(next.getValueAsQueryToken());
|
||||
}
|
||||
}
|
||||
|
||||
public String getQualifier() {
|
||||
return myQualifier;
|
||||
}
|
||||
|
|
|
@ -159,6 +159,8 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
return false;
|
||||
|
||||
}
|
||||
} else {
|
||||
methodParamsTemp.add(name);
|
||||
}
|
||||
}
|
||||
if (myQueryName != null) {
|
||||
|
@ -181,11 +183,17 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
methodParamsTemp.add(next);
|
||||
}
|
||||
}
|
||||
boolean retVal = methodParamsTemp.containsAll(theRequest.getParameters().keySet());
|
||||
Set<String> keySet = theRequest.getParameters().keySet();
|
||||
for (String next : keySet) {
|
||||
if (next.startsWith("_")) {
|
||||
continue;
|
||||
}
|
||||
if (!methodParamsTemp.contains(next)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ourLog.trace("Method {} matches: {}", getMethod().getName(), retVal);
|
||||
|
||||
return retVal;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setResourceType(Class<?> resourceType) {
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.model.dstu.composite.CodingDt;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
|
||||
|
@ -97,10 +98,10 @@ public class CodingListParam implements IQueryParameterOr, Iterable<CodingDt> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public QualifiedParamList getValuesAsQueryTokens() {
|
||||
QualifiedParamList retVal = new QualifiedParamList();
|
||||
public List<IQueryParameterType> getValuesAsQueryTokens() {
|
||||
ArrayList<IQueryParameterType> retVal = new ArrayList<IQueryParameterType>();
|
||||
for (CodingDt next : myCodings) {
|
||||
retVal.add(next.getValueAsQueryToken());
|
||||
retVal.add(next);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Date;
|
|||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
|
@ -156,13 +157,13 @@ public class DateRangeParam implements IQueryParameterAnd {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<QualifiedParamList> getValuesAsQueryTokens() {
|
||||
ArrayList<QualifiedParamList> retVal = new ArrayList<QualifiedParamList>();
|
||||
public List<IQueryParameterOr> getValuesAsQueryTokens() {
|
||||
ArrayList<IQueryParameterOr> retVal = new ArrayList<IQueryParameterOr>();
|
||||
if (myLowerBound != null) {
|
||||
retVal.add(QualifiedParamList.singleton(myLowerBound.getValueAsQueryToken()));
|
||||
retVal.add(ParameterUtil.singleton(myLowerBound));
|
||||
}
|
||||
if (myUpperBound != null) {
|
||||
retVal.add(QualifiedParamList.singleton(myUpperBound.getValueAsQueryToken()));
|
||||
retVal.add(ParameterUtil.singleton(myUpperBound));
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
|
|
@ -23,13 +23,14 @@ package ca.uhn.fhir.rest.param;
|
|||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
interface IParamBinder {
|
||||
|
||||
List<QualifiedParamList> encode(FhirContext theContext, Object theString) throws InternalErrorException;
|
||||
List<IQueryParameterOr> encode(FhirContext theContext, Object theString) throws InternalErrorException;
|
||||
|
||||
Object parse(List<QualifiedParamList> theList) throws InternalErrorException, InvalidRequestException;
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
|
||||
|
@ -39,10 +40,10 @@ public class IdentifierListParam implements IQueryParameterOr {
|
|||
}
|
||||
|
||||
@Override
|
||||
public QualifiedParamList getValuesAsQueryTokens() {
|
||||
QualifiedParamList retVal = new QualifiedParamList();
|
||||
public List<IQueryParameterType> getValuesAsQueryTokens() {
|
||||
ArrayList<IQueryParameterType> retVal = new ArrayList<IQueryParameterType>();
|
||||
for (IdentifierDt next : myIdentifiers) {
|
||||
retVal.add(next.getValueAsQueryToken());
|
||||
retVal.add(next);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import org.apache.commons.lang3.time.DateUtils;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.PathSpecification;
|
||||
import ca.uhn.fhir.model.api.TagList;
|
||||
|
@ -56,7 +58,9 @@ import ca.uhn.fhir.rest.annotation.RequiredParam;
|
|||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.ServerBase;
|
||||
import ca.uhn.fhir.rest.annotation.Since;
|
||||
import ca.uhn.fhir.rest.annotation.Sort;
|
||||
import ca.uhn.fhir.rest.annotation.VersionIdParam;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
import ca.uhn.fhir.util.ReflectionUtil;
|
||||
|
||||
public class ParameterUtil {
|
||||
|
@ -69,7 +73,7 @@ public class ParameterUtil {
|
|||
intTypes.add(IntegerDt.class);
|
||||
intTypes.add(Integer.class);
|
||||
BINDABLE_INTEGER_TYPES = Collections.unmodifiableSet(intTypes);
|
||||
|
||||
|
||||
HashSet<Class<?>> timeTypes = new HashSet<Class<?>>();
|
||||
timeTypes.add(InstantDt.class);
|
||||
timeTypes.add(Date.class);
|
||||
|
@ -135,6 +139,7 @@ public class ParameterUtil {
|
|||
public static Set<Class<?>> getBindableInstantTypes() {
|
||||
return BINDABLE_TIME_TYPES;
|
||||
}
|
||||
|
||||
public static Set<Class<?>> getBindableIntegerTypes() {
|
||||
return BINDABLE_INTEGER_TYPES;
|
||||
}
|
||||
|
@ -153,7 +158,7 @@ public class ParameterUtil {
|
|||
Class<? extends java.util.Collection<?>> innerCollectionType = null;
|
||||
if (TagList.class.isAssignableFrom(parameterType)) {
|
||||
// TagList is handled directly within the method bindings
|
||||
param=new NullParameter();
|
||||
param = new NullParameter();
|
||||
} else {
|
||||
if (Collection.class.isAssignableFrom(parameterType)) {
|
||||
innerCollectionType = (Class<? extends java.util.Collection<?>>) parameterType;
|
||||
|
@ -218,6 +223,8 @@ public class ParameterUtil {
|
|||
param = new SinceParameter();
|
||||
} else if (nextAnnotation instanceof Count) {
|
||||
param = new CountParameter();
|
||||
} else if (nextAnnotation instanceof Sort) {
|
||||
param = new SortParameter();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
@ -227,7 +234,7 @@ public class ParameterUtil {
|
|||
}
|
||||
|
||||
if (param == null) {
|
||||
throw new ConfigurationException("Parameter #" + paramIndex + " of method '" + theMethod.getName() + "' on type '" + theMethod.getDeclaringClass().getCanonicalName()
|
||||
throw new ConfigurationException("Parameter #" + ((paramIndex+1))+"/" + (parameterTypes.length) + " of method '" + theMethod.getName() + "' on type '" + theMethod.getDeclaringClass().getCanonicalName()
|
||||
+ "' has no recognized FHIR interface parameter annotations. Don't know how to handle this parameter");
|
||||
}
|
||||
|
||||
|
@ -290,4 +297,25 @@ public class ParameterUtil {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static IQueryParameterOr singleton(final IQueryParameterType theParam) {
|
||||
return new IQueryParameterOr() {
|
||||
|
||||
@Override
|
||||
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
|
||||
if (theParameters.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (theParameters.size() > 1) {
|
||||
throw new IllegalArgumentException("Type " + theParam.getClass().getCanonicalName() + " does not support multiple values");
|
||||
}
|
||||
theParam.setValueAsQueryToken(theParameters.getQualifier(), theParameters.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IQueryParameterType> getValuesAsQueryTokens() {
|
||||
return Collections.singletonList(theParam);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
@ -36,8 +37,8 @@ final class QueryParameterAndBinder implements IParamBinder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<QualifiedParamList> encode(FhirContext theContext, Object theString) throws InternalErrorException {
|
||||
List<QualifiedParamList> retVal = ((IQueryParameterAnd) theString).getValuesAsQueryTokens();
|
||||
public List<IQueryParameterOr> encode(FhirContext theContext, Object theString) throws InternalErrorException {
|
||||
List<IQueryParameterOr> retVal = ((IQueryParameterAnd) theString).getValuesAsQueryTokens();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ final class QueryParameterOrBinder implements IParamBinder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<QualifiedParamList> encode(FhirContext theContext, Object theString) throws InternalErrorException {
|
||||
QualifiedParamList retVal = ((IQueryParameterOr) theString).getValuesAsQueryTokens();
|
||||
public List<IQueryParameterOr> encode(FhirContext theContext, Object theString) throws InternalErrorException {
|
||||
IQueryParameterOr retVal = ((IQueryParameterOr) theString);
|
||||
return Collections.singletonList(retVal);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
|
@ -37,11 +38,9 @@ final class QueryParameterTypeBinder implements IParamBinder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<QualifiedParamList> encode(FhirContext theContext, Object theString) throws InternalErrorException {
|
||||
public List<IQueryParameterOr> encode(FhirContext theContext, Object theString) throws InternalErrorException {
|
||||
IQueryParameterType param = (IQueryParameterType) theString;
|
||||
String retVal = param.getValueAsQueryToken();
|
||||
String qualifier=param.getQueryParameterQualifier(theContext);
|
||||
return Collections.singletonList(QualifiedParamList.singleton(qualifier, retVal));
|
||||
return Collections.singletonList(ParameterUtil.singleton(param));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,6 +20,7 @@ package ca.uhn.fhir.rest.param;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
@ -27,7 +28,7 @@ import ca.uhn.fhir.model.api.IResource;
|
|||
public class ReferenceParam implements IQueryParameterType {
|
||||
|
||||
private String myChain;
|
||||
private Class<? extends IResource> myType;
|
||||
private String myResourceType;
|
||||
private String myValue;
|
||||
|
||||
public ReferenceParam() {
|
||||
|
@ -42,8 +43,8 @@ public class ReferenceParam implements IQueryParameterType {
|
|||
setChain(theChain);
|
||||
}
|
||||
|
||||
public ReferenceParam(Class<? extends IResource> theType, String theChain, String theValue) {
|
||||
setType(theType);
|
||||
public ReferenceParam(String theResourceType, String theChain, String theValue) {
|
||||
setResourceType(theResourceType);
|
||||
setValueAsQueryToken(null, theValue);
|
||||
setChain(theChain);
|
||||
}
|
||||
|
@ -52,8 +53,25 @@ public class ReferenceParam implements IQueryParameterType {
|
|||
return myChain;
|
||||
}
|
||||
|
||||
public Class<? extends IResource> getType() {
|
||||
return myType;
|
||||
@Override
|
||||
public String getQueryParameterQualifier(FhirContext theContext) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
if (isNotBlank(myResourceType)) {
|
||||
b.append(':');
|
||||
b.append(myResourceType);
|
||||
}
|
||||
if (isNotBlank(myChain)) {
|
||||
b.append('.');
|
||||
b.append(myChain);
|
||||
}
|
||||
if (b.length() != 0) {
|
||||
return b.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return myResourceType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -65,21 +83,39 @@ public class ReferenceParam implements IQueryParameterType {
|
|||
myChain = theChain;
|
||||
}
|
||||
|
||||
public void setType(Class<? extends IResource> theType) {
|
||||
myType = theType;
|
||||
public Class<? extends IResource> getResourceType(FhirContext theCtx) {
|
||||
if (isBlank(myResourceType)) {
|
||||
return null;
|
||||
}
|
||||
return theCtx.getResourceDefinition(myResourceType).getImplementingClass();
|
||||
}
|
||||
|
||||
public void setResourceType(String theResourceType) {
|
||||
myResourceType = theResourceType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValueAsQueryToken(String theQualifier, String theValue) {
|
||||
String q = theQualifier;
|
||||
if (isNotBlank(q)) {
|
||||
if (q.startsWith(":")) {
|
||||
int nextIdx = q.indexOf('.');
|
||||
if (nextIdx != -1) {
|
||||
myResourceType = q.substring(1, nextIdx);
|
||||
myChain = q.substring(nextIdx + 1);
|
||||
} else {
|
||||
myResourceType = q.substring(1);
|
||||
}
|
||||
} else if (q.startsWith(".")) {
|
||||
myChain = q.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
myValue = theValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQueryParameterQualifier(FhirContext theContext) {
|
||||
if (myType != null) {
|
||||
return ":" + theContext.getResourceDefinition(myType).getName();
|
||||
}
|
||||
return null;
|
||||
public String getValue() {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package ca.uhn.fhir.rest.param;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -63,7 +64,14 @@ public class SearchParameter extends BaseQueryParameter {
|
|||
*/
|
||||
@Override
|
||||
public List<QualifiedParamList> encode(FhirContext theContext, Object theObject) throws InternalErrorException {
|
||||
return myParamBinder.encode(theContext, theObject);
|
||||
ArrayList<QualifiedParamList> retVal = new ArrayList<QualifiedParamList>();
|
||||
|
||||
List<IQueryParameterOr> val = myParamBinder.encode(theContext, theObject);
|
||||
for (IQueryParameterOr nextOr : val) {
|
||||
retVal.add(new QualifiedParamList(theContext, nextOr));
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
|
@ -131,7 +139,7 @@ public class SearchParameter extends BaseQueryParameter {
|
|||
} else if (IQueryParameterAnd.class.isAssignableFrom(type)) {
|
||||
myParamBinder = new QueryParameterAndBinder((Class<? extends IQueryParameterAnd>) type);
|
||||
} else if (String.class.equals(type)) {
|
||||
myParamBinder=new StringBinder();
|
||||
myParamBinder = new StringBinder();
|
||||
} else {
|
||||
throw new ConfigurationException("Unsupported data type for parameter: " + type.getCanonicalName());
|
||||
}
|
||||
|
@ -150,6 +158,8 @@ public class SearchParameter extends BaseQueryParameter {
|
|||
myParamType = SearchParamTypeEnum.TOKEN;
|
||||
} else if (QuantityDt.class.isAssignableFrom(type)) {
|
||||
myParamType = SearchParamTypeEnum.QUANTITY;
|
||||
} else if (ReferenceParam.class.isAssignableFrom(type)) {
|
||||
myParamType = SearchParamTypeEnum.REFERENCE;
|
||||
} else {
|
||||
throw new ConfigurationException("Unknown search parameter type: " + type);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,10 @@ package ca.uhn.fhir.rest.param;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -41,41 +44,82 @@ public class SortParameter implements IParameter {
|
|||
@Override
|
||||
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, BaseClientInvocation theClientInvocation) throws InternalErrorException {
|
||||
SortSpec ss = (SortSpec) theSourceClientArgument;
|
||||
if (ss ==null) {
|
||||
if (ss == null) {
|
||||
return;
|
||||
}
|
||||
String name;
|
||||
if (ss.getOrder()==null) {
|
||||
if (ss.getOrder() == null) {
|
||||
name = Constants.PARAM_SORT;
|
||||
}else if (ss.getOrder() == SortOrderEnum.ASC) {
|
||||
} else if (ss.getOrder() == SortOrderEnum.ASC) {
|
||||
name = Constants.PARAM_SORT_ASC;
|
||||
}else {
|
||||
} else {
|
||||
name = Constants.PARAM_SORT_DESC;
|
||||
}
|
||||
|
||||
|
||||
if (ss.getFieldName() != null) {
|
||||
if (!theTargetQueryArguments.containsKey(name)) {
|
||||
// TODO: implement
|
||||
theTargetQueryArguments.put(name, new ArrayList<String>());
|
||||
}
|
||||
theTargetQueryArguments.get(name).add(ss.getFieldName());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
if (!theRequest.getParameters().containsKey(Constants.PARAM_SORT)) {
|
||||
if (!theRequest.getParameters().containsKey(Constants.PARAM_SORT_ASC)) {
|
||||
if (!theRequest.getParameters().containsKey(Constants.PARAM_SORT_DESC)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SortSpec outerSpec = null;
|
||||
SortSpec innerSpec = null;
|
||||
for (String nextParamName : theRequest.getParameters().keySet()) {
|
||||
SortOrderEnum order;
|
||||
if (Constants.PARAM_SORT.equals(nextParamName)) {
|
||||
order = null;
|
||||
} else if (Constants.PARAM_SORT_ASC.equals(nextParamName)) {
|
||||
order = SortOrderEnum.ASC;
|
||||
} else if (Constants.PARAM_SORT_DESC.equals(nextParamName)) {
|
||||
order = SortOrderEnum.DESC;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] values = theRequest.getParameters().get(nextParamName);
|
||||
if (values != null) {
|
||||
for (String nextValue : values) {
|
||||
if (isNotBlank(nextValue)) {
|
||||
SortSpec spec = new SortSpec();
|
||||
spec.setOrder(order);
|
||||
spec.setFieldName(nextValue);
|
||||
if (innerSpec == null) {
|
||||
outerSpec = spec;
|
||||
innerSpec = spec;
|
||||
} else {
|
||||
innerSpec.setChain(spec);
|
||||
innerSpec = spec;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return outerSpec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) {
|
||||
if (theOuterCollectionType != null) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + "' is annotated with @" + Sort.class.getName() + " but can not be of collection type");
|
||||
if (theOuterCollectionType != null || theInnerCollectionType!=null) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" +theMethod.getDeclaringClass().getCanonicalName()+ "' is annotated with @" + Sort.class.getName() + " but can not be of collection type");
|
||||
}
|
||||
if (!ParameterUtil.getBindableInstantTypes().contains(theParameterType)) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + "' is annotated with @" + Sort.class.getName() + " but is an invalid type, must be: " + SortSpec.class.getCanonicalName());
|
||||
if (!theParameterType.equals(SortSpec.class)) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '"+theMethod.getDeclaringClass().getCanonicalName() + "' is annotated with @" + Sort.class.getName() + " but is an invalid type, must be: " + SortSpec.class.getCanonicalName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
@ -33,9 +34,9 @@ final class StringBinder implements IParamBinder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<QualifiedParamList> encode(FhirContext theContext, Object theString) throws InternalErrorException {
|
||||
public List<IQueryParameterOr> encode(FhirContext theContext, Object theString) throws InternalErrorException {
|
||||
String retVal = ((String) theString);
|
||||
return Collections.singletonList(QualifiedParamList.singleton(retVal));
|
||||
return Collections.singletonList(ParameterUtil.singleton(new StringParam(retVal)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -360,31 +360,35 @@ public class RestfulServer extends HttpServlet {
|
|||
|
||||
private void findResourceMethods(Object theProvider, Class<?> clazz) {
|
||||
for (Method m : clazz.getDeclaredMethods()) {
|
||||
if (Modifier.isPublic(m.getModifiers()) && !Modifier.isStatic(m.getModifiers())) {
|
||||
ourLog.debug("Scanning public method: {}#{}", theProvider.getClass(), m.getName());
|
||||
if (!Modifier.isPublic(m.getModifiers())) {
|
||||
ourLog.debug("Ignoring non-public method: {}",m);
|
||||
} else {
|
||||
if (!Modifier.isStatic(m.getModifiers())) {
|
||||
ourLog.debug("Scanning public method: {}#{}", theProvider.getClass(), m.getName());
|
||||
|
||||
BaseMethodBinding<?> foundMethodBinding = BaseMethodBinding.bindMethod(m, myFhirContext, theProvider);
|
||||
if (foundMethodBinding != null) {
|
||||
BaseMethodBinding<?> foundMethodBinding = BaseMethodBinding.bindMethod(m, myFhirContext, theProvider);
|
||||
if (foundMethodBinding != null) {
|
||||
|
||||
String resourceName = foundMethodBinding.getResourceName();
|
||||
ResourceBinding resourceBinding;
|
||||
if (resourceName == null) {
|
||||
resourceBinding = myNullResourceBinding;
|
||||
} else {
|
||||
RuntimeResourceDefinition definition = myFhirContext.getResourceDefinition(resourceName);
|
||||
if (myResourceNameToProvider.containsKey(definition.getName())) {
|
||||
resourceBinding = myResourceNameToProvider.get(definition.getName());
|
||||
String resourceName = foundMethodBinding.getResourceName();
|
||||
ResourceBinding resourceBinding;
|
||||
if (resourceName == null) {
|
||||
resourceBinding = myNullResourceBinding;
|
||||
} else {
|
||||
resourceBinding = new ResourceBinding();
|
||||
resourceBinding.setResourceName(resourceName);
|
||||
myResourceNameToProvider.put(resourceName, resourceBinding);
|
||||
RuntimeResourceDefinition definition = myFhirContext.getResourceDefinition(resourceName);
|
||||
if (myResourceNameToProvider.containsKey(definition.getName())) {
|
||||
resourceBinding = myResourceNameToProvider.get(definition.getName());
|
||||
} else {
|
||||
resourceBinding = new ResourceBinding();
|
||||
resourceBinding.setResourceName(resourceName);
|
||||
myResourceNameToProvider.put(resourceName, resourceBinding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resourceBinding.addMethod(foundMethodBinding);
|
||||
ourLog.debug(" * Method: {}#{} is a handler", theProvider.getClass(), m.getName());
|
||||
} else {
|
||||
ourLog.debug(" * Method: {}#{} is not a handler", theProvider.getClass(), m.getName());
|
||||
resourceBinding.addMethod(foundMethodBinding);
|
||||
ourLog.debug(" * Method: {}#{} is a handler", theProvider.getClass(), m.getName());
|
||||
} else {
|
||||
ourLog.debug(" * Method: {}#{} is not a handler", theProvider.getClass(), m.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -535,7 +539,7 @@ public class RestfulServer extends HttpServlet {
|
|||
} else {
|
||||
resourceBinding = myResourceNameToProvider.get(resourceName);
|
||||
if (resourceBinding == null) {
|
||||
throw new ResourceNotFoundException("Unknown resource type '" + resourceName + "' - Server knows how to handle: " + myResourceNameToProvider.keySet());
|
||||
throw new InvalidRequestException("Unknown resource type '" + resourceName + "' - Server knows how to handle: " + myResourceNameToProvider.keySet());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -614,7 +618,7 @@ public class RestfulServer extends HttpServlet {
|
|||
resourceMethod = resourceBinding.getMethod(r);
|
||||
}
|
||||
if (null == resourceMethod) {
|
||||
throw new ResourceNotFoundException("No resource method available for the supplied parameters " + params);
|
||||
throw new InvalidRequestException("No resource method available for the supplied parameters " + params);
|
||||
}
|
||||
|
||||
resourceMethod.invokeServer(this, r, theResponse);
|
||||
|
|
|
@ -20,6 +20,7 @@ package ca.uhn.fhir.rest.server.provider;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
|
@ -89,7 +90,7 @@ public class ServerConformanceProvider {
|
|||
resource.getProfile().setId(new IdDt(def.getResourceProfile()));
|
||||
|
||||
Map<String, Conformance.RestResourceSearchParam> nameToSearchParam = new HashMap<String, Conformance.RestResourceSearchParam>();
|
||||
for (BaseMethodBinding nextMethodBinding : next.getMethodBindings()) {
|
||||
for (BaseMethodBinding<?> nextMethodBinding : next.getMethodBindings()) {
|
||||
RestfulOperationTypeEnum resOp = nextMethodBinding.getResourceOperationType();
|
||||
if (resOp != null) {
|
||||
if (resourceOps.contains(resOp) == false) {
|
||||
|
@ -108,19 +109,34 @@ public class ServerConformanceProvider {
|
|||
|
||||
if (nextMethodBinding instanceof SearchMethodBinding) {
|
||||
List<IParameter> params = ((SearchMethodBinding) nextMethodBinding).getParameters();
|
||||
// TODO: this would probably work best if we sorted these by
|
||||
// required first, then optional
|
||||
|
||||
List<SearchParameter> searchParameters = new ArrayList<SearchParameter>();
|
||||
for (IParameter nextParameter : params) {
|
||||
if ((nextParameter instanceof SearchParameter)) {
|
||||
searchParameters.add((SearchParameter) nextParameter);
|
||||
}
|
||||
}
|
||||
Collections.sort(searchParameters, new Comparator<SearchParameter>() {
|
||||
@Override
|
||||
public int compare(SearchParameter theO1, SearchParameter theO2) {
|
||||
if (theO1.isRequired() == theO2.isRequired()) {
|
||||
return 0;
|
||||
}
|
||||
if (theO1.isRequired()) {
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
});
|
||||
if (searchParameters.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
boolean allOptional = searchParameters.get(0).isRequired()==false;
|
||||
|
||||
RestResourceSearchParam searchParam = null;
|
||||
ExtensionDt searchParamChain = null;
|
||||
for (IParameter nextParameterObj : params) {
|
||||
if (!(nextParameterObj instanceof SearchParameter)) {
|
||||
continue;
|
||||
}
|
||||
for (SearchParameter nextParameter : searchParameters) {
|
||||
|
||||
SearchParameter nextParameter = (SearchParameter) nextParameterObj;
|
||||
|
||||
if (searchParam == null) {
|
||||
if (searchParam == null || allOptional) {
|
||||
if (!nameToSearchParam.containsKey(nextParameter.getName())) {
|
||||
RestResourceSearchParam param = resource.addSearchParam();
|
||||
param.setName(nextParameter.getName());
|
||||
|
|
|
@ -59,6 +59,7 @@ import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
|||
import ca.uhn.fhir.rest.param.CodingListParam;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.param.QualifiedDateParam;
|
||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
|
@ -90,6 +91,34 @@ public List<Patient> findPatients(
|
|||
}
|
||||
//END SNIPPET: underlyingReq
|
||||
|
||||
//START SNIPPET: reference
|
||||
@Search
|
||||
public List<Patient> findPatients(
|
||||
@RequiredParam(name=Patient.SP_PROVIDER) ReferenceParam theProvider
|
||||
) {
|
||||
|
||||
// May be populated with the resource type (e.g. "Patient") if the client requested one
|
||||
String type = theProvider.getResourceType();
|
||||
|
||||
// May be populated with the chain (e.g. "name") if the client requested one
|
||||
String chain = theProvider.getChain();
|
||||
|
||||
/* The actual parameter value. This will be the resource ID if no chain was provided,
|
||||
* but refers to the value of a specific property noted by the chain if one was given.
|
||||
* For example, the following request:
|
||||
* http://example.com/fhir/Patient?provider:Organization.name=FooOrg
|
||||
* has a type of "Organization" and a chain of "name", meaning that
|
||||
* the returned patients should have a provider which is an Organization
|
||||
* with a name matching "FooOrg".
|
||||
*/
|
||||
String value = theProvider.getValue();
|
||||
|
||||
List<Patient> retVal=new ArrayList<Patient>(); // populate this
|
||||
return retVal;
|
||||
|
||||
}
|
||||
//END SNIPPET: reference
|
||||
|
||||
|
||||
//START SNIPPET: read
|
||||
@Read()
|
||||
|
@ -557,7 +586,7 @@ private interface IPatientClient extends IBasicClient
|
|||
// Only one method is shown here, but many methods may be
|
||||
// added to the same client interface!
|
||||
}
|
||||
//START SNIPPET: clientReadInterface
|
||||
//END SNIPPET: clientReadInterface
|
||||
|
||||
public void clientRead() {
|
||||
//START SNIPPET: clientReadTags
|
||||
|
|
|
@ -693,6 +693,49 @@
|
|||
|
||||
</subsection>
|
||||
|
||||
<subsection name="Search Parameters: Resource Reference">
|
||||
|
||||
<p>
|
||||
Many search parameters refer to resource references. For instance, the Patient
|
||||
parameter "provider" refers to the resource marked as the managing organization
|
||||
for patients.
|
||||
</p>
|
||||
<p>
|
||||
Reference parameters use the
|
||||
<a href="./apidocs/ca/uhn/fhir/rest/param/ReferenceParam.html">ReferenceParam</a>
|
||||
type. Reference param objects being passed into server methods will have three properties
|
||||
populated:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<b>The resource type (optional):</b> This is the type of resource
|
||||
being targeted, if the client specifies one in the URL.
|
||||
</li>
|
||||
<li>
|
||||
<b>The chain property (optional):</b> This is the name of the
|
||||
property on the target resource to search for
|
||||
</li>
|
||||
<li>
|
||||
<b>The value (required):</b> This is the actual value to search for. If
|
||||
a chain property has not been specified, this is the ID of the resource.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<macro name="snippet">
|
||||
<param name="id" value="reference" />
|
||||
<param name="file" value="src/site/example/java/example/RestfulPatientResourceProviderMore.java" />
|
||||
</macro>
|
||||
|
||||
<p>
|
||||
Example URLs to invoke this method:
|
||||
<br />
|
||||
Resource by ID: <code>http://fhir.example.com/Patient?provider=1234</code>
|
||||
<br />
|
||||
Resource by chained parameter value: <code>http://fhir.example.com/Patient?provider:Organization.name=FooOrg</code>
|
||||
</p>
|
||||
|
||||
</subsection>
|
||||
|
||||
<subsection name="Combining Multiple Parameters">
|
||||
|
||||
<p>
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
package ca.uhn.fhir.model.dstu.composite;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
|
||||
public class ResourceReferenceDtTest {
|
||||
|
||||
private static FhirContext ourCtx;
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceReferenceDtTest.class);
|
||||
|
||||
@Test
|
||||
public void testParseValueAbsolute() {
|
||||
Patient patient = new Patient();
|
||||
ResourceReferenceDt rr = new ResourceReferenceDt();
|
||||
rr.setReference("http://foo/fhir/Organization/123");
|
||||
patient.setManagingOrganization(rr);
|
||||
|
||||
Patient actual = parseAndEncode(patient);
|
||||
rr = actual.getManagingOrganization();
|
||||
assertEquals(Organization.class, rr.getResourceType());
|
||||
assertEquals("123", rr.getResourceId());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseValueMissingType1() {
|
||||
Patient patient = new Patient();
|
||||
ResourceReferenceDt rr = new ResourceReferenceDt();
|
||||
rr.setReference("/123");
|
||||
patient.setManagingOrganization(rr);
|
||||
|
||||
Patient actual = parseAndEncode(patient);
|
||||
rr = actual.getManagingOrganization();
|
||||
assertEquals(null, rr.getResourceType());
|
||||
assertEquals("123", rr.getResourceId());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseValueMissingType2() {
|
||||
Patient patient = new Patient();
|
||||
ResourceReferenceDt rr = new ResourceReferenceDt();
|
||||
rr.setReference("123");
|
||||
patient.setManagingOrganization(rr);
|
||||
|
||||
Patient actual = parseAndEncode(patient);
|
||||
rr = actual.getManagingOrganization();
|
||||
assertEquals(null, rr.getResourceType());
|
||||
assertEquals("123", rr.getResourceId());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseValueRelative1() {
|
||||
Patient patient = new Patient();
|
||||
ResourceReferenceDt rr = new ResourceReferenceDt();
|
||||
rr.setReference("Organization/123");
|
||||
patient.setManagingOrganization(rr);
|
||||
|
||||
Patient actual = parseAndEncode(patient);
|
||||
rr = actual.getManagingOrganization();
|
||||
assertEquals(Organization.class, rr.getResourceType());
|
||||
assertEquals("123", rr.getResourceId());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseValueRelative2() {
|
||||
Patient patient = new Patient();
|
||||
ResourceReferenceDt rr = new ResourceReferenceDt();
|
||||
rr.setReference("/Organization/123");
|
||||
patient.setManagingOrganization(rr);
|
||||
|
||||
Patient actual = parseAndEncode(patient);
|
||||
rr = actual.getManagingOrganization();
|
||||
assertEquals(Organization.class, rr.getResourceType());
|
||||
assertEquals("123", rr.getResourceId());
|
||||
|
||||
}
|
||||
|
||||
private Patient parseAndEncode(Patient patient) {
|
||||
String encoded = ourCtx.newXmlParser().encodeResourceToString(patient);
|
||||
ourLog.info("\n" + encoded);
|
||||
return ourCtx.newXmlParser().parseResource(Patient.class, encoded);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
ourCtx = new FhirContext();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
package ca.uhn.fhir.rest.client;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.input.ReaderInputStream;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
||||
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.client.api.IBasicClient;
|
||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
|
||||
public class ReferenceClientTest {
|
||||
|
||||
private FhirContext ctx;
|
||||
private HttpClient httpClient;
|
||||
private HttpResponse httpResponse;
|
||||
|
||||
// atom-document-large.xml
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
ctx = new FhirContext(Patient.class, Conformance.class);
|
||||
|
||||
httpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||
ctx.getRestfulClientFactory().setHttpClient(httpClient);
|
||||
|
||||
httpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithParam() throws Exception {
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_ATOM_XML + "; charset=UTF-8"));
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(createBundle()), Charset.forName("UTF-8")));
|
||||
|
||||
IClient client = ctx.newRestfulClient(IClient.class, "http://foo");
|
||||
client.search(new ReferenceParam("123"));
|
||||
|
||||
assertEquals(HttpGet.class, capt.getValue().getClass());
|
||||
HttpGet get = (HttpGet) capt.getValue();
|
||||
assertEquals("http://foo/Patient?provider=123", get.getURI().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithParamAndChain() throws Exception {
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_ATOM_XML + "; charset=UTF-8"));
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(createBundle()), Charset.forName("UTF-8")));
|
||||
|
||||
IClient client = ctx.newRestfulClient(IClient.class, "http://foo");
|
||||
client.search(new ReferenceParam("chain", "123"));
|
||||
|
||||
assertEquals(HttpGet.class, capt.getValue().getClass());
|
||||
HttpGet get = (HttpGet) capt.getValue();
|
||||
assertEquals("http://foo/Patient?provider.chain=123", get.getURI().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithParamAndTypeAndChain() throws Exception {
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_ATOM_XML + "; charset=UTF-8"));
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(createBundle()), Charset.forName("UTF-8")));
|
||||
|
||||
IClient client = ctx.newRestfulClient(IClient.class, "http://foo");
|
||||
client.search(new ReferenceParam("Organization", "chain", "123"));
|
||||
|
||||
assertEquals(HttpGet.class, capt.getValue().getClass());
|
||||
HttpGet get = (HttpGet) capt.getValue();
|
||||
assertEquals("http://foo/Patient?provider%3AOrganization.chain=123", get.getURI().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithParamAndType() throws Exception {
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_ATOM_XML + "; charset=UTF-8"));
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(createBundle()), Charset.forName("UTF-8")));
|
||||
|
||||
IClient client = ctx.newRestfulClient(IClient.class, "http://foo");
|
||||
client.search(new ReferenceParam("Organization", null, "123"));
|
||||
|
||||
assertEquals(HttpGet.class, capt.getValue().getClass());
|
||||
HttpGet get = (HttpGet) capt.getValue();
|
||||
assertEquals("http://foo/Patient?provider%3AOrganization=123", get.getURI().toString());
|
||||
}
|
||||
|
||||
private String createBundle() {
|
||||
return ctx.newXmlParser().encodeBundleToString(new Bundle());
|
||||
}
|
||||
|
||||
|
||||
private interface IClient extends IBasicClient {
|
||||
|
||||
@Search(type=Patient.class)
|
||||
public List<Patient> search(@RequiredParam(name=Patient.SP_PROVIDER) ReferenceParam theString);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
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.BundleEntry;
|
||||
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.ReferenceParam;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
public class ReferenceParameterTest {
|
||||
|
||||
private static CloseableHttpClient ourClient;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ReferenceParameterTest.class);
|
||||
private static int ourPort;
|
||||
private static Server ourServer;
|
||||
private static FhirContext ourCtx;
|
||||
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testSearchWithValue() throws Exception {
|
||||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?" + Patient.SP_PROVIDER+"=123");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
List<BundleEntry> entries = new FhirContext().newXmlParser().parseBundle(responseContent).getEntries();
|
||||
assertEquals(1, entries.size());
|
||||
Patient p = (Patient) entries.get(0).getResource();
|
||||
assertEquals("0123",p.getName().get(0).getFamilyFirstRep().getValue());
|
||||
assertEquals("1",p.getName().get(1).getFamilyFirstRep().getValue());
|
||||
assertEquals("2",p.getName().get(2).getFamilyFirstRep().getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithValueAndType() throws Exception {
|
||||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?" + Patient.SP_PROVIDER+":Organization=123");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
List<BundleEntry> entries = new FhirContext().newXmlParser().parseBundle(responseContent).getEntries();
|
||||
assertEquals(1, entries.size());
|
||||
Patient p = (Patient) entries.get(0).getResource();
|
||||
assertEquals("0123",p.getName().get(0).getFamilyFirstRep().getValue());
|
||||
assertEquals("1Organization",p.getName().get(1).getFamilyFirstRep().getValue());
|
||||
assertEquals("2",p.getName().get(2).getFamilyFirstRep().getValue());
|
||||
}
|
||||
}
|
||||
@Test
|
||||
public void testSearchWithValueAndTypeAndChain() throws Exception {
|
||||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?" + Patient.SP_PROVIDER+":Organization.name=123");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
List<BundleEntry> entries = new FhirContext().newXmlParser().parseBundle(responseContent).getEntries();
|
||||
assertEquals(1, entries.size());
|
||||
Patient p = (Patient) entries.get(0).getResource();
|
||||
assertEquals("0123",p.getName().get(0).getFamilyFirstRep().getValue());
|
||||
assertEquals("1Organization",p.getName().get(1).getFamilyFirstRep().getValue());
|
||||
assertEquals("2name",p.getName().get(2).getFamilyFirstRep().getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithValueAndChain() throws Exception {
|
||||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?" + Patient.SP_PROVIDER+".name=123");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
List<BundleEntry> entries = new FhirContext().newXmlParser().parseBundle(responseContent).getEntries();
|
||||
assertEquals(1, entries.size());
|
||||
Patient p = (Patient) entries.get(0).getResource();
|
||||
assertEquals("0123",p.getName().get(0).getFamilyFirstRep().getValue());
|
||||
assertEquals("1",p.getName().get(1).getFamilyFirstRep().getValue());
|
||||
assertEquals("2name",p.getName().get(2).getFamilyFirstRep().getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@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();
|
||||
|
||||
ourCtx = servlet.getFhirContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
public static class DummyPatientResourceProvider implements IResourceProvider {
|
||||
|
||||
@Search
|
||||
public List<Patient> findPatient(@RequiredParam(name = Patient.SP_PROVIDER) ReferenceParam theParam) {
|
||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily("0"+theParam.getValueAsQueryToken());
|
||||
p.addName().addFamily("1"+defaultString(theParam.getResourceType()));
|
||||
p.addName().addFamily("2"+defaultString(theParam.getChain()));
|
||||
retVal.add(p);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Class<? extends IResource> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -96,7 +96,9 @@ public class ResourceMethodTest {
|
|||
inputParams.add("lastName");
|
||||
inputParams.add("mrn");
|
||||
|
||||
assertEquals(true, rm.incomingServerRequestMatchesMethod(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // True
|
||||
Request params = Request.withResourceAndParams("Patient", RequestType.GET, inputParams);
|
||||
boolean actual = rm.incomingServerRequestMatchesMethod(params);
|
||||
assertTrue( actual); // True
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -13,6 +13,8 @@ import ca.uhn.fhir.model.api.annotation.Description;
|
|||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
||||
|
@ -20,9 +22,9 @@ import ca.uhn.fhir.rest.method.SearchMethodBinding;
|
|||
import ca.uhn.fhir.rest.param.SearchParameter;
|
||||
import ca.uhn.fhir.rest.server.provider.ServerConformanceProvider;
|
||||
|
||||
public class DocumentationTest {
|
||||
public class ServerConformanceProviderTest {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DocumentationTest.class);
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerConformanceProviderTest.class);
|
||||
|
||||
@Test
|
||||
public void testSearchParameterDocumentation() throws Exception {
|
||||
|
@ -55,6 +57,39 @@ public class DocumentationTest {
|
|||
assertThat(conf, containsString("<type value=\"token\"/>"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMultiOptionalDocumentation() throws Exception {
|
||||
|
||||
RestfulServer rs = new RestfulServer();
|
||||
rs.setProviders(new MultiOptionalProvider());
|
||||
|
||||
ServerConformanceProvider sc = new ServerConformanceProvider(rs);
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(null);
|
||||
|
||||
boolean found=false;
|
||||
Collection<ResourceBinding> resourceBindings = rs.getResourceBindings();
|
||||
for (ResourceBinding resourceBinding : resourceBindings) {
|
||||
if (resourceBinding.getResourceName().equals("Patient")) {
|
||||
List<BaseMethodBinding<?>> methodBindings = resourceBinding.getMethodBindings();
|
||||
SearchMethodBinding binding = (SearchMethodBinding) methodBindings.get(0);
|
||||
SearchParameter param = (SearchParameter) binding.getParameters().iterator().next();
|
||||
assertEquals("The patient's identifier", param.getDescription());
|
||||
found=true;
|
||||
}
|
||||
}
|
||||
assertTrue(found);
|
||||
Conformance conformance = sc.getServerConformance();
|
||||
String conf = new FhirContext().newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance);
|
||||
ourLog.info(conf);
|
||||
|
||||
assertThat(conf, containsString("<documentation value=\"The patient's identifier (MRN or other card number)\"/>"));
|
||||
assertThat(conf, containsString("<type value=\"token\"/>"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
|
@ -69,5 +104,23 @@ public class DocumentationTest {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public static class MultiOptionalProvider {
|
||||
|
||||
@Search(type = Patient.class)
|
||||
public Patient findPatient(
|
||||
@Description(shortDefinition = "The patient's identifier")
|
||||
@OptionalParam(name = Patient.SP_IDENTIFIER) IdentifierDt theIdentifier,
|
||||
@Description(shortDefinition = "The patient's name")
|
||||
@OptionalParam(name=Patient.SP_NAME) StringDt theName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
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.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.annotation.Sort;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
public class SortTest {
|
||||
|
||||
private static CloseableHttpClient ourClient;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SortTest.class);
|
||||
private static int ourPort;
|
||||
private static Server ourServer;
|
||||
|
||||
@Test
|
||||
public void testNoSort() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
Bundle bundle = new FhirContext().newXmlParser().parseBundle(responseContent);
|
||||
assertEquals(1, bundle.size());
|
||||
|
||||
Patient p = bundle.getResources(Patient.class).get(0);
|
||||
assertEquals(1, p.getName().size());
|
||||
assertEquals("Hello", p.getNameFirstRep().getFamilyFirstRep().getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleSort() throws Exception {
|
||||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello&_sort=given");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
Bundle bundle = new FhirContext().newXmlParser().parseBundle(responseContent);
|
||||
assertEquals(1, bundle.size());
|
||||
|
||||
Patient p = bundle.getResources(Patient.class).get(0);
|
||||
assertEquals(2, p.getName().size());
|
||||
assertEquals("Hello", p.getNameFirstRep().getFamilyFirstRep().getValue());
|
||||
assertEquals("given|null", p.getName().get(1).getFamilyFirstRep().getValue());
|
||||
}
|
||||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello&_sort:asc=given");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
Bundle bundle = new FhirContext().newXmlParser().parseBundle(responseContent);
|
||||
assertEquals(1, bundle.size());
|
||||
|
||||
Patient p = bundle.getResources(Patient.class).get(0);
|
||||
assertEquals(2, p.getName().size());
|
||||
assertEquals("Hello", p.getNameFirstRep().getFamilyFirstRep().getValue());
|
||||
assertEquals("given|ASC", p.getName().get(1).getFamilyFirstRep().getValue());
|
||||
}
|
||||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello&_sort:desc=given");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
Bundle bundle = new FhirContext().newXmlParser().parseBundle(responseContent);
|
||||
assertEquals(1, bundle.size());
|
||||
|
||||
Patient p = bundle.getResources(Patient.class).get(0);
|
||||
assertEquals(2, p.getName().size());
|
||||
assertEquals("Hello", p.getNameFirstRep().getFamilyFirstRep().getValue());
|
||||
assertEquals("given|DESC", p.getName().get(1).getFamilyFirstRep().getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSortChain() throws Exception {
|
||||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello&_sort=given&_sort=family&_sort=name");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
Bundle bundle = new FhirContext().newXmlParser().parseBundle(responseContent);
|
||||
assertEquals(1, bundle.size());
|
||||
|
||||
Patient p = bundle.getResources(Patient.class).get(0);
|
||||
assertEquals(4, p.getName().size());
|
||||
assertEquals("Hello", p.getNameFirstRep().getFamilyFirstRep().getValue());
|
||||
assertEquals("given|null", p.getName().get(1).getFamilyFirstRep().getValue());
|
||||
assertEquals("family|null", p.getName().get(2).getFamilyFirstRep().getValue());
|
||||
assertEquals("name|null", p.getName().get(3).getFamilyFirstRep().getValue());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@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 = Patient.SP_NAME) StringDt theName, @Sort SortSpec theSort) {
|
||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily().setValue(theName.getValue());
|
||||
SortSpec sort = theSort;
|
||||
while (sort != null) {
|
||||
p.addName().addFamily().setValue(sort.getFieldName() + "|" + sort.getOrder());
|
||||
sort = sort.getChain();
|
||||
}
|
||||
|
||||
retVal.add(p);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends IResource> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,151 +1,152 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/test/java" output="target/test-classes" including="**/*.java"/>
|
||||
<classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
|
||||
<classpathentry kind="src" path="src/main/java" including="**/*.java"/>
|
||||
<classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
<classpathentry kind="var" path="M2_REPO/javax/activation/activation/1.1/activation-1.1.jar" sourcepath="M2_REPO/javax/activation/activation/1.1/activation-1.1-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"/>
|
||||
<classpathentry kind="var" path="M2_REPO/javax/mail/javax.mail-api/1.5.0/javax.mail-api-1.5.0.jar" sourcepath="M2_REPO/javax/mail/javax.mail-api/1.5.0/javax.mail-api-1.5.0-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/javax/mail/javax.mail-api/1.5.0/javax.mail-api-1.5.0-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/javax/transaction/jta/1.1/jta-1.1.jar" sourcepath="M2_REPO/javax/transaction/jta/1.1/jta-1.1-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2.jar" sourcepath="M2_REPO/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final.jar" sourcepath="M2_REPO/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/antlr/antlr/2.7.7/antlr-2.7.7.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0.jar" sourcepath="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/com/fasterxml/classmate/1.0.0/classmate-1.0.0.jar" sourcepath="M2_REPO/com/fasterxml/classmate/1.0.0/classmate-1.0.0-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/commons-codec/commons-codec/1.9/commons-codec-1.9.jar" sourcepath="M2_REPO/commons-codec/commons-codec/1.9/commons-codec-1.9-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/commons-codec/commons-codec/1.9/commons-codec-1.9-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/commons-dbcp/commons-dbcp/1.4/commons-dbcp-1.4.jar" sourcepath="M2_REPO/commons-dbcp/commons-dbcp/1.4/commons-dbcp-1.4-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/commons-io/commons-io/2.4/commons-io-2.4.jar" sourcepath="M2_REPO/commons-io/commons-io/2.4/commons-io-2.4-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/commons-io/commons-io/2.4/commons-io-2.4-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1.jar" sourcepath="M2_REPO/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar" sourcepath="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/commons-pool/commons-pool/1.5.4/commons-pool-1.5.4.jar" sourcepath="M2_REPO/commons-pool/commons-pool/1.5.4/commons-pool-1.5.4-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/org/apache/derby/derby/10.10.2.0/derby-10.10.2.0.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar" sourcepath="M2_REPO/dom4j/dom4j/1.6.1/dom4j-1.6.1-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-all/1.3/hamcrest-all-1.3.jar" sourcepath="M2_REPO/org/hamcrest/hamcrest-all/1.3/hamcrest-all-1.3-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/hamcrest/hamcrest-all/1.3/hamcrest-all-1.3-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar" sourcepath="M2_REPO/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="/hapi-fhir-base"/>
|
||||
<classpathentry kind="var" path="M2_REPO/org/hibernate/common/hibernate-commons-annotations/4.0.4.Final/hibernate-commons-annotations-4.0.4.Final.jar" sourcepath="M2_REPO/org/hibernate/common/hibernate-commons-annotations/4.0.4.Final/hibernate-commons-annotations-4.0.4.Final-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-core/4.3.5.Final/hibernate-core-4.3.5.Final.jar" sourcepath="M2_REPO/org/hibernate/hibernate-core/4.3.5.Final/hibernate-core-4.3.5.Final-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-ehcache/4.3.5.Final/hibernate-ehcache-4.3.5.Final.jar" sourcepath="M2_REPO/org/hibernate/hibernate-ehcache/4.3.5.Final/hibernate-ehcache-4.3.5.Final-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-entitymanager/4.3.5.Final/hibernate-entitymanager-4.3.5.Final.jar" sourcepath="M2_REPO/org/hibernate/hibernate-entitymanager/4.3.5.Final/hibernate-entitymanager-4.3.5.Final-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/org/hibernate/javax/persistence/hibernate-jpa-2.1-api/1.0.0.Final/hibernate-jpa-2.1-api-1.0.0.Final.jar" sourcepath="M2_REPO/org/hibernate/javax/persistence/hibernate-jpa-2.1-api/1.0.0.Final/hibernate-jpa-2.1-api-1.0.0.Final-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/hibernate/javax/persistence/hibernate-jpa-2.1-api/1.0.0.Final/hibernate-jpa-2.1-api-1.0.0.Final-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-validator/5.1.0.Final/hibernate-validator-5.1.0.Final.jar" sourcepath="M2_REPO/org/hibernate/hibernate-validator/5.1.0.Final/hibernate-validator-5.1.0.Final-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar" sourcepath="M2_REPO/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar" sourcepath="M2_REPO/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/org/jboss/jandex/1.1.0.Final/jandex-1.1.0.Final.jar" sourcepath="M2_REPO/org/jboss/jandex/1.1.0.Final/jandex-1.1.0.Final-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA.jar" sourcepath="M2_REPO/org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/glassfish/javax.json/1.0.4/javax.json-1.0.4.jar" sourcepath="M2_REPO/org/glassfish/javax.json/1.0.4/javax.json-1.0.4-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/org/jboss/logging/jboss-logging/3.1.3.GA/jboss-logging-3.1.3.GA.jar" sourcepath="M2_REPO/org/jboss/logging/jboss-logging/3.1.3.GA/jboss-logging-3.1.3.GA-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/jboss/logging/jboss-logging/3.1.3.GA/jboss-logging-3.1.3.GA-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/jboss/logging/jboss-logging-annotations/1.2.0.Beta1/jboss-logging-annotations-1.2.0.Beta1.jar" sourcepath="M2_REPO/org/jboss/logging/jboss-logging-annotations/1.2.0.Beta1/jboss-logging-annotations-1.2.0.Beta1-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/jboss/logging/jboss-logging-annotations/1.2.0.Beta1/jboss-logging-annotations-1.2.0.Beta1-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/jboss/spec/javax/transaction/jboss-transaction-api_1.2_spec/1.0.0.Final/jboss-transaction-api_1.2_spec-1.0.0.Final.jar" sourcepath="M2_REPO/org/jboss/spec/javax/transaction/jboss-transaction-api_1.2_spec/1.0.0.Final/jboss-transaction-api_1.2_spec-1.0.0.Final-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/jboss/spec/javax/transaction/jboss-transaction-api_1.2_spec/1.0.0.Final/jboss-transaction-api_1.2_spec-1.0.0.Final-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/junit/junit/4.11/junit-4.11.jar" sourcepath="M2_REPO/junit/junit/4.11/junit-4.11-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/junit/junit/4.11/junit-4.11-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.7.6/slf4j-api-1.7.6.jar" sourcepath="M2_REPO/org/slf4j/slf4j-api/1.7.6/slf4j-api-1.7.6-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/slf4j/slf4j-api/1.7.6/slf4j-api-1.7.6-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-aop/4.0.1.RELEASE/spring-aop-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-aop/4.0.1.RELEASE/spring-aop-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-aop/4.0.1.RELEASE/spring-aop-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-beans/4.0.1.RELEASE/spring-beans-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-beans/4.0.1.RELEASE/spring-beans-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-beans/4.0.1.RELEASE/spring-beans-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-context/4.0.1.RELEASE/spring-context-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-context/4.0.1.RELEASE/spring-context-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-context/4.0.1.RELEASE/spring-context-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-context-support/4.0.1.RELEASE/spring-context-support-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-context-support/4.0.1.RELEASE/spring-context-support-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-context-support/4.0.1.RELEASE/spring-context-support-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-core/4.0.1.RELEASE/spring-core-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-core/4.0.1.RELEASE/spring-core-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-core/4.0.1.RELEASE/spring-core-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-expression/4.0.1.RELEASE/spring-expression-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-expression/4.0.1.RELEASE/spring-expression-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-expression/4.0.1.RELEASE/spring-expression-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-jdbc/4.0.1.RELEASE/spring-jdbc-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-jdbc/4.0.1.RELEASE/spring-jdbc-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-jdbc/4.0.1.RELEASE/spring-jdbc-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-orm/4.0.1.RELEASE/spring-orm-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-orm/4.0.1.RELEASE/spring-orm-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-orm/4.0.1.RELEASE/spring-orm-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-tx/4.0.1.RELEASE/spring-tx-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-tx/4.0.1.RELEASE/spring-tx-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-tx/4.0.1.RELEASE/spring-tx-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/org/codehaus/woodstox/stax2-api/3.1.1/stax2-api-3.1.1.jar" sourcepath="M2_REPO/org/codehaus/woodstox/stax2-api/3.1.1/stax2-api-3.1.1-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0.jar" sourcepath="M2_REPO/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0-sources.jar">
|
||||
<attributes>
|
||||
<attribute value="jar:file:/Users/james/.m2/repository/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0-javadoc.jar!/" name="javadoc_location"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
</classpath>
|
||||
<classpathentry including="**/*.java" kind="src" output="target/test-classes" path="src/test/java"/>
|
||||
<classpathentry excluding="**/*.java" kind="src" output="target/test-classes" path="src/test/resources"/>
|
||||
<classpathentry including="**/*.java" kind="src" path="src/main/java"/>
|
||||
<classpathentry excluding="**/*.java" kind="src" path="src/main/resources"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/javax/activation/activation/1.1/activation-1.1.jar" sourcepath="M2_REPO/javax/activation/activation/1.1/activation-1.1-sources.jar"/>
|
||||
<classpathentry exported="true" 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 exported="true" kind="var" path="M2_REPO/javax/mail/javax.mail-api/1.5.0/javax.mail-api-1.5.0.jar" sourcepath="M2_REPO/javax/mail/javax.mail-api/1.5.0/javax.mail-api-1.5.0-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/javax/mail/javax.mail-api/1.5.0/javax.mail-api-1.5.0-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/javax/transaction/jta/1.1/jta-1.1.jar" sourcepath="M2_REPO/javax/transaction/jta/1.1/jta-1.1-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2.jar" sourcepath="M2_REPO/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final.jar" sourcepath="M2_REPO/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/antlr/antlr/2.7.7/antlr-2.7.7.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0.jar" sourcepath="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/com/fasterxml/classmate/1.0.0/classmate-1.0.0.jar" sourcepath="M2_REPO/com/fasterxml/classmate/1.0.0/classmate-1.0.0-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/commons-codec/commons-codec/1.9/commons-codec-1.9.jar" sourcepath="M2_REPO/commons-codec/commons-codec/1.9/commons-codec-1.9-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/commons-codec/commons-codec/1.9/commons-codec-1.9-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/commons-dbcp/commons-dbcp/1.4/commons-dbcp-1.4.jar" sourcepath="M2_REPO/commons-dbcp/commons-dbcp/1.4/commons-dbcp-1.4-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/commons-io/commons-io/2.4/commons-io-2.4.jar" sourcepath="M2_REPO/commons-io/commons-io/2.4/commons-io-2.4-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/commons-io/commons-io/2.4/commons-io-2.4-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1.jar" sourcepath="M2_REPO/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar" sourcepath="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/commons-pool/commons-pool/1.5.4/commons-pool-1.5.4.jar" sourcepath="M2_REPO/commons-pool/commons-pool/1.5.4/commons-pool-1.5.4-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/apache/derby/derby/10.10.2.0/derby-10.10.2.0.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar" sourcepath="M2_REPO/dom4j/dom4j/1.6.1/dom4j-1.6.1-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/hamcrest/hamcrest-all/1.3/hamcrest-all-1.3.jar" sourcepath="M2_REPO/org/hamcrest/hamcrest-all/1.3/hamcrest-all-1.3-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/hamcrest/hamcrest-all/1.3/hamcrest-all-1.3-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar" sourcepath="M2_REPO/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="/hapi-fhir-base"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/hibernate/common/hibernate-commons-annotations/4.0.4.Final/hibernate-commons-annotations-4.0.4.Final.jar" sourcepath="M2_REPO/org/hibernate/common/hibernate-commons-annotations/4.0.4.Final/hibernate-commons-annotations-4.0.4.Final-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/hibernate/hibernate-core/4.3.5.Final/hibernate-core-4.3.5.Final.jar" sourcepath="M2_REPO/org/hibernate/hibernate-core/4.3.5.Final/hibernate-core-4.3.5.Final-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/hibernate/hibernate-ehcache/4.3.5.Final/hibernate-ehcache-4.3.5.Final.jar" sourcepath="M2_REPO/org/hibernate/hibernate-ehcache/4.3.5.Final/hibernate-ehcache-4.3.5.Final-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/hibernate/hibernate-entitymanager/4.3.5.Final/hibernate-entitymanager-4.3.5.Final.jar" sourcepath="M2_REPO/org/hibernate/hibernate-entitymanager/4.3.5.Final/hibernate-entitymanager-4.3.5.Final-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/hibernate/javax/persistence/hibernate-jpa-2.1-api/1.0.0.Final/hibernate-jpa-2.1-api-1.0.0.Final.jar" sourcepath="M2_REPO/org/hibernate/javax/persistence/hibernate-jpa-2.1-api/1.0.0.Final/hibernate-jpa-2.1-api-1.0.0.Final-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/hibernate/javax/persistence/hibernate-jpa-2.1-api/1.0.0.Final/hibernate-jpa-2.1-api-1.0.0.Final-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/hibernate/hibernate-validator/5.1.0.Final/hibernate-validator-5.1.0.Final.jar" sourcepath="M2_REPO/org/hibernate/hibernate-validator/5.1.0.Final/hibernate-validator-5.1.0.Final-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar" sourcepath="M2_REPO/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar" sourcepath="M2_REPO/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/jandex/1.1.0.Final/jandex-1.1.0.Final.jar" sourcepath="M2_REPO/org/jboss/jandex/1.1.0.Final/jandex-1.1.0.Final-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA.jar" sourcepath="M2_REPO/org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/glassfish/javax.json/1.0.4/javax.json-1.0.4.jar" sourcepath="M2_REPO/org/glassfish/javax.json/1.0.4/javax.json-1.0.4-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/logging/jboss-logging/3.1.3.GA/jboss-logging-3.1.3.GA.jar" sourcepath="M2_REPO/org/jboss/logging/jboss-logging/3.1.3.GA/jboss-logging-3.1.3.GA-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/jboss/logging/jboss-logging/3.1.3.GA/jboss-logging-3.1.3.GA-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/logging/jboss-logging-annotations/1.2.0.Beta1/jboss-logging-annotations-1.2.0.Beta1.jar" sourcepath="M2_REPO/org/jboss/logging/jboss-logging-annotations/1.2.0.Beta1/jboss-logging-annotations-1.2.0.Beta1-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/jboss/logging/jboss-logging-annotations/1.2.0.Beta1/jboss-logging-annotations-1.2.0.Beta1-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/spec/javax/transaction/jboss-transaction-api_1.2_spec/1.0.0.Final/jboss-transaction-api_1.2_spec-1.0.0.Final.jar" sourcepath="M2_REPO/org/jboss/spec/javax/transaction/jboss-transaction-api_1.2_spec/1.0.0.Final/jboss-transaction-api_1.2_spec-1.0.0.Final-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/jboss/spec/javax/transaction/jboss-transaction-api_1.2_spec/1.0.0.Final/jboss-transaction-api_1.2_spec-1.0.0.Final-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/junit/junit/4.11/junit-4.11.jar" sourcepath="M2_REPO/junit/junit/4.11/junit-4.11-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/junit/junit/4.11/junit-4.11-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.7.6/slf4j-api-1.7.6.jar" sourcepath="M2_REPO/org/slf4j/slf4j-api/1.7.6/slf4j-api-1.7.6-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/slf4j/slf4j-api/1.7.6/slf4j-api-1.7.6-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/springframework/spring-aop/4.0.1.RELEASE/spring-aop-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-aop/4.0.1.RELEASE/spring-aop-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-aop/4.0.1.RELEASE/spring-aop-4.0.1.RELEASE-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/springframework/spring-beans/4.0.1.RELEASE/spring-beans-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-beans/4.0.1.RELEASE/spring-beans-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-beans/4.0.1.RELEASE/spring-beans-4.0.1.RELEASE-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/springframework/spring-context/4.0.1.RELEASE/spring-context-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-context/4.0.1.RELEASE/spring-context-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-context/4.0.1.RELEASE/spring-context-4.0.1.RELEASE-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/springframework/spring-context-support/4.0.1.RELEASE/spring-context-support-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-context-support/4.0.1.RELEASE/spring-context-support-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-context-support/4.0.1.RELEASE/spring-context-support-4.0.1.RELEASE-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/springframework/spring-core/4.0.1.RELEASE/spring-core-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-core/4.0.1.RELEASE/spring-core-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-core/4.0.1.RELEASE/spring-core-4.0.1.RELEASE-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/springframework/spring-expression/4.0.1.RELEASE/spring-expression-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-expression/4.0.1.RELEASE/spring-expression-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-expression/4.0.1.RELEASE/spring-expression-4.0.1.RELEASE-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/springframework/spring-jdbc/4.0.1.RELEASE/spring-jdbc-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-jdbc/4.0.1.RELEASE/spring-jdbc-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-jdbc/4.0.1.RELEASE/spring-jdbc-4.0.1.RELEASE-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/springframework/spring-orm/4.0.1.RELEASE/spring-orm-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-orm/4.0.1.RELEASE/spring-orm-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-orm/4.0.1.RELEASE/spring-orm-4.0.1.RELEASE-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/springframework/spring-tx/4.0.1.RELEASE/spring-tx-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-tx/4.0.1.RELEASE/spring-tx-4.0.1.RELEASE-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-tx/4.0.1.RELEASE/spring-tx-4.0.1.RELEASE-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/codehaus/woodstox/stax2-api/3.1.1/stax2-api-3.1.1.jar" sourcepath="M2_REPO/org/codehaus/woodstox/stax2-api/3.1.1/stax2-api-3.1.1-sources.jar"/>
|
||||
<classpathentry exported="true" kind="var" path="M2_REPO/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0.jar" sourcepath="M2_REPO/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
target/
|
||||
/bin
|
||||
|
|
|
@ -175,6 +175,59 @@
|
|||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>de.juplo</groupId>
|
||||
<artifactId>hibernate4-maven-plugin</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<configuration>
|
||||
<force>true</force>
|
||||
<target>SCRIPT</target>
|
||||
<skip>false</skip>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>o10g</id>
|
||||
<goals>
|
||||
<goal>export</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<hibernateDialect>org.hibernate.dialect.Oracle10gDialect</hibernateDialect>
|
||||
<outputFile>${project.build.directory}/schema_oracle_10g.sql</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>derby</id>
|
||||
<goals>
|
||||
<goal>export</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<hibernateDialect>org.hibernate.dialect.DerbyTenSevenDialect</hibernateDialect>
|
||||
<outputFile>${project.build.directory}/schema_derby.sql</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>hsql</id>
|
||||
<goals>
|
||||
<goal>export</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<hibernateDialect>org.hibernate.dialect.HSQLDialect</hibernateDialect>
|
||||
<outputFile>${project.build.directory}/schema_hsql.sql</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>mysql5</id>
|
||||
<goals>
|
||||
<goal>export</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<hibernateDialect>org.hibernate.dialect.MySQL5Dialect</hibernateDialect>
|
||||
<outputFile>${project.build.directory}/schema_mysql_5.sql</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
@ -56,8 +56,10 @@ import ca.uhn.fhir.model.api.IResource;
|
|||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.model.api.Tag;
|
||||
import ca.uhn.fhir.model.api.TagList;
|
||||
import ca.uhn.fhir.model.dstu.composite.AddressDt;
|
||||
import ca.uhn.fhir.model.dstu.composite.CodeableConceptDt;
|
||||
import ca.uhn.fhir.model.dstu.composite.CodingDt;
|
||||
import ca.uhn.fhir.model.dstu.composite.ContactDt;
|
||||
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
|
||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu.composite.QuantityDt;
|
||||
|
@ -96,6 +98,312 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
|||
|
||||
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) {
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
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 search(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> search(SearchParameterMap 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;
|
||||
}
|
||||
}
|
||||
|
||||
@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> searchForIds(String theParameterName, IQueryParameterType theValue) {
|
||||
return searchForIds(Collections.singletonMap(theParameterName, theValue));
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@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);
|
||||
entity.setUpdated(entity.getPublished());
|
||||
|
||||
final ResourceHistoryTable historyEntry = entity.toHistory(myCtx);
|
||||
|
||||
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);
|
||||
|
||||
populateResourceIntoEntity(theResource, entity);
|
||||
myEntityManager.persist(historyEntry);
|
||||
|
||||
entity.setUpdated(new Date());
|
||||
myEntityManager.persist(entity);
|
||||
|
||||
if (entity.isParamsStringPopulated()) {
|
||||
for (ResourceIndexedSearchParamString next : entity.getParamsString()) {
|
||||
myEntityManager.remove(next);
|
||||
}
|
||||
}
|
||||
for (ResourceIndexedSearchParamString next : stringParams) {
|
||||
myEntityManager.persist(next);
|
||||
}
|
||||
|
||||
if (entity.isParamsTokenPopulated()) {
|
||||
for (ResourceIndexedSearchParamToken next : entity.getParamsToken()) {
|
||||
myEntityManager.remove(next);
|
||||
}
|
||||
}
|
||||
for (ResourceIndexedSearchParamToken next : tokenParams) {
|
||||
myEntityManager.persist(next);
|
||||
}
|
||||
|
||||
if (entity.isParamsNumberPopulated()) {
|
||||
for (ResourceIndexedSearchParamNumber next : entity.getParamsNumber()) {
|
||||
myEntityManager.remove(next);
|
||||
}
|
||||
}
|
||||
for (ResourceIndexedSearchParamNumber next : numberParams) {
|
||||
myEntityManager.persist(next);
|
||||
}
|
||||
|
||||
if (entity.isParamsDatePopulated()) {
|
||||
for (ResourceIndexedSearchParamDate next : entity.getParamsDate()) {
|
||||
myEntityManager.remove(next);
|
||||
}
|
||||
}
|
||||
for (ResourceIndexedSearchParamDate next : dateParams) {
|
||||
myEntityManager.persist(next);
|
||||
}
|
||||
|
||||
if (entity.isHasLinks()) {
|
||||
for (ResourceLink next : entity.getResourceLinks()) {
|
||||
myEntityManager.remove(next);
|
||||
}
|
||||
}
|
||||
for (ResourceLink next : links) {
|
||||
myEntityManager.persist(next);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
});
|
||||
|
||||
return toMethodOutcome(savedEntity);
|
||||
}
|
||||
|
||||
private Set<Long> addPredicateDate(Set<Long> thePids, List<IQueryParameterType> theOrParams) {
|
||||
if (theOrParams == null || theOrParams.isEmpty()) {
|
||||
return thePids;
|
||||
|
@ -266,19 +574,19 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
|||
Predicate eq = builder.equal(from.get("myTargetResourcePid"), targetPid);
|
||||
codePredicates.add(eq);
|
||||
} else {
|
||||
// TODO: handle chain with resource type
|
||||
String chain = myCtx.getResourceDefinition(myResourceType).getSearchParam(theParamName).getPath();
|
||||
BaseRuntimeChildDefinition def = myCtx.newTerser().getDefinition(myResourceType, chain);
|
||||
if (!(def instanceof RuntimeChildResourceDefinition)) {
|
||||
throw new ConfigurationException("Property " + chain + " of type " + myResourceName + " is not a resource: " + def.getClass());
|
||||
}
|
||||
List<Class<? extends IResource>> resourceTypes;
|
||||
if (ref.getType() == null) {
|
||||
if (isBlank(ref.getResourceType())) {
|
||||
RuntimeChildResourceDefinition resDef = (RuntimeChildResourceDefinition) def;
|
||||
resourceTypes = resDef.getResourceTypes();
|
||||
} else {
|
||||
resourceTypes = new ArrayList<>();
|
||||
resourceTypes.add(ref.getType());
|
||||
RuntimeResourceDefinition resDef = myCtx.getResourceDefinition(ref.getResourceType());
|
||||
resourceTypes.add(resDef.getImplementingClass());
|
||||
}
|
||||
for (Class<? extends IResource> nextType : resourceTypes) {
|
||||
RuntimeResourceDefinition typeDef = myCtx.getResourceDefinition(nextType);
|
||||
|
@ -313,7 +621,10 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
|||
|
||||
Predicate masterCodePredicate = builder.or(codePredicates.toArray(new Predicate[0]));
|
||||
|
||||
Predicate type = builder.equal(from.get("mySourcePath"), myResourceName + "." + theParamName);
|
||||
RuntimeSearchParam param = myCtx.getResourceDefinition(getResourceType()).getSearchParam(theParamName);
|
||||
String path = param.getPath();
|
||||
|
||||
Predicate type = builder.equal(from.get("mySourcePath"), path);
|
||||
if (pidsToRetain.size() > 0) {
|
||||
Predicate inPids = (from.get("mySourceResourcePid").in(pidsToRetain));
|
||||
cq.where(builder.and(type, inPids, masterCodePredicate));
|
||||
|
@ -422,53 +733,6 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
|||
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) {
|
||||
ArrayList<ResourceLink> retVal = new ArrayList<ResourceLink>();
|
||||
|
||||
|
@ -533,6 +797,8 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
|||
}
|
||||
}
|
||||
|
||||
theEntity.setHasLinks(retVal.size() > 0);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
@ -580,6 +846,8 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
|||
}
|
||||
}
|
||||
|
||||
theEntity.setParamsDatePopulated(retVal.size() > 0);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
@ -608,8 +876,7 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
|||
|
||||
if (nextObject instanceof QuantityDt) {
|
||||
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());
|
||||
retVal.add(nextEntity);
|
||||
} else {
|
||||
|
@ -622,6 +889,8 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
|||
}
|
||||
}
|
||||
|
||||
theEntity.setParamsNumberPopulated(retVal.size() > 0);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
@ -657,42 +926,57 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
|||
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(resourceName, normalizeString(nextValue.getValueAsString()), nextValue.getValueAsString());
|
||||
nextEntity.setResource(theEntity, def.getName());
|
||||
retVal.add(nextEntity);
|
||||
} else if (nextObject instanceof HumanNameDt) {
|
||||
ArrayList<StringDt> allNames = new ArrayList<>();
|
||||
allNames.addAll(((HumanNameDt) nextObject).getFamily());
|
||||
allNames.addAll(((HumanNameDt) nextObject).getGiven());
|
||||
for (StringDt nextName : allNames) {
|
||||
if (nextName.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(resourceName, normalizeString(nextName.getValueAsString()), nextName.getValueAsString());
|
||||
nextEntity.setResource(theEntity, def.getName());
|
||||
retVal.add(nextEntity);
|
||||
}
|
||||
} else {
|
||||
if (!multiType) {
|
||||
throw new ConfigurationException("Search param " + resourceName + " is of unexpected datatype: " + nextObject.getClass());
|
||||
if (nextObject instanceof HumanNameDt) {
|
||||
ArrayList<StringDt> allNames = new ArrayList<>();
|
||||
HumanNameDt nextHumanName = (HumanNameDt) nextObject;
|
||||
allNames.addAll(nextHumanName.getFamily());
|
||||
allNames.addAll(nextHumanName.getGiven());
|
||||
for (StringDt nextName : allNames) {
|
||||
if (nextName.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(resourceName, normalizeString(nextName.getValueAsString()), nextName.getValueAsString());
|
||||
nextEntity.setResource(theEntity, def.getName());
|
||||
retVal.add(nextEntity);
|
||||
}
|
||||
} else if (nextObject instanceof AddressDt) {
|
||||
ArrayList<StringDt> allNames = new ArrayList<>();
|
||||
AddressDt nextAddress = (AddressDt) nextObject;
|
||||
allNames.addAll(nextAddress.getLine());
|
||||
allNames.add(nextAddress.getCity());
|
||||
allNames.add(nextAddress.getState());
|
||||
allNames.add(nextAddress.getCountry());
|
||||
allNames.add(nextAddress.getZip());
|
||||
for (StringDt nextName : allNames) {
|
||||
if (nextName.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(resourceName, normalizeString(nextName.getValueAsString()), nextName.getValueAsString());
|
||||
nextEntity.setResource(theEntity, def.getName());
|
||||
retVal.add(nextEntity);
|
||||
}
|
||||
} else if (nextObject instanceof ContactDt) {
|
||||
ContactDt nextContact = (ContactDt) nextObject;
|
||||
if (nextContact.getValue().isEmpty() == false) {
|
||||
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(resourceName, normalizeString(nextContact.getValue().getValueAsString()), nextContact.getValue().getValueAsString());
|
||||
nextEntity.setResource(theEntity, def.getName());
|
||||
retVal.add(nextEntity);
|
||||
}
|
||||
} else {
|
||||
if (!multiType) {
|
||||
throw new ConfigurationException("Search param " + resourceName + " is of unexpected datatype: " + nextObject.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
theEntity.setParamsStringPopulated(retVal.size() > 0);
|
||||
|
||||
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) {
|
||||
ArrayList<ResourceIndexedSearchParamToken> retVal = new ArrayList<ResourceIndexedSearchParamToken>();
|
||||
|
||||
|
@ -753,11 +1037,9 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
|||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
theEntity.setParamsTokenPopulated(retVal.size() > 0);
|
||||
|
||||
public Class<T> getResourceType() {
|
||||
return myResourceType;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private Map<Class<? extends IResource>, IFhirResourceDao<?>> getResourceTypeToDao() {
|
||||
|
@ -772,39 +1054,17 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
|||
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));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
retVal.add(read(theId));
|
||||
} catch (ResourceNotFoundException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (retVal.isEmpty()) {
|
||||
throw new ResourceNotFoundException(theId);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
return new String(out).toUpperCase();
|
||||
}
|
||||
|
||||
private void populateResourceIntoEntity(T theResource, X retVal) {
|
||||
|
@ -820,22 +1080,6 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
|||
|
||||
}
|
||||
|
||||
@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) {
|
||||
X entity = (X) myEntityManager.find(myTableType, theId.asLong());
|
||||
if (entity == null) {
|
||||
|
@ -844,132 +1088,6 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
|||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> search(Map<String, IQueryParameterType> theParams) {
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
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 search(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> search(SearchParameterMap 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) {
|
||||
X retVal;
|
||||
try {
|
||||
|
@ -1034,27 +1152,4 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
|||
}
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,15 +5,17 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
|
||||
public class SearchParameterMap extends HashMap<String, List<List<IQueryParameterType>>> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public void add(String theName, IQueryParameterType theParam) {
|
||||
if (theParam == null) {
|
||||
return;
|
||||
}
|
||||
if (!containsKey(theName)) {
|
||||
put(theName, new ArrayList<List<IQueryParameterType>>());
|
||||
}
|
||||
|
@ -22,13 +24,19 @@ public class SearchParameterMap extends HashMap<String, List<List<IQueryParamete
|
|||
get(theName).add(list);
|
||||
}
|
||||
|
||||
public void add(String theName, IQueryParameterAnd theBirthdate) {
|
||||
public void add(String theName, IQueryParameterAnd theAnd) {
|
||||
if (theAnd==null) {
|
||||
return;
|
||||
}
|
||||
if (!containsKey(theName)) {
|
||||
put(theName, new ArrayList<List<IQueryParameterType>>());
|
||||
}
|
||||
|
||||
for (QualifiedParamList next : theBirthdate.getValuesAsQueryTokens()) {
|
||||
next.get
|
||||
for (IQueryParameterOr next : theAnd.getValuesAsQueryTokens()) {
|
||||
if (next==null) {
|
||||
continue;
|
||||
}
|
||||
get(theName).add(next.getValuesAsQueryTokens());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,17 +28,29 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
|||
@DiscriminatorColumn(name = "SVCVER_TYPE", length = 20, discriminatorType = DiscriminatorType.STRING)
|
||||
public abstract class BaseResourceTable<T extends IResource> extends BaseHasResource {
|
||||
|
||||
@Column(name = "SP_HAS_LINKS")
|
||||
private boolean myHasLinks;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
@Column(name = "RES_ID")
|
||||
private Long myId;
|
||||
|
||||
@OneToMany(mappedBy = "myTargetResource", cascade = {}, fetch = FetchType.LAZY, orphanRemoval = false)
|
||||
private Collection<ResourceLink> myIncomingResourceLinks;
|
||||
|
||||
@OneToMany(mappedBy = "myResource", cascade = {}, fetch = FetchType.LAZY, orphanRemoval = false)
|
||||
private Collection<ResourceIndexedSearchParamDate> myParamsDate;
|
||||
|
||||
@Column(name = "SP_DATE_PRESENT")
|
||||
private boolean myParamsDatePopulated;
|
||||
|
||||
@OneToMany(mappedBy = "myResource", cascade = {}, fetch = FetchType.LAZY, orphanRemoval = false)
|
||||
private Collection<ResourceIndexedSearchParamNumber> myParamsNumber;
|
||||
|
||||
@Column(name = "SP_NUMBER_PRESENT")
|
||||
private boolean myParamsNumberPopulated;
|
||||
|
||||
@OneToMany(mappedBy = "myResource", cascade = {}, fetch = FetchType.LAZY, orphanRemoval = false)
|
||||
private Collection<ResourceIndexedSearchParamString> myParamsString;
|
||||
|
||||
|
@ -51,6 +63,9 @@ public abstract class BaseResourceTable<T extends IResource> extends BaseHasReso
|
|||
@Column(name = "SP_TOKEN_PRESENT")
|
||||
private boolean myParamsTokenPopulated;
|
||||
|
||||
@OneToMany(mappedBy = "mySourceResource", cascade = {}, fetch = FetchType.LAZY, orphanRemoval = false)
|
||||
private Collection<ResourceLink> myResourceLinks;
|
||||
|
||||
@OneToMany(mappedBy = "myResource", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
|
||||
private Collection<ResourceTag> myTags;
|
||||
|
||||
|
@ -67,14 +82,14 @@ public abstract class BaseResourceTable<T extends IResource> extends BaseHasReso
|
|||
getTags().add(new ResourceTag(this, theTerm, theLabel, theScheme));
|
||||
}
|
||||
|
||||
public Long getIdAsLong() {
|
||||
return myId;
|
||||
}
|
||||
|
||||
public IdDt getId() {
|
||||
return new IdDt(myId);
|
||||
}
|
||||
|
||||
public Long getIdAsLong() {
|
||||
return myId;
|
||||
}
|
||||
|
||||
public Collection<ResourceIndexedSearchParamDate> getParamsDate() {
|
||||
if (myParamsDate == null) {
|
||||
myParamsDate = new ArrayList<>();
|
||||
|
@ -82,6 +97,13 @@ public abstract class BaseResourceTable<T extends IResource> extends BaseHasReso
|
|||
return myParamsDate;
|
||||
}
|
||||
|
||||
public Collection<ResourceIndexedSearchParamNumber> getParamsNumber() {
|
||||
if (myParamsNumber == null) {
|
||||
myParamsNumber = new ArrayList<>();
|
||||
}
|
||||
return myParamsNumber;
|
||||
}
|
||||
|
||||
public Collection<ResourceIndexedSearchParamString> getParamsString() {
|
||||
if (myParamsString == null) {
|
||||
myParamsString = new ArrayList<>();
|
||||
|
@ -96,6 +118,13 @@ public abstract class BaseResourceTable<T extends IResource> extends BaseHasReso
|
|||
return myParamsToken;
|
||||
}
|
||||
|
||||
public Collection<ResourceLink> getResourceLinks() {
|
||||
if (myResourceLinks == null) {
|
||||
myResourceLinks = new ArrayList<>();
|
||||
}
|
||||
return myResourceLinks;
|
||||
}
|
||||
|
||||
public abstract Class<T> getResourceType();
|
||||
|
||||
public Collection<ResourceTag> getTags() {
|
||||
|
@ -109,10 +138,18 @@ public abstract class BaseResourceTable<T extends IResource> extends BaseHasReso
|
|||
return new IdDt(myVersion);
|
||||
}
|
||||
|
||||
public boolean isHasLinks() {
|
||||
return myHasLinks;
|
||||
}
|
||||
|
||||
public boolean isParamsDatePopulated() {
|
||||
return myParamsDatePopulated;
|
||||
}
|
||||
|
||||
public boolean isParamsNumberPopulated() {
|
||||
return myParamsNumberPopulated;
|
||||
}
|
||||
|
||||
public boolean isParamsStringPopulated() {
|
||||
return myParamsStringPopulated;
|
||||
}
|
||||
|
@ -121,6 +158,10 @@ public abstract class BaseResourceTable<T extends IResource> extends BaseHasReso
|
|||
return myParamsTokenPopulated;
|
||||
}
|
||||
|
||||
public void setHasLinks(boolean theHasLinks) {
|
||||
myHasLinks = theHasLinks;
|
||||
}
|
||||
|
||||
public void setId(IdDt theId) {
|
||||
myId = theId.asLong();
|
||||
}
|
||||
|
@ -133,6 +174,10 @@ public abstract class BaseResourceTable<T extends IResource> extends BaseHasReso
|
|||
myParamsDatePopulated = theParamsDatePopulated;
|
||||
}
|
||||
|
||||
public void setParamsNumberPopulated(boolean theParamsNumberPopulated) {
|
||||
myParamsNumberPopulated = theParamsNumberPopulated;
|
||||
}
|
||||
|
||||
public void setParamsString(Collection<ResourceIndexedSearchParamString> theParamsString) {
|
||||
myParamsString = theParamsString;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.entity;
|
|||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
@ -26,7 +27,7 @@ public class ResourceHistoryTag extends BaseTag implements Serializable {
|
|||
@JoinColumn(name="RES_TYPE", referencedColumnName="RES_TYPE"),
|
||||
@JoinColumn(name="PID", referencedColumnName="PID"),
|
||||
@JoinColumn(name="VERSION", referencedColumnName="VERSION")
|
||||
})
|
||||
}, foreignKey=@ForeignKey(name="FK_HT_RT"))
|
||||
private ResourceHistoryTable myResourceHistory;
|
||||
|
||||
public ResourceHistoryTag() {
|
||||
|
|
|
@ -4,6 +4,8 @@ import java.util.Date;
|
|||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
@ -11,7 +13,7 @@ import javax.persistence.Temporal;
|
|||
import javax.persistence.TemporalType;
|
||||
|
||||
@Entity
|
||||
@Table(name = "IDX_SP_DATE")
|
||||
@Table(name = "SPIDX_DATE", indexes= {@Index(name="IDX_SP_DATE", columnList="myValueLow,myValueHigh")})
|
||||
public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchParam {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -25,7 +27,7 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
|
|||
public Date myValueLow;
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
@JoinColumn(name = "RESOURCE_PID", nullable = false)
|
||||
@JoinColumn(name = "RESOURCE_PID", nullable = false, foreignKey=@ForeignKey(name="FK_ISD_RESOURCE"))
|
||||
private BaseResourceTable<?> myResource;
|
||||
|
||||
@Column(name = "RESOURCE_PID", insertable = false, updatable = false)
|
||||
|
|
|
@ -4,12 +4,14 @@ import java.math.BigDecimal;
|
|||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "IDX_SP_NUMBER")
|
||||
@Table(name = "SPIDX_NUMBER", indexes= {@Index(name="IDX_SP_NUMBER", columnList="myValue")})
|
||||
public class ResourceIndexedSearchParamNumber extends BaseResourceIndexedSearchParam {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -24,7 +26,7 @@ public class ResourceIndexedSearchParamNumber extends BaseResourceIndexedSearchP
|
|||
public BigDecimal myValue;
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
@JoinColumn(name = "RESOURCE_PID", nullable = false)
|
||||
@JoinColumn(name = "RESOURCE_PID", nullable = false, foreignKey=@ForeignKey(name="FK_ISN_RESOURCE"))
|
||||
private BaseResourceTable<?> myResource;
|
||||
|
||||
@Column(name = "RESOURCE_PID", insertable = false, updatable = false)
|
||||
|
|
|
@ -3,18 +3,20 @@ package ca.uhn.fhir.jpa.entity;
|
|||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "IDX_SP_STRING")
|
||||
@Table(name = "SPIDX_STRING", indexes= {@Index(name="IDX_SP_STRING", columnList="myValueNormalized")})
|
||||
public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchParam {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ManyToOne(optional = false, cascade = {}, fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "RESOURCE_PID", nullable = false)
|
||||
@JoinColumn(name = "RESOURCE_PID", nullable = false, foreignKey=@ForeignKey(name="FK_ISS_RESOURCE"))
|
||||
private BaseResourceTable<?> myResource;
|
||||
|
||||
@Column(name = "RESOURCE_PID", insertable=false, updatable=false)
|
||||
|
|
|
@ -2,18 +2,20 @@ package ca.uhn.fhir.jpa.entity;
|
|||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "IDX_SP_TOKEN")
|
||||
@Table(name = "SPIDX_TOKEN", indexes= {@Index(name="IDX_SP_STRING", columnList="mySystem,myValue")})
|
||||
public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchParam {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
@JoinColumn(name = "RESOURCE_PID", nullable = false)
|
||||
@JoinColumn(name = "RESOURCE_PID", nullable = false, foreignKey=@ForeignKey(name="FK_IST_RESOURCE"))
|
||||
private BaseResourceTable<?> myResource;
|
||||
|
||||
@Column(name = "RESOURCE_PID", insertable=false, updatable=false)
|
||||
|
@ -33,6 +35,9 @@ public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchPa
|
|||
mySystem = theSystem;
|
||||
}
|
||||
|
||||
public ResourceIndexedSearchParamToken() {
|
||||
}
|
||||
|
||||
public ResourceIndexedSearchParamToken(String theName, String theSystem, String theValue) {
|
||||
setName(theName);
|
||||
setSystem(theSystem);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package ca.uhn.fhir.jpa.entity;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
@ -19,7 +20,7 @@ public class ResourceTag extends BaseTag {
|
|||
private Long myId;
|
||||
|
||||
@ManyToOne(cascade= {})
|
||||
@JoinColumn(name = "RESOURCE_PID", nullable=false)
|
||||
@JoinColumn(name = "RESOURCE_PID", nullable=false, foreignKey=@ForeignKey(name="FK_RESTAG_RESOURCE"))
|
||||
private BaseResourceTable<?> myResource;
|
||||
|
||||
public ResourceTag() {
|
||||
|
|
|
@ -1,18 +1,14 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
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 static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hamcrest.core.StringContains;
|
||||
import org.junit.AfterClass;
|
||||
|
@ -190,7 +186,7 @@ public class FhirResourceDaoTest {
|
|||
found = ourPatientDao.search(Patient.SP_GENDER, new IdentifierDt(null, "F"));
|
||||
assertEquals(0, found.size());
|
||||
|
||||
Map<String, List<List<IQueryParameterType>>> map = new HashMap<>();
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.put(Patient.SP_IDENTIFIER, new ArrayList<List<IQueryParameterType>>());
|
||||
map.get(Patient.SP_IDENTIFIER).add(new ArrayList<IQueryParameterType>());
|
||||
map.get(Patient.SP_IDENTIFIER).get(0).add(new IdentifierDt("urn:system", "001testPersistSearchParams"));
|
||||
|
@ -201,7 +197,7 @@ public class FhirResourceDaoTest {
|
|||
assertEquals(1, found.size());
|
||||
assertEquals(id, found.get(0).getId().asLong().longValue());
|
||||
|
||||
map = new HashMap<>();
|
||||
map = new SearchParameterMap();
|
||||
map.put(Patient.SP_IDENTIFIER, new ArrayList<List<IQueryParameterType>>());
|
||||
map.get(Patient.SP_IDENTIFIER).add(new ArrayList<IQueryParameterType>());
|
||||
map.get(Patient.SP_IDENTIFIER).get(0).add(new IdentifierDt("urn:system", "001testPersistSearchParams"));
|
||||
|
@ -358,7 +354,7 @@ public class FhirResourceDaoTest {
|
|||
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"));
|
||||
result = ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam("Patient", Patient.SP_NAME, "testSearchResourceLinkWithChainWithMultipleTypes01"));
|
||||
assertEquals(1,result.size());
|
||||
assertEquals(obsId01, result.get(0).getId());
|
||||
|
||||
|
@ -505,6 +501,36 @@ public class FhirResourceDaoTest {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testUpdateMaintainsSearchParams() throws InterruptedException {
|
||||
Patient p1 = new Patient();
|
||||
p1.addIdentifier("urn:system", "testUpdateMaintainsSearchParamsAAA");
|
||||
p1.addName().addFamily("Tester").addGiven("testUpdateMaintainsSearchParamsAAA");
|
||||
IdDt p1id = ourPatientDao.create(p1).getId();
|
||||
|
||||
Patient p2 = new Patient();
|
||||
p2.addIdentifier("urn:system", "testUpdateMaintainsSearchParamsBBB");
|
||||
p2.addName().addFamily("Tester").addGiven("testUpdateMaintainsSearchParamsBBB");
|
||||
IdDt p2id = ourPatientDao.create(p2).getId();
|
||||
|
||||
Set<Long> ids = ourPatientDao.searchForIds(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsAAA"));
|
||||
assertEquals(1,ids.size());
|
||||
assertThat(ids, contains(p1id.asLong()));
|
||||
|
||||
// Update the name
|
||||
p1.getNameFirstRep().getGivenFirstRep().setValue("testUpdateMaintainsSearchParamsBBB");
|
||||
ourPatientDao.update(p1, p1id);
|
||||
|
||||
ids = ourPatientDao.searchForIds(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsAAA"));
|
||||
assertEquals(0,ids.size());
|
||||
|
||||
ids = ourPatientDao.searchForIds(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsBBB"));
|
||||
assertEquals(2,ids.size());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() {
|
||||
ourCtx.close();
|
||||
|
@ -514,7 +540,7 @@ public class FhirResourceDaoTest {
|
|||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
ourTestStarted = new Date();
|
||||
ourCtx = new ClassPathXmlApplicationContext("fhir-spring-test-config.xml");
|
||||
ourCtx = new ClassPathXmlApplicationContext("fhir-jpabase-spring-test-config.xml");
|
||||
ourPatientDao = ourCtx.getBean("myPatientDao", IFhirResourceDao.class);
|
||||
ourObservationDao = ourCtx.getBean("myObservationDao", IFhirResourceDao.class);
|
||||
ourDiagnosticReportDao = ourCtx.getBean("myDiagnosticReportDao", IFhirResourceDao.class);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package ca.uhn.fhir.jpa.entity;
|
||||
package ca.uhn.fhir.jpa.testentity;
|
||||
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.BaseResourceTable;
|
||||
import ca.uhn.fhir.model.dstu.resource.Device;
|
||||
|
||||
@Entity
|
|
@ -1,8 +1,9 @@
|
|||
package ca.uhn.fhir.jpa.entity;
|
||||
package ca.uhn.fhir.jpa.testentity;
|
||||
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.BaseResourceTable;
|
||||
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
|
||||
|
||||
@Entity
|
|
@ -1,8 +1,9 @@
|
|||
package ca.uhn.fhir.jpa.entity;
|
||||
package ca.uhn.fhir.jpa.testentity;
|
||||
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.BaseResourceTable;
|
||||
import ca.uhn.fhir.model.dstu.resource.Location;
|
||||
|
||||
@Entity
|
|
@ -1,8 +1,9 @@
|
|||
package ca.uhn.fhir.jpa.entity;
|
||||
package ca.uhn.fhir.jpa.testentity;
|
||||
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.BaseResourceTable;
|
||||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||
|
||||
@Entity
|
|
@ -1,8 +1,9 @@
|
|||
package ca.uhn.fhir.jpa.entity;
|
||||
package ca.uhn.fhir.jpa.testentity;
|
||||
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.BaseResourceTable;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
|
||||
@Entity
|
|
@ -1,8 +1,9 @@
|
|||
package ca.uhn.fhir.jpa.entity;
|
||||
package ca.uhn.fhir.jpa.testentity;
|
||||
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.BaseResourceTable;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
|
||||
@Entity
|
|
@ -1,8 +1,9 @@
|
|||
package ca.uhn.fhir.jpa.entity;
|
||||
package ca.uhn.fhir.jpa.testentity;
|
||||
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.BaseResourceTable;
|
||||
import ca.uhn.fhir.model.dstu.resource.Questionnaire;
|
||||
|
||||
@Entity
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
|
||||
version="2.0">
|
||||
|
||||
<persistence-unit name="FHIR_UT" transaction-type="RESOURCE_LOCAL">
|
||||
<provider>org.hibernate.ejb.HibernatePersistence</provider>
|
||||
<!-- <class>ca.uhn.fhir.jpa.entity.PatientResourceTable</class> -->
|
||||
|
||||
<class>ca.uhn.fhir.jpa.testentity.DeviceResourceTable</class>
|
||||
<class>ca.uhn.fhir.jpa.testentity.DiagnosticReportResourceTable</class>
|
||||
<class>ca.uhn.fhir.jpa.testentity.LocationResourceTable</class>
|
||||
<class>ca.uhn.fhir.jpa.testentity.ObservationResourceTable</class>
|
||||
<class>ca.uhn.fhir.jpa.testentity.OrganizationResourceTable</class>
|
||||
<class>ca.uhn.fhir.jpa.testentity.PatientResourceTable</class>
|
||||
<class>ca.uhn.fhir.jpa.testentity.QuestionnaireResourceTable</class>
|
||||
<class>ca.uhn.fhir.jpa.testentity.QuestionnaireResourceTable</class>
|
||||
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceHistoryTable</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceHistoryTag</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamDate</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamNumber</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamToken</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceLink</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceTag</class>
|
||||
|
||||
<exclude-unlisted-classes>false</exclude-unlisted-classes>
|
||||
<properties>
|
||||
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:unit-testing-jpa" />
|
||||
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyTenSevenDialect" />
|
||||
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||
<property name="hibernate.connection.username" value="sa" />
|
||||
<property name="hibernate.connection.password" value="" />
|
||||
<property name="hibernate.jdbc.batch_size" value="0" />
|
||||
<property name="hibernate.cache.use_minimal_puts" value="false" />
|
||||
<property name="hibernate.show_sql" value="false" />
|
||||
<property name="hibernate.cache.use_query_cache" value="false" />
|
||||
<property name="hibernate.cache.use_second_level_cache" value="false" />
|
||||
<property name="hibernate.cache.use_structured_entries" value="false" />
|
||||
<property name="hibernate.ejb.naming_strategy" value="ca.uhn.fhir.jpa.util.CustomNamingStrategy" />
|
||||
<!--
|
||||
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory" />
|
||||
-->
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
|
@ -14,22 +14,22 @@
|
|||
<context:mbean-server />
|
||||
|
||||
<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.testentity.PatientResourceTable"/>
|
||||
</bean>
|
||||
<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.testentity.ObservationResourceTable"/>
|
||||
</bean>
|
||||
<bean id="myDiagnosticReportDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||
<property name="tableType" value="ca.uhn.fhir.jpa.entity.DiagnosticReportResourceTable"/>
|
||||
<property name="tableType" value="ca.uhn.fhir.jpa.testentity.DiagnosticReportResourceTable"/>
|
||||
</bean>
|
||||
<bean id="myDeviceDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||
<property name="tableType" value="ca.uhn.fhir.jpa.entity.DeviceResourceTable"/>
|
||||
<property name="tableType" value="ca.uhn.fhir.jpa.testentity.DeviceResourceTable"/>
|
||||
</bean>
|
||||
<bean id="myLocationDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||
<property name="tableType" value="ca.uhn.fhir.jpa.entity.LocationResourceTable"/>
|
||||
<property name="tableType" value="ca.uhn.fhir.jpa.testentity.LocationResourceTable"/>
|
||||
</bean>
|
||||
<bean id="myOrganizationDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||
<property name="tableType" value="ca.uhn.fhir.jpa.entity.OrganizationResourceTable"/>
|
||||
<property name="tableType" value="ca.uhn.fhir.jpa.testentity.OrganizationResourceTable"/>
|
||||
</bean>
|
||||
|
||||
<bean id="myPersistenceDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" lazy-init="true">
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry excluding="**/*.java" kind="src" output="target/test-classes" path="src/test/resources"/>
|
||||
<classpathentry kind="src" path="target/generated-sources/tinder"/>
|
||||
<classpathentry including="**/*.java" kind="src" path="src/main/java"/>
|
||||
<classpathentry excluding="**/*.java" kind="src" path="src/main/resources"/>
|
||||
<classpathentry kind="var" path="M2_REPO/javax/activation/activation/1.1/activation-1.1.jar" sourcepath="M2_REPO/javax/activation/activation/1.1/activation-1.1-sources.jar"/>
|
||||
|
|
|
@ -80,6 +80,33 @@
|
|||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-tinder-plugin</artifactId>
|
||||
<version>0.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>buildclient</id>
|
||||
<goals>
|
||||
<goal>generate-jparest-server</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<packageBase>ca.uhn.test.jpasrv</packageBase>
|
||||
<baseResourceNames>
|
||||
<baseResourceName>device</baseResourceName>
|
||||
<baseResourceName>location</baseResourceName>
|
||||
<baseResourceName>observation</baseResourceName>
|
||||
<baseResourceName>organization</baseResourceName>
|
||||
<baseResourceName>patient</baseResourceName>
|
||||
<baseResourceName>practitioner</baseResourceName>
|
||||
<baseResourceName>questionnaire</baseResourceName>
|
||||
<baseResourceName>valueset</baseResourceName>
|
||||
</baseResourceNames>
|
||||
<buildDatatypes>true</buildDatatypes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
package ca.uhn.fhir.jpa.test;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
||||
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.Questionnaire;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.tester.RestfulServerTesterServlet;
|
||||
import ca.uhn.test.jpasrv.ObservationResourceProvider;
|
||||
import ca.uhn.test.jpasrv.OrganizationResourceProvider;
|
||||
import ca.uhn.test.jpasrv.PatientResourceProvider;
|
||||
|
||||
public class CompleteResourceProviderTest {
|
||||
|
||||
private static ClassPathXmlApplicationContext ourAppCtx;
|
||||
private static FhirContext ourCtx;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CompleteResourceProviderTest.class);
|
||||
|
||||
private static Server ourServer;
|
||||
private static IFhirResourceDao<Patient> patientDao;
|
||||
private static IFhirResourceDao<Questionnaire> questionnaireDao;
|
||||
private static IGenericClient ourClient;
|
||||
private static IFhirResourceDao<Observation> observationDao;
|
||||
|
||||
// @Test
|
||||
// public void test01UploadTestResources() throws Exception {
|
||||
//
|
||||
// IGenericClient client = ourCtx.newRestfulGenericClient("http://localhost:8888/fhir/context");
|
||||
//
|
||||
// File[] files = new File("src/test/resources/resources").listFiles(new PatternFilenameFilter(".*patient.*"));
|
||||
// for (File file : files) {
|
||||
// ourLog.info("Uploading: {}", file);
|
||||
// Patient patient = ourCtx.newXmlParser().parseResource(Patient.class, new FileReader(file));
|
||||
// client.create(patient);
|
||||
// }
|
||||
//
|
||||
// files = new File("src/test/resources/resources").listFiles(new PatternFilenameFilter(".*questionnaire.*"));
|
||||
// for (File file : files) {
|
||||
// ourLog.info("Uploading: {}", file);
|
||||
// Questionnaire patient = ourCtx.newXmlParser().parseResource(Questionnaire.class, new FileReader(file));
|
||||
// client.create(patient);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void testSearchByIdentifier() {
|
||||
Patient p1 = new Patient();
|
||||
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier01");
|
||||
p1.addName().addFamily("testSearchByIdentifierFamily01").addGiven("testSearchByIdentifierGiven01");
|
||||
IdDt p1Id = ourClient.create(p1).getId();
|
||||
|
||||
Patient p2 = new Patient();
|
||||
p2.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier02");
|
||||
p2.addName().addFamily("testSearchByIdentifierFamily01").addGiven("testSearchByIdentifierGiven02");
|
||||
ourClient.create(p2).getId();
|
||||
|
||||
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode("urn:system", "testSearchByIdentifier01")).encodedJson().prettyPrint().execute();
|
||||
assertEquals(1, actual.size());
|
||||
assertEquals(p1Id, actual.getEntries().get(0).getId());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchByResourceChain() {
|
||||
Organization o1 = new Organization();
|
||||
o1.setName("testSearchByResourceChainName01");
|
||||
IdDt o1id = ourClient.create(o1).getId();
|
||||
|
||||
Patient p1 = new Patient();
|
||||
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
|
||||
p1.addName().addFamily("testSearchByResourceChainFamily01").addGiven("testSearchByResourceChainGiven01");
|
||||
p1.setManagingOrganization(new ResourceReferenceDt(Organization.class, o1id));
|
||||
IdDt p1Id = ourClient.create(p1).getId();
|
||||
|
||||
//@formatter:off
|
||||
Bundle actual = ourClient.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.PROVIDER.hasId(o1id))
|
||||
.encodedJson().prettyPrint().execute();
|
||||
//@formatter:on
|
||||
assertEquals(1, actual.size());
|
||||
assertEquals(p1Id, actual.getEntries().get(0).getId());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertBadReference() {
|
||||
Patient p1 = new Patient();
|
||||
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
|
||||
p1.addName().addFamily("testSearchByResourceChainFamily01").addGiven("testSearchByResourceChainGiven01");
|
||||
p1.setManagingOrganization(new ResourceReferenceDt(Organization.class, "132312323"));
|
||||
|
||||
try {
|
||||
ourClient.create(p1).getId();
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertThat(e.getMessage(), containsString("Organization/132312323"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
ourServer.stop();
|
||||
ourAppCtx.stop();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourAppCtx = new ClassPathXmlApplicationContext("fhir-spring-test-config.xml");
|
||||
|
||||
patientDao = (IFhirResourceDao<Patient>) ourAppCtx.getBean("myPatientDao", IFhirResourceDao.class);
|
||||
PatientResourceProvider patientRp = new PatientResourceProvider();
|
||||
patientRp.setDao(patientDao);
|
||||
|
||||
questionnaireDao = (IFhirResourceDao<Questionnaire>) ourAppCtx.getBean("myQuestionnaireDao", IFhirResourceDao.class);
|
||||
QuestionnaireResourceProvider questionnaireRp = new QuestionnaireResourceProvider();
|
||||
questionnaireRp.setDao(questionnaireDao);
|
||||
|
||||
observationDao = (IFhirResourceDao<Observation>) ourAppCtx.getBean("myObservationDao", IFhirResourceDao.class);
|
||||
ObservationResourceProvider observationRp = new ObservationResourceProvider();
|
||||
observationRp.setDao(observationDao);
|
||||
|
||||
IFhirResourceDao<Organization> organizationDao = (IFhirResourceDao<Organization>) ourAppCtx.getBean("myOrganizationDao", IFhirResourceDao.class);
|
||||
OrganizationResourceProvider organizationRp = new OrganizationResourceProvider();
|
||||
organizationRp.setDao(organizationDao);
|
||||
|
||||
RestfulServer restServer = new RestfulServer();
|
||||
restServer.setResourceProviders(patientRp, questionnaireRp, observationRp, organizationRp);
|
||||
|
||||
int myPort = 8888;
|
||||
ourServer = new Server(myPort);
|
||||
|
||||
ServletContextHandler proxyHandler = new ServletContextHandler();
|
||||
proxyHandler.setContextPath("/");
|
||||
|
||||
RestfulServerTesterServlet testerServlet = new RestfulServerTesterServlet();
|
||||
String serverBase = "http://localhost:" + myPort + "/fhir/context";
|
||||
testerServlet.setServerBase(serverBase);
|
||||
// testerServlet.setServerBase("http://fhir.healthintersections.com.au/open");
|
||||
ServletHolder handler = new ServletHolder();
|
||||
handler.setServlet(testerServlet);
|
||||
proxyHandler.addServlet(handler, "/fhir/tester/*");
|
||||
|
||||
ServletHolder servletHolder = new ServletHolder();
|
||||
servletHolder.setServlet(restServer);
|
||||
proxyHandler.addServlet(servletHolder, "/fhir/context/*");
|
||||
|
||||
ourServer.setHandler(proxyHandler);
|
||||
ourServer.start();
|
||||
|
||||
ourCtx = restServer.getFhirContext();
|
||||
|
||||
ourClient = ourCtx.newRestfulGenericClient(serverBase);
|
||||
}
|
||||
|
||||
}
|
|
@ -10,6 +10,7 @@ import ca.uhn.fhir.model.dstu.resource.Patient;
|
|||
import ca.uhn.fhir.model.dstu.resource.Questionnaire;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.tester.RestfulServerTesterServlet;
|
||||
import ca.uhn.test.jpasrv.PatientResourceProvider;
|
||||
|
||||
public class JpaTestApp {
|
||||
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
package ca.uhn.fhir.jpa.test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.BaseJpaResourceProvider;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
|
||||
public class PatientResourceProvider extends BaseJpaResourceProvider<Patient> {
|
||||
|
||||
@Override
|
||||
public Class<? extends IResource> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
@Search
|
||||
public List<Patient> searchByName(
|
||||
@Description(shortDefinition="Matches the patient's family (last) name")
|
||||
@RequiredParam(name=Patient.SP_NAME) StringDt theFamily,
|
||||
@Description(shortDefinition="Matches the patient's given (first) name")
|
||||
@OptionalParam(name=Patient.SP_GIVEN) StringDt theGiven) {
|
||||
|
||||
Map<String, IQueryParameterType> params = new HashMap<>();
|
||||
params.put(Patient.SP_NAME, theFamily);
|
||||
params.put(Patient.SP_GIVEN, theGiven);
|
||||
|
||||
return getDao().search(params);
|
||||
}
|
||||
|
||||
@Search
|
||||
public List<Patient> searchByGiven(
|
||||
@Description(shortDefinition="Matches the patient's given (first) name")
|
||||
@RequiredParam(name=Patient.SP_GIVEN) StringDt theValue
|
||||
) {
|
||||
return getDao().search(Patient.SP_GIVEN, theValue);
|
||||
}
|
||||
|
||||
}
|
|
@ -14,18 +14,29 @@
|
|||
<context:mbean-server />
|
||||
|
||||
<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.test.jpasrv.PatientResourceTable"/>
|
||||
</bean>
|
||||
<bean id="myObservationDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||
<property name="tableType" value="ca.uhn.test.jpasrv.ObservationResourceTable"/>
|
||||
</bean>
|
||||
<bean id="myOrganizationDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||
<property name="tableType" value="ca.uhn.test.jpasrv.OrganizationResourceTable"/>
|
||||
</bean>
|
||||
<bean id="myLocationDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||
<property name="tableType" value="ca.uhn.test.jpasrv.LocationResourceTable"/>
|
||||
</bean>
|
||||
<bean id="myQuestionnaireDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||
<property name="tableType" value="ca.uhn.fhir.jpa.entity.QuestionnaireResourceTable"/>
|
||||
<property name="tableType" value="ca.uhn.test.jpasrv.QuestionnaireResourceTable"/>
|
||||
</bean>
|
||||
|
||||
<bean id="myPersistenceDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" lazy-init="true">
|
||||
<property name="url" value="jdbc:derby:directory:myUnitTestDB;create=true" />
|
||||
<property name="url" value="jdbc:derby:memory:myUnitTestDB;create=true" />
|
||||
<!-- <property name="url" value="jdbc:derby:directory:myUnitTestDB;create=true" /> -->
|
||||
</bean>
|
||||
|
||||
<bean id="myEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||
<property name="dataSource" ref="myPersistenceDataSource" />
|
||||
<property name="persistenceXmlLocation" value="classpath:fhir_jpatest_persistence.xml" />
|
||||
<property name="persistenceUnitName" value="FHIR_UT" />
|
||||
<property name="jpaVendorAdapter">
|
||||
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
|
||||
|
|
|
@ -6,8 +6,21 @@
|
|||
|
||||
<persistence-unit name="FHIR_UT" transaction-type="RESOURCE_LOCAL">
|
||||
<provider>org.hibernate.ejb.HibernatePersistence</provider>
|
||||
<!-- <class>ca.uhn.fhir.jpa.entity.PatientResourceTable</class> -->
|
||||
<exclude-unlisted-classes>false</exclude-unlisted-classes>
|
||||
<class>ca.uhn.test.jpasrv.PatientResourceTable</class>
|
||||
<class>ca.uhn.test.jpasrv.LocationResourceTable</class>
|
||||
<class>ca.uhn.test.jpasrv.ObservationResourceTable</class>
|
||||
<class>ca.uhn.test.jpasrv.OrganizationResourceTable</class>
|
||||
<class>ca.uhn.test.jpasrv.QuestionnaireResourceTable</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceHistoryTable</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceHistoryTag</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamDate</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamNumber</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamToken</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceLink</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceTag</class>
|
||||
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
<properties>
|
||||
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:unit-testing-jpa" />
|
||||
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
|
|
@ -45,7 +45,7 @@ public class TinderJpaRestServerMojo extends AbstractMojo {
|
|||
private String packageBase;
|
||||
|
||||
@Parameter(required = true)
|
||||
private List<String> resources;
|
||||
private List<String> baseResourceNames;
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||
|
@ -54,14 +54,20 @@ public class TinderJpaRestServerMojo extends AbstractMojo {
|
|||
directoryBase.mkdirs();
|
||||
|
||||
ResourceGeneratorUsingSpreadsheet gen = new ResourceGeneratorUsingSpreadsheet();
|
||||
gen.setBaseResourceNames(resources);
|
||||
gen.setBaseResourceNames(baseResourceNames);
|
||||
|
||||
gen.setFilenameSuffix("ResourceProvider");
|
||||
gen.setTemplate("/vm/jpa_resource_provider.vm");
|
||||
|
||||
try {
|
||||
gen.parse();
|
||||
|
||||
gen.setFilenameSuffix("ResourceProvider");
|
||||
gen.setTemplate("/vm/jpa_resource_provider.vm");
|
||||
gen.writeAll(directoryBase, packageBase);
|
||||
|
||||
gen.setFilenameSuffix("ResourceTable");
|
||||
gen.setTemplate("/vm/jpa_resource_table.vm");
|
||||
gen.writeAll(directoryBase, packageBase);
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new MojoFailureException("Failed to generate server",e);
|
||||
}
|
||||
|
@ -114,7 +120,7 @@ public class TinderJpaRestServerMojo extends AbstractMojo {
|
|||
|
||||
TinderJpaRestServerMojo mojo = new TinderJpaRestServerMojo();
|
||||
mojo.packageBase = "ca.uhn.test";
|
||||
mojo.resources =java.util.Collections.singletonList("patient");
|
||||
mojo.baseResourceNames =java.util.Collections.singletonList("patient");
|
||||
mojo.targetDirectory = new File("target/gen");
|
||||
mojo.execute();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,16 @@ public abstract class BaseRootType extends BaseElement {
|
|||
return mySearchParameters;
|
||||
}
|
||||
|
||||
public List<SearchParameter> getSearchParametersWithoutComposite() {
|
||||
ArrayList<SearchParameter> retVal = new ArrayList<SearchParameter>();
|
||||
for(SearchParameter next:getSearchParameters()) {
|
||||
if(!next.getType().equals("composite")) {
|
||||
retVal.add(next);
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeSuffix() {
|
||||
return "";
|
||||
|
|
|
@ -50,6 +50,7 @@ public abstract class BaseStructureParser {
|
|||
private TreeSet<String> myImports = new TreeSet<String>();
|
||||
private Map<String, String> myLocallyDefinedClassNames = new HashMap<String, String>();
|
||||
private List<BaseRootType> myResources = new ArrayList<BaseRootType>();
|
||||
private boolean myImportsResolved;
|
||||
|
||||
public void addResource(BaseRootType theResource) {
|
||||
myResources.add(theResource);
|
||||
|
@ -286,6 +287,7 @@ public abstract class BaseStructureParser {
|
|||
ctx.put("resourceBlockChildren", theResource.getResourceBlockChildren());
|
||||
ctx.put("childExtensionTypes", ObjectUtils.defaultIfNull(myExtensions, new ArrayList<Extension>()));
|
||||
ctx.put("searchParams", (theResource.getSearchParameters()));
|
||||
ctx.put("searchParamsWithoutComposite", (theResource.getSearchParametersWithoutComposite()));
|
||||
|
||||
VelocityEngine v = new VelocityEngine();
|
||||
v.setProperty("resource.loader", "cp");
|
||||
|
@ -319,9 +321,12 @@ public abstract class BaseStructureParser {
|
|||
throw new MojoFailureException(theOutputDirectory + " is not a directory");
|
||||
}
|
||||
|
||||
for (BaseRootType next : myResources) {
|
||||
ourLog.info("Scanning resource for imports {}", next.getName());
|
||||
scanForImportsNames(next);
|
||||
if (!myImportsResolved) {
|
||||
for (BaseRootType next : myResources) {
|
||||
ourLog.info("Scanning resource for imports {}", next.getName());
|
||||
scanForImportsNames(next);
|
||||
}
|
||||
myImportsResolved = true;
|
||||
}
|
||||
|
||||
for (BaseRootType next : myResources) {
|
||||
|
@ -330,7 +335,8 @@ public abstract class BaseStructureParser {
|
|||
scanForTypeNameConflicts(next);
|
||||
fixResourceReferenceClassNames(next, thePackageBase);
|
||||
|
||||
// File f = new File(theOutputDirectory, (next.getDeclaringClassNameComplete()) /*+ getFilenameSuffix()*/ + ".java");
|
||||
// File f = new File(theOutputDirectory, (next.getDeclaringClassNameComplete()) /*+ getFilenameSuffix()*/ +
|
||||
// ".java");
|
||||
File f = new File(theOutputDirectory, (next.getElementName()) + getFilenameSuffix() + ".java");
|
||||
try {
|
||||
write(next, f, thePackageBase);
|
||||
|
@ -348,9 +354,8 @@ public abstract class BaseStructureParser {
|
|||
// }
|
||||
|
||||
/**
|
||||
* Example: Encounter has an internal block class named "Location", but it
|
||||
* also has a reference to the Location resource type, so we need to use the
|
||||
* fully qualified name for that resource reference
|
||||
* Example: Encounter has an internal block class named "Location", but it also has a reference to the Location
|
||||
* resource type, so we need to use the fully qualified name for that resource reference
|
||||
*/
|
||||
private void fixResourceReferenceClassNames(BaseElement theNext, String thePackageBase) {
|
||||
for (BaseElement next : theNext.getChildren()) {
|
||||
|
|
|
@ -23,8 +23,8 @@ public class ${className}ResourceProvider extends BaseJpaResourceProvider<${clas
|
|||
}
|
||||
|
||||
@Search()
|
||||
List<${className}> search(
|
||||
#foreach ( $param in $searchParams ) #{if}(true) #{end}
|
||||
public List<${className}> search(
|
||||
#foreach ( $param in $searchParamsWithoutComposite ) #{if}(true) #{end}
|
||||
|
||||
@Description(shortDefinition="${param.description}")
|
||||
@OptionalParam(name="${param.name}")
|
||||
|
@ -40,12 +40,14 @@ public class ${className}ResourceProvider extends BaseJpaResourceProvider<${clas
|
|||
QuantityDt the${param.nameCapitalized} #{if}($foreach.hasNext), #{end}
|
||||
#elseif (${param.type} == 'reference' )
|
||||
ReferenceParam the${param.nameCapitalized} #{if}($foreach.hasNext), #{end}
|
||||
#elseif (${param.type} == 'composite' )
|
||||
ReferenceParam the${param.nameCapitalized} #{if}($foreach.hasNext), #{end}
|
||||
#end
|
||||
#end
|
||||
) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
|
||||
#foreach ( $param in $searchParams )
|
||||
#foreach ( $param in $searchParamsWithoutComposite )
|
||||
paramMap.add("${param.name}", the${param.nameCapitalized});
|
||||
#end
|
||||
|
||||
|
|
|
@ -3,13 +3,13 @@ package ${packageBase};
|
|||
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
import ca.uhn.fhir.model.dstu.resource.*;
|
||||
|
||||
public class ${className}ResourceTable extends BaseResourceTable<${className}> {
|
||||
import ca.uhn.fhir.jpa.entity.BaseResourceTable;
|
||||
import ca.uhn.fhir.model.dstu.resource.*;
|
||||
|
||||
@Entity
|
||||
@DiscriminatorValue("${className}")
|
||||
public class PatientResourceTable extends BaseResourceTable<Patient> {
|
||||
public class ${className}ResourceTable extends BaseResourceTable<${className}> {
|
||||
|
||||
@Override
|
||||
public Class<${className}> getResourceType() {
|
||||
|
|
Loading…
Reference in New Issue