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}