001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.http.annotation;
018
019import static java.lang.annotation.ElementType.*;
020import static java.lang.annotation.RetentionPolicy.*;
021
022import java.lang.annotation.*;
023
024/**
025 * REST has-form-data annotation.
026 *
027 * Identifies whether or not an HTTP request has the specified multipart form POST parameter.
028 *
029 * <p>
030 * Can be used in the following locations:
031 * <ul>
032 *    <li>Arguments and argument-types of server-side <ja>@RestOp</ja>-annotated methods.
033 * </ul>
034 * <p>
035 *    This annotation can be used to detect the existence of a parameter when it's not set to a particular value.
036 * </p>
037 *
038 * <h5 class='figure'>Example:</h5>
039 * <p class='bjava'>
040 *    <ja>@RestPost</ja>
041 *    <jk>public void</jk> doPost(<ja>@HasFormData</ja>(<js>"p1"</js>) <jk>boolean</jk> <jv>p1</jv>) {...}
042 * </p>
043 * <p>
044 *    This is functionally equivalent to the following code:
045 * </p>
046 * <p class='bjava'>
047 *    <ja>@RestPost</ja>
048 *    <jk>public void</jk> doPost(RestRequest <jv>req</jv>) {
049 *       <jk>boolean</jk> <jv>p1</jv> = <jv>req</jv>.getFormParam(<js>"p1"</js>).isPresent();
050 *       ...
051 *    }
052 * </p>
053 * <p>
054 *    The parameter type must be either <jk>boolean</jk> or {@link java.lang.Boolean}.
055 * </p>
056 * <p>
057 *    The following table shows the behavioral differences between <ja>@HasFormData</ja> and <ja>@FormData</ja>:
058 * </p>
059 * <table class='styled w400'>
060 *    <tr>
061 *       <th><c>Body content</c></th>
062 *       <th><c><ja>@HasFormData</ja>(<js>"a"</js>)</c></th>
063 *       <th><c><ja>@FormData</ja>(<js>"a"</js>)</c></th>
064 *    </tr>
065 *    <tr>
066 *       <td><c>a=foo</c></td>
067 *       <td><jk>true</jk></td>
068 *       <td><js>"foo"</js></td>
069 *    </tr>
070 *    <tr>
071 *       <td><c>a=</c></td>
072 *       <td><jk>true</jk></td>
073 *       <td><js>""</js></td>
074 *    </tr>
075 *    <tr>
076 *       <td><c>a</c></td>
077 *       <td><jk>true</jk></td>
078 *       <td><jk>null</jk></td>
079 *    </tr>
080 *    <tr>
081 *       <td><c>b=foo</c></td>
082 *       <td><jk>false</jk></td>
083 *       <td><jk>null</jk></td>
084 *    </tr>
085 * </table>
086 *
087 * <h5 class='topic'>Important note concerning FORM posts</h5>
088 * <p>
089 *    This annotation should not be combined with the {@link Content @Content} annotation or {@code RestRequest.getContent()} method
090 *    for <c>application/x-www-form-urlencoded POST</c> posts, since it will trigger the underlying servlet API to
091 *    parse the body content as key-value pairs, resulting in empty content.
092 * </p>
093 * <p>
094 *    The {@link HasQuery @HasQuery} annotation can be used to check for the existing of a URL parameter in the URL string
095 *    without triggering the servlet to drain the body content.
096 * </p>
097 *
098 * <p>
099 * <h5 class='section'>See Also:</h5><ul>
100
101 * </ul>
102 */
103@Documented
104@Target({PARAMETER})
105@Retention(RUNTIME)
106@Inherited
107public @interface HasFormData {
108
109    /**
110     * Optional description for the exposed API.
111     *
112     * @return The annotation value.
113     * @since 9.2.0
114     */
115    String[] description() default {};
116
117    /**
118    * FORM parameter name.
119    *
120    * Required. The name of the parameter. Parameter names are case sensitive.
121    *
122    * <h5 class='section'>Notes:</h5><ul>
123    *    <li class='note'>
124    *       The format is plain-text.
125    * </ul>
126    *
127    * @return The annotation value.
128    */
129   String name() default "";
130
131   /**
132    * A synonym for {@link #name()}.
133    *
134    * <p>
135    * Allows you to use shortened notation if you're only specifying the name.
136    *
137    * <p>
138    * The following are completely equivalent ways of defining the existence of a form post entry:
139    * <p class='bjava'>
140    *    <jk>public</jk> Order placeOrder(<ja>@HasFormData</ja>(name=<js>"petId"</js>) <jk>boolean</jk> <jv>hasPetId</jv>) {...}
141    * </p>
142    * <p class='bjava'>
143    *    <jk>public</jk> Order placeOrder(<ja>@HasFormData</ja>(<js>"petId"</js>) <jk>boolean</jk> <jv>hasPetId</jv>) {...}
144    * </p>
145    *
146    * @return The annotation value.
147    */
148   String value() default "";
149}