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

This commit is contained in:
James Agnew 2015-06-18 17:49:54 -04:00
commit 12f3cfcab8
8 changed files with 104 additions and 45 deletions

View File

@ -401,15 +401,11 @@ public class IdDt extends UriDt implements IPrimitiveDatatype<String>, IIdType {
}
/**
* Returns <code>true</code> if the ID is a local reference (in other words, it begins with the '#' character
* or it begins with "cid:" or "urn:")
* Returns <code>true</code> if the ID is a local reference (in other words, it begins with the '#' character)
*/
@Override
public boolean isLocal() {
if (myBaseUrl == null) {
return false;
}
return "#".equals(myBaseUrl) || myBaseUrl.equals("cid:") || myBaseUrl.startsWith("urn:");
return "#".equals(myBaseUrl);
}
/**

View File

@ -1672,6 +1672,16 @@ class ParserState<T> {
myExtension = theExtension;
}
@Override
public void attributeValue(String theName, String theValue) throws DataFormatException {
if ("url".equals(theName)) {
// The URL attribute is handles in the XML loop as a special case since it is "url" instead
// of "value" like every single other place
return;
}
super.attributeValue(theName, theValue);
}
@Override
public void endingElement() throws DataFormatException {
if (myExtension.getValue() != null && myExtension.getExtension().size() > 0) {

View File

@ -35,14 +35,15 @@ public enum SearchStyleEnum {
GET,
/**
* This is the most common (and generally the default) behaviour. Performs the search using the style:
* Performs the search using the style below. Note that this style is less commonly supported
* in servers so it should not be used unless there is a specific reason for needing to.
* <br>
* <code>GET [base]/[resource type]/_search?[params]</code>
*/
GET_WITH_SEARCH,
/**
* This is the most common (and generally the default) behaviour. Performs the search using the style:
* Performs the search using the style below. This style is useful when you have long search strings.
* <br>
* <code>POST [base]/[resource type]/_search</code>
* <br>

View File

@ -85,8 +85,8 @@ public class ReferenceParam extends IdDt implements IQueryParameterType {
if (myBase.getMissing()!=null) {
return myBase.getValueAsQueryToken();
}
if (isLocal()) {
return getValue();
if (isBlank(getResourceType())) {
return getValue(); // e.g. urn:asdjd or 123 or cid:wieiuru or #1
} else {
return getIdPart();
}

View File

@ -50,6 +50,11 @@ import ca.uhn.fhir.util.FhirTerser;
public class FhirSystemDaoDstu1 extends BaseFhirSystemDao<List<IResource>> {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirSystemDaoDstu1.class);
@Override
public MetaDt metaGetOperation() {
throw new NotImplementedOperationException("meta not supported in DSTU1");
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public List<IResource> transaction(List<IResource> theResources) {
@ -60,14 +65,14 @@ public class FhirSystemDaoDstu1 extends BaseFhirSystemDao<List<IResource>> {
for (int i = 0; i < theResources.size(); i++) {
IResource res = theResources.get(i);
if (res.getId().hasIdPart() && !res.getId().hasResourceType() && !res.getId().isLocal()) {
if (res.getId().hasIdPart() && !res.getId().hasResourceType() && !isPlaceholder(res.getId())) {
res.setId(new IdDt(toResourceName(res.getClass()), res.getId().getIdPart()));
}
/*
* Ensure that the bundle doesn't have any duplicates, since this causes all kinds of weirdness
*/
if (res.getId().isLocal()) {
if (isPlaceholder(res.getId())) {
if (!allIds.add(res.getId())) {
throw new InvalidRequestException("Transaction bundle contains multiple resources with ID: " + res.getId());
}
@ -138,7 +143,7 @@ public class FhirSystemDaoDstu1 extends BaseFhirSystemDao<List<IResource>> {
} else {
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseFhirSystemDao.class, "transactionOperationWithMultipleMatchFailure", nextResouceOperationIn.name(), matchUrl, candidateMatches.size()));
}
} else if (nextId.isEmpty() || nextId.isLocal()) {
} else if (nextId.isEmpty() || isPlaceholder(nextId)) {
entity = null;
} else {
entity = tryToLoadEntity(nextId);
@ -213,8 +218,8 @@ public class FhirSystemDaoDstu1 extends BaseFhirSystemDao<List<IResource>> {
if (nextId.toUnqualifiedVersionless().equals(newId)) {
ourLog.info("Transaction resource ID[{}] is being updated", newId);
} else {
if (nextId.isLocal()) {
// nextId = new IdDt(resourceName, nextId.getIdPart());
if (isPlaceholder(nextId)) {
// nextId = new IdDt(resourceName, nextId.getIdPart());
ourLog.info("Transaction resource ID[{}] has been assigned new ID[{}]", nextId, newId);
idConversions.put(nextId, newId);
idConversions.put(new IdDt(resourceName + "/" + nextId.getValue()), newId);
@ -267,10 +272,11 @@ public class FhirSystemDaoDstu1 extends BaseFhirSystemDao<List<IResource>> {
return retVal;
}
@Override
public MetaDt metaGetOperation() {
throw new NotImplementedOperationException("meta not supported in DSTU1");
private static boolean isPlaceholder(IdDt theId) {
if ("cid:".equals(theId.getBaseUrl())) {
return true;
}
return false;
}
}

View File

@ -24,7 +24,6 @@ import static org.apache.commons.lang3.StringUtils.*;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@ -60,6 +59,26 @@ import ca.uhn.fhir.util.FhirTerser;
public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirSystemDaoDstu2.class);
private String extractTransactionUrlOrThrowException(Entry nextEntry, HTTPVerbEnum verb) {
String url = nextEntry.getTransaction().getUrl();
if (isBlank(url)) {
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseFhirSystemDao.class, "transactionMissingUrl", verb.name()));
}
return url;
}
@Override
public MetaDt metaGetOperation() {
String sql = "SELECT d FROM TagDefinition d WHERE d.myId IN (SELECT DISTINCT t.myTagId FROM ResourceTag t)";
TypedQuery<TagDefinition> q = myEntityManager.createQuery(sql, TagDefinition.class);
List<TagDefinition> tagDefinitions = q.getResultList();
MetaDt retVal = super.toMetaDt(tagDefinitions);
return retVal;
}
private UrlParts parseUrl(String theAction, String theUrl) {
UrlParts retVal = new UrlParts();
@ -151,7 +170,7 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
if (res != null) {
nextResourceId = res.getId();
if (nextResourceId.hasIdPart() && !nextResourceId.hasResourceType() && !nextResourceId.isLocal()) {
if (nextResourceId.hasIdPart() && !nextResourceId.hasResourceType() && !isPlaceholder(nextResourceId)) {
nextResourceId = new IdDt(toResourceName(res.getClass()), nextResourceId.getIdPart());
res.setId(nextResourceId);
}
@ -159,7 +178,7 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
/*
* Ensure that the bundle doesn't have any duplicates, since this causes all kinds of weirdness
*/
if (nextResourceId.isLocal()) {
if (isPlaceholder(nextResourceId)) {
if (!allIds.add(nextResourceId)) {
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseFhirSystemDao.class, "transactionContainsMultipleWithDuplicateId", nextResourceId));
}
@ -317,33 +336,13 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
return response;
}
@Override
public MetaDt metaGetOperation() {
String sql = "SELECT d FROM TagDefinition d WHERE d.myId IN (SELECT DISTINCT t.myTagId FROM ResourceTag t)";
TypedQuery<TagDefinition> q = myEntityManager.createQuery(sql, TagDefinition.class);
List<TagDefinition> tagDefinitions = q.getResultList();
MetaDt retVal = super.toMetaDt(tagDefinitions);
return retVal;
}
private String extractTransactionUrlOrThrowException(Entry nextEntry, HTTPVerbEnum verb) {
String url = nextEntry.getTransaction().getUrl();
if (isBlank(url)) {
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseFhirSystemDao.class, "transactionMissingUrl", verb.name()));
}
return url;
}
private static void handleTransactionCreateOrUpdateOutcome(Map<IdDt, IdDt> idSubstitutions, Map<IdDt, DaoMethodOutcome> idToPersistedOutcome, IdDt nextResourceId, DaoMethodOutcome outcome,
Entry newEntry, String theResourceType) {
IdDt newId = outcome.getId().toUnqualifiedVersionless();
IdDt resourceId = nextResourceId.isLocal() ? nextResourceId : nextResourceId.toUnqualifiedVersionless();
IdDt resourceId = isPlaceholder(nextResourceId) ? nextResourceId : nextResourceId.toUnqualifiedVersionless();
if (newId.equals(resourceId) == false) {
idSubstitutions.put(resourceId, newId);
if (resourceId.isLocal()) {
if (isPlaceholder(resourceId)) {
/*
* The correct way for substitution IDs to be is to be with no resource type, but we'll accept the qualified kind too just to be lenient.
*/
@ -360,6 +359,13 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
newEntry.getTransactionResponse().setEtag(outcome.getId().getVersionIdPart());
}
private static boolean isPlaceholder(IdDt theId) {
if ("urn:oid:".equals(theId.getBaseUrl()) || "urn:uuid:".equals(theId.getBaseUrl())) {
return true;
}
return false;
}
private static class UrlParts {
private IFhirResourceDao<? extends IResource> myDao;
private String myParams;

View File

@ -197,7 +197,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>

View File

@ -39,6 +39,7 @@ import ca.uhn.fhir.model.dstu2.resource.AllergyIntolerance;
import ca.uhn.fhir.model.dstu2.resource.Binary;
import ca.uhn.fhir.model.dstu2.resource.Composition;
import ca.uhn.fhir.model.dstu2.resource.DataElement;
import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport;
import ca.uhn.fhir.model.dstu2.resource.Encounter;
import ca.uhn.fhir.model.dstu2.resource.Medication;
import ca.uhn.fhir.model.dstu2.resource.MedicationPrescription;
@ -55,6 +56,8 @@ import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.client.IGenericClient;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
public class XmlParserDstu2Test {
private static final FhirContext ourCtx = FhirContext.forDstu2();
@ -129,6 +132,8 @@ public class XmlParserDstu2Test {
}
@Test
public void testEncodeAndParseBundleWithoutResourceIds() {
Organization org = new Organization();
@ -143,6 +148,42 @@ public class XmlParserDstu2Test {
assertTrue(parsed.getEntries().get(0).getResource().getId().isEmpty());
}
public static void main(String[] args) {
IGenericClient c = ourCtx.newRestfulGenericClient("http://fhir-dev.healthintersections.com.au/open");
// c.registerInterceptor(new LoggingInterceptor(true));
c.read().resource("Patient").withId("324").execute();
}
@Test
public void testEncodeBundleWithContained() {
DiagnosticReport rpt = new DiagnosticReport();
rpt.addResult().setResource(new Observation().setCode(new CodeableConceptDt().setText("Sharp1")).setId("#1"));
rpt.addResult().setResource(new Observation().setCode(new CodeableConceptDt().setText("Uuid1")).setId("urn:uuid:UUID1"));
ca.uhn.fhir.model.dstu2.resource.Bundle b = new ca.uhn.fhir.model.dstu2.resource.Bundle();
b.addEntry().setResource(rpt);
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b);
ourLog.info(encoded);
assertThat(encoded, stringContainsInOrder(
"<DiagnosticReport",
"<contained",
"<Observation",
"<text value=\"Sharp1\"",
"</DiagnosticReport"
));
assertThat(encoded, not(stringContainsInOrder(
"<DiagnosticReport",
"<contained",
"<Observation",
"<contained",
"<Observation",
"</DiagnosticReport"
)));
}
@Test
public void testEncodeAndParseContained() {
IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true);