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.commons.bean;
018
019import static java.lang.annotation.ElementType.*;
020import static java.lang.annotation.RetentionPolicy.*;
021
022import java.lang.annotation.*;
023
024/**
025 * Maps constructor arguments to property names on beans with read-only properties.
026 *
027 * <p>
028 * The bean-modeling sibling to {@code @MarshalledProp}/{@code @BeanProp}: where those describe
029 * individual bean properties, this annotation describes how a constructor's parameters map to the
030 * bean's logical property set so the framework can instantiate read-only beans during parsing and
031 * deserialize property values through the constructor instead of via setters.
032 *
033 * <p>
034 * Lives in <c>juneau-commons</c> so the bean-modeling layer can describe constructor argument
035 * mappings without depending on the marshalling layer.
036 *
037 * <p>
038 * Can be used in the following locations:
039 * <ul>
040 *    <li>Bean constructors.
041 * </ul>
042 *
043 * <p>
044 * This annotation can be used in the case of beans with properties whose values can only be set by passing them in
045 * through a constructor on the class.
046 * <br>Since method parameter names are lost during compilation, this annotation essentially redefines them so that they
047 * are available at runtime.
048 *
049 * <p>
050 * This annotation can only be applied to constructors and can only be applied to one constructor per class.
051 *
052 * <h5 class='section'>Java Records:</h5>
053 * <p>
054 * For Java records, the canonical constructor and its property mappings are automatically detected, so this
055 * annotation is not required.  It can still be used to specify a non-canonical constructor if needed, for example
056 * to provide default values for certain components.
057 *
058 * <h5 class='section'>See Also:</h5><ul>
059 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/BeanCtorAnnotation">@BeanCtor Annotation</a>
060 * </ul>
061 */
062@Documented
063@Target({ CONSTRUCTOR })
064@Retention(RUNTIME)
065@Inherited
066public @interface BeanCtor {
067
068   /**
069    * Optional description for the exposed API.
070    *
071    * @return The annotation value.
072    * @since 9.2.0
073    */
074   String[] description() default {};
075
076   /**
077    * The names of the properties of the constructor arguments.
078    *
079    * <p>
080    * The {@link BeanCtor @BeanCtor} annotation is used to map constructor arguments to property
081    * names on beans with read-only properties.
082    * <br>Since method parameter names are lost during compilation, this annotation essentially redefines them so that
083    * they are available at runtime.
084    *
085    * <p>
086    * The definition of a read-only bean is a bean with properties with only getters, like shown below:
087    * <p class='bjava'>
088    *    <jc>// Our read-only bean.</jc>
089    *    <jk>public class</jk> Person {
090    *       <jk>private final</jk> String <jf>name</jf>;
091    *       <jk>private final int</jk> <jf>age</jf>;
092    *
093    *       <ja>@BeanCtor</ja>(properties=<js>"name,age"</js>)
094    *       <jk>public</jk> Person(String <jv>name</jv>, <jk>int</jk> <jv>age</jv>) {
095    *          <jk>this</jk>.<jf>name</jf> = <jv>name</jv>;
096    *          <jk>this</jk>.<jf>age</jf> = <jv>age</jv>;
097    *       }
098    *
099    *       <jc>// Read only properties.</jc>
100    *       <jc>// Getters, but no setters.</jc>
101    *
102    *       <jk>public</jk> String getName() {
103    *          <jk>return</jk> <jf>name</jf>;
104    *       }
105    *
106    *       <jk>public int</jk> getAge() {
107    *          <jk>return</jk> <jf>age</jf>;
108    *       }
109    *    }
110    * </p>
111    * <p>
112    *    Note that the {@link Name @Name} annotation can also be used to identify bean property names on constructor
113    *    arguments.  If neither this annotation or {@link Name @Name} is used, then we try to get the property names
114    *    from the parameter names if they are available in the bytecode.
115    * </p>
116    *
117    * @return The annotation value.
118    */
119   String properties() default "";
120}