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