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 &gt; juneau-commons &gt; 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&lt;?&gt; <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}