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-query-parameter annotation.
026 *
027 * <p>
028 * Identifies whether or not an HTTP request has the specified query parameter.
029 *
030 * <p>
031 * Can be used in the following locations:
032 * <ul>
033 *    <li>Arguments and argument-types of server-side <ja>@RestOp</ja>-annotated methods.
034 * </ul>
035 * <p>
036 *    Identical to {@link HasFormData @HasFormData}, but only checks the existing of the parameter in the URL string, not
037 *    URL-encoded form posts.
038 * </p>
039 * <p>
040 *    Unlike {@link HasFormData @HasFormData}, using this annotation does not result in the servlet reading the contents
041 *    of URL-encoded form posts.
042 *    Therefore, this annotation can be used in conjunction with the {@link Content @Cpmtemt} annotation or
043 *    {@code RestRequest.getContent()} method for <c>application/x-www-form-urlencoded POST</c> calls.
044 *  </p>
045 * <h5 class='figure'>Example:</h5>
046 * <p class='bjava'>
047 *    <ja>@RestGet</ja>
048 *    <jk>public void</jk> doGet(<ja>@HasQuery</ja>(<js>"p1"</js>) <jk>boolean</jk> <jv>p1</jv>) {...}
049 * </p>
050 * <p>
051 *    This is functionally equivalent to the following code:
052 * </p>
053 * <p class='bjava'>
054 *    <ja>@RestGet</ja>
055 *    <jk>public void</jk> doGet(RestRequest <jv>req</jv>) {
056 *       <jk>boolean</jk> <jv>p1</jv> = <jv>req</jv>.getQueryParam(<js>"p1"</js>).isPresent();
057 *       ...
058 *    }
059 * </p>
060 * <p>
061 *    The parameter type must be either <jk>boolean</jk> or {@link java.lang.Boolean}.
062 * </p>
063 * <p>
064 *    The following table shows the behavioral differences between <ja>@HasQuery</ja> and <ja>@Query</ja>:
065 * </p>
066 * <table class='styled w400'>
067 *    <tr>
068 *       <th><c>Query content</c></th>
069 *       <th><c><ja>@HasQuery</ja>(<js>"a"</js>)</c></th>
070 *       <th><c><ja>@Query</ja>(<js>"a"</js>)</c></th>
071 *    </tr>
072 *    <tr>
073 *       <td><c>?a=foo</c></td>
074 *       <td><jk>true</jk></td>
075 *       <td><js>"foo"</js></td>
076 *    </tr>
077 *    <tr>
078 *       <td><c>?a=</c></td>
079 *       <td><jk>true</jk></td>
080 *       <td><js>""</js></td>
081 *    </tr>
082 *    <tr>
083 *       <td><c>?a</c></td>
084 *       <td><jk>true</jk></td>
085 *       <td><jk>null</jk></td>
086 *    </tr>
087 *    <tr>
088 *       <td><c>?b=foo</c></td>
089 *       <td><jk>false</jk></td>
090 *       <td><jk>null</jk></td>
091 *    </tr>
092 * </table>
093 * <p>
094 * <h5 class='section'>See Also:</h5><ul>
095
096 * </ul>
097 */
098@Documented
099@Target({PARAMETER})
100@Retention(RUNTIME)
101@Inherited
102public @interface HasQuery {
103
104    /**
105     * Optional description for the exposed API.
106     *
107     * @return The annotation value.
108     * @since 9.2.0
109     */
110    String[] description() default {};
111
112    /**
113    * URL query parameter name.
114    *
115    * Required. The name of the parameter. Parameter names are case sensitive.
116    *
117    * <h5 class='section'>Notes:</h5><ul>
118    *    <li class='note'>
119    *       The format is plain-text.
120    * </ul>
121    *
122    * @return The annotation value.
123    */
124   String name() default "";
125
126   /**
127    * A synonym for {@link #name()}.
128    *
129    * <p>
130    * Allows you to use shortened notation if you're only specifying the name.
131    *
132    * <p>
133    * The following are completely equivalent ways of defining the existence of a query entry:
134    * <p class='bjava'>
135    *    <jk>public</jk> Order placeOrder(<ja>@HasQuery</ja>(name=<js>"petId"</js>) <jk>boolean</jk> <jv>hasPetId</jv>) {...}
136    * </p>
137    * <p class='bjava'>
138    *    <jk>public</jk> Order placeOrder(<ja>@HasQuery</ja>(<js>"petId"</js>) <jk>boolean</jk> <jv>hasPetId</jv>) {...}
139    * </p>
140    *
141    * @return The annotation value.
142    */
143   String value() default "";
144}