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 FORM post 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 form data 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>@FormData</ja>(<js>"foo"</js>)</ja> String foo,
036 *          <ja>@FormData</ja>(<js>"bar"</js>)</ja> MyPojo pojo);
037 * 
038 *       <jc>// Multiple values pulled from a NameValuePairs object.</jc>
039 *       <jc>// Same as @FormData("*").</jc>
040 *       <ja>@RemoteMethod</ja>(path=<js>"/mymethod2"</js>)
041 *       String myProxyMethod2(<ja>@FormData</ja> NameValuePairs nameValuePairs);
042 * 
043 *       <jc>// Multiple values pulled from a Map.</jc>
044 *       <jc>// Same as @FormData("*").</jc>
045 *       <ja>@RemoteMethod</ja>(path=<js>"/mymethod3"</js>)
046 *       String myProxyMethod3(<ja>@FormData</ja> Map&lt;String,Object&gt; map);
047 * 
048 *       <jc>// Multiple values pulled from a bean.</jc>
049 *       <jc>// Same as @FormData("*").</jc>
050 *       <ja>@RemoteMethod</ja>(path=<js>"/mymethod4"</js>)
051 *       String myProxyMethod4(<ja>@FormData</ja> MyBean myBean);
052 * 
053 *       <jc>// An entire form-data HTTP body as a String.</jc>
054 *       <jc>// Same as @FormData("*").</jc>
055 *       <ja>@RemoteMethod</ja>(path=<js>"/mymethod5"</js>)
056 *       String myProxyMethod5(<ja>@FormData</ja> String string);
057 * 
058 *       <jc>// An entire form-data HTTP body as a Reader.</jc>
059 *       <jc>// Same as @FormData("*").</jc>
060 *       <ja>@RemoteMethod</ja>(path=<js>"/mymethod6"</js>)
061 *       String myProxyMethod6(<ja>@FormData</ja> Reader reader);
062 * 
063 *    }
064 * </p>
065 * 
066 * <p>
067 * The annotation can also be applied to a bean property field or getter when the argument is annotated with
068 * {@link RequestBean @RequestBean}:
069 * 
070 * <h5 class='section'>Example:</h5>
071 * <p class='bcode'>
072 *    <ja>@Remoteable</ja>(path=<js>"/myproxy"</js>)
073 *    <jk>public interface</jk> MyProxy {
074 * 
075 *       <ja>@RemoteMethod</ja>(path=<js>"/mymethod"</js>)
076 *       String myProxyMethod(<ja>@RequestBean</ja> MyRequestBean bean);
077 *    }
078 * 
079 *    <jk>public interface</jk> MyRequestBean {
080 * 
081 *       <jc>// Name explicitly specified.</jc>
082 *       <ja>@FormData</ja>(<js>"foo"</js>)
083 *       String getX();
084 * 
085 *       <jc>// Name inherited from bean property.</jc>
086 *       <jc>// Same as @FormData("bar")</jc>
087 *       <ja>@FormData</ja>
088 *       String getBar();
089 * 
090 *       <jc>// Name inherited from bean property.</jc>
091 *       <jc>// Same as @FormData("baz")</jc>
092 *       <ja>@FormData</ja>
093 *       <ja>@BeanProperty</ja>(<js>"baz"</js>)
094 *       String getY();
095 * 
096 *       <jc>// Multiple values pulled from NameValuePairs object.</jc>
097 *       <jc>// Same as @FormData("*")</jc>
098 *       <ja>@FormData</ja>
099 *       NameValuePairs getNameValuePairs();
100 * 
101 *       <jc>// Multiple values pulled from Map.</jc>
102 *       <jc>// Same as @FormData("*")</jc>
103 *       <ja>@FormData</ja>
104 *       Map&lt;String,Object&gt; getMap();
105 * 
106 *       <jc>// Multiple values pulled from bean.</jc>
107 *       <jc>// Same as @FormData("*")</jc>
108 *       <ja>@FormData</ja>
109 *       MyBean getMyBean();
110 * 
111 *       <jc>// An entire form-data HTTP body as a Reader.</jc>
112 *       <jc>// Same as @FormData("*")</jc>
113 *       <ja>@FormData</ja>
114 *       Reader getReader();
115 *    }
116 * </p>
117 * 
118 * <p>
119 * The {@link #name()} and {@link #value()} elements are synonyms for specifying the parameter name.
120 * Only one should be used.
121 * <br>The following annotations are fully equivalent:
122 * <p class='bcode'>
123 *    <ja>@FormData</ja>(name=<js>"foo"</js>)
124 * 
125 *    <ja>@FormData</ja>(<js>"foo"</js>)
126 * </p>
127 * 
128 * <h5 class='section'>See Also:</h5>
129 * <ul class='doctree'>
130 *    <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>
131 * </ul>
132 */
133@Documented
134@Target({PARAMETER,FIELD,METHOD})
135@Retention(RUNTIME)
136@Inherited
137public @interface FormData {
138
139   /**
140    * The form post parameter name.
141    * 
142    * <p>
143    * Note that {@link #name()} and {@link #value()} are synonyms.
144    * 
145    * <p>
146    * The value should be either <js>"*"</js> to represent multiple name/value pairs, or a label that defines the
147    * form data parameter name.
148    * 
149    * <p>
150    * A blank value (the default) has the following behavior:
151    * <ul class='spaced-list'>
152    *    <li>
153    *       If the data type is <code>NameValuePairs</code>, <code>Map</code>, or a bean,
154    *       then it's the equivalent to <js>"*"</js> which will cause the value to be serialized as name/value pairs.
155    * 
156    *       <h5 class='figure'>Example:</h5>
157    *       <p class='bcode'>
158    *    <jc>// When used on a remote method parameter</jc>
159    *    <ja>@Remoteable</ja>(path=<js>"/myproxy"</js>)
160    *    <jk>public interface</jk> MyProxy {
161    * 
162    *       <jc>// Equivalent to @FormData("*")</jc>
163    *       <ja>@RemoteMethod</ja>(path=<js>"/mymethod"</js>)
164    *       String myProxyMethod1(<ja>@FormData</ja> Map&lt;String,Object&gt; formData);
165    *    }
166    * 
167    *    <jc>// When used on a request bean method</jc>
168    *    <jk>public interface</jk> MyRequestBean {
169    * 
170    *       <jc>// Equivalent to @FormData("*")</jc>
171    *       <ja>@FormData</ja>
172    *       Map&lt;String,Object&gt; getFoo();
173    *    }
174    *       </p>
175    *    </li>
176    *    <li>
177    *       If used on a request bean method, uses the bean property name.
178    * 
179    *       <h5 class='figure'>Example:</h5>
180    *       <p class='bcode'>
181    *    <jk>public interface</jk> MyRequestBean {
182    * 
183    *       <jc>// Equivalent to @FormData("foo")</jc>
184    *       <ja>@FormData</ja>
185    *       String getFoo();
186    *    }
187    *       </p>
188    *    </li>
189    * </ul>
190    */
191   String name() default "";
192
193   /**
194    * A synonym for {@link #name()}.
195    * 
196    * <p>
197    * Allows you to use shortened notation if you're only specifying the name.
198    */
199   String value() default "";
200
201   /**
202    * Skips this value if it's an empty string or empty collection/array.
203    * 
204    * <p>
205    * Note that <jk>null</jk> values are already ignored.
206    */
207   boolean skipIfEmpty() default false;
208
209   /**
210    * Specifies the {@link HttpPartSerializer} class used for serializing values to strings.
211    * 
212    * <p>
213    * The default value defaults to the using the part serializer defined on the {@link RequestBean @RequestBean} annotation,
214    * then on the client which by default is {@link UrlEncodingSerializer}.
215    * 
216    * <p>
217    * This annotation is provided to allow values to be custom serialized.
218    */
219   Class<? extends HttpPartSerializer> serializer() default HttpPartSerializer.Null.class;
220}