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.annotation;
021
022import ca.uhn.fhir.model.valueset.BundleTypeEnum;
023import org.hl7.fhir.instance.model.api.IBaseResource;
024
025import java.lang.annotation.ElementType;
026import java.lang.annotation.Retention;
027import java.lang.annotation.RetentionPolicy;
028import java.lang.annotation.Target;
029
030/**
031 * RESTful method annotation used for a method which provides FHIR "operations".
032 */
033@Retention(RetentionPolicy.RUNTIME)
034@Target(value = ElementType.METHOD)
035public @interface Operation {
036
037        /**
038         * This constant is a special return value for {@link #name()}. If this name is
039         * used, the given operation method will match all operation calls. This is
040         * generally not desirable, but can be useful if you have a server that should
041         * dynamically match any FHIR operations that are requested.
042         */
043        String NAME_MATCH_ALL = "*";
044
045        /**
046         * The name of the operation, e.g. "<code>$everything</code>"
047         *
048         * <p>
049         * This may be specified with or without a leading
050         * '$'. (If the leading '$' is omitted, it will be added internally by the API).
051         * </p>
052         */
053        String name();
054
055        /**
056         * This value may be populated with the resource type that the operation applies to. If set to
057         * {@link IBaseResource} (which is the default) than the operation applies to the server and not to a specific
058         * resource type.
059         * <p>
060         * This attribute should not be used a resource provider implementing
061         * <code>IResourceProvider</code> since the type can be inferred from the
062         * resource provider type.
063         * </p>
064         * @see #typeName() may also be used to specify a value as a String
065         */
066        Class<? extends IBaseResource> type() default IBaseResource.class;
067
068        /**
069         * This value may be populated with the resource type that the operation applies to. If set to
070         * {@link IBaseResource} (which is the default) than the operation applies to the server and not to a specific
071         * resource type.
072         * <p>
073         * This attribute should not be used a resource provider implementing
074         * <code>IResourceProvider</code> since the type can be inferred from the
075         * resource provider type.
076         * </p>
077         * @see #type() may also be used to specify a value for this setting as a class type
078         */
079        String typeName() default "";
080
081        /**
082         * If a given operation method is <b><a href="http://en.wikipedia.org/wiki/Idempotence">idempotent</a></b>
083         * (meaning roughly that it does not modify any data or state on the server)
084         * then this flag should be set to <code>true</code> (default is <code>false</code>).
085         * <p>
086         * One the server, setting this to <code>true</code> means that the
087         * server will allow the operation to be invoked using an <code>HTTP GET</code>
088         * (on top of the standard <code>HTTP POST</code>)
089         * </p>
090         */
091        boolean idempotent() default false;
092
093        /**
094         * To support cancelling of a job,
095         * this flag should be set to <code>true</code> (default is <code>false</code>).
096         * <p>
097         * The server, when setting this to <code>true</code>,
098         * will allow the operation to be invoked using an <code>HTTP DELETE</code>
099         * (on top of the standard <code>HTTP POST</code>)
100         * </p>
101         */
102        boolean deleteEnabled() default false;
103
104        /**
105         * This parameter may be used to specify the parts which will be found in the
106         * response to this operation.
107         */
108        OperationParam[] returnParameters() default {};
109
110        /**
111         * If this operation returns a bundle, this parameter can be used to specify the
112         * bundle type to set in the bundle.
113         */
114        BundleTypeEnum bundleType() default BundleTypeEnum.COLLECTION;
115
116        /**
117         * If this is set to <code>true</code> (default is <code>false</code> and this is almost
118         * always the right choice), the framework will not attempt to generate a response to
119         * this method.
120         * <p>
121         * This is useful if you want to include an {@link jakarta.servlet.http.HttpServletResponse}
122         * in your method parameters and create a response yourself directly from your
123         * <code>@Operation</code> method.
124         * </p>
125         * <p>
126         * Note that this will mean that interceptor methods will not get fired for the
127         * response, so there are security implications to using this flag.
128         * </p>
129         */
130        boolean manualResponse() default false;
131
132        /**
133         * If this is set to <code>true</code> (default is <code>false</code> and this is almost
134         * always the right choice), the framework will not attempt to parse the request body,
135         * but will instead delegate it to the <code>@Operation</code> method.
136         * <p>
137         * This is useful if you want to include an {@link jakarta.servlet.http.HttpServletRequest}
138         * in your method parameters and parse the request yourself.
139         * </p>
140         */
141        boolean manualRequest() default false;
142
143        /**
144         * If this is set to <code>true</code>, this method will be a <b>global operation</b>
145         * meaning that it applies to all resource types. Operations with this flag set should be
146         * placed in Plain Providers (i.e. they don't need to be placed in a resource-type-specific
147         * <code>IResourceProvider</code> instance) and should have a parameter annotated with
148         * {@link IdParam}.
149         */
150        boolean global() default false;
151
152        /**
153         * The canonical URL of the operation, e.g. "http://hl7.org/fhir/us/davinci-hrex/OperationDefinition/member-match|1.0.0"
154         *
155         * <p>
156         * This may be specified with or without a version. e.g. @Operation(name = "$everything", canonicalUrl = "http://hl7.org/fhir/OperationDefinition/Patient-everything")
157         * or @Operation(name = "$member-match", canonicalUrl = "http://hl7.org/fhir/us/davinci-hrex/OperationDefinition/member-match|1.0.0")
158         * </p>
159         */
160        String canonicalUrl() default "";
161}