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

This commit is contained in:
James Agnew 2015-04-15 10:57:43 -04:00
commit 41c215efe2
9 changed files with 133 additions and 76 deletions

View File

@ -2001,7 +2001,7 @@ class ParserState<T> {
terser.visit(myInstance, new IModelVisitor() { terser.visit(myInstance, new IModelVisitor() {
@Override @Override
public void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) { public void acceptElement(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
if (theElement instanceof BaseResourceReferenceDt) { if (theElement instanceof BaseResourceReferenceDt) {
BaseResourceReferenceDt nextRef = (BaseResourceReferenceDt) theElement; BaseResourceReferenceDt nextRef = (BaseResourceReferenceDt) theElement;
String ref = nextRef.getReference().getValue(); String ref = nextRef.getReference().getValue();
@ -2019,8 +2019,8 @@ class ParserState<T> {
} }
@Override @Override
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) { public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) {
acceptElement(theNextExt.getValue(), null, null); acceptElement(theNextExt.getValue(), null, null, null);
} }
}); });

View File

@ -20,6 +20,8 @@ package ca.uhn.fhir.rest.param;
* #L% * #L%
*/ */
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
@ -217,6 +219,22 @@ public class ParameterUtil {
return b.toString(); return b.toString();
} }
/**
* Escapes a string according to the rules for parameter escaping specified in the <a href="http://www.hl7.org/implement/standards/fhir/search.html#escaping">FHIR Specification Escaping
* Section</a>
*/
public static String escapeAndUrlEncode(String theValue) {
if (theValue == null) {
return null;
}
try {
return URLEncoder.encode(escape(theValue), "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new Error("UTF-8 not supported on this platform");
}
}
/** /**
* Unescapes a string according to the rules for parameter escaping specified in the <a href="http://www.hl7.org/implement/standards/fhir/search.html#escaping">FHIR Specification Escaping * Unescapes a string according to the rules for parameter escaping specified in the <a href="http://www.hl7.org/implement/standards/fhir/search.html#escaping">FHIR Specification Escaping
* Section</a> * Section</a>

View File

@ -39,7 +39,6 @@ import ca.uhn.fhir.context.RuntimeChildChoiceDefinition;
import ca.uhn.fhir.context.RuntimeChildDirectResource; import ca.uhn.fhir.context.RuntimeChildDirectResource;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.ExtensionDt; import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.IElement;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions; import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
import ca.uhn.fhir.model.base.composite.BaseContainedDt; import ca.uhn.fhir.model.base.composite.BaseContainedDt;
@ -61,7 +60,7 @@ public class FhirTerser {
if (theElement instanceof ISupportsUndeclaredExtensions) { if (theElement instanceof ISupportsUndeclaredExtensions) {
ISupportsUndeclaredExtensions containingElement = (ISupportsUndeclaredExtensions) theElement; ISupportsUndeclaredExtensions containingElement = (ISupportsUndeclaredExtensions) theElement;
for (ExtensionDt nextExt : containingElement.getUndeclaredExtensions()) { for (ExtensionDt nextExt : containingElement.getUndeclaredExtensions()) {
theCallback.acceptUndeclaredExtension(containingElement, theChildDefinition, theDefinition, nextExt); theCallback.acceptUndeclaredExtension(containingElement, null, theChildDefinition, theDefinition, nextExt);
addUndeclaredExtensions(nextExt, theDefinition, theChildDefinition, theCallback); addUndeclaredExtensions(nextExt, theDefinition, theChildDefinition, theCallback);
} }
} }
@ -87,10 +86,10 @@ public class FhirTerser {
public <T extends IBase> List<T> getAllPopulatedChildElementsOfType(IBaseResource theResource, final Class<T> theType) { public <T extends IBase> List<T> getAllPopulatedChildElementsOfType(IBaseResource theResource, final Class<T> theType) {
final ArrayList<T> retVal = new ArrayList<T>(); final ArrayList<T> retVal = new ArrayList<T>();
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource); BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
visit(theResource, null, def, new IModelVisitor() { visit(theResource, null, null, def, new IModelVisitor() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) { public void acceptElement(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
if (theElement == null || theElement.isEmpty()) { if (theElement == null || theElement.isEmpty()) {
return; return;
} }
@ -102,7 +101,7 @@ public class FhirTerser {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition,
ExtensionDt theNextExt) { ExtensionDt theNextExt) {
if (theType.isAssignableFrom(theNextExt.getClass())) { if (theType.isAssignableFrom(theNextExt.getClass())) {
retVal.add((T) theNextExt); retVal.add((T) theNextExt);
@ -118,36 +117,31 @@ public class FhirTerser {
public <T extends IBase> List<ResourceReferenceInfo> getAllResourceReferences(final IBaseResource theResource) { public <T extends IBase> List<ResourceReferenceInfo> getAllResourceReferences(final IBaseResource theResource) {
final ArrayList<ResourceReferenceInfo> retVal = new ArrayList<ResourceReferenceInfo>(); final ArrayList<ResourceReferenceInfo> retVal = new ArrayList<ResourceReferenceInfo>();
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource); BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
visit(theResource, null, def, new IModelVisitor() { visit(theResource, null, null, def, new IModelVisitor() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) { public void acceptElement(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
if (theElement == null || theElement.isEmpty()) { if (theElement == null || theElement.isEmpty()) {
return; return;
} }
String name = null;
if (theChildDefinition != null) {
name = theChildDefinition.getElementName();
}
if (BaseResourceReferenceDt.class.isAssignableFrom(theElement.getClass())) { if (BaseResourceReferenceDt.class.isAssignableFrom(theElement.getClass())) {
retVal.add(new ResourceReferenceInfo(theResource, name, (BaseResourceReferenceDt)theElement)); retVal.add(new ResourceReferenceInfo(theResource, thePathToElement, (BaseResourceReferenceDt)theElement));
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition,
ExtensionDt theNextExt) { ExtensionDt theNextExt) {
String name = null;
if (theChildDefinition != null) {
name = theChildDefinition.getElementName();
}
if (theNextExt.getValue() != null && BaseResourceReferenceDt.class.isAssignableFrom(theNextExt.getValue().getClass())) { if (theNextExt.getValue() != null && BaseResourceReferenceDt.class.isAssignableFrom(theNextExt.getValue().getClass())) {
retVal.add(new ResourceReferenceInfo(theResource, name, (BaseResourceReferenceDt)theNextExt.getValue())); retVal.add(new ResourceReferenceInfo(theResource, thePathToElement, (BaseResourceReferenceDt)theNextExt.getValue()));
} }
} }
}); });
return retVal; } private BaseRuntimeChildDefinition getDefinition(BaseRuntimeElementCompositeDefinition<?> theCurrentDef, List<String> theSubList) { return retVal;
}
private BaseRuntimeChildDefinition getDefinition(BaseRuntimeElementCompositeDefinition<?> theCurrentDef, List<String> theSubList) {
BaseRuntimeChildDefinition nextDef = theCurrentDef.getChildByNameOrThrowDataFormatException(theSubList.get(0)); BaseRuntimeChildDefinition nextDef = theCurrentDef.getChildByNameOrThrowDataFormatException(theSubList.get(0));
if (theSubList.size() == 1) { if (theSubList.size() == 1) {
@ -220,8 +214,19 @@ public class FhirTerser {
} }
private void visit(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, IModelVisitor theCallback) { private List<String> addNameToList(List<String> theCurrentList, BaseRuntimeChildDefinition theChildDefinition) {
theCallback.acceptElement(theElement, theChildDefinition, theDefinition); if (theChildDefinition == null)
return null;
if (theCurrentList== null || theCurrentList.isEmpty())
return new ArrayList<String>(Arrays.asList(theChildDefinition.getElementName()));
List<String> newList = new ArrayList<String>(theCurrentList);
newList.add(theChildDefinition.getElementName());
return newList;
}
private void visit(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, IModelVisitor theCallback) {
List<String> pathToElement = addNameToList(thePathToElement, theChildDefinition);
theCallback.acceptElement(theElement, pathToElement, theChildDefinition, theDefinition);
addUndeclaredExtensions(theElement, theDefinition, theChildDefinition, theCallback); addUndeclaredExtensions(theElement, theDefinition, theChildDefinition, theCallback);
// if (theElement.isEmpty()) { // if (theElement.isEmpty()) {
@ -242,7 +247,7 @@ public class FhirTerser {
IResource theResource = resRefDt.getResource(); IResource theResource = resRefDt.getResource();
if (theResource.getId() == null || theResource.getId().isEmpty() || theResource.getId().isLocal()) { if (theResource.getId() == null || theResource.getId().isEmpty() || theResource.getId().isLocal()) {
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource); BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
visit(theResource, null, def, theCallback); visit(theResource, pathToElement, null, def, theCallback);
} }
} }
break; break;
@ -284,9 +289,9 @@ public class FhirTerser {
if (nextChild instanceof RuntimeChildDirectResource) { if (nextChild instanceof RuntimeChildDirectResource) {
// Don't descend into embedded resources // Don't descend into embedded resources
theCallback.acceptElement(nextValue, nextChild, childElementDef); theCallback.acceptElement(nextValue, null, nextChild, childElementDef);
} else { } else {
visit(nextValue, nextChild, childElementDef, theCallback); visit(nextValue, pathToElement, nextChild, childElementDef, theCallback);
} }
} }
} }
@ -297,7 +302,7 @@ public class FhirTerser {
BaseContainedDt value = (BaseContainedDt) theElement; BaseContainedDt value = (BaseContainedDt) theElement;
for (IResource next : value.getContainedResources()) { for (IResource next : value.getContainedResources()) {
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(next); BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(next);
visit(next, null, def, theCallback); visit(next, pathToElement, null, def, theCallback);
} }
break; break;
} }
@ -322,7 +327,7 @@ public class FhirTerser {
*/ */
public void visit(IBaseResource theResource, IModelVisitor theVisitor) { public void visit(IBaseResource theResource, IModelVisitor theVisitor) {
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource); BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
visit(theResource, null, def, theVisitor); visit(theResource, null, null, def, theVisitor);
} }
public Object getSingleValueOrNull(IBase theTarget, String thePath) { public Object getSingleValueOrNull(IBase theTarget, String thePath) {

View File

@ -28,6 +28,8 @@ import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.model.api.ExtensionDt; import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions; import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
import java.util.List;
/** /**
* @see FhirTerser#visit(IBaseResource, IModelVisitor) * @see FhirTerser#visit(IBaseResource, IModelVisitor)
*/ */
@ -39,7 +41,7 @@ public interface IModelVisitor {
* @param theChildDefinition May be null if this is a root element * @param theChildDefinition May be null if this is a root element
* @param theDefinition * @param theDefinition
*/ */
void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition); void acceptElement(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition);
/** /**
* *
@ -48,7 +50,7 @@ public interface IModelVisitor {
* @param theDefinition * @param theDefinition
* @param theNextExt * @param theNextExt
*/ */
void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt); void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt);

