package ca.uhn.fhir.model.api;
/*
* #%L
* HAPI FHIR Library
* %%
* Copyright (C) 2014 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 java.io.IOException;
import java.io.Reader;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.client.BaseClient;
import ca.uhn.fhir.rest.client.api.IRestfulClient;
public abstract class BaseResourceReference extends BaseIdentifiableElement {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseResourceReference.class);
private IResource myResource;
/**
* Constructor
* @param theResource
*/
public BaseResourceReference() {
// nothing
}
/**
* Constructor
*
* @param theResource The loaded resource itself
*/
public BaseResourceReference(IResource theResource) {
myResource = theResource;
setReference(theResource.getId());
}
public abstract BaseResourceReference setReference(IdDt theReference);
/**
* Gets the actual loaded and parsed resource instance, <b>if it is already present</b>. This
* method will return the resource instance only if it has previously been loaded using
* {@link #loadResource(IRestfulClient)} or it was contained within the resource containing
* this resource.
*
* @see See {@link #loadResource(IRestfulClient)}
* @see See the FHIR specification section on <a href="http://www.hl7.org/implement/standards/fhir/references.html#id>contained resources</a>
*/
public IResource getResource() {
return myResource;
}
@Override
protected boolean isBaseEmpty() {
return super.isBaseEmpty() && myResource == null;
}
/**
* Returns the referenced resource, fetching it <b>if it has not already been loaded</b>. This method invokes the HTTP client to retrieve the resource unless it has already been loaded, or was a
* contained resource in which case it is simply returned.
*/
public IResource loadResource(IRestfulClient theClient) throws IOException {
if (myResource != null) {
return myResource;
}
IdDt resourceId = getReference();
if (resourceId == null) {
throw new IllegalStateException("Reference has no resource ID defined");
}
String resourceUrl = resourceId.getValue();
ourLog.debug("Loading resource at URL: {}", resourceUrl);
HttpClient httpClient = theClient.getHttpClient();
FhirContext context = theClient.getFhirContext();
if (!resourceUrl.startsWith("http")) {
resourceUrl = theClient.getServerBase() + resourceUrl;
}
HttpGet get = new HttpGet(resourceUrl);
HttpResponse response = httpClient.execute(get);
try {
// TODO: choose appropriate parser based on response CT
IParser parser = context.newXmlParser();
Reader responseReader = BaseClient.createReaderFromResponse(response);
myResource = parser.parseResource(responseReader);
} finally {
if (response instanceof CloseableHttpResponse) {
((CloseableHttpResponse) response).close();
}
}
return myResource;
}
protected abstract IdDt getReference();
public void setResource(IResource theResource) {
myResource = theResource;
}
}