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;
018
019import static java.lang.annotation.ElementType.*;
020import static java.lang.annotation.RetentionPolicy.*;
021
022import java.lang.annotation.*;
023
024/**
025 * REST request <c>multipart/form-data</c> part annotation.
026 *
027 * <p>
028 * Identifies a method parameter on a {@link org.apache.juneau.http.remote.Remote}-proxy method (which must also be
029 * marked {@link org.apache.juneau.http.remote.Multipart @Multipart}) as a single part of a {@code multipart/form-data}
030 * request body &mdash; the Retrofit <c>@Part</c> pattern.  The engine adapts each {@code @Part} parameter into the
031 * streaming {@link org.apache.juneau.http.entity.MultipartBody}.
032 *
033 * <h5 class='topic'>Accepted part-source types</h5>
034 * <p>
035 * The bound argument type determines how the part body is produced:
036 * <ul class='spaced-list'>
037 *    <li>{@link CharSequence}/{@link String} (and other scalars such as numbers/booleans) &mdash; sent as a text field.
038 *    <li><c><jk>byte</jk>[]</c> &mdash; sent verbatim (repeatable).
039 *    <li>{@link java.io.File} &mdash; <b>streamed</b> from disk; the {@link #fileName()} defaults to the file's name.
040 *    <li>{@link java.io.InputStream} &mdash; <b>streamed</b> (one-shot; makes the request body non-repeatable).
041 *    <li>{@link java.io.Reader} &mdash; <b>streamed</b> as UTF-8 (one-shot; not drained during request building).
042 *    <li>An {@link HttpBody} &mdash; used directly.
043 *    <li>Any other object (a bean) &mdash; serialized with the client's default serializer (e.g. JSON).
044 * </ul>
045 *
046 * <p>
047 * A <jk>null</jk> argument contributes no part.
048 *
049 * <h5 class='figure'>Example:</h5>
050 * <p class='bjava'>
051 *    <ja>@RemotePost</ja>(<js>"/upload"</js>)
052 *    <ja>@Multipart</ja>
053 *    String upload(
054 *       <ja>@Part</ja>(<js>"title"</js>) String <jv>title</jv>,
055 *       <ja>@Part</ja>(name=<js>"attachment"</js>, fileName=<js>"report.pdf"</js>, contentType=<js>"application/pdf"</js>) <jk>byte</jk>[] <jv>data</jv>);
056 * </p>
057 *
058 * <h5 class='section'>Notes:</h5><ul>
059 *    <li class='note'>
060 *       Valid only on a method also annotated {@link org.apache.juneau.http.remote.Multipart @Multipart}; a
061 *       {@code @Part} parameter on a non-multipart method is rejected at proxy-build time.
062 *    <li class='note'>
063 *       Honored by the next-generation engine (<c>RestClient.remote(...)</c>) only; the classic engine currently
064 *       ignores this annotation.
065 * </ul>
066 *
067 * <h5 class='section'>See Also:</h5><ul>
068 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/NextGenRestClient">Next-Generation REST Client</a>
069 * </ul>
070 *
071 * @since 9.2.1
072 */
073@Documented
074@Target(PARAMETER)
075@Retention(RUNTIME)
076@Inherited
077public @interface Part {
078
079   /**
080    * The part (form-field) name.
081    *
082    * <p>
083    * When blank, falls back to {@link #value()}, then to the reflected parameter name (requires the
084    * <c>-parameters</c> compiler flag).
085    *
086    * @return The annotation value.
087    */
088   String name() default "";
089
090   /**
091    * A synonym for {@link #name()}.
092    *
093    * <p>
094    * Allows shortened notation when only the part name is specified: <c><ja>@Part</ja>(<js>"title"</js>)</c>.
095    *
096    * @return The annotation value.
097    */
098   String value() default "";
099
100   /**
101    * The filename advertised in the part's {@code Content-Disposition} header.
102    *
103    * <p>
104    * When blank, no {@code filename} is emitted &mdash; except for a {@link java.io.File} argument, whose filename
105    * defaults to {@link java.io.File#getName()}.
106    *
107    * @return The annotation value.
108    */
109   String fileName() default "";
110
111   /**
112    * The per-part {@code Content-Type} (e.g. {@code "application/pdf"}, {@code "application/json"}).
113    *
114    * <p>
115    * When blank, a sensible default is used based on the argument type (e.g. {@code text/plain; charset=UTF-8} for
116    * text fields, the serializer's media type for beans, {@code application/octet-stream} for binary sources).
117    *
118    * @return The annotation value.
119    */
120   String contentType() default "";
121}