All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ca.uhn.fhir.model.api.Bundle Maven / Gradle / Ivy

There is a newer version: 7.6.1
Show newest version
package ca.uhn.fhir.model.api;

/*
 * #%L
 * HAPI FHIR - Core Library
 * %%
 * Copyright (C) 2014 - 2016 University Health Network
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
import static org.apache.commons.lang3.StringUtils.isNotBlank;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.hl7.fhir.instance.model.api.IBase;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.base.resource.ResourceMetadataMap;
import ca.uhn.fhir.model.primitive.BoundCodeDt;
import ca.uhn.fhir.model.primitive.DecimalDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.IntegerDt;
import ca.uhn.fhir.model.primitive.StringDt;
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.server.Constants;
import ca.uhn.fhir.util.UrlUtil;

public class Bundle extends BaseBundle implements IBase /* implements IElement */{

	private ResourceMetadataMap myResourceMetadata;
	private BoundCodeDt myType;
	private StringDt myBundleId;
	private TagList myCategories;
	private List myEntries;
	private volatile transient Map myIdToEntries;
	private StringDt myLinkBase;
	private StringDt myLinkFirst;
	private StringDt myLinkLast;
	private StringDt myLinkNext;
	private StringDt myLinkPrevious;
	private StringDt myLinkSelf;
	private StringDt myTitle;
	private IntegerDt myTotalResults;

	/**
	 * @deprecated Tags wil become immutable in a future release of HAPI, so
	 *             {@link #addCategory(String, String, String)} should be used instead
	 */
	@Deprecated
	public Tag addCategory() {
		Tag retVal = new Tag();
		getCategories().add(retVal);
		return retVal;
	}

	public void addCategory(String theScheme, String theTerm, String theLabel) {
		getCategories().add(new Tag(theScheme, theTerm, theLabel));
	}

	public void addCategory(Tag theTag) {
		getCategories().add(theTag);
	}

	/**
	 * Adds and returns a new bundle entry
	 */
	public BundleEntry addEntry() {
		BundleEntry retVal = new BundleEntry();
		getEntries().add(retVal);
		return retVal;
	}

	/**
	 * Adds a new entry
	 * 
	 * @param theBundleEntry
	 *            The entry to add
	 */
	public void addEntry(BundleEntry theBundleEntry) {
		Validate.notNull(theBundleEntry, "theBundleEntry can not be null");
		getEntries().add(theBundleEntry);
	}

