Deprecate redundant IVersionSpecificBundleProvider method

This commit is contained in:
James Agnew 2019-09-30 09:44:47 -04:00
parent 1b2892f475
commit c8ce07c40e
13 changed files with 345 additions and 579 deletions

View File

@ -25,8 +25,9 @@ public class IncludesExamples {
FhirContext ctx = FhirContext.forDstu2();
Dstu2BundleFactory bf = new Dstu2BundleFactory(ctx);
bf.initializeBundleFromResourceList(null, resources, "http://example.com/base", "http://example.com/base/Patient", 1, BundleTypeEnum.SEARCHSET);
IBaseResource b = bf.getResourceBundle();
bf.addRootPropertiesToBundle(null, null, null, null, null, resources.size(), BundleTypeEnum.SEARCHSET, null);
bf.addResourcesToBundle(new ArrayList<>(resources), BundleTypeEnum.SEARCHSET, null, null, null);
IBaseResource b = bf.getResourceBundle();
// Encode the bundle
String encoded = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b);

View File

@ -19,14 +19,17 @@ package ca.uhn.fhir.rest.api;
* limitations under the License.
* #L%
*/
import java.util.*;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import ca.uhn.fhir.context.api.BundleInclusionRule;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
* This interface should be considered experimental and will likely change in future releases of HAPI. Use with caution!
@ -39,7 +42,15 @@ public interface IVersionSpecificBundleFactory {
IBaseResource getResourceBundle();
void initializeBundleFromResourceList(String theAuthor, List<? extends IBaseResource> theResult, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType);
/**
* @deprecated This was deprecated in HAPI FHIR 4.1.0 as it provides duplicate functionality to the {@link #addRootPropertiesToBundle(String, String, String, String, String, Integer, BundleTypeEnum, IPrimitiveType)}
* and {@link #addResourcesToBundle(List, BundleTypeEnum, String, BundleInclusionRule, Set)} methods
*/
@Deprecated
default void initializeBundleFromResourceList(String theAuthor, List<? extends IBaseResource> theResult, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType) {
addRootPropertiesToBundle(null, null, null, null, null, theResult.size(), theBundleType, null);
addResourcesToBundle(new ArrayList<>(theResult), theBundleType, null, null, null);
}
void initializeWithBundleResource(IBaseResource theResource);

View File

@ -715,7 +715,8 @@ public class ExampleDataUploader extends BaseCommand {
ourLog.info("About to upload {} examples in a transaction, {} remaining", subResourceList.size(), resources.size());
IVersionSpecificBundleFactory bundleFactory = ctx.newBundleFactory();
bundleFactory.initializeBundleFromResourceList(null, subResourceList, null, null, 0, BundleTypeEnum.TRANSACTION);
bundleFactory.addRootPropertiesToBundle(null, null, null, null, null, subResourceList.size(), BundleTypeEnum.TRANSACTION, null);
bundleFactory.addResourcesToBundle(new ArrayList<>(subResourceList), BundleTypeEnum.TRANSACTION, null, null, null);
IBaseResource subBundle = bundleFactory.getResourceBundle();
String encoded = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(subBundle);

View File

@ -22,6 +22,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
* #L%
*/
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -52,7 +53,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
private boolean myOmitResourceId = false;
private Map<String, List<String>> myParams;
private final IBaseResource myResource;
private final List<? extends IBaseResource> myResources;
private final List<IBaseResource> myResources;
private final String myUrlPath;
private IIdType myForceResourceId;
@ -70,7 +71,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
super(theContext);
myResource = null;
myUrlPath = null;
myResources = theResources;
myResources = new ArrayList<>(theResources);
myContents = null;
myBundleType = theBundleType;
}
@ -172,11 +173,8 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
parser.setOmitResourceId(myOmitResourceId);
if (myResources != null) {
IVersionSpecificBundleFactory bundleFactory = getContext().newBundleFactory();
bundleFactory.initializeBundleFromResourceList("", myResources, "", "", myResources.size(), myBundleType);
IBaseResource bundle = bundleFactory.getResourceBundle();
if (bundle != null) {
return parser.encodeResourceToString(bundle);
}
bundleFactory.addRootPropertiesToBundle(null, null, null, null, null, myResources.size(), myBundleType, null);
bundleFactory.addResourcesToBundle(myResources, myBundleType, null, null, null);
IBaseResource bundleRes = bundleFactory.getResourceBundle();
return parser.encodeResourceToString(bundleRes);
} else if (myContents != null) {

View File

@ -44,8 +44,9 @@ public class IncludesExamples {
FhirContext ctx = FhirContext.forDstu2();
R4BundleFactory bf = new R4BundleFactory(ctx);
bf.initializeBundleFromResourceList(null, resources, "http://example.com/base", "http://example.com/base/Patient", 1, BundleTypeEnum.SEARCHSET);
IBaseResource b = bf.getResourceBundle();
bf.addRootPropertiesToBundle(null, null, null, null, null, resources.size(), BundleTypeEnum.SEARCHSET, null);
bf.addResourcesToBundle(new ArrayList<>(resources), BundleTypeEnum.SEARCHSET, null, null, null);
IBaseResource b = bf.getResourceBundle();
// Encode the bundle
String encoded = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b);

View File

@ -19,13 +19,6 @@ package org.hl7.fhir.dstu2016may.hapi.rest.server;
* limitations under the License.
* #L%
*/
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.util.*;
import org.hl7.fhir.dstu2016may.model.*;
import org.hl7.fhir.dstu2016may.model.Bundle.*;
import org.hl7.fhir.instance.model.api.*;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.api.BundleInclusionRule;
@ -35,6 +28,18 @@ import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.IVersionSpecificBundleFactory;
import ca.uhn.fhir.util.ResourceReferenceInfo;
import org.hl7.fhir.dstu2016may.model.Bundle;
import org.hl7.fhir.dstu2016may.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu2016may.model.Bundle.BundleLinkComponent;
import org.hl7.fhir.dstu2016may.model.Bundle.SearchEntryMode;
import org.hl7.fhir.dstu2016may.model.DomainResource;
import org.hl7.fhir.dstu2016may.model.IdType;
import org.hl7.fhir.dstu2016may.model.Resource;
import org.hl7.fhir.instance.model.api.*;
import java.util.*;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class Dstu2_1BundleFactory implements IVersionSpecificBundleFactory {
@ -282,44 +287,6 @@ public class Dstu2_1BundleFactory implements IVersionSpecificBundleFactory {
return false;
}
@Override
public void initializeBundleFromResourceList(String theAuthor, List<? extends IBaseResource> theResources, String theServerBase, String theCompleteUrl, int theTotalResults,
BundleTypeEnum theBundleType) {
ensureBundle();
myBundle.setId(UUID.randomUUID().toString());
myBundle.getMeta().setLastUpdated(new Date());
myBundle.addLink().setRelation(Constants.LINK_FHIR_BASE).setUrl(theServerBase);
myBundle.addLink().setRelation(Constants.LINK_SELF).setUrl(theCompleteUrl);
myBundle.getTypeElement().setValueAsString(theBundleType.getCode());
if (theBundleType.equals(BundleTypeEnum.TRANSACTION)) {
for (IBaseResource nextBaseRes : theResources) {
Resource next = (Resource) nextBaseRes;
BundleEntryComponent nextEntry = myBundle.addEntry();
nextEntry.setResource(next);
if (next.getIdElement().isEmpty()) {
nextEntry.getRequest().setMethod(HTTPVerb.POST);
} else {
nextEntry.getRequest().setMethod(HTTPVerb.PUT);
if (next.getIdElement().isAbsolute()) {
nextEntry.getRequest().setUrl(next.getId());
} else {
String resourceType = myContext.getResourceDefinition(next).getName();
nextEntry.getRequest().setUrl(new IdType(theServerBase, resourceType, next.getIdElement().getIdPart(), next.getIdElement().getVersionIdPart()).getValue());
}
}
}
} else {
addResourcesForSearch(theResources);
}
myBundle.getTotalElement().setValue(theTotalResults);
}
@Override
public void initializeWithBundleResource(IBaseResource theBundle) {
myBundle = (Bundle) theBundle;

View File

@ -275,44 +275,6 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
return false;
}
@Override
public void initializeBundleFromResourceList(String theAuthor, List<? extends IBaseResource> theResources, String theServerBase, String theCompleteUrl, int theTotalResults,
BundleTypeEnum theBundleType) {
ensureBundle();
myBundle.setId(UUID.randomUUID().toString());
ResourceMetadataKeyEnum.PUBLISHED.put(myBundle, InstantDt.withCurrentTime());
myBundle.addLink().setRelation(Constants.LINK_FHIR_BASE).setUrl(theServerBase);
myBundle.addLink().setRelation(Constants.LINK_SELF).setUrl(theCompleteUrl);
myBundle.getTypeElement().setValueAsString(theBundleType.getCode());
if (theBundleType.equals(BundleTypeEnum.TRANSACTION)) {
for (IBaseResource nextBaseRes : theResources) {
IResource next = (IResource) nextBaseRes;
Entry nextEntry = myBundle.addEntry();
nextEntry.setResource(next);
if (next.getId().isEmpty()) {
nextEntry.getRequest().setMethod(HTTPVerbEnum.POST);
} else {
nextEntry.getRequest().setMethod(HTTPVerbEnum.PUT);
if (next.getId().isAbsolute()) {
nextEntry.getRequest().setUrl(next.getId());
} else {
String resourceType = myContext.getResourceDefinition(next).getName();
nextEntry.getRequest().setUrl(new IdDt(theServerBase, resourceType, next.getId().getIdPart(), next.getId().getVersionIdPart()).getValue());
}
}
}
} else {
addResourcesForSearch(theResources);
}
myBundle.getTotalElement().setValue(theTotalResults);
}
@Override
public void initializeWithBundleResource(IBaseResource theBundle) {
myBundle = (Bundle) theBundle;

View File

@ -32,7 +32,6 @@ import ca.uhn.fhir.util.ResourceReferenceInfo;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.Bundle.BundleLinkComponent;
import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb;
import org.hl7.fhir.dstu3.model.Bundle.SearchEntryMode;
import org.hl7.fhir.dstu3.model.DomainResource;
import org.hl7.fhir.dstu3.model.IdType;
@ -314,44 +313,6 @@ public class Dstu3BundleFactory implements IVersionSpecificBundleFactory {
return false;
}
@Override
public void initializeBundleFromResourceList(String theAuthor, List<? extends IBaseResource> theResources, String theServerBase, String theCompleteUrl, int theTotalResults,
BundleTypeEnum theBundleType) {
myBundle = new Bundle();
myBundle.setId(UUID.randomUUID().toString());
myBundle.getMeta().setLastUpdated(new Date());
myBundle.addLink().setRelation(Constants.LINK_FHIR_BASE).setUrl(theServerBase);
myBundle.addLink().setRelation(Constants.LINK_SELF).setUrl(theCompleteUrl);
myBundle.getTypeElement().setValueAsString(theBundleType.getCode());
if (theBundleType.equals(BundleTypeEnum.TRANSACTION)) {
for (IBaseResource nextBaseRes : theResources) {
Resource next = (Resource) nextBaseRes;
BundleEntryComponent nextEntry = myBundle.addEntry();
nextEntry.setResource(next);
if (next.getIdElement().isEmpty()) {
nextEntry.getRequest().setMethod(HTTPVerb.POST);
} else {
nextEntry.getRequest().setMethod(HTTPVerb.PUT);
if (next.getIdElement().isAbsolute()) {
nextEntry.getRequest().setUrl(next.getId());
} else {
String resourceType = myContext.getResourceDefinition(next).getName();
nextEntry.getRequest().setUrl(new IdType(theServerBase, resourceType, next.getIdElement().getIdPart(), next.getIdElement().getVersionIdPart()).getValue());
}
}
}
} else {
addResourcesForSearch(theResources);
}
myBundle.getTotalElement().setValue(theTotalResults);
}
@Override
public void initializeWithBundleResource(IBaseResource theBundle) {
myBundle = (Bundle) theBundle;

View File

@ -30,7 +30,6 @@ import ca.uhn.fhir.util.ResourceReferenceInfo;
import org.hl7.fhir.dstu2.model.Bundle;
import org.hl7.fhir.dstu2.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu2.model.Bundle.BundleLinkComponent;
import org.hl7.fhir.dstu2.model.Bundle.HTTPVerb;
import org.hl7.fhir.dstu2.model.Bundle.SearchEntryMode;
import org.hl7.fhir.dstu2.model.IdType;
import org.hl7.fhir.dstu2.model.InstantType;
@ -116,9 +115,9 @@ public class Dstu2Hl7OrgBundleFactory implements IVersionSpecificBundleFactory {
populateBundleEntryFullUrl(next, entry);
}
/*
* Actually add the resources to the bundle
*/
/*
* Actually add the resources to the bundle
*/
for (IBaseResource next : includedResources) {
BundleEntryComponent entry = myBundle.addEntry();
entry.setResource((Resource) next).getSearch().setMode(SearchEntryMode.INCLUDE);
@ -208,9 +207,9 @@ public class Dstu2Hl7OrgBundleFactory implements IVersionSpecificBundleFactory {
// }
}
/*
* Actually add the resources to the bundle
*/
/*
* Actually add the resources to the bundle
*/
for (IBaseResource next : includedResources) {
myBundle.addEntry().setResource((Resource) next).getSearch().setMode(SearchEntryMode.INCLUDE);
}
@ -276,45 +275,6 @@ public class Dstu2Hl7OrgBundleFactory implements IVersionSpecificBundleFactory {
return false;
}
@Override
public void initializeBundleFromResourceList(String theAuthor, List<? extends IBaseResource> theResources,
String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType) {
ensureBundle();
myBundle.setId(UUID.randomUUID().toString());
myBundle.getMeta().setLastUpdatedElement(InstantType.withCurrentTime());
myBundle.addLink().setRelation(Constants.LINK_FHIR_BASE).setUrl(theServerBase);
myBundle.addLink().setRelation(Constants.LINK_SELF).setUrl(theCompleteUrl);
myBundle.getTypeElement().setValueAsString(theBundleType.getCode());
if (theBundleType.equals(BundleTypeEnum.TRANSACTION)) {
for (IBaseResource nextBaseRes : theResources) {
IBaseResource next = (IBaseResource) nextBaseRes;
BundleEntryComponent nextEntry = myBundle.addEntry();
nextEntry.setResource((Resource) next);
if (next.getIdElement().isEmpty()) {
nextEntry.getRequest().setMethod(HTTPVerb.POST);
} else {
nextEntry.getRequest().setMethod(HTTPVerb.PUT);
if (next.getIdElement().isAbsolute()) {
nextEntry.getRequest().setUrl(next.getIdElement().getValue());
} else {
String resourceType = myContext.getResourceDefinition(next).getName();
nextEntry.getRequest().setUrl(new IdType(theServerBase, resourceType, next.getIdElement().getIdPart(),
next.getIdElement().getVersionIdPart()).getValue());
}
}
}
} else {
addResourcesForSearch(theResources);
}
myBundle.getTotalElement().setValue(theTotalResults);
}
@Override
public void initializeWithBundleResource(IBaseResource theBundle) {
myBundle = (Bundle) theBundle;

View File

@ -33,7 +33,6 @@ import org.hl7.fhir.instance.model.api.*;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r4.model.Bundle.BundleLinkComponent;
import org.hl7.fhir.r4.model.Bundle.HTTPVerb;
import org.hl7.fhir.r4.model.Bundle.SearchEntryMode;
import org.hl7.fhir.r4.model.DomainResource;
import org.hl7.fhir.r4.model.IdType;
@ -316,44 +315,6 @@ public class R4BundleFactory implements IVersionSpecificBundleFactory {
return false;
}
@Override
public void initializeBundleFromResourceList(String theAuthor, List<? extends IBaseResource> theResources, String theServerBase, String theCompleteUrl, int theTotalResults,
BundleTypeEnum theBundleType) {
myBundle = new Bundle();
myBundle.setId(UUID.randomUUID().toString());
myBundle.getMeta().setLastUpdated(new Date());
myBundle.addLink().setRelation(Constants.LINK_FHIR_BASE).setUrl(theServerBase);
myBundle.addLink().setRelation(Constants.LINK_SELF).setUrl(theCompleteUrl);
myBundle.getTypeElement().setValueAsString(theBundleType.getCode());
if (theBundleType.equals(BundleTypeEnum.TRANSACTION)) {
for (IBaseResource nextBaseRes : theResources) {
Resource next = (Resource) nextBaseRes;
BundleEntryComponent nextEntry = myBundle.addEntry();
nextEntry.setResource(next);
if (next.getIdElement().isEmpty()) {
nextEntry.getRequest().setMethod(HTTPVerb.POST);
} else {
nextEntry.getRequest().setMethod(HTTPVerb.PUT);
if (next.getIdElement().isAbsolute()) {
nextEntry.getRequest().setUrl(next.getId());
} else {
String resourceType = myContext.getResourceDefinition(next).getName();
nextEntry.getRequest().setUrl(new IdType(theServerBase, resourceType, next.getIdElement().getIdPart(), next.getIdElement().getVersionIdPart()).getValue());
}
}
}
} else {
addResourcesForSearch(theResources);
}
myBundle.getTotalElement().setValue(theTotalResults);
}
@Override
public void initializeWithBundleResource(IBaseResource theBundle) {
myBundle = (Bundle) theBundle;

View File

@ -33,7 +33,6 @@ import org.hl7.fhir.instance.model.api.*;
import org.hl7.fhir.r5.model.Bundle;
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r5.model.Bundle.BundleLinkComponent;
import org.hl7.fhir.r5.model.Bundle.HTTPVerb;
import org.hl7.fhir.r5.model.Bundle.SearchEntryMode;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.IdType;
@ -45,352 +44,315 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
@SuppressWarnings("Duplicates")
public class R5BundleFactory implements IVersionSpecificBundleFactory {
private String myBase;
private Bundle myBundle;
private FhirContext myContext;
private String myBase;
private Bundle myBundle;
private FhirContext myContext;
public R5BundleFactory(FhirContext theContext) {
myContext = theContext;
}
public R5BundleFactory(FhirContext theContext) {
myContext = theContext;
}
private void addResourcesForSearch(List<? extends IBaseResource> theResult) {
List<IBaseResource> includedResources = new ArrayList<IBaseResource>();
Set<IIdType> addedResourceIds = new HashSet<IIdType>();
private void addResourcesForSearch(List<? extends IBaseResource> theResult) {
List<IBaseResource> includedResources = new ArrayList<IBaseResource>();
Set<IIdType> addedResourceIds = new HashSet<IIdType>();
for (IBaseResource next : theResult) {
if (next.getIdElement().isEmpty() == false) {
addedResourceIds.add(next.getIdElement());
}
}
for (IBaseResource next : theResult) {
if (next.getIdElement().isEmpty() == false) {
addedResourceIds.add(next.getIdElement());
}
}
for (IBaseResource nextBaseRes : theResult) {
Resource next = (Resource) nextBaseRes;
Set<String> containedIds = new HashSet<String>();
if (next instanceof DomainResource) {
for (Resource nextContained : ((DomainResource) next).getContained()) {
if (nextContained.getIdElement().isEmpty() == false) {
containedIds.add(nextContained.getIdElement().getValue());
}
}
}
for (IBaseResource nextBaseRes : theResult) {
Resource next = (Resource) nextBaseRes;
Set<String> containedIds = new HashSet<String>();
if (next instanceof DomainResource) {
for (Resource nextContained : ((DomainResource) next).getContained()) {
if (nextContained.getIdElement().isEmpty() == false) {
containedIds.add(nextContained.getIdElement().getValue());
}
}
}
List<IBaseReference> references = myContext.newTerser().getAllPopulatedChildElementsOfType(next, IBaseReference.class);
do {
List<IAnyResource> addedResourcesThisPass = new ArrayList<>();
List<IBaseReference> references = myContext.newTerser().getAllPopulatedChildElementsOfType(next, IBaseReference.class);
do {
List<IAnyResource> addedResourcesThisPass = new ArrayList<>();
for (IBaseReference nextRef : references) {
IAnyResource nextRes = (IAnyResource) nextRef.getResource();
if (nextRes != null) {
if (nextRes.getIdElement().hasIdPart()) {
if (containedIds.contains(nextRes.getIdElement().getValue())) {
// Don't add contained IDs as top level resources
continue;
}
for (IBaseReference nextRef : references) {
IAnyResource nextRes = (IAnyResource) nextRef.getResource();
if (nextRes != null) {
if (nextRes.getIdElement().hasIdPart()) {
if (containedIds.contains(nextRes.getIdElement().getValue())) {
// Don't add contained IDs as top level resources
continue;
}
IIdType id = nextRes.getIdElement();
if (id.hasResourceType() == false) {
String resName = myContext.getResourceDefinition(nextRes).getName();
id = id.withResourceType(resName);
}
IIdType id = nextRes.getIdElement();
if (id.hasResourceType() == false) {
String resName = myContext.getResourceDefinition(nextRes).getName();
id = id.withResourceType(resName);
}
if (!addedResourceIds.contains(id)) {
addedResourceIds.add(id);
addedResourcesThisPass.add(nextRes);
}
if (!addedResourceIds.contains(id)) {
addedResourceIds.add(id);
addedResourcesThisPass.add(nextRes);
}
}
}
}
}
}
}
// Linked resources may themselves have linked resources
references = new ArrayList<>();
for (IAnyResource iResource : addedResourcesThisPass) {
List<IBaseReference> newReferences = myContext.newTerser().getAllPopulatedChildElementsOfType(iResource, IBaseReference.class);
references.addAll(newReferences);
}
// Linked resources may themselves have linked resources
references = new ArrayList<>();
for (IAnyResource iResource : addedResourcesThisPass) {
List<IBaseReference> newReferences = myContext.newTerser().getAllPopulatedChildElementsOfType(iResource, IBaseReference.class);
references.addAll(newReferences);
}
includedResources.addAll(addedResourcesThisPass);
includedResources.addAll(addedResourcesThisPass);
} while (references.isEmpty() == false);
} while (references.isEmpty() == false);
BundleEntryComponent entry = myBundle.addEntry().setResource(next);
if (next.getIdElement().hasBaseUrl()) {
entry.setFullUrl(next.getId());
}
BundleEntryComponent entry = myBundle.addEntry().setResource(next);
if (next.getIdElement().hasBaseUrl()) {
entry.setFullUrl(next.getId());
}
String httpVerb = ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.get(next);
if (httpVerb != null) {
entry.getRequest().getMethodElement().setValueAsString(httpVerb);
entry.getRequest().getUrlElement().setValue(next.getId());
}
if ("DELETE".equals(httpVerb)) {
entry.setResource(null);
}
}
String httpVerb = ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.get(next);
if (httpVerb != null) {
entry.getRequest().getMethodElement().setValueAsString(httpVerb);
entry.getRequest().getUrlElement().setValue(next.getId());
}
if ("DELETE".equals(httpVerb)) {
entry.setResource(null);
}
}
/*
* Actually add the resources to the bundle
*/
for (IBaseResource next : includedResources) {
BundleEntryComponent entry = myBundle.addEntry();
entry.setResource((Resource) next).getSearch().setMode(SearchEntryMode.INCLUDE);
if (next.getIdElement().hasBaseUrl()) {
entry.setFullUrl(next.getIdElement().getValue());
}
}
}
/*
* Actually add the resources to the bundle
*/
for (IBaseResource next : includedResources) {
BundleEntryComponent entry = myBundle.addEntry();
entry.setResource((Resource) next).getSearch().setMode(SearchEntryMode.INCLUDE);
if (next.getIdElement().hasBaseUrl()) {
entry.setFullUrl(next.getIdElement().getValue());
}
}
}
@Override
public void addResourcesToBundle(List<IBaseResource> theResult, BundleTypeEnum theBundleType, String theServerBase, BundleInclusionRule theBundleInclusionRule, Set<Include> theIncludes) {
ensureBundle();
@Override
public void addResourcesToBundle(List<IBaseResource> theResult, BundleTypeEnum theBundleType, String theServerBase, BundleInclusionRule theBundleInclusionRule, Set<Include> theIncludes) {
ensureBundle();
List<IAnyResource> includedResources = new ArrayList<IAnyResource>();
Set<IIdType> addedResourceIds = new HashSet<IIdType>();
List<IAnyResource> includedResources = new ArrayList<IAnyResource>();
Set<IIdType> addedResourceIds = new HashSet<IIdType>();
for (IBaseResource next : theResult) {
if (next.getIdElement().isEmpty() == false) {
addedResourceIds.add(next.getIdElement());
}
}
for (IBaseResource next : theResult) {
if (next.getIdElement().isEmpty() == false) {
addedResourceIds.add(next.getIdElement());
}
}
for (IBaseResource next : theResult) {
for (IBaseResource next : theResult) {
Set<String> containedIds = new HashSet<String>();
Set<String> containedIds = new HashSet<String>();
if (next instanceof DomainResource) {
for (Resource nextContained : ((DomainResource) next).getContained()) {
if (isNotBlank(nextContained.getId())) {
containedIds.add(nextContained.getId());
}
}
}
if (next instanceof DomainResource) {
for (Resource nextContained : ((DomainResource) next).getContained()) {
if (isNotBlank(nextContained.getId())) {
containedIds.add(nextContained.getId());
}
}
}
List<ResourceReferenceInfo> references = myContext.newTerser().getAllResourceReferences(next);
do {
List<IAnyResource> addedResourcesThisPass = new ArrayList<IAnyResource>();
List<ResourceReferenceInfo> references = myContext.newTerser().getAllResourceReferences(next);
do {
List<IAnyResource> addedResourcesThisPass = new ArrayList<IAnyResource>();
for (ResourceReferenceInfo nextRefInfo : references) {
if (!theBundleInclusionRule.shouldIncludeReferencedResource(nextRefInfo, theIncludes)) {
continue;
}
for (ResourceReferenceInfo nextRefInfo : references) {
if (!theBundleInclusionRule.shouldIncludeReferencedResource(nextRefInfo, theIncludes)) {
continue;
}
IAnyResource nextRes = (IAnyResource) nextRefInfo.getResourceReference().getResource();
if (nextRes != null) {
if (nextRes.getIdElement().hasIdPart()) {
if (containedIds.contains(nextRes.getIdElement().getValue())) {
// Don't add contained IDs as top level resources
continue;
}
IAnyResource nextRes = (IAnyResource) nextRefInfo.getResourceReference().getResource();
if (nextRes != null) {
if (nextRes.getIdElement().hasIdPart()) {
if (containedIds.contains(nextRes.getIdElement().getValue())) {
// Don't add contained IDs as top level resources
continue;
}
IIdType id = nextRes.getIdElement();
if (id.hasResourceType() == false) {
String resName = myContext.getResourceDefinition(nextRes).getName();
id = id.withResourceType(resName);
}
IIdType id = nextRes.getIdElement();
if (id.hasResourceType() == false) {
String resName = myContext.getResourceDefinition(nextRes).getName();
id = id.withResourceType(resName);
}
if (!addedResourceIds.contains(id)) {
addedResourceIds.add(id);
addedResourcesThisPass.add(nextRes);
}
if (!addedResourceIds.contains(id)) {
addedResourceIds.add(id);
addedResourcesThisPass.add(nextRes);
}
}
}
}
}
}
}
includedResources.addAll(addedResourcesThisPass);
includedResources.addAll(addedResourcesThisPass);
// Linked resources may themselves have linked resources
references = new ArrayList<>();
for (IAnyResource iResource : addedResourcesThisPass) {
List<ResourceReferenceInfo> newReferences = myContext.newTerser().getAllResourceReferences(iResource);
references.addAll(newReferences);
}
} while (references.isEmpty() == false);
// Linked resources may themselves have linked resources
references = new ArrayList<>();
for (IAnyResource iResource : addedResourcesThisPass) {
List<ResourceReferenceInfo> newReferences = myContext.newTerser().getAllResourceReferences(iResource);
references.addAll(newReferences);
}
} while (references.isEmpty() == false);
BundleEntryComponent entry = myBundle.addEntry().setResource((Resource) next);
Resource nextAsResource = (Resource) next;
IIdType id = populateBundleEntryFullUrl(next, entry);
BundleEntryComponent entry = myBundle.addEntry().setResource((Resource) next);
Resource nextAsResource = (Resource) next;
IIdType id = populateBundleEntryFullUrl(next, entry);
// Populate Request
String httpVerb = ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.get(nextAsResource);
if (httpVerb != null) {
entry.getRequest().getMethodElement().setValueAsString(httpVerb);
if (id != null) {
entry.getRequest().setUrl(id.getValue());
}
}
if ("DELETE".equals(httpVerb)) {
entry.setResource(null);
}
// Populate Request
String httpVerb = ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.get(nextAsResource);
if (httpVerb != null) {
entry.getRequest().getMethodElement().setValueAsString(httpVerb);
if (id != null) {
entry.getRequest().setUrl(id.getValue());
}
}
if ("DELETE".equals(httpVerb)) {
entry.setResource(null);
}
// Populate Bundle.entry.response
if (theBundleType != null) {
switch (theBundleType) {
case BATCH_RESPONSE:
case TRANSACTION_RESPONSE:
case HISTORY:
if ("1".equals(id.getVersionIdPart())) {
entry.getResponse().setStatus("201 Created");
} else if (isNotBlank(id.getVersionIdPart())) {
entry.getResponse().setStatus("200 OK");
}
if (isNotBlank(id.getVersionIdPart())) {
entry.getResponse().setEtag(RestfulServerUtils.createEtag(id.getVersionIdPart()));
}
break;
}
}
// Populate Bundle.entry.response
if (theBundleType != null) {
switch (theBundleType) {
case BATCH_RESPONSE:
case TRANSACTION_RESPONSE:
case HISTORY:
if ("1".equals(id.getVersionIdPart())) {
entry.getResponse().setStatus("201 Created");
} else if (isNotBlank(id.getVersionIdPart())) {
entry.getResponse().setStatus("200 OK");
}
if (isNotBlank(id.getVersionIdPart())) {
entry.getResponse().setEtag(RestfulServerUtils.createEtag(id.getVersionIdPart()));
}
break;
}
}
// Populate Bundle.entry.search
String searchMode = ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.get(nextAsResource);
if (searchMode != null) {
entry.getSearch().getModeElement().setValueAsString(searchMode);
}
}
// Populate Bundle.entry.search
String searchMode = ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.get(nextAsResource);
if (searchMode != null) {
entry.getSearch().getModeElement().setValueAsString(searchMode);
}
}
/*
* Actually add the resources to the bundle
*/
for (IAnyResource next : includedResources) {
BundleEntryComponent entry = myBundle.addEntry();
entry.setResource((Resource) next).getSearch().setMode(SearchEntryMode.INCLUDE);
populateBundleEntryFullUrl(next, entry);
}
/*
* Actually add the resources to the bundle
*/
for (IAnyResource next : includedResources) {
BundleEntryComponent entry = myBundle.addEntry();
entry.setResource((Resource) next).getSearch().setMode(SearchEntryMode.INCLUDE);
populateBundleEntryFullUrl(next, entry);
}
}
}
@Override
public void addRootPropertiesToBundle(String theId, String theServerBase, String theLinkSelf, String theLinkPrev, String theLinkNext, Integer theTotalResults, BundleTypeEnum theBundleType,
IPrimitiveType<Date> theLastUpdated) {
ensureBundle();
@Override
public void addRootPropertiesToBundle(String theId, String theServerBase, String theLinkSelf, String theLinkPrev, String theLinkNext, Integer theTotalResults, BundleTypeEnum theBundleType,
IPrimitiveType<Date> theLastUpdated) {
ensureBundle();
myBase = theServerBase;
myBase = theServerBase;
if (myBundle.getIdElement().isEmpty()) {
myBundle.setId(theId);
}
if (myBundle.getIdElement().isEmpty()) {
myBundle.setId(UUID.randomUUID().toString());
}
if (myBundle.getIdElement().isEmpty()) {
myBundle.setId(theId);
}
if (myBundle.getIdElement().isEmpty()) {
myBundle.setId(UUID.randomUUID().toString());
}
if (myBundle.getMeta().getLastUpdated() == null && theLastUpdated != null) {
myBundle.getMeta().getLastUpdatedElement().setValueAsString(theLastUpdated.getValueAsString());
}
if (myBundle.getMeta().getLastUpdated() == null && theLastUpdated != null) {
myBundle.getMeta().getLastUpdatedElement().setValueAsString(theLastUpdated.getValueAsString());
}
if (!hasLink(Constants.LINK_SELF, myBundle) && isNotBlank(theLinkSelf)) {
myBundle.addLink().setRelation(Constants.LINK_SELF).setUrl(theLinkSelf);
}
if (!hasLink(Constants.LINK_NEXT, myBundle) && isNotBlank(theLinkNext)) {
myBundle.addLink().setRelation(Constants.LINK_NEXT).setUrl(theLinkNext);
}
if (!hasLink(Constants.LINK_PREVIOUS, myBundle) && isNotBlank(theLinkPrev)) {
myBundle.addLink().setRelation(Constants.LINK_PREVIOUS).setUrl(theLinkPrev);
}
if (!hasLink(Constants.LINK_SELF, myBundle) && isNotBlank(theLinkSelf)) {
myBundle.addLink().setRelation(Constants.LINK_SELF).setUrl(theLinkSelf);
}
if (!hasLink(Constants.LINK_NEXT, myBundle) && isNotBlank(theLinkNext)) {
myBundle.addLink().setRelation(Constants.LINK_NEXT).setUrl(theLinkNext);
}
if (!hasLink(Constants.LINK_PREVIOUS, myBundle) && isNotBlank(theLinkPrev)) {
myBundle.addLink().setRelation(Constants.LINK_PREVIOUS).setUrl(theLinkPrev);
}
if (myBundle.getTypeElement().isEmpty() && theBundleType != null) {
myBundle.getTypeElement().setValueAsString(theBundleType.getCode());
}
if (myBundle.getTypeElement().isEmpty() && theBundleType != null) {
myBundle.getTypeElement().setValueAsString(theBundleType.getCode());
}
if (myBundle.getTotalElement().isEmpty() && theTotalResults != null) {
myBundle.getTotalElement().setValue(theTotalResults);
}
}
if (myBundle.getTotalElement().isEmpty() && theTotalResults != null) {
myBundle.getTotalElement().setValue(theTotalResults);
}
}
private void ensureBundle() {
if (myBundle == null) {
myBundle = new Bundle();
}
}
private void ensureBundle() {
if (myBundle == null) {
myBundle = new Bundle();
}
}
@Override
public IBaseResource getResourceBundle() {
return myBundle;
}
@Override
public IBaseResource getResourceBundle() {
return myBundle;
}
private boolean hasLink(String theLinkType, Bundle theBundle) {
for (BundleLinkComponent next : theBundle.getLink()) {
if (theLinkType.equals(next.getRelation())) {
return true;
}
}
return false;
}
private boolean hasLink(String theLinkType, Bundle theBundle) {
for (BundleLinkComponent next : theBundle.getLink()) {
if (theLinkType.equals(next.getRelation())) {
return true;
}
}
return false;
}
@Override
public void initializeBundleFromResourceList(String theAuthor, List<? extends IBaseResource> theResources, String theServerBase, String theCompleteUrl, int theTotalResults,
BundleTypeEnum theBundleType) {
myBundle = new Bundle();
myBundle.setId(UUID.randomUUID().toString());
@Override
public void initializeWithBundleResource(IBaseResource theBundle) {
myBundle = (Bundle) theBundle;
}
myBundle.getMeta().setLastUpdated(new Date());
private IIdType populateBundleEntryFullUrl(IBaseResource next, BundleEntryComponent entry) {
IIdType idElement = null;
if (next.getIdElement().hasBaseUrl()) {
idElement = next.getIdElement();
entry.setFullUrl(idElement.toVersionless().getValue());
} else {
if (isNotBlank(myBase) && next.getIdElement().hasIdPart()) {
idElement = next.getIdElement();
idElement = idElement.withServerBase(myBase, myContext.getResourceDefinition(next).getName());
entry.setFullUrl(idElement.toVersionless().getValue());
}
}
return idElement;
}
myBundle.addLink().setRelation(Constants.LINK_FHIR_BASE).setUrl(theServerBase);
myBundle.addLink().setRelation(Constants.LINK_SELF).setUrl(theCompleteUrl);
myBundle.getTypeElement().setValueAsString(theBundleType.getCode());
if (theBundleType.equals(BundleTypeEnum.TRANSACTION)) {
for (IBaseResource nextBaseRes : theResources) {
Resource next = (Resource) nextBaseRes;
BundleEntryComponent nextEntry = myBundle.addEntry();
nextEntry.setResource(next);
if (next.getIdElement().isEmpty()) {
nextEntry.getRequest().setMethod(HTTPVerb.POST);
} else {
nextEntry.getRequest().setMethod(HTTPVerb.PUT);
if (next.getIdElement().isAbsolute()) {
nextEntry.getRequest().setUrl(next.getId());
} else {
String resourceType = myContext.getResourceDefinition(next).getName();
nextEntry.getRequest().setUrl(new IdType(theServerBase, resourceType, next.getIdElement().getIdPart(), next.getIdElement().getVersionIdPart()).getValue());
}
}
}
} else {
addResourcesForSearch(theResources);
}
myBundle.getTotalElement().setValue(theTotalResults);
}
@Override
public void initializeWithBundleResource(IBaseResource theBundle) {
myBundle = (Bundle) theBundle;
}
private IIdType populateBundleEntryFullUrl(IBaseResource next, BundleEntryComponent entry) {
IIdType idElement = null;
if (next.getIdElement().hasBaseUrl()) {
idElement = next.getIdElement();
entry.setFullUrl(idElement.toVersionless().getValue());
} else {
if (isNotBlank(myBase) && next.getIdElement().hasIdPart()) {
idElement = next.getIdElement();
idElement = idElement.withServerBase(myBase, myContext.getResourceDefinition(next).getName());
entry.setFullUrl(idElement.toVersionless().getValue());
}
}
return idElement;
}
@Override
public List<IBaseResource> toListOfResources() {
ArrayList<IBaseResource> retVal = new ArrayList<IBaseResource>();
for (BundleEntryComponent next : myBundle.getEntry()) {
if (next.getResource() != null) {
retVal.add(next.getResource());
} else if (next.getResponse().getLocationElement().isEmpty() == false) {
IdType id = new IdType(next.getResponse().getLocation());
String resourceType = id.getResourceType();
if (isNotBlank(resourceType)) {
IAnyResource res = (IAnyResource) myContext.getResourceDefinition(resourceType).newInstance();
res.setId(id);
retVal.add(res);
}
}
}
return retVal;
}
@Override
public List<IBaseResource> toListOfResources() {
ArrayList<IBaseResource> retVal = new ArrayList<IBaseResource>();
for (BundleEntryComponent next : myBundle.getEntry()) {
if (next.getResource() != null) {
retVal.add(next.getResource());
} else if (next.getResponse().getLocationElement().isEmpty() == false) {
IdType id = new IdType(next.getResponse().getLocation());
String resourceType = id.getResourceType();
if (isNotBlank(resourceType)) {
IAnyResource res = (IAnyResource) myContext.getResourceDefinition(resourceType).newInstance();
res.setId(id);
retVal.add(res);
}
}
}
return retVal;
}
}

View File

@ -19,27 +19,32 @@ package ca.uhn.fhir.rest.server.provider.dstu2;
* limitations under the License.
* #L%
*/
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.util.*;
import org.hl7.fhir.instance.model.api.*;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.api.BundleInclusionRule;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Link;
import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum;
import ca.uhn.fhir.model.dstu2.valueset.SearchEntryModeEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.valueset.*;
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.IVersionSpecificBundleFactory;
import ca.uhn.fhir.util.ResourceReferenceInfo;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import java.util.*;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
private Bundle myBundle;
@ -282,44 +287,6 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
return false;
}
@Override
public void initializeBundleFromResourceList(String theAuthor, List<? extends IBaseResource> theResources, String theServerBase, String theCompleteUrl, int theTotalResults,
BundleTypeEnum theBundleType) {
myBundle = new Bundle();
myBundle.setId(UUID.randomUUID().toString());
ResourceMetadataKeyEnum.PUBLISHED.put(myBundle, InstantDt.withCurrentTime());
myBundle.addLink().setRelation(Constants.LINK_FHIR_BASE).setUrl(theServerBase);
myBundle.addLink().setRelation(Constants.LINK_SELF).setUrl(theCompleteUrl);
myBundle.getTypeElement().setValueAsString(theBundleType.getCode());
if (theBundleType.equals(BundleTypeEnum.TRANSACTION)) {
for (IBaseResource nextBaseRes : theResources) {
IResource next = (IResource) nextBaseRes;
Entry nextEntry = myBundle.addEntry();
nextEntry.setResource(next);
if (next.getId().isEmpty()) {
nextEntry.getRequest().setMethod(HTTPVerbEnum.POST);
} else {
nextEntry.getRequest().setMethod(HTTPVerbEnum.PUT);
if (next.getId().isAbsolute()) {
nextEntry.getRequest().setUrl(next.getId());
} else {
String resourceType = myContext.getResourceDefinition(next).getName();
nextEntry.getRequest().setUrl(new IdDt(theServerBase, resourceType, next.getId().getIdPart(), next.getId().getVersionIdPart()).getValue());
}
}
}
} else {
addResourcesForSearch(theResources);
}
myBundle.getTotalElement().setValue(theTotalResults);
}
@Override
public void initializeWithBundleResource(IBaseResource theBundle) {
myBundle = (Bundle) theBundle;

View File

@ -41,6 +41,16 @@
only system level export is currently supported but others will follow.
]]>
</action>
<action type="add">
<![CDATA[
<b>New Feature</b>:
Support for ElasticSearch has been added to the JPA server directly (i.e. without needing a separate
module) and a new class called "ElasticsearchHibernatePropertiesBuilder" has been added to facilitate
the creation of relevant properties. Instructions have been added to the hapi-fhir-jpaserver-starter
project to get started with Elasticsearch. It is likely we will switch our default recommendation
to Elastic in the future.
]]>
</action>
<action type="add" issue="1489">
<![CDATA[
<b>Improvement</b>:
@ -253,10 +263,14 @@
The JPA server failed to find codes defined in not-present codesystems in some cases, and reported
that the CodeSystem did not exist. This has been corrected.
</action>
<action type="add">
Support for ElasticSearch has been added to the JPA server directly (i.e. without needing a separate
module) and a new class called "ElasticsearchHibernatePropertiesBuilder" has been added to facilitate
the creation of relevant properties.
<action type="remove">
The method
<![CDATA[
<code>IVersionSpecificBundleFactory#initializeBundleFromResourceList</code>
]]>
has been deprecated, as it provided duplicate functionality to other methods and had an
outdated argument list based on the Bundle needs in DSTU1. We are not aware of any
public use of this API, please let us know if this deprecation causes any issues.
</action>
</release>
<release version="4.0.3" date="2019-09-03" description="Igloo (Point Release)">