Revert change to make IdDt#isLocal() return true if the base is "urn:". This caused all kinds of regressions and was obviously a bad idea.

This commit is contained in:
jamesagnew 2015-06-18 09:00:56 -04:00
parent 0f2d742872
commit d0cffbf8c7
6 changed files with 101 additions and 42 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 * 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:")
*/ */
@Override @Override
public boolean isLocal() { public boolean isLocal() {
if (myBaseUrl == null) { return "#".equals(myBaseUrl);
return false;
}
return "#".equals(myBaseUrl) || myBaseUrl.equals("cid:") || myBaseUrl.startsWith("urn:");
} }
/** /**

View File

@ -1672,6 +1672,16 @@ class ParserState<T> {
myExtension = theExtension; 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 @Override
public void endingElement() throws DataFormatException { public void endingElement() throws DataFormatException {
if (myExtension.getValue() != null && myExtension.getExtension().size() > 0) { if (myExtension.getValue() != null && myExtension.getExtension().size() > 0) {

View File

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

View File

@ -50,6 +50,11 @@ import ca.uhn.fhir.util.FhirTerser;
public class FhirSystemDaoDstu1 extends BaseFhirSystemDao<List<IResource>> { public class FhirSystemDaoDstu1 extends BaseFhirSystemDao<List<IResource>> {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirSystemDaoDstu1.class); 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) @Transactional(propagation = Propagation.REQUIRED)
@Override @Override
public List<IResource> transaction(List<IResource> theResources) { 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++) { for (int i = 0; i < theResources.size(); i++) {
IResource res = theResources.get(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())); 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 * 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())) { if (!allIds.add(res.getId())) {
throw new InvalidRequestException("Transaction bundle contains multiple resources with ID: " + 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 { } else {
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseFhirSystemDao.class, "transactionOperationWithMultipleMatchFailure", nextResouceOperationIn.name(), matchUrl, candidateMatches.size())); 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; entity = null;
} else { } else {
entity = tryToLoadEntity(nextId); entity = tryToLoadEntity(nextId);
@ -213,7 +218,7 @@ public class FhirSystemDaoDstu1 extends BaseFhirSystemDao<List<IResource>> {
if (nextId.toUnqualifiedVersionless().equals(newId)) { if (nextId.toUnqualifiedVersionless().equals(newId)) {
ourLog.info("Transaction resource ID[{}] is being updated", newId); ourLog.info("Transaction resource ID[{}] is being updated", newId);
} else { } else {
if (nextId.isLocal()) { if (isPlaceholder(nextId)) {
// nextId = new IdDt(resourceName, nextId.getIdPart()); // nextId = new IdDt(resourceName, nextId.getIdPart());
ourLog.info("Transaction resource ID[{}] has been assigned new ID[{}]", nextId, newId); ourLog.info("Transaction resource ID[{}] has been assigned new ID[{}]", nextId, newId);
idConversions.put(nextId, newId); idConversions.put(nextId, newId);
@ -267,10 +272,11 @@ public class FhirSystemDaoDstu1 extends BaseFhirSystemDao<List<IResource>> {
return retVal; return retVal;
} }
@Override private static boolean isPlaceholder(IdDt theId) {
public MetaDt metaGetOperation() { if ("cid:".equals(theId.getBaseUrl())) {
throw new NotImplementedOperationException("meta not supported in DSTU1"); return true;
}
return false;
} }
} }

View File

@ -24,7 +24,6 @@ import static org.apache.commons.lang3.StringUtils.*;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -60,6 +59,26 @@ import ca.uhn.fhir.util.FhirTerser;
public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> { public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirSystemDaoDstu2.class); 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) { private UrlParts parseUrl(String theAction, String theUrl) {
UrlParts retVal = new UrlParts(); UrlParts retVal = new UrlParts();
@ -151,7 +170,7 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
if (res != null) { if (res != null) {
nextResourceId = res.getId(); 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()); nextResourceId = new IdDt(toResourceName(res.getClass()), nextResourceId.getIdPart());
res.setId(nextResourceId); 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 * 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)) { if (!allIds.add(nextResourceId)) {
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseFhirSystemDao.class, "transactionContainsMultipleWithDuplicateId", nextResourceId)); throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseFhirSystemDao.class, "transactionContainsMultipleWithDuplicateId", nextResourceId));
} }
@ -317,33 +336,13 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
return response; 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, private static void handleTransactionCreateOrUpdateOutcome(Map<IdDt, IdDt> idSubstitutions, Map<IdDt, DaoMethodOutcome> idToPersistedOutcome, IdDt nextResourceId, DaoMethodOutcome outcome,
Entry newEntry, String theResourceType) { Entry newEntry, String theResourceType) {
IdDt newId = outcome.getId().toUnqualifiedVersionless(); IdDt newId = outcome.getId().toUnqualifiedVersionless();
IdDt resourceId = nextResourceId.isLocal() ? nextResourceId : nextResourceId.toUnqualifiedVersionless(); IdDt resourceId = isPlaceholder(nextResourceId) ? nextResourceId : nextResourceId.toUnqualifiedVersionless();
if (newId.equals(resourceId) == false) { if (newId.equals(resourceId) == false) {
idSubstitutions.put(resourceId, newId); 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. * 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()); 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 static class UrlParts {
private IFhirResourceDao<? extends IResource> myDao; private IFhirResourceDao<? extends IResource> myDao;
private String myParams; private String myParams;

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.Binary;
import ca.uhn.fhir.model.dstu2.resource.Composition; import ca.uhn.fhir.model.dstu2.resource.Composition;
import ca.uhn.fhir.model.dstu2.resource.DataElement; 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.Encounter;
import ca.uhn.fhir.model.dstu2.resource.Medication; import ca.uhn.fhir.model.dstu2.resource.Medication;
import ca.uhn.fhir.model.dstu2.resource.MedicationPrescription; 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.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.client.IGenericClient;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
public class XmlParserDstu2Test { public class XmlParserDstu2Test {
private static final FhirContext ourCtx = FhirContext.forDstu2(); private static final FhirContext ourCtx = FhirContext.forDstu2();
@ -129,6 +132,8 @@ public class XmlParserDstu2Test {
} }
@Test @Test
public void testEncodeAndParseBundleWithoutResourceIds() { public void testEncodeAndParseBundleWithoutResourceIds() {
Organization org = new Organization(); Organization org = new Organization();
@ -143,6 +148,42 @@ public class XmlParserDstu2Test {
assertTrue(parsed.getEntries().get(0).getResource().getId().isEmpty()); 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 @Test
public void testEncodeAndParseContained() { public void testEncodeAndParseContained() {
IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true); IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true);