001package ca.uhn.fhir.rest.server.exceptions;
002
003import java.util.LinkedHashSet;
004import java.util.Set;
005
006import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
007
008import ca.uhn.fhir.rest.api.Constants;
009import ca.uhn.fhir.rest.api.RequestTypeEnum;
010
011/*
012 * #%L
013 * HAPI FHIR - Core Library
014 * %%
015 * Copyright (C) 2014 - 2021 Smile CDR, Inc.
016 * %%
017 * Licensed under the Apache License, Version 2.0 (the "License");
018 * you may not use this file except in compliance with the License.
019 * You may obtain a copy of the License at
020 *
021 * http://www.apache.org/licenses/LICENSE-2.0
022 *
023 * Unless required by applicable law or agreed to in writing, software
024 * distributed under the License is distributed on an "AS IS" BASIS,
025 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
026 * See the License for the specific language governing permissions and
027 * limitations under the License.
028 * #L%
029 */
030
031/**
032 * Represents an <b>HTTP 405 Method Not Allowed</b> response.
033 * 
034 * <p>
035 * Note that a complete list of RESTful exceptions is available in the <a href="./package-summary.html">Package Summary</a>.
036 * </p>
037 * 
038 * @see UnprocessableEntityException Which should be used for business level validation failures
039 */
040public class MethodNotAllowedException extends BaseServerResponseException {
041        private static final long serialVersionUID = 1L;
042        public static final int STATUS_CODE = Constants.STATUS_HTTP_405_METHOD_NOT_ALLOWED;
043        private Set<RequestTypeEnum> myAllowedMethods;
044
045        /**
046         * Constructor
047         * 
048         * @param theMessage
049         *           The message
050         * @param theOperationOutcome
051         *           The OperationOutcome resource to return to the client
052         * @param theAllowedMethods
053         *           A list of allowed methods (see {@link #setAllowedMethods(RequestTypeEnum...)} )
054         */
055        public MethodNotAllowedException(String theMessage, IBaseOperationOutcome theOperationOutcome, RequestTypeEnum... theAllowedMethods) {
056                super(STATUS_CODE, theMessage, theOperationOutcome);
057                setAllowedMethods(theAllowedMethods);
058        }
059
060        /**
061         * Constructor
062         * 
063         * @param theMessage
064         *           The message
065         * @param theAllowedMethods
066         *           A list of allowed methods (see {@link #setAllowedMethods(RequestTypeEnum...)} )
067         */
068        public MethodNotAllowedException(String theMessage, RequestTypeEnum... theAllowedMethods) {
069                super(STATUS_CODE, theMessage);
070                setAllowedMethods(theAllowedMethods);
071        }
072
073        /**
074         * Constructor
075         * 
076         * @param theMessage
077         *           The message
078         * @param theOperationOutcome
079         *           The OperationOutcome resource to return to the client
080         */
081        public MethodNotAllowedException(String theMessage, IBaseOperationOutcome theOperationOutcome) {
082                super(STATUS_CODE, theMessage, theOperationOutcome);
083        }
084
085        /**
086         * Constructor
087         * 
088         * @param theMessage
089         *           The message
090         */
091        public MethodNotAllowedException(String theMessage) {
092                super(STATUS_CODE, theMessage);
093        }
094
095        /**
096         * Specifies the list of allowed HTTP methods (GET, POST, etc). This is provided in an <code>Allow</code> header, as required by the HTTP specification (RFC 2616).
097         */
098        public Set<RequestTypeEnum> getAllowedMethods() {
099                return myAllowedMethods;
100        }
101
102        /**
103         * Specifies the list of allowed HTTP methods (GET, POST, etc). This is provided in an <code>Allow</code> header, as required by the HTTP specification (RFC 2616).
104         */
105        public void setAllowedMethods(RequestTypeEnum... theAllowedMethods) {
106                if (theAllowedMethods == null || theAllowedMethods.length == 0) {
107                        myAllowedMethods = null;
108                } else {
109                        myAllowedMethods = new LinkedHashSet<RequestTypeEnum>();
110                        for (RequestTypeEnum next : theAllowedMethods) {
111                                myAllowedMethods.add(next);
112                        }
113                }
114                updateAllowHeader();
115        }
116
117        /**
118         * Specifies the list of allowed HTTP methods (GET, POST, etc). This is provided in an <code>Allow</code> header, as required by the HTTP specification (RFC 2616).
119         */
120        public void setAllowedMethods(Set<RequestTypeEnum> theAllowedMethods) {
121                myAllowedMethods = theAllowedMethods;
122                updateAllowHeader();
123        }
124
125        private void updateAllowHeader() {
126                getResponseHeaders().remove(Constants.HEADER_ALLOW);
127
128                StringBuilder b = new StringBuilder();
129                for (RequestTypeEnum next : myAllowedMethods) {
130                        if (b.length() > 0) {
131                                b.append(',');
132                        }
133                        b.append(next.name());
134                }
135                addResponseHeader(Constants.HEADER_ALLOW, b.toString());
136        }
137
138}