View File

@ -28,58 +28,71 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import org.hl7.fhir.instance.model.IBaseResource; import org.hl7.fhir.instance.model.IBaseResource;
import java.util.Iterator;
import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
* Created by Bill de Beaubien on 2/26/2015. * Created by Bill de Beaubien on 2/26/2015.
*/ */
public class ResourceReferenceInfo { public class ResourceReferenceInfo {
private String myOwningResource; private String myOwningResource;
private String myName; private String myName;
private BaseResourceReferenceDt myResource; private BaseResourceReferenceDt myResource;
public ResourceReferenceInfo(IBaseResource theOwningResource, String theName, BaseResourceReferenceDt theResource) { public ResourceReferenceInfo(IBaseResource theOwningResource, List<String> thePathToElement, BaseResourceReferenceDt theResource) {
myOwningResource = theOwningResource.getClass().getAnnotation(ResourceDef.class).name(); myOwningResource = theOwningResource.getClass().getAnnotation(ResourceDef.class).name();
myName = theName; myResource = theResource;
myResource = theResource; if (thePathToElement != null && !thePathToElement.isEmpty()) {
} StringBuilder sb = new StringBuilder();
thePathToElement.iterator();
for (Iterator<String> iterator = thePathToElement.iterator(); iterator.hasNext(); ) {
sb.append(iterator.next());
if (iterator.hasNext())
sb.append(".");
}
myName = sb.toString();
} else {
myName = null;
}
}
@Override @Override
public String toString() { public String toString() {
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
b.append("name", myName); b.append("name", myName);
b.append("resource", myResource.getReference()); b.append("resource", myResource.getReference());
return b.build(); return b.build();
} }
public String getName() { public String getName() {
return myName; return myName;
} }
public BaseResourceReferenceDt getResourceReference() { public BaseResourceReferenceDt getResourceReference() {
return myResource; return myResource;
} }
public boolean matchesIncludeSet(Set<Include> theIncludes) { public boolean matchesIncludeSet(Set<Include> theIncludes) {
if (theIncludes == null) if (theIncludes == null)
return false; return false;
for (Include include : theIncludes) { for (Include include : theIncludes) {
if (matchesInclude(include)) if (matchesInclude(include))
return true; return true;
} }
return false; return false;
} }
public boolean matchesInclude(Include theInclude) { public boolean matchesInclude(Include theInclude) {
if (theInclude.getValue().equals("*")) { if (theInclude.getValue().equals("*")) {
return true; return true;
} }
if (theInclude.getValue().indexOf(':') != -1) { if (theInclude.getValue().indexOf(':') != -1) {
// DSTU2 style // DSTU2 style
return (theInclude.getValue().equals(myOwningResource + ':' + myName)); return (theInclude.getValue().equals(myOwningResource + ':' + myName));
} else { } else {
// DSTU1 style // DSTU1 style
return (theInclude.getValue().equals(myOwningResource + '.' + myName)); return (theInclude.getValue().equals(myOwningResource + '.' + myName));
} }
} }
} }

