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