001package ca.uhn.fhir.rest.method; 002 003/* 004 * #%L 005 * HAPI FHIR - Core Library 006 * %% 007 * Copyright (C) 2014 - 2016 University Health Network 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 java.io.IOException; 024import java.io.Reader; 025import java.lang.reflect.Method; 026import java.lang.reflect.Modifier; 027import java.util.List; 028import java.util.Map; 029 030import org.hl7.fhir.instance.model.api.IBaseResource; 031 032import ca.uhn.fhir.context.ConfigurationException; 033import ca.uhn.fhir.context.FhirContext; 034import ca.uhn.fhir.model.api.IResource; 035import ca.uhn.fhir.model.api.TagList; 036import ca.uhn.fhir.model.primitive.IdDt; 037import ca.uhn.fhir.parser.IParser; 038import ca.uhn.fhir.rest.annotation.GetTags; 039import ca.uhn.fhir.rest.annotation.IdParam; 040import ca.uhn.fhir.rest.api.RequestTypeEnum; 041import ca.uhn.fhir.rest.api.RestOperationTypeEnum; 042import ca.uhn.fhir.rest.client.BaseHttpClientInvocation; 043import ca.uhn.fhir.rest.server.Constants; 044import ca.uhn.fhir.rest.server.IResourceProvider; 045import ca.uhn.fhir.rest.server.IRestfulServer; 046import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; 047import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; 048import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; 049 050public class GetTagsMethodBinding extends BaseMethodBinding<TagList> { 051 052 private Integer myIdParamIndex; 053 private String myResourceName; 054 private Class<? extends IBaseResource> myType; 055 private Integer myVersionIdParamIndex; 056 057 public GetTagsMethodBinding(Method theMethod, FhirContext theConetxt, Object theProvider, GetTags theAnnotation) { 058 super(theMethod, theConetxt, theProvider); 059 060 if (theProvider instanceof IResourceProvider) { 061 myType = ((IResourceProvider) theProvider).getResourceType(); 062 } else { 063 myType = theAnnotation.type(); 064 } 065 066 if (!Modifier.isInterface(myType.getModifiers())) { 067 myResourceName = theConetxt.getResourceDefinition(myType).getName(); 068 } 069 070 myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); 071 myVersionIdParamIndex = MethodUtil.findVersionIdParameterIndex(theMethod); 072 073 if (myIdParamIndex != null && myType.equals(IResource.class)) { 074 throw new ConfigurationException("Method '" + theMethod.getName() + "' does not specify a resource type, but has an @" + IdParam.class.getSimpleName() 075 + " parameter. Please specity a resource type in the @" + GetTags.class.getSimpleName() + " annotation"); 076 } 077 } 078 079 @Override 080 public String getResourceName() { 081 return myResourceName; 082 } 083 084 @Override 085 public RestOperationTypeEnum getRestOperationType() { 086 return RestOperationTypeEnum.GET_TAGS; 087 } 088 089 @Override 090 public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { 091 if (theRequest.getRequestType() != RequestTypeEnum.GET) { 092 return false; 093 } 094 if (!Constants.PARAM_TAGS.equals(theRequest.getOperation())) { 095 return false; 096 } 097 if (myResourceName == null) { 098 if (getResourceName() != null) { 099 return false; 100 } 101 } else if (!myResourceName.equals(theRequest.getResourceName())) { 102 return false; 103 104 } 105 if ((myIdParamIndex != null) != (theRequest.getId() != null)) { 106 return false; 107 } 108 // if ((myVersionIdParamIndex != null) != (theRequest.getVersionId() != null)) { 109 // return false; 110 // } 111 return true; 112 } 113 114 @Override 115 public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException { 116 HttpGetClientInvocation retVal; 117 118 IdDt id = null; 119 IdDt versionId = null; 120 if (myIdParamIndex != null) { 121 id = (IdDt) theArgs[myIdParamIndex]; 122 if (myVersionIdParamIndex != null) { 123 versionId = (IdDt) theArgs[myVersionIdParamIndex]; 124 } 125 } 126 127 if (myType != IResource.class) { 128 if (id != null) { 129 if (versionId != null) { 130 retVal = new HttpGetClientInvocation(getResourceName(), id.getIdPart(), Constants.PARAM_HISTORY, versionId.getValue(), Constants.PARAM_TAGS); 131 } else if (id.hasVersionIdPart()) { 132 retVal = new HttpGetClientInvocation(getResourceName(), id.getIdPart(), Constants.PARAM_HISTORY, id.getVersionIdPart(), Constants.PARAM_TAGS); 133 } else { 134 retVal = new HttpGetClientInvocation(getResourceName(), id.getIdPart(), Constants.PARAM_TAGS); 135 } 136 } else { 137 retVal = new HttpGetClientInvocation(getResourceName(), Constants.PARAM_TAGS); 138 } 139 } else { 140 retVal = new HttpGetClientInvocation(Constants.PARAM_TAGS); 141 } 142 143 if (theArgs != null) { 144 for (int idx = 0; idx < theArgs.length; idx++) { 145 IParameter nextParam = getParameters().get(idx); 146 nextParam.translateClientArgumentIntoQueryArgument(getContext(), theArgs[idx], null, null); 147 } 148 } 149 150 return retVal; 151 } 152 153 @Override 154 public TagList invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws BaseServerResponseException { 155 if (theResponseStatusCode == Constants.STATUS_HTTP_200_OK) { 156 IParser parser = createAppropriateParserForParsingResponse(theResponseMimeType, theResponseReader, theResponseStatusCode); 157 TagList retVal = parser.parseTagList(theResponseReader); 158 return retVal; 159 } else { 160 throw processNon2xxResponseAndReturnExceptionToThrow(theResponseStatusCode, theResponseMimeType, theResponseReader); 161 } 162 163 } 164 165 @Override 166 public Object invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException { 167 Object[] params = createParametersForServerRequest(theRequest); 168 169 if (myIdParamIndex != null) { 170 params[myIdParamIndex] = theRequest.getId(); 171 } 172 if (myVersionIdParamIndex != null) { 173 params[myVersionIdParamIndex] = theRequest.getId(); 174 } 175 176 TagList resp = (TagList) invokeServerMethod(theServer, theRequest, params); 177 178 for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) { 179 IServerInterceptor next = theServer.getInterceptors().get(i); 180 boolean continueProcessing = next.outgoingResponse(theRequest, resp); 181 if (!continueProcessing) { 182 return null; 183 } 184 } 185 186 return theRequest.getResponse().returnResponse(ParseAction.create(resp), Constants.STATUS_HTTP_200_OK, false, null, null); 187 } 188 189}