001package ca.uhn.fhir.model.base.composite; 002 003/* 004 * #%L 005 * HAPI FHIR - Core Library 006 * %% 007 * Copyright (C) 2014 - 2021 Smile CDR, Inc. 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import static org.apache.commons.lang3.StringUtils.isBlank; 024 025import org.hl7.fhir.instance.model.api.IBaseDatatype; 026import org.hl7.fhir.instance.model.api.IBaseReference; 027import org.hl7.fhir.instance.model.api.IBaseResource; 028import org.hl7.fhir.instance.model.api.IIdType; 029 030import ca.uhn.fhir.context.RuntimeResourceDefinition; 031import ca.uhn.fhir.model.api.BaseIdentifiableElement; 032import ca.uhn.fhir.model.api.IResource; 033import ca.uhn.fhir.model.primitive.IdDt; 034import ca.uhn.fhir.model.primitive.StringDt; 035import ca.uhn.fhir.rest.client.api.IRestfulClient; 036 037public abstract class BaseResourceReferenceDt extends BaseIdentifiableElement implements IBaseDatatype, IBaseReference { 038 039 private static final long serialVersionUID = 1L; 040 041 private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseResourceReferenceDt.class); 042 private IBaseResource myResource; 043 044 /** 045 * Constructor 046 */ 047 public BaseResourceReferenceDt() { 048 // nothing 049 } 050 051 /** 052 * Constructor 053 * 054 * @param theResource 055 * The loaded resource itself 056 */ 057 public BaseResourceReferenceDt(IResource theResource) { 058 myResource = theResource; 059 setReference(theResource.getId()); 060 } 061 062 @Override 063 public abstract StringDt getDisplayElement(); 064 065 public abstract IdDt getReference(); 066 067 /** 068 * Gets the actual loaded and parsed resource instance, <b>if it is already present</b>. This method will return the 069 * resource instance only if it has previously been loaded using {@link #loadResource(IRestfulClient)} or it was 070 * contained within the resource containing this resource. 071 * 072 * See the FHIR specification section on <a 073 * href="http://www.hl7.org/implement/standards/fhir/references.html#id">contained resources</a> for more 074 * information. 075 * 076 * @see #loadResource(IRestfulClient) 077 */ 078 @Override 079 public IBaseResource getResource() { 080 return myResource; 081 } 082 083 @Override 084 protected boolean isBaseEmpty() { 085 return super.isBaseEmpty() && myResource == null; 086 } 087 088 /** 089 * Returns the referenced resource, fetching it <b>if it has not already been loaded</b>. This method invokes the 090 * HTTP client to retrieve the resource unless it has already been loaded, or was a contained resource in which case 091 * it is simply returned. 092 */ 093 public IBaseResource loadResource(IRestfulClient theClient) { 094 if (myResource != null) { 095 return myResource; 096 } 097 098 IdDt resourceId = getReference(); 099 if (resourceId == null || isBlank(resourceId.getValue())) { 100 throw new IllegalStateException("Reference has no resource ID defined"); 101 } 102 if (isBlank(resourceId.getBaseUrl()) || isBlank(resourceId.getResourceType())) { 103 throw new IllegalStateException("Reference is not complete (must be in the form [baseUrl]/[resource type]/[resource ID]) - Reference is: " + resourceId.getValue()); 104 } 105 106 String resourceUrl = resourceId.getValue(); 107 108 ourLog.debug("Loading resource at URL: {}", resourceUrl); 109 110 RuntimeResourceDefinition definition = theClient.getFhirContext().getResourceDefinition(resourceId.getResourceType()); 111 Class<? extends IBaseResource> resourceType = definition.getImplementingClass(); 112 myResource = theClient.fetchResourceFromUrl(resourceType, resourceUrl); 113 myResource.setId(resourceUrl); 114 return myResource; 115 } 116 117 public abstract BaseResourceReferenceDt setReference(IdDt theReference); 118 119 public BaseResourceReferenceDt setReference(IIdType theReference) { 120 if (theReference instanceof IdDt) { 121 setReference((IdDt) theReference); 122 } else if (theReference != null) { 123 setReference(new IdDt(theReference.getValue())); 124 } else { 125 setReference((IdDt) null); 126 } 127 return this; 128 } 129 130 @Override 131 public BaseResourceReferenceDt setResource(IBaseResource theResource) { 132 myResource = theResource; 133 return this; 134 } 135 136 @Override 137 public String toString() { 138 org.apache.commons.lang3.builder.ToStringBuilder b = new org.apache.commons.lang3.builder.ToStringBuilder(this, org.apache.commons.lang3.builder.ToStringStyle.SHORT_PREFIX_STYLE); 139 b.append("reference", getReference().getValueAsString()); 140 b.append("loaded", getResource() != null); 141 return b.toString(); 142 } 143 144}