001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.remoteable;
014
015import static java.lang.annotation.ElementType.*;
016import static java.lang.annotation.RetentionPolicy.*;
017
018import java.lang.annotation.*;
019
020import org.apache.juneau.httppart.*;
021import org.apache.juneau.urlencoding.*;
022
023/**
024 * Annotation applied to Java method arguments of interface proxies to denote that they are QUERY parameters on the
025 * request.
026 * 
027 * <h5 class='section'>Example:</h5>
028 * <p class='bcode'>
029 *    <ja>@Remoteable</ja>(path=<js>"/myproxy"</js>)
030 *    <jk>public interface</jk> MyProxy {
031 * 
032 *       <jc>// Explicit names specified for query parameters.</jc>
033 *       <jc>// pojo will be converted to UON notation (unless plain-text parts enabled).</jc>
034 *       <ja>@RemoteMethod</ja>(path=<js>"/mymethod1"</js>)
035 *       String myProxyMethod1(<ja>@Query</ja>(<js>"foo"</js>)</ja> String foo,
036 *          <ja>@Query</ja>(<js>"bar"</js>)</ja> MyPojo pojo);
037 * 
038 *       <jc>// Multiple values pulled from a NameValuePairs object.</jc>
039 *       <jc>// Same as @Query("*").</jc>
040 *       <ja>@RemoteMethod</ja>(path=<js>"/mymethod2"</js>)
041 *       String myProxyMethod2(<ja>@Query</ja> NameValuePairs nameValuePairs);
042 * 
043 *       <jc>// Multiple values pulled from a Map.</jc>
044 *       <jc>// Same as @Query("*").</jc>
045 *       <ja>@RemoteMethod</ja>(path=<js>"/mymethod3"</js>)
046 *       String myProxyMethod3(<ja>@Query</ja> Map&lt;String,Object&gt; map);
047 * 
048 *       <jc>// Multiple values pulled from a bean.</jc>
049 *       <jc>// Same as @Query("*").</jc>
050 *       <ja>@RemoteMethod</ja>(path=<js>"/mymethod4"</js>)
051 *       String myProxyMethod4(<ja>@Query</ja> MyBean myBean);
052 * 
053 *       <jc>// An entire query string as a String.</jc>
054 *       <jc>// Same as @FQuery("*").</jc>
055 *       <ja>@RemoteMethod</ja>(path=<js>"/mymethod5"</js>)
056 *       String myProxyMethod5(<ja>@Query</ja> String string);
057 * 
058 *       <jc>// An entire query string as a Reader.</jc>
059 *       <jc>// Same as @Query("*").</jc>
060 *       <ja>@RemoteMethod</ja>(path=<js>"/mymethod6"</js>)
061 *       String myProxyMethod6(<ja>@Query</ja> Reader reader);
062 *    }
063 * </p>
064 * 
065 * <p>
066 * The annotation can also be applied to a bean property field or getter when the argument is annotated with
067 * {@link RequestBean @RequestBean}:
068 * 
069 * <h5 class='section'>Example:</h5>
070 * <p class='bcode'>
071 *    <ja>@Remoteable</ja>(path=<js>"/myproxy"</js>)
072 *    <jk>public interface</jk> MyProxy {
073 * 
074 *       <ja>@RemoteMethod</ja>(path=<js>"/mymethod"</js>)
075 *       String myProxyMethod(<ja>@RequestBean</ja> MyRequestBean bean);
076 *    }
077 * 
078 *    <jk>public interface</jk> MyRequestBean {
079 * 
080 *       <jc>// Name explicitly specified.</jc>
081 *       <ja>@Query</ja>(<js>"foo"</js>)
082 *       String getX();
083 * 
084 *       <jc>// Name inherited from bean property.</jc>
085 *       <jc>// Same as @Query("bar")</jc>
086 *       <ja>@Query</ja>
087 *       String getBar();
088 * 
089 *       <jc>// Name inherited from bean property.</jc>
090 *       <jc>// Same as @Query("baz")</jc>
091 *       <ja>@Query</ja>
092 *       <ja>@BeanProperty</ja>(<js>"baz"</js>)
093 *       String getY();
094 * 
095 *       <jc>// Multiple values pulled from NameValuePairs object.</jc>
096 *       <jc>// Same as @Query("*")</jc>
097 *       <ja>@Query</ja>
098 *       NameValuePairs getNameValuePairs();
099 * 
100 *       <jc>// Multiple values pulled from Map.</jc>
101 *       <jc>// Same as @Query("*")</jc>
102 *       <ja>@Query</ja>
103 *       Map&lt;String,Object&gt; getMap();
104 * 
105 *       <jc>// Multiple values pulled from bean.</jc>
106 *       <jc>// Same as @Query("*")</jc>
107 *       <ja>@Query</ja>
108 *       MyBean getMyBean();
109 * 
110 *       <jc>// An entire query string as a Reader.</jc>
111 *       <jc>// Same as @Query("*")</jc>
112 *       <ja>@Query</ja>
113 *       Reader getReader();
114 *    }
115 * </p>
116 * 
117 * <p>
118 * The {@link #name()} and {@link #value()} elements are synonyms for specifying the parameter name.
119 * Only one should be used.
120 * <br>The following annotations are fully equivalent:
121 * <p class='bcode'>
122 *    <ja>@Query</ja>(name=<js>"foo"</js>)
123 * 
124 *    <ja>@Query</ja>(<js>"foo"</js>)
125 * </p>
126 * 
127 * <h5 class='section'>See Also:</h5>
128 * <ul class='doctree'>
129 *    <li class='link'><a class='doclink' href='../../../../overview-summary.html#juneau-rest-client.3rdPartyProxies'>Overview &gt; juneau-rest-client &gt; Interface Proxies Against 3rd-party REST Interfaces</a>
130 * </ul>
131 */
132@Documented
133@Target({PARAMETER,FIELD,METHOD})
134@Retention(RUNTIME)
135@Inherited
136public @interface Query {
137
138   /**
139    * The query parameter name.
140    * 
141    * <p>
142    * Note that {@link #name()} and {@link #value()} are synonyms.
143    * 
144    * <p>
145    * The value should be either <js>"*"</js> to represent multiple name/value pairs, or a label that defines the
146    * query parameter name.
147    * 
148    * <p>
149    * A blank value (the default) has the following behavior:
150    * <ul class='spaced-list'>
151    *    <li>
152    *       If the data type is <code>NameValuePairs</code>, <code>Map</code>, or a bean,
153    *       then it's the equivalent to <js>"*"</js> which will cause the value to be serialized as name/value pairs.
154    * 
155    *       <h5 class='figure'>Example:</h5>
156    *       <p class='bcode'>
157    *    <jc>// When used on a remote method parameter</jc>
158    *    <ja>@Remoteable</ja>(path=<js>"/myproxy"</js>)
159    *    <jk>public interface</jk> MyProxy {
160    * 
161    *       <jc>// Equivalent to @Query("*")</jc>
162    *       <ja>@RemoteMethod</ja>(path=<js>"/mymethod"</js>)
163    *       String myProxyMethod1(<ja>@Query</ja> Map&lt;String,Object&gt; formData);
164    *    }
165    * 
166    *    <jc>// When used on a request bean method</jc>
167    *    <jk>public interface</jk> MyRequestBean {
168    * 
169    *       <jc>// Equivalent to @Query("*")</jc>
170    *       <ja>@Query</ja>
171    *       Map&lt;String,Object&gt; getFoo();
172    *    }
173    *       </p>
174    *    </li>
175    *    <li>
176    *       If used on a request bean method, uses the bean property name.
177    * 
178    *       <h5 class='figure'>Example:</h5>
179    *       <p class='bcode'>
180    *    <jk>public interface</jk> MyRequestBean {
181    * 
182    *       <jc>// Equivalent to @Query("foo")</jc>
183    *       <ja>@Query</ja>
184    *       String getFoo();
185    *    }
186    *       </p>
187    *    </li>
188    * </ul>
189    */
190   String name() default "";
191
192   /**
193    * A synonym for {@link #name()}.
194    * 
195    * <p>
196    * Allows you to use shortened notation if you're only specifying the name.
197    */
198   String value() default "";
199
200   /**
201    * Skips this value if it's an empty string or empty collection/array.
202    * 
203    * <p>
204    * Note that <jk>null</jk> values are already ignored.
205    */
206   boolean skipIfEmpty() default false;
207
208   /**
209    * Specifies the {@link HttpPartSerializer} class used for serializing values to strings.
210    * 
211    * <p>
212    * The default value defaults to the using the part serializer defined on the {@link RequestBean @RequestBean} annotation,
213    * then on the client which by default is {@link UrlEncodingSerializer}.
214    * 
215    * <p>
216    * This annotation is provided to allow values to be custom serialized.
217    */
218   Class<? extends HttpPartSerializer> serializer() default HttpPartSerializer.Null.class;
219}