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 adding a parent reference to a child object. 026 * 027 * <p> 028 * This annotation is used by parsers to automatically establish parent-child relationships when parsing 029 * nested objects. When a child object is created within a parent object (e.g., in a list or as a property), 030 * the parser automatically sets the parent reference on the child. 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 (the parent object type) 036 * <li>For fields: Can be any type (typically the parent object 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 * <jk>public class</jk> AddressBook { 050 * <jk>public</jk> List<Person> people; 051 * } 052 * 053 * <jk>public class</jk> Person { 054 * <ja>@ParentProperty</ja> 055 * <jk>public</jk> AddressBook addressBook; <jc>// Automatically set to containing AddressBook</jc> 056 * 057 * <jk>public</jk> String name; 058 * <jk>public</jk> <jk>char</jk> sex; 059 * } 060 * 061 * <jc>// Or using a setter method:</jc> 062 * <jk>public class</jk> Person { 063 * <jk>private</jk> AddressBook parent; 064 * 065 * <ja>@ParentProperty</ja> 066 * <jk>protected void</jk> setParent(AddressBook <jv>parent</jv>) { 067 * <jk>this</jk>.parent = <jv>parent</jv>; 068 * } 069 * 070 * <jk>public</jk> String name; 071 * <jk>public</jk> <jk>char</jk> sex; 072 * } 073 * </p> 074 * 075 * <h5 class='section'>When It's Called:</h5> 076 * <ul class='spaced-list'> 077 * <li>During parsing when a child object is created within a parent object 078 * <li>The parser automatically calls the setter or sets the field with a reference to the parent object 079 * <li>This allows child objects to navigate back to their parent if needed 080 * </ul> 081 * 082 * <h5 class='section'>See Also:</h5><ul> 083 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/ParentPropertyAnnotation">@ParentProperty Annotation</a> 084 085 * </ul> 086 */ 087@Target({ METHOD, FIELD, TYPE }) 088@Retention(RUNTIME) 089@Inherited 090@Repeatable(ParentPropertyAnnotation.Array.class) 091@ContextApply(ParentPropertyAnnotation.Applier.class) 092public @interface ParentProperty { 093 094 /** 095 * Optional description for the exposed API. 096 * 097 * @return The annotation value. 098 * @since 9.2.0 099 */ 100 String[] description() default {}; 101 102 /** 103 * Dynamically apply this annotation to the specified methods/fields. 104 * 105 * <p> 106 * Used in conjunction with {@link org.apache.juneau.BeanContext.Builder#applyAnnotations(Class...)} to dynamically apply an annotation to an existing method/field. 107 * It is ignored when the annotation is applied directly to methods/fields. 108 * 109 * <h5 class='section'>Valid patterns:</h5> 110 * <ul class='spaced-list'> 111 * <li>Methods: 112 * <ul> 113 * <li>Fully qualified with args: 114 * <ul> 115 * <li><js>"com.foo.MyClass.myMethod(String,int)"</js> 116 * <li><js>"com.foo.MyClass.myMethod(java.lang.String,int)"</js> 117 * <li><js>"com.foo.MyClass.myMethod()"</js> 118 * </ul> 119 * <li>Fully qualified: 120 * <ul> 121 * <li><js>"com.foo.MyClass.myMethod"</js> 122 * </ul> 123 * <li>Simple with args: 124 * <ul> 125 * <li><js>"MyClass.myMethod(String,int)"</js> 126 * <li><js>"MyClass.myMethod(java.lang.String,int)"</js> 127 * <li><js>"MyClass.myMethod()"</js> 128 * </ul> 129 * <li>Simple: 130 * <ul> 131 * <li><js>"MyClass.myMethod"</js> 132 * </ul> 133 * <li>Simple inner class: 134 * <ul> 135 * <li><js>"MyClass$Inner1$Inner2.myMethod"</js> 136 * <li><js>"Inner1$Inner2.myMethod"</js> 137 * <li><js>"Inner2.myMethod"</js> 138 * </ul> 139 * </ul> 140 * <li>Fields: 141 * <ul> 142 * <li>Fully qualified: 143 * <ul> 144 * <li><js>"com.foo.MyClass.myField"</js> 145 * </ul> 146 * <li>Simple: 147 * <ul> 148 * <li><js>"MyClass.myField"</js> 149 * </ul> 150 * <li>Simple inner class: 151 * <ul> 152 * <li><js>"MyClass$Inner1$Inner2.myField"</js> 153 * <li><js>"Inner1$Inner2.myField"</js> 154 * <li><js>"Inner2.myField"</js> 155 * </ul> 156 * </ul> 157 * <li>A comma-delimited list of anything on this list. 158 * </ul> 159 * 160 * <h5 class='section'>See Also:</h5><ul> 161 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a> 162 * </ul> 163 * 164 * @return The annotation value. 165 */ 166 String[] on() default {}; 167}