View File

@ -123,7 +123,8 @@ public abstract class BaseFhirDao implements IDao {
private FhirContext myContext; private FhirContext myContext;
@PersistenceContext(name = "FHIR_UT", type = PersistenceContextType.TRANSACTION, unitName = "FHIR_UT") // @PersistenceContext(name = "FHIR_UT", type = PersistenceContextType.TRANSACTION, unitName = "FHIR_UT")
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
private EntityManager myEntityManager; private EntityManager myEntityManager;
private List<IDaoListener> myListeners = new ArrayList<IDaoListener>(); private List<IDaoListener> myListeners = new ArrayList<IDaoListener>();

View File

@ -39,6 +39,7 @@ import java.util.Set;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.TemporalType; import javax.persistence.TemporalType;
import javax.persistence.Tuple; import javax.persistence.Tuple;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
@ -129,7 +130,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseFhirResourceDao.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseFhirResourceDao.class);
@PersistenceContext() @PersistenceContext(type = PersistenceContextType.TRANSACTION)
private EntityManager myEntityManager; private EntityManager myEntityManager;
@Autowired @Autowired

View File

@ -76,6 +76,23 @@ public class Dstu1BundleFactoryTest {
myBundleFactory = new Dstu1BundleFactory(ourCtx); myBundleFactory = new Dstu1BundleFactory(ourCtx);
} }
@Test
public void whenMedicationHasIngredients_include_shouldIncludeThem() throws Exception {
Medication medication = new Medication();
medication.setName("Main Medication");
medication.setId("Medication/1");
Medication ingredientMedication = new Medication();
ingredientMedication.setName("Ingredient");
ingredientMedication.setId("Medication/2");
Medication.ProductIngredient ingredient = new Medication.ProductIngredient();
ingredient.setItem(new ResourceReferenceDt(ingredientMedication));
medication.getProduct().getIngredient().add(ingredient);
myResourceList = Arrays.asList(new IResource[]{medication});
Bundle bundle = makeBundle(BundleInclusionRule.BASED_ON_INCLUDES, includes("Medication.product.ingredient.item"));
assertEquals(2, bundle.getEntries().size());
}
@Test @Test
public void whenIncludeIsAsterisk_bundle_shouldContainAllReferencedResources() throws Exception { public void whenIncludeIsAsterisk_bundle_shouldContainAllReferencedResources() throws Exception {
Bundle bundle = makeBundle(BundleInclusionRule.BASED_ON_INCLUDES, includes("*")); Bundle bundle = makeBundle(BundleInclusionRule.BASED_ON_INCLUDES, includes("*"));

View File

@ -202,7 +202,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<servlet_api_version>3.1.0</servlet_api_version> <servlet_api_version>3.1.0</servlet_api_version>
<slf4j_version>1.7.10</slf4j_version> <slf4j_version>1.7.10</slf4j_version>
<spring_version>4.1.5.RELEASE</spring_version> <spring_version>4.1.6.RELEASE</spring_version>
<spring_security_version>3.2.4.RELEASE</spring_security_version> <spring_security_version>3.2.4.RELEASE</spring_security_version>
<thymeleaf-version>2.1.4.RELEASE</thymeleaf-version> <thymeleaf-version>2.1.4.RELEASE</thymeleaf-version>
<ebay_cors_filter_version>1.0.1</ebay_cors_filter_version> <ebay_cors_filter_version>1.0.1</ebay_cors_filter_version>