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<String,Object> 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<String,Object> 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 > juneau-rest-client > 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<String,Object> 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<String,Object> 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}