Package ca.uhn.fhir.rest.client

Source Code of ca.uhn.fhir.rest.client.GenericClient$BundleResponseHandler

package ca.uhn.fhir.rest.client;

/*
* #%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 java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpRequestBase;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Conformance;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
import ca.uhn.fhir.rest.gclient.ICriterion;
import ca.uhn.fhir.rest.gclient.ICriterionInternal;
import ca.uhn.fhir.rest.gclient.IParam;
import ca.uhn.fhir.rest.gclient.IQuery;
import ca.uhn.fhir.rest.gclient.ISort;
import ca.uhn.fhir.rest.gclient.IUntypedQuery;
import ca.uhn.fhir.rest.gclient.Include;
import ca.uhn.fhir.rest.method.BaseOutcomeReturningMethodBinding;
import ca.uhn.fhir.rest.method.ConformanceMethodBinding;
import ca.uhn.fhir.rest.method.CreateMethodBinding;
import ca.uhn.fhir.rest.method.DeleteMethodBinding;
import ca.uhn.fhir.rest.method.HistoryMethodBinding;
import ca.uhn.fhir.rest.method.IClientResponseHandler;
import ca.uhn.fhir.rest.method.ReadMethodBinding;
import ca.uhn.fhir.rest.method.SearchMethodBinding;
import ca.uhn.fhir.rest.method.UpdateMethodBinding;
import ca.uhn.fhir.rest.method.ValidateMethodBinding;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;

public class GenericClient extends BaseClient implements IGenericClient {

  private FhirContext myContext;

  private HttpRequestBase myLastRequest;

  /**
   * For now, this is a part of the internal API of HAPI - Use with caution as this method may change!
   */
  public GenericClient(FhirContext theContext, HttpClient theHttpClient, String theServerBase) {
    super(theHttpClient, theServerBase);
    myContext = theContext;
  }

  @Override
  public Conformance conformance() {
    GetClientInvocation invocation = ConformanceMethodBinding.createConformanceInvocation();
    if (isKeepResponses()) {
      myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
    }

    ResourceResponseHandler<Conformance> binding = new ResourceResponseHandler<Conformance>(Conformance.class);
    Conformance resp = invokeClient(binding, invocation);
    return resp;
  }

  @Override
  public MethodOutcome create(IResource theResource) {
    BaseClientInvocation invocation = CreateMethodBinding.createCreateInvocation(theResource, myContext);
    if (isKeepResponses()) {
      myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
    }

    RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
    final String resourceName = def.getName();

    OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName);

    MethodOutcome resp = invokeClient(binding, invocation);
    return resp;

  }

  @Override
  public MethodOutcome delete(final Class<? extends IResource> theType, IdDt theId) {
    DeleteClientInvocation invocation = DeleteMethodBinding.createDeleteInvocation(toResourceName(theType), theId);
    if (isKeepResponses()) {
      myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
    }

    final String resourceName = myContext.getResourceDefinition(theType).getName();
    OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName);
    MethodOutcome resp = invokeClient(binding, invocation);
    return resp;
  }

  @Override
  public MethodOutcome delete(Class<? extends IResource> theType, String theId) {
    return delete(theType, new IdDt(theId));
  }

  public HttpRequestBase getLastRequest() {
    return myLastRequest;
  }

  @Override
  public <T extends IResource> Bundle history(final Class<T> theType, IdDt theIdDt) {
    GetClientInvocation invocation = HistoryMethodBinding.createHistoryInvocation(toResourceName(theType), theIdDt);
    if (isKeepResponses()) {
      myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
    }

    BundleResponseHandler binding = new BundleResponseHandler(theType);
    Bundle resp = invokeClient(binding, invocation);
    return resp;

  }

  @Override
  public <T extends IResource> Bundle history(Class<T> theType, String theId) {
    return history(theType, new IdDt(theId));
  }

  @Override
  public <T extends IResource> T read(final Class<T> theType, IdDt theId) {
    GetClientInvocation invocation = ReadMethodBinding.createReadInvocation(theId, toResourceName(theType));
    if (isKeepResponses()) {
      myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
    }

    ResourceResponseHandler<T> binding = new ResourceResponseHandler<T>(theType);
    T resp = invokeClient(binding, invocation);
    return resp;
  }

  @Override
  public <T extends IResource> T read(Class<T> theType, String theId) {
    return read(theType, new IdDt(theId));
  }

  @Override
  public IUntypedQuery search() {
    return new QueryInternal();
  }

  @Override
  public <T extends IResource> Bundle search(final Class<T> theType, Map<String, List<IQueryParameterType>> theParams) {
    LinkedHashMap<String, List<String>> params = new LinkedHashMap<String, List<String>>();
    for (Entry<String, List<IQueryParameterType>> nextEntry : theParams.entrySet()) {
      ArrayList<String> valueList = new ArrayList<String>();
      params.put(nextEntry.getKey(), valueList);
      for (IQueryParameterType nextValue : nextEntry.getValue()) {
        valueList.add(nextValue.getValueAsQueryToken());
      }
    }

    GetClientInvocation invocation = SearchMethodBinding.createSearchInvocation(toResourceName(theType), params);
    if (isKeepResponses()) {
      myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
    }

    BundleResponseHandler binding = new BundleResponseHandler(theType);
    Bundle resp = invokeClient(binding, invocation);
    return resp;
  }

  /**
   * For now, this is a part of the internal API of HAPI - Use with caution as this method may change!
   */
  public void setLastRequest(HttpRequestBase theLastRequest) {
    myLastRequest = theLastRequest;
  }

  @Override
  public MethodOutcome update(IdDt theIdDt, IResource theResource) {
    BaseClientInvocation invocation = UpdateMethodBinding.createUpdateInvocation(theResource, theIdDt, null, myContext);
    if (isKeepResponses()) {
      myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
    }

    RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
    final String resourceName = def.getName();

    OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName);
    MethodOutcome resp = invokeClient(binding, invocation);
    return resp;
  }

  @Override
  public MethodOutcome update(String theId, IResource theResource) {
    return update(new IdDt(theId), theResource);
  }

  @Override
  public MethodOutcome validate(IResource theResource) {
    BaseClientInvocation invocation = ValidateMethodBinding.createValidateInvocation(theResource, null, myContext);
    if (isKeepResponses()) {
      myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
    }

    RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
    final String resourceName = def.getName();

    OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName);
    MethodOutcome resp = invokeClient(binding, invocation);
    return resp;
  }

  @Override
  public <T extends IResource> T vread(final Class<T> theType, IdDt theId, IdDt theVersionId) {
    GetClientInvocation invocation = ReadMethodBinding.createVReadInvocation(theId, theVersionId, toResourceName(theType));
    if (isKeepResponses()) {
      myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
    }

    ResourceResponseHandler<T> binding = new ResourceResponseHandler<T>(theType);
    T resp = invokeClient(binding, invocation);
    return resp;
  }

  @Override
  public <T extends IResource> T vread(Class<T> theType, String theId, String theVersionId) {
    return vread(theType, new IdDt(theId), new IdDt(theVersionId));
  }

  private String toResourceName(Class<? extends IResource> theType) {
    return myContext.getResourceDefinition(theType).getName();
  }

  private final class OutcomeResponseHandler implements IClientResponseHandler<MethodOutcome> {
    private final String myResourceName;

    private OutcomeResponseHandler(String theResourceName) {
      myResourceName = theResourceName;
    }

    @Override
    public MethodOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException,
        BaseServerResponseException {
      MethodOutcome response = BaseOutcomeReturningMethodBinding.process2xxResponse(myContext, myResourceName, theResponseStatusCode, theResponseMimeType, theResponseReader, theHeaders);
      return response;
    }
  }

  private final class ResourceResponseHandler<T extends IResource> implements IClientResponseHandler<T> {

    private Class<T> myType;

    public ResourceResponseHandler(Class<T> theType) {
      myType = theType;
    }

    @Override
    public T invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
      EncodingEnum respType = EncodingEnum.forContentType(theResponseMimeType);
      IParser parser = respType.newParser(myContext);
      return parser.parseResource(myType, theResponseReader);
    }
  }

  private final class BundleResponseHandler implements IClientResponseHandler<Bundle> {

    private Class<? extends IResource> myType;

    public BundleResponseHandler(Class<? extends IResource> theType) {
      myType = theType;
    }

    @Override
    public Bundle invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException,
        BaseServerResponseException {
      EncodingEnum respType = EncodingEnum.forContentType(theResponseMimeType);
      if (respType == null) {
        throw NonFhirResponseException.newInstance(theResponseStatusCode, theResponseMimeType, theResponseReader);
      }
      IParser parser = respType.newParser(myContext);
      return parser.parseBundle(myType, theResponseReader);
    }
  }

  private class ForInternal implements IQuery {

    private List<ICriterionInternal> myCriterion = new ArrayList<ICriterionInternal>();
    private List<Include> myInclude = new ArrayList<Include>();
    private boolean myLogRequestAndResponse;
    private EncodingEnum myParamEncoding;
    private Integer myParamLimit;
    private String myResourceName;
    private Class<? extends IResource> myResourceType;
    private List<SortInternal> mySort = new ArrayList<SortInternal>();

    public ForInternal(Class<? extends IResource> theResourceType) {
      myResourceType = theResourceType;
      myResourceName = myContext.getResourceDefinition(theResourceType).getName();
    }

    public ForInternal(String theResourceName) {
      myResourceType = myContext.getResourceDefinition(theResourceName).getImplementingClass();
      myResourceName = theResourceName;
    }

    @Override
    public IQuery and(ICriterion theCriterion) {
      myCriterion.add((ICriterionInternal) theCriterion);
      return this;
    }

    @Override
    public IQuery andLogRequestAndResponse(boolean theLogRequestAndResponse) {
      myLogRequestAndResponse = theLogRequestAndResponse;
      return this;
    }

    @Override
    public IQuery encodedJson() {
      myParamEncoding = EncodingEnum.JSON;
      return this;
    }

    @Override
    public IQuery encodedXml() {
      myParamEncoding = EncodingEnum.XML;
      return null;
    }

    @Override
    public Bundle execute() {

      StringBuilder b = new StringBuilder();
      b.append(getServerBase());
      b.append('/');
      b.append(myResourceType);
      b.append('?');

      Map<String, List<String>> params = new LinkedHashMap<String, List<String>>();
      for (ICriterionInternal next : myCriterion) {
        String parameterName = next.getParameterName();
        String parameterValue = next.getParameterValue();
        addParam(params, parameterName, parameterValue);
      }

      for (Include next : myInclude) {
        addParam(params, Constants.PARAM_INCLUDE, next.getInclude());
      }

      for (SortInternal next : mySort) {
        addParam(params, next.getParamName(), next.getParamValue());
      }

      if (myParamEncoding != null) {
        addParam(params, Constants.PARAM_FORMAT, myParamEncoding.getFormatContentType());
      }

      if (myParamLimit != null) {
        addParam(params, Constants.PARAM_COUNT, Integer.toString(myParamLimit));
      }

      GetClientInvocation invocation = new GetClientInvocation(params, myResourceName);
      if (isKeepResponses()) {
        myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
      }

      BundleResponseHandler binding = new BundleResponseHandler(myResourceType);

      Bundle resp = invokeClient(binding, invocation, myLogRequestAndResponse);
      return resp;

    }

    @Override
    public IQuery include(Include theInclude) {
      myInclude.add(theInclude);
      return this;
    }

    @Override
    public IQuery limitTo(int theLimitTo) {
      if (theLimitTo > 0) {
        myParamLimit = theLimitTo;
      } else {
        myParamLimit = null;
      }
      return this;
    }

    @Override
    public ISort sort() {
      SortInternal retVal = new SortInternal(this);
      mySort.add(retVal);
      return retVal;
    }

    @Override
    public IQuery where(ICriterion theCriterion) {
      myCriterion.add((ICriterionInternal) theCriterion);
      return this;
    }

    private void addParam(Map<String, List<String>> params, String parameterName, String parameterValue) {
      if (!params.containsKey(parameterName)) {
        params.put(parameterName, new ArrayList<String>());
      }
      params.get(parameterName).add(parameterValue);
    }

  }

  private class QueryInternal implements IUntypedQuery {

    @Override
    public IQuery forResource(Class<? extends IResource> theResourceType) {
      return new ForInternal(theResourceType);
    }

    @Override
    public IQuery forResource(String theResourceName) {
      return new ForInternal(theResourceName);
    }

  }

  private class SortInternal implements ISort {

    private ForInternal myFor;
    private String myParamName;
    private String myParamValue;

    public SortInternal(ForInternal theFor) {
      myFor = theFor;
    }

    @Override
    public IQuery ascending(IParam theParam) {
      myParamName = Constants.PARAM_SORT_ASC;
      myParamValue = theParam.getParamName();
      return myFor;
    }

    @Override
    public IQuery defaultOrder(IParam theParam) {
      myParamName = Constants.PARAM_SORT;
      myParamValue = theParam.getParamName();
      return myFor;
    }

    @Override
    public IQuery descending(IParam theParam) {
      myParamName = Constants.PARAM_SORT_DESC;
      myParamValue = theParam.getParamName();
      return myFor;
    }

    public String getParamName() {
      return myParamName;
    }

    public String getParamValue() {
      return myParamValue;
    }

  }

}
TOP

Related Classes of ca.uhn.fhir.rest.client.GenericClient$BundleResponseHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.