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.annotation;
018
019import static java.lang.annotation.ElementType.*;
020import static java.lang.annotation.RetentionPolicy.*;
021
022import java.lang.annotation.*;
023
024/**
025 * Identifies a setter method or field for setting the name of a POJO as it's known by its parent object.
026 *
027 * <p>
028 * This annotation is used by parsers to automatically set the name/key of an object when parsing structured data
029 * (e.g., JSON maps, XML elements). A common use case is when parsing a map where the map key should be stored
030 * as a property on the bean.
031 *
032 * <h5 class='section'>Requirements:</h5>
033 * <ul class='spaced-list'>
034 *    <li>Must be an <strong>instance</strong> method or field (not static)
035 *    <li>For methods: Must accept exactly one parameter (any type)
036 *    <li>For fields: Can be any type
037 *    <li>The method or field does not need to be public (will be made accessible automatically)
038 * </ul>
039 *
040 * <p>
041 * Can be used in the following locations:
042 * <ul>
043 *    <li>Bean setter methods or fields
044 *    <li><ja>@Rest</ja>-annotated classes and <ja>@RestOp</ja>-annotated methods when an {@link #on()} value is specified
045 * </ul>
046 *
047 * <h5 class='section'>Example:</h5>
048 * <p class='bjava'>
049 *    <jc>// JSON being parsed:</jc>
050 *    <jc>// {</jc>
051 *    <jc>//   "id1": {name: "John Smith", sex: "M"},</jc>
052 *    <jc>//   "id2": {name: "Jane Doe", sex: "F"}</jc>
053 *    <jc>// }</jc>
054 *
055 *    <jk>public class</jk> Person {
056 *       <ja>@NameProperty</ja>
057 *       <jk>public</jk> String id;  <jc>// Gets set to "id1" or "id2" from map key</jc>
058 *
059 *       <jk>public</jk> String name;
060 *       <jk>public</jk> <jk>char</jk> sex;
061 *    }
062 *
063 *    <jc>// Or using a setter method:</jc>
064 *    <jk>public class</jk> Person {
065 *       <jk>private</jk> String id;
066 *
067 *       <ja>@NameProperty</ja>
068 *       <jk>protected void</jk> setName(String <jv>name</jv>) {
069 *          <jk>this</jk>.id = <jv>name</jv>;
070 *       }
071 *
072 *       <jk>public</jk> String name;
073 *       <jk>public</jk> <jk>char</jk> sex;
074 *    }
075 * </p>
076 *
077 * <h5 class='section'>When It's Called:</h5>
078 * <ul class='spaced-list'>
079 *    <li>During parsing when an object is created as a value in a map/collection
080 *    <li>The parser automatically calls the setter or sets the field with the key/name from the parent structure
081 * </ul>
082 *
083 * <h5 class='section'>See Also:</h5><ul>
084 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/NamePropertyAnnotation">@NameProperty Annotation</a>
085
086 * </ul>
087 */
088@Target({ METHOD, FIELD, TYPE })
089@Retention(RUNTIME)
090@Inherited
091@Repeatable(NamePropertyAnnotation.Array.class)
092@ContextApply(NamePropertyAnnotation.Applier.class)
093public @interface NameProperty {
094
095   /**
096    * Optional description for the exposed API.
097    *
098    * @return The annotation value.
099    * @since 9.2.0
100    */
101   String[] description() default {};
102
103   /**
104    * Dynamically apply this annotation to the specified methods/fields.
105    *
106    * <p>
107    * Used in conjunction with {@link org.apache.juneau.BeanContext.Builder#applyAnnotations(Class...)} to dynamically apply an annotation to an existing method/field.
108    * It is ignored when the annotation is applied directly to methods/fields.
109    *
110    * <h5 class='section'>Valid patterns:</h5>
111    * <ul class='spaced-list'>
112    *    <li>Methods:
113    *       <ul>
114    *          <li>Fully qualified with args:
115    *             <ul>
116    *                <li><js>"com.foo.MyClass.myMethod(String,int)"</js>
117    *                <li><js>"com.foo.MyClass.myMethod(java.lang.String,int)"</js>
118    *                <li><js>"com.foo.MyClass.myMethod()"</js>
119    *             </ul>
120    *          <li>Fully qualified:
121    *             <ul>
122    *                <li><js>"com.foo.MyClass.myMethod"</js>
123    *             </ul>
124    *          <li>Simple with args:
125    *             <ul>
126    *                <li><js>"MyClass.myMethod(String,int)"</js>
127    *                <li><js>"MyClass.myMethod(java.lang.String,int)"</js>
128    *                <li><js>"MyClass.myMethod()"</js>
129    *             </ul>
130    *          <li>Simple:
131    *             <ul>
132    *                <li><js>"MyClass.myMethod"</js>
133    *             </ul>
134    *          <li>Simple inner class:
135    *             <ul>
136    *                <li><js>"MyClass$Inner1$Inner2.myMethod"</js>
137    *                <li><js>"Inner1$Inner2.myMethod"</js>
138    *                <li><js>"Inner2.myMethod"</js>
139    *             </ul>
140    *       </ul>
141    *    <li>Fields:
142    *       <ul>
143    *          <li>Fully qualified:
144    *             <ul>
145    *                <li><js>"com.foo.MyClass.myField"</js>
146    *             </ul>
147    *          <li>Simple:
148    *             <ul>
149    *                <li><js>"MyClass.myField"</js>
150    *             </ul>
151    *          <li>Simple inner class:
152    *             <ul>
153    *                <li><js>"MyClass$Inner1$Inner2.myField"</js>
154    *                <li><js>"Inner1$Inner2.myField"</js>
155    *                <li><js>"Inner2.myField"</js>
156    *             </ul>
157    *       </ul>
158    *    <li>A comma-delimited list of anything on this list.
159    * </ul>
160    *
161    * <h5 class='section'>See Also:</h5><ul>
162    *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a>
163    * </ul>
164    *
165    * @return The annotation value.
166    */
167   String[] on() default {};
168}