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; 018 019import static org.apache.juneau.commons.reflect.ReflectionUtils.*; 020import static org.apache.juneau.commons.utils.CollectionUtils.*; 021import static org.apache.juneau.commons.utils.Shorts.*; 022 023import java.lang.annotation.*; 024import java.lang.reflect.*; 025 026import org.apache.juneau.commons.reflect.*; 027 028/** 029 * An implementation of an annotation that can be dynamically applied to classes, methods, fields, and constructors at runtime. 030 * 031 * <p> 032 * This class extends {@link AnnotationObject} to provide support for annotations that have an <c>on</c> property which 033 * allows them to be targeted to specific program elements based on their fully-qualified names. 034 * 035 * <h5 class='section'>Overview:</h5> 036 * <p> 037 * Applied annotations allow you to define annotation properties in external configuration or programmatically at runtime, 038 * rather than requiring them to be declared directly on classes, methods, fields, or constructors at compile-time. 039 * 040 * <p> 041 * This is particularly useful for: 042 * <ul class='spaced-list'> 043 * <li>Configuration-driven behavior - Define annotation properties in config files without modifying source code 044 * <li>Dynamic application - Apply annotations to third-party classes where you can't modify the source 045 * <li>Runtime customization - Change annotation properties based on runtime conditions 046 * <li>Centralized configuration - Define annotation properties for multiple classes in one place 047 * </ul> 048 * 049 * <h5 class='section'>Targeting with <c>on</c>:</h5> 050 * <p> 051 * The base {@link Builder#on(String...)} method accepts fully-qualified names in the following formats: 052 * <ul class='spaced-list'> 053 * <li><js>"com.example.MyClass"</js> - Target a specific class 054 * <li><js>"com.example.MyClass.myMethod"</js> - Target a specific method 055 * <li><js>"com.example.MyClass.myField"</js> - Target a specific field 056 * <li><js>"com.example.MyClass(java.lang.String,int)"</js> - Target a specific constructor 057 * </ul> 058 * 059 * <h5 class='section'>Builder Variants:</h5> 060 * <p> 061 * This class provides specialized builder variants for different targeting scenarios: 062 * <ul class='javatree'> 063 * <li class='jc'>{@link Builder} - Base builder with string-based targeting via {@link Builder#on(String...)} 064 * <li class='jc'>{@link BuilderT} - For targeting classes 065 * <ul> 066 * <li class='jm'>{@link BuilderT#on(Class...) on(Class...)} - Target by class, stored as strings 067 * <li class='jm'>{@link BuilderT#on(ClassInfo...) on(ClassInfo...)} - Target by ClassInfo, stored as strings 068 * <li class='jm'>{@link BuilderT#onClass(Class...) onClass(Class...)} - Target by class, stored as Class objects 069 * <li class='jm'>{@link BuilderT#onClass(ClassInfo...) onClass(ClassInfo...)} - Target by ClassInfo, stored as Class objects 070 * </ul> 071 * <li class='jc'>{@link BuilderM} - For targeting methods 072 * <ul> 073 * <li class='jm'>{@link BuilderM#on(Method...) on(Method...)} - Target by Method object 074 * <li class='jm'>{@link BuilderM#on(MethodInfo...) on(MethodInfo...)} - Target by MethodInfo object 075 * </ul> 076 * <li class='jc'>{@link BuilderC} - For targeting constructors 077 * <ul> 078 * <li class='jm'>{@link BuilderC#on(Constructor...) on(Constructor...)} - Target by Constructor object 079 * <li class='jm'>{@link BuilderC#on(ConstructorInfo...) on(ConstructorInfo...)} - Target by ConstructorInfo object 080 * </ul> 081 * <li class='jc'>{@link BuilderMF} - For targeting methods and fields 082 * <ul> 083 * <li class='jm'>{@link BuilderMF#on(Method...) on(Method...)} - Target by Method object 084 * <li class='jm'>{@link BuilderMF#on(MethodInfo...) on(MethodInfo...)} - Target by MethodInfo object 085 * <li class='jm'>{@link BuilderMF#on(Field...) on(Field...)} - Target by Field object 086 * <li class='jm'>{@link BuilderMF#on(FieldInfo...) on(FieldInfo...)} - Target by FieldInfo object 087 * </ul> 088 * <li class='jc'>{@link BuilderTM} - For targeting classes and methods 089 * <li class='jc'>{@link BuilderTMF} - For targeting classes, methods, and fields 090 * <li class='jc'>{@link BuilderTMFC} - For targeting classes, methods, fields, and constructors 091 * </ul> 092 * 093 * <h5 class='section'>Example:</h5> 094 * <p class='bjava'> 095 * <jc>// Create a Bean annotation that applies to MyClass</jc> 096 * MarshalledAnnotation <jv>annotation</jv> = MarshalledAnnotation 097 * .<jsm>create</jsm>(MyClass.<jk>class</jk>) 098 * .sort(<jk>true</jk>) 099 * .build(); 100 * 101 * <jc>// Or target by string name</jc> 102 * MarshalledAnnotation <jv>annotation2</jv> = MarshalledAnnotation 103 * .<jsm>create</jsm>() 104 * .on(<js>"com.example.MyClass"</js>) 105 * .sort(<jk>true</jk>) 106 * .build(); 107 * </p> 108 * 109 * <h5 class='section'>Notes:</h5> 110 * <ul class='spaced-list'> 111 * <li>The {@link #on()} method returns the string-based targets 112 * <li>Subclasses may provide additional {@code onClass()}, {@code onMethod()}, etc. methods for type-safe access 113 * <li>All builder methods return the builder for method chaining 114 * <li>Hashcode is calculated lazily on first access and then cached for performance 115 * </ul> 116 * 117 * <h5 class='section'>See Also:</h5><ul> 118 * <li class='link'><a class="doclink" href="../../../../../overview-summary.html#juneau-commons.Annotations">Overview > juneau-commons > Annotations</a> 119 * </ul> 120 */ 121@SuppressWarnings({ 122 "java:S1192", // Duplicated literals (argument/property names) read more clearly inline than as constants 123 "java:S2160" // equals() inherited from AnnotationObject compares all annotation interface methods; subclass fields accessed via those methods 124}) 125public class AppliedAnnotationObject extends AnnotationObject { 126 127 //----------------------------------------------------------------------------------------------------------------- 128 // Static 129 //----------------------------------------------------------------------------------------------------------------- 130 131 /** 132 * Builder for {@link AppliedAnnotationObject} objects. 133 * 134 * <p> 135 * Provides string-based targeting via the {@link #on(String...)} method. 136 * 137 * <h5 class='section'>Example:</h5> 138 * <p class='bjava'> 139 * <jc>// Target specific classes and methods by name</jc> 140 * MyAnnotation <jv>annotation</jv> = MyAnnotation 141 * .<jsm>create</jsm>() 142 * .on(<js>"com.example.MyClass"</js>) 143 * .on(<js>"com.example.MyClass.myMethod"</js>) 144 * .build(); 145 * </p> 146 * 147 * <h5 class='section'>See Also:</h5><ul> 148 * <li class='jc'>{@link BuilderT} - For type-safe class targeting 149 * <li class='jc'>{@link BuilderM} - For method targeting 150 * <li class='jc'>{@link BuilderC} - For constructor targeting 151 * <li class='jc'>{@link BuilderMF} - For method and field targeting 152 * </ul> 153 */ 154 public static class Builder extends AnnotationObject.Builder { 155 156 String[] on = {}; 157 158 /** 159 * Constructor. 160 * 161 * @param annotationType The annotation type of the annotation implementation class. Must not be <jk>null</jk>. 162 */ 163 public Builder(Class<? extends Annotation> annotationType) { 164 super(annotationType); 165 } 166 167 /** 168 * The targets this annotation applies to. 169 * 170 * @param values The targets this annotation applies to. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 171 * @return This object. 172 */ 173 public Builder on(String...values) { 174 reqnns("values", values); 175 for (var v : values) 176 on = addAll(on, v); 177 return this; 178 } 179 } 180 181 /** 182 * Builder for applied annotations targeting constructors. 183 * 184 * <p> 185 * Adds constructor targeting capabilities to the base builder: 186 * <ul class='javatree'> 187 * <li class='jm'>{@link #on(Constructor...) on(Constructor...)} - Target by Constructor reflection object 188 * <li class='jm'>{@link #on(ConstructorInfo...) on(ConstructorInfo...)} - Target by ConstructorInfo wrapper 189 * </ul> 190 * 191 * <h5 class='section'>Example:</h5> 192 * <p class='bjava'> 193 * <jc>// Target specific constructors</jc> 194 * Constructor<?> <jv>ctor</jv> = MyClass.<jk>class</jk>.getConstructor(String.<jk>class</jk>, <jk>int</jk>.<jk>class</jk>); 195 * 196 * MyAnnotation <jv>annotation</jv> = MyAnnotation 197 * .<jsm>create</jsm>() 198 * .on(<jv>ctor</jv>) 199 * .build(); 200 * </p> 201 */ 202 public static class BuilderC extends Builder { 203 204 /** 205 * Constructor. 206 * 207 * @param annotationType The annotation type of the annotation implementation class. Must not be <jk>null</jk>. 208 */ 209 public BuilderC(Class<? extends Annotation> annotationType) { 210 super(annotationType); 211 } 212 213 /** 214 * Appends the constructors that this annotation applies to. 215 * 216 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 217 * @return This object. 218 */ 219 public BuilderC on(Constructor<?>...value) { 220 reqnns("value", value); 221 for (var v : value) 222 super.on(info(v).getNameFull()); 223 return this; 224 } 225 226 /** 227 * Appends the constructors that this annotation applies to. 228 * 229 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 230 * @return This object. 231 */ 232 public BuilderC on(ConstructorInfo...value) { 233 reqnns("value", value); 234 for (var v : value) 235 super.on(v.getNameFull()); 236 return this; 237 } 238 } 239 240 /** 241 * Builder for applied annotations targeting methods. 242 * 243 * <p> 244 * Adds method targeting capabilities to the base builder: 245 * <ul class='javatree'> 246 * <li class='jm'>{@link #on(Method...) on(Method...)} - Target by Method reflection object 247 * <li class='jm'>{@link #on(MethodInfo...) on(MethodInfo...)} - Target by MethodInfo wrapper 248 * </ul> 249 * 250 * <h5 class='section'>Example:</h5> 251 * <p class='bjava'> 252 * <jc>// Target specific methods</jc> 253 * Method <jv>method1</jv> = MyClass.<jk>class</jk>.getMethod(<js>"myMethod"</js>); 254 * Method <jv>method2</jv> = MyClass.<jk>class</jk>.getMethod(<js>"otherMethod"</js>); 255 * 256 * MyAnnotation <jv>annotation</jv> = MyAnnotation 257 * .<jsm>create</jsm>() 258 * .on(<jv>method1</jv>, <jv>method2</jv>) 259 * .build(); 260 * </p> 261 */ 262 public static class BuilderM extends Builder { 263 264 /** 265 * Constructor. 266 * 267 * @param annotationType The annotation type of the annotation implementation class. Must not be <jk>null</jk>. 268 */ 269 public BuilderM(Class<? extends Annotation> annotationType) { 270 super(annotationType); 271 } 272 273 /** 274 * Appends the methods that this annotation applies to. 275 * 276 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 277 * @return This object. 278 */ 279 public BuilderM on(Method...value) { 280 reqnns("value", value); 281 for (var v : value) 282 super.on(info(v).getNameFull()); 283 return this; 284 } 285 286 /** 287 * Appends the methods that this annotation applies to. 288 * 289 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 290 * @return This object. 291 */ 292 public BuilderM on(MethodInfo...value) { 293 reqnns("value", value); 294 for (var v : value) 295 super.on(v.getNameFull()); 296 return this; 297 } 298 } 299 300 /** 301 * Builder for applied annotations targeting methods and fields. 302 * 303 * <p> 304 * Adds method and field targeting capabilities to the base builder: 305 * <ul class='javatree'> 306 * <li class='jm'>{@link #on(Method...) on(Method...)} - Target by Method reflection object 307 * <li class='jm'>{@link #on(MethodInfo...) on(MethodInfo...)} - Target by MethodInfo wrapper 308 * <li class='jm'>{@link #on(Field...) on(Field...)} - Target by Field reflection object 309 * <li class='jm'>{@link #on(FieldInfo...) on(FieldInfo...)} - Target by FieldInfo wrapper 310 * </ul> 311 * 312 * <h5 class='section'>Example:</h5> 313 * <p class='bjava'> 314 * <jc>// Target specific methods and fields</jc> 315 * Method <jv>method</jv> = MyClass.<jk>class</jk>.getMethod(<js>"myMethod"</js>); 316 * Field <jv>field</jv> = MyClass.<jk>class</jk>.getField(<js>"myField"</js>); 317 * 318 * MyAnnotation <jv>annotation</jv> = MyAnnotation 319 * .<jsm>create</jsm>() 320 * .on(<jv>method</jv>) 321 * .on(<jv>field</jv>) 322 * .build(); 323 * </p> 324 */ 325 public static class BuilderMF extends Builder { 326 327 /** 328 * Constructor. 329 * 330 * @param annotationType The annotation type of the annotation implementation class. Must not be <jk>null</jk>. 331 */ 332 public BuilderMF(Class<? extends Annotation> annotationType) { 333 super(annotationType); 334 } 335 336 /** 337 * Appends the fields that this annotation applies to. 338 * 339 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 340 * @return This object. 341 */ 342 public BuilderMF on(Field...value) { 343 reqnns("value", value); 344 for (var v : value) 345 super.on(info(v).getNameFull()); 346 return this; 347 } 348 349 /** 350 * Appends the fields that this annotation applies to. 351 * 352 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 353 * @return This object. 354 */ 355 public BuilderMF on(FieldInfo...value) { 356 reqnns("value", value); 357 for (var v : value) 358 super.on(v.getNameFull()); 359 return this; 360 } 361 362 /** 363 * Appends the methods that this annotation applies to. 364 * 365 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 366 * @return This object. 367 */ 368 public BuilderMF on(Method...value) { 369 reqnns("value", value); 370 for (var v : value) 371 super.on(info(v).getNameFull()); 372 return this; 373 } 374 375 /** 376 * Appends the methods that this annotation applies to. 377 * 378 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 379 * @return This object. 380 */ 381 public BuilderMF on(MethodInfo...value) { 382 reqnns("value", value); 383 for (var v : value) 384 super.on(v.getNameFull()); 385 return this; 386 } 387 } 388 389 /** 390 * Builder for applied annotations targeting classes. 391 * 392 * <p> 393 * Adds type-safe class targeting methods to the base builder: 394 * <ul class='javatree'> 395 * <li class='jm'>{@link #on(Class...) on(Class...)} - Target by class, stored as strings in {@link AppliedAnnotationObject#on()} 396 * <li class='jm'>{@link #on(ClassInfo...) on(ClassInfo...)} - Target by ClassInfo, stored as strings 397 * <li class='jm'>{@link #onClass(Class...) onClass(Class...)} - Target by class, stored as Class objects in {@link AppliedOnClassAnnotationObject#onClass()} 398 * <li class='jm'>{@link #onClass(ClassInfo...) onClass(ClassInfo...)} - Target by ClassInfo, stored as Class objects 399 * </ul> 400 * 401 * <h5 class='section'>Example:</h5> 402 * <p class='bjava'> 403 * <jc>// Target classes using type-safe references</jc> 404 * MyAnnotation <jv>annotation</jv> = MyAnnotation 405 * .<jsm>create</jsm>() 406 * .on(MyClass.<jk>class</jk>, MyOtherClass.<jk>class</jk>) <jc>// Stored as strings</jc> 407 * .onClass(ThirdClass.<jk>class</jk>) <jc>// Stored as Class object</jc> 408 * .build(); 409 * </p> 410 * 411 * <h5 class='section'>Notes:</h5> 412 * <ul class='spaced-list'> 413 * <li>Use {@link #on(Class...)} when you want string-based matching (e.g., for configuration) 414 * <li>Use {@link #onClass(Class...)} when you need direct Class object references 415 * <li>Both can be used together on the same builder 416 * </ul> 417 */ 418 public static class BuilderT extends Builder { 419 420 Class<?>[] onClass = {}; 421 422 /** 423 * Constructor. 424 * 425 * @param annotationType The annotation type of the annotation implementation class. Must not be <jk>null</jk>. 426 */ 427 public BuilderT(Class<? extends Annotation> annotationType) { 428 super(annotationType); 429 } 430 431 /** 432 * Appends the classes that this annotation applies to. 433 * 434 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 435 * @return This object. 436 */ 437 public BuilderT on(Class<?>...value) { 438 reqnns("value", value); 439 for (var v : value) 440 on = addAll(on, v.getName()); 441 return this; 442 } 443 444 /** 445 * Appends the classes that this annotation applies to. 446 * 447 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 448 * @return This object. 449 */ 450 public BuilderT on(ClassInfo...value) { 451 reqnns("value", value); 452 for (var v : value) 453 on = addAll(on, cn(v)); 454 return this; 455 } 456 457 /** 458 * Appends the classes that this annotation applies to. 459 * 460 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 461 * @return This object. 462 */ 463 public BuilderT onClass(Class<?>...value) { 464 reqnns("value", value); 465 for (var v : value) 466 onClass = addAll(onClass, v); 467 return this; 468 } 469 470 /** 471 * Appends the classes that this annotation applies to. 472 * 473 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 474 * @return This object. 475 */ 476 public BuilderT onClass(ClassInfo...value) { 477 reqnns("value", value); 478 for (var v : value) 479 onClass = addAll(onClass, v.inner()); 480 return this; 481 } 482 } 483 484 /** 485 * Builder for applied annotations targeting classes and methods. 486 * 487 * <p> 488 * Combines the capabilities of {@link BuilderT} and {@link BuilderM}, providing targeting for both classes and methods. 489 * 490 * <h5 class='section'>Example:</h5> 491 * <p class='bjava'> 492 * <jc>// Target both classes and methods</jc> 493 * MyAnnotation <jv>annotation</jv> = MyAnnotation 494 * .<jsm>create</jsm>() 495 * .on(MyClass.<jk>class</jk>) <jc>// Target class</jc> 496 * .on(MyClass.<jk>class</jk>.getMethod(<js>"myMethod"</js>)) <jc>// Target method</jc> 497 * .build(); 498 * </p> 499 */ 500 public static class BuilderTM extends BuilderT { 501 502 /** 503 * Constructor. 504 * 505 * @param annotationType The annotation type of the annotation implementation class. Must not be <jk>null</jk>. 506 */ 507 public BuilderTM(Class<? extends Annotation> annotationType) { 508 super(annotationType); 509 } 510 511 /** 512 * Appends the methods that this annotation applies to. 513 * 514 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 515 * @return This object. 516 */ 517 public BuilderTM on(Method...value) { 518 reqnns("value", value); 519 for (var v : value) 520 on(info(v).getNameFull()); 521 return this; 522 } 523 524 /** 525 * Appends the methods that this annotation applies to. 526 * 527 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 528 * @return This object. 529 */ 530 public BuilderTM on(MethodInfo...value) { 531 reqnns("value", value); 532 for (var v : value) 533 on(v.getNameFull()); 534 return this; 535 } 536 537 @Override /* Overridden from AppliedAnnotationObject.Builder */ 538 public BuilderTM on(String...value) { 539 super.on(value); 540 return this; 541 } 542 543 @Override /* Overridden from AppliedOnClassAnnotationObject.Builder */ 544 public BuilderTM onClass(Class<?>...value) { 545 super.onClass(value); 546 return this; 547 } 548 } 549 550 /** 551 * Builder for applied annotations targeting classes, methods, and fields. 552 * 553 * <p> 554 * Combines the capabilities of {@link BuilderT}, {@link BuilderM}, and field targeting, 555 * providing comprehensive targeting for classes, methods, and fields. 556 * 557 * <h5 class='section'>Example:</h5> 558 * <p class='bjava'> 559 * <jc>// Target classes, methods, and fields</jc> 560 * MyAnnotation <jv>annotation</jv> = MyAnnotation 561 * .<jsm>create</jsm>() 562 * .on(MyClass.<jk>class</jk>) <jc>// Target class</jc> 563 * .on(MyClass.<jk>class</jk>.getMethod(<js>"myMethod"</js>)) <jc>// Target method</jc> 564 * .on(MyClass.<jk>class</jk>.getField(<js>"myField"</js>)) <jc>// Target field</jc> 565 * .build(); 566 * </p> 567 */ 568 public static class BuilderTMF extends BuilderT { 569 570 /** 571 * Constructor. 572 * 573 * @param annotationType The annotation type of the annotation implementation class. Must not be <jk>null</jk>. 574 */ 575 public BuilderTMF(Class<? extends Annotation> annotationType) { 576 super(annotationType); 577 } 578 579 /** 580 * Appends the fields that this annotation applies to. 581 * 582 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 583 * @return This object. 584 */ 585 public BuilderTMF on(Field...value) { 586 reqnns("value", value); 587 for (var v : value) 588 super.on(info(v).getNameFull()); 589 return this; 590 } 591 592 /** 593 * Appends the fields that this annotation applies to. 594 * 595 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 596 * @return This object. 597 */ 598 public BuilderTMF on(FieldInfo...value) { 599 reqnns("value", value); 600 for (var v : value) 601 super.on(v.getNameFull()); 602 return this; 603 } 604 605 /** 606 * Appends the methods that this annotation applies to. 607 * 608 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 609 * @return This object. 610 */ 611 public BuilderTMF on(Method...value) { 612 reqnns("value", value); 613 for (var v : value) 614 super.on(info(v).getNameFull()); 615 return this; 616 } 617 618 /** 619 * Appends the methods that this annotation applies to. 620 * 621 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 622 * @return This object. 623 */ 624 public BuilderTMF on(MethodInfo...value) { 625 reqnns("value", value); 626 for (var v : value) 627 super.on(v.getNameFull()); 628 return this; 629 } 630 } 631 632 /** 633 * Builder for applied annotations targeting classes, methods, fields, and constructors. 634 * 635 * <p> 636 * The most comprehensive builder variant, combining all targeting capabilities from {@link BuilderT}, {@link BuilderM}, 637 * field targeting, and {@link BuilderC}, providing complete targeting for all program elements. 638 * 639 * <h5 class='section'>Example:</h5> 640 * <p class='bjava'> 641 * <jc>// Target any program element</jc> 642 * MyAnnotation <jv>annotation</jv> = MyAnnotation 643 * .<jsm>create</jsm>() 644 * .on(MyClass.<jk>class</jk>) <jc>// Target class</jc> 645 * .on(MyClass.<jk>class</jk>.getMethod(<js>"myMethod"</js>)) <jc>// Target method</jc> 646 * .on(MyClass.<jk>class</jk>.getField(<js>"myField"</js>)) <jc>// Target field</jc> 647 * .on(MyClass.<jk>class</jk>.getConstructor()) <jc>// Target constructor</jc> 648 * .build(); 649 * </p> 650 */ 651 public static class BuilderTMFC extends BuilderTMF { 652 653 /** 654 * Constructor. 655 * 656 * @param annotationType The annotation type of the annotation implementation class. Must not be <jk>null</jk>. 657 */ 658 public BuilderTMFC(Class<? extends Annotation> annotationType) { 659 super(annotationType); 660 } 661 662 /** 663 * Appends the constructors that this annotation applies to. 664 * 665 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 666 * @return This object. 667 */ 668 public BuilderTMFC on(Constructor<?>...value) { 669 reqnns("value", value); 670 for (var v : value) 671 super.on(info(v).getNameFull()); 672 return this; 673 } 674 675 /** 676 * Appends the constructors that this annotation applies to. 677 * 678 * @param value The values to append. Cannot be <jk>null</jk> or contain <jk>null</jk> elements. 679 * @return This object. 680 */ 681 public BuilderTMFC on(ConstructorInfo...value) { 682 reqnns("value", value); 683 for (var v : value) 684 super.on(v.getNameFull()); 685 return this; 686 } 687 } 688 689 //----------------------------------------------------------------------------------------------------------------- 690 // Instance 691 //----------------------------------------------------------------------------------------------------------------- 692 693 private final String[] on; 694 695 /** 696 * Constructor. 697 * 698 * @param b The builder used to instantiate the fields of this class. Must not be <jk>null</jk>. 699 */ 700 public AppliedAnnotationObject(Builder b) { 701 super(b); 702 this.on = cp(b.on); 703 } 704 705 /** 706 * The targets this annotation applies to. 707 * 708 * @return The targets this annotation applies to. 709 */ 710 public String[] on() { 711 return cp(on); 712 } 713}