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:
parent
0f2d742872
commit
d0cffbf8c7
|
@ -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:");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue