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 */
100@Documented
101@Target({ PARAMETER })
102@Retention(RUNTIME)
103@Inherited
104public @interface HasFormData {
105
106   /**
107    * Optional description for the exposed API.
108    *
109    * @return The annotation value.
110    * @since 9.2.0
111    */
112   String[] description() default {};
113
114   /**
115    * FORM parameter name.
116    *
117    * Required. The name of the parameter. Parameter names are case sensitive.
118    *
119    * <h5 class='section'>Notes:</h5><ul>
120    *    <li class='note'>
121    *       The format is plain-text.
122    * </ul>
123    *
124    * @return The annotation value.
125    */
126   String name() default "";
127
128   /**
129    * A synonym for {@link #name()}.
130    *
131    * <p>
132    * Allows you to use shortened notation if you're only specifying the name.
133    *
134    * <p>
135    * The following are completely equivalent ways of defining the existence of a form post entry:
136    * <p class='bjava'>
137    *    <jk>public</jk> Order placeOrder(<ja>@HasFormData</ja>(name=<js>"petId"</js>) <jk>boolean</jk> <jv>hasPetId</jv>) {...}
138    * </p>
139    * <p class='bjava'>
140    *    <jk>public</jk> Order placeOrder(<ja>@HasFormData</ja>(<js>"petId"</js>) <jk>boolean</jk> <jv>hasPetId</jv>) {...}
141    * </p>
142    *
143    * @return The annotation value.
144    */
145   String value() default "";
146}