	/**
	 * Creates a new entry using the given resource and populates it accordingly
	 * 
	 * @param theResource
	 *            The resource to add
	 * @return Returns the newly created bundle entry that was added to the bundle
	 */
	public BundleEntry addResource(IResource theResource, FhirContext theContext, String theServerBase) {
		BundleEntry entry = addEntry();
		entry.setResource(theResource);

		RuntimeResourceDefinition def = theContext.getResourceDefinition(theResource);

		String title = ResourceMetadataKeyEnum.TITLE.get(theResource);
		if (title != null) {
			entry.getTitle().setValue(title);
		} else {
			entry.getTitle().setValue(def.getName() + " " + StringUtils.defaultString(theResource.getId().getValue(), "(no ID)"));
		}

		if (theResource.getId() != null) {
			if (theResource.getId().isAbsolute()) {

				entry.getLinkSelf().setValue(theResource.getId().getValue());
				entry.getId().setValue(theResource.getId().toVersionless().getValue());

			} else if (StringUtils.isNotBlank(theResource.getId().getValue())) {

				StringBuilder b = new StringBuilder();
				b.append(theServerBase);
				if (b.length() > 0 && b.charAt(b.length() - 1) != '/') {
					b.append('/');
				}
				b.append(def.getName());
				b.append('/');
				String resId = theResource.getId().getIdPart();
				b.append(resId);

				entry.getId().setValue(b.toString());

				if (isNotBlank(theResource.getId().getVersionIdPart())) {
					b.append('/');
					b.append(Constants.PARAM_HISTORY);
					b.append('/');
					b.append(theResource.getId().getVersionIdPart());
				} else {
					IdDt versionId = (IdDt) ResourceMetadataKeyEnum.VERSION_ID.get(theResource);
					if (versionId != null) {
						b.append('/');
						b.append(Constants.PARAM_HISTORY);
						b.append('/');
						b.append(versionId.getValue());
					}
				}

				String qualifiedId = b.toString();
				entry.getLinkSelf().setValue(qualifiedId);

				// String resourceType = theContext.getResourceDefinition(theResource).getName();


			}
		}

		InstantDt published = ResourceMetadataKeyEnum.PUBLISHED.get(theResource);
		if (published == null) {
			entry.getPublished().setToCurrentTimeInLocalTimeZone();
		} else {
			entry.setPublished(published);
		}

		InstantDt updated = ResourceMetadataKeyEnum.UPDATED.get(theResource);
		if (updated != null) {
			entry.setUpdated(updated);
		}

		InstantDt deleted = ResourceMetadataKeyEnum.DELETED_AT.get(theResource);
		if (deleted != null) {
			entry.setDeleted(deleted);
		}

		IdDt previous = ResourceMetadataKeyEnum.PREVIOUS_ID.get(theResource);
		if (previous != null) {
			entry.getLinkAlternate().setValue(previous.withServerBase(theServerBase, def.getName()).getValue());
		}

		TagList tagList = ResourceMetadataKeyEnum.TAG_LIST.get(theResource);
		if (tagList != null) {
			for (Tag nextTag : tagList) {
				entry.addCategory(nextTag);
			}
		}

		String linkSearch = ResourceMetadataKeyEnum.LINK_SEARCH.get(theResource);
		if (isNotBlank(linkSearch)) {
			if (!UrlUtil.isAbsolute(linkSearch)) {
				linkSearch = (theServerBase + "/" + linkSearch);
			}
			entry.getLinkSearch().setValue(linkSearch);
		}

		String linkAlternate = ResourceMetadataKeyEnum.LINK_ALTERNATE.get(theResource);
		if (isNotBlank(linkAlternate)) {
			if (!UrlUtil.isAbsolute(linkAlternate)) {
				linkSearch = (theServerBase + "/" + linkAlternate);
			}
			entry.getLinkAlternate().setValue(linkSearch);
		}
		
		BundleEntrySearchModeEnum entryStatus = ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.get(theResource);
		if (entryStatus != null) {
			entry.getSearchMode().setValueAsEnum(entryStatus);
		}

		BundleEntryTransactionMethodEnum entryTransactionOperation = ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.get(theResource);
		if (entryTransactionOperation != null) {
			entry.getTransactionMethod().setValueAsEnum(entryTransactionOperation);
		}

		DecimalDt entryScore = ResourceMetadataKeyEnum.ENTRY_SCORE.get(theResource);
		if (entryScore != null) {
			entry.setScore(entryScore);
		}

		return entry;
	}

	public StringDt getBundleId() {
		if (myBundleId == null) {
			myBundleId = new StringDt();
		}
		return myBundleId;
	}

	public TagList getCategories() {
		if (myCategories == null) {
			myCategories = new TagList();
		}
		return myCategories;
	}

	public List getEntries() {
		if (myEntries == null) {
			myEntries = new ArrayList();
		}
		return myEntries;
	}

	public StringDt getLinkBase() {
		if (myLinkBase == null) {
			myLinkBase = new StringDt();
		}
		return myLinkBase;
	}

	public StringDt getLinkFirst() {
		if (myLinkFirst == null) {
			myLinkFirst = new StringDt();
		}
		return myLinkFirst;
	}

	public StringDt getLinkLast() {
		if (myLinkLast == null) {
			myLinkLast = new StringDt();
		}
		return myLinkLast;
	}

	public StringDt getLinkNext() {
		if (myLinkNext == null) {
			myLinkNext = new StringDt();
		}
		return myLinkNext;
	}

	public StringDt getLinkPrevious() {
		if (myLinkPrevious == null) {
			myLinkPrevious = new StringDt();
		}
		return myLinkPrevious;
	}

	public StringDt getLinkSelf() {
		if (myLinkSelf == null) {
			myLinkSelf = new StringDt();
		}
		return myLinkSelf;
	}

	/*
	public InstantDt getPublished() {
		InstantDt retVal = (InstantDt) getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED);
		if (retVal == null) {
			retVal= new InstantDt();
			getResourceMetadata().put(ResourceMetadataKeyEnum.PUBLISHED, retVal);
		}
		return retVal;
	}
	*/

	/**
	 * Retrieves a resource from a bundle given its logical ID.
	 * 

* Important usage notes: This method ignores base URLs (so passing in an ID of * http://foo/Patient/123 will return a resource if it has the logical ID of * http://bar/Patient/123. Also, this method is intended to be used for bundles which have already been * populated. It will cache its results for fast performance, but that means that modifications to the bundle after * this method is called may not be accurately reflected. *

* * @param theId * The resource ID * @return Returns the resource with the given ID, or null if none is found */ public IResource getResourceById(IdDt theId) { Map map = myIdToEntries; if (map == null) { map = new HashMap(); for (BundleEntry next : this.getEntries()) { if (next.getId().isEmpty() == false) { map.put(next.getId().toUnqualified(), next.getResource()); } } myIdToEntries = map; } return map.get(theId.toUnqualified()); } public ResourceMetadataMap getResourceMetadata() { if (myResourceMetadata == null) { myResourceMetadata = new ResourceMetadataMap(); } return myResourceMetadata; } /** * Returns a list containing all resources of the given type from this bundle */ public List getResources(Class theClass) { ArrayList retVal = new ArrayList(); for (BundleEntry next : getEntries()) { if (next.getResource() != null && theClass.isAssignableFrom(next.getResource().getClass())) { @SuppressWarnings("unchecked") T resource = (T) next.getResource(); retVal.add(resource); } } return retVal; } public StringDt getTitle() { if (myTitle == null) { myTitle = new StringDt(); } return myTitle; } public IntegerDt getTotalResults() { if (myTotalResults == null) { myTotalResults = new IntegerDt(); } return myTotalResults; } public BoundCodeDt getType() { if (myType == null) { myType = new BoundCodeDt(BundleTypeEnum.VALUESET_BINDER); } return myType; } public InstantDt getUpdated() { InstantDt retVal = (InstantDt) getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED); if (retVal == null) { retVal= new InstantDt(); getResourceMetadata().put(ResourceMetadataKeyEnum.UPDATED, retVal); } return retVal; } /** * Returns true if this bundle contains zero entries */ @Override public boolean isEmpty() { return getEntries().isEmpty(); } public void setCategories(TagList theCategories) { myCategories = theCategories; } /* public void setPublished(InstantDt thePublished) { getResourceMetadata().put(ResourceMetadataKeyEnum.PUBLISHED, thePublished); } */ public void setType(BoundCodeDt theType) { myType = theType; } /** * Returns the number of entries in this bundle */ public int size() { return getEntries().size(); } public List toListOfResources() { ArrayList retVal = new ArrayList(); for (BundleEntry next : getEntries()) { if (next.getResource() != null) { retVal.add(next.getResource()); } } return retVal; } @Override public String toString() { ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); b.append(getEntries().size() + " entries"); b.append("id", getId()); return b.toString(); } public static Bundle withResources(List theResources, FhirContext theContext, String theServerBase) { Bundle retVal = new Bundle(); for (IResource next : theResources) { retVal.addResource(next, theContext, theServerBase); } return retVal; } public static Bundle withSingleResource(IResource theResource) { Bundle retVal = new Bundle(); retVal.addEntry().setResource(theResource); return retVal; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy