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.utils.Shorts.*;
020
021/**
022 * An implementation of an annotation that can be dynamically applied to classes, methods, fields, and constructors,
023 * with additional support for type-safe class targeting via the {@link #onClass()} property.
024 *
025 * <p>
026 * This class extends {@link AppliedAnnotationObject} to provide both string-based targeting (via {@link #on()})
027 * and type-safe class-based targeting (via {@link #onClass()}).
028 *
029 * <h5 class='section'>Difference between <c>on</c> and <c>onClass</c>:</h5>
030 * <ul class='spaced-list'>
031 *    <li><b>{@link #on()}</b> - Returns string-based targets (e.g., <js>"com.example.MyClass"</js>)
032 *       <br>Useful for:
033 *       <ul>
034 *          <li>Configuration files where class references aren't available
035 *          <li>Targeting classes that may not be loaded yet
036 *          <li>Pattern matching or wildcard targeting
037 *       </ul>
038 *    <li><b>{@link #onClass()}</b> - Returns Class object targets (e.g., <c>MyClass.<jk>class</jk></c>)
039 *       <br>Useful for:
040 *       <ul>
041 *          <li>Type-safe programmatic configuration
042 *          <li>Direct class references in code
043 *          <li>Avoiding string-based name matching
044 *       </ul>
045 * </ul>
046 *
047 * <h5 class='section'>Example:</h5>
048 * <p class='bjava'>
049 *    <jc>// Using onClass() for type-safe targeting</jc>
050 *    MarshalledAnnotation <jv>annotation</jv> = MarshalledAnnotation
051 *       .<jsm>create</jsm>()
052 *       .onClass(MyClass.<jk>class</jk>, MyOtherClass.<jk>class</jk>)
053 *       .sort(<jk>true</jk>)
054 *       .build();
055 *
056 *    <jc>// Using on() for string-based targeting</jc>
057 *    MarshalledAnnotation <jv>annotation2</jv> = MarshalledAnnotation
058 *       .<jsm>create</jsm>()
059 *       .on(<js>"com.example.MyClass"</js>, <js>"com.example.MyOtherClass"</js>)
060 *       .sort(<jk>true</jk>)
061 *       .build();
062 *
063 *    <jc>// Can use both together</jc>
064 *    MarshalledAnnotation <jv>annotation3</jv> = MarshalledAnnotation
065 *       .<jsm>create</jsm>()
066 *       .on(<js>"com.example.MyClass"</js>)  <jc>// String-based</jc>
067 *       .onClass(MyOtherClass.<jk>class</jk>)  <jc>// Type-safe</jc>
068 *       .sort(<jk>true</jk>)
069 *       .build();
070 * </p>
071 *
072 * <h5 class='section'>Notes:</h5>
073 * <ul class='spaced-list'>
074 *    <li>The {@link #on()} method returns string representations of ALL targets (both string-based and class-based)
075 *    <li>The {@link #onClass()} method returns only the Class object targets
076 *    <li>When using {@link AppliedAnnotationObject.BuilderT#on(Class...) BuilderT.on(Class...)}, classes are converted to strings and stored in {@link #on()}
077 *    <li>When using {@link AppliedAnnotationObject.BuilderT#onClass(Class...) BuilderT.onClass(Class...)}, classes are stored as Class objects in {@link #onClass()}
078 * </ul>
079 *
080 * <h5 class='section'>See Also:</h5><ul>
081 *    <li class='jc'>{@link AppliedAnnotationObject} - Parent class documentation
082 *    <li class='link'><a class="doclink" href="../../../../../overview-summary.html#juneau-commons.Annotations">Overview &gt; juneau-commons &gt; Annotations</a>
083 * </ul>
084 */
085// java:S2160: Intentionally inherit equals/hashCode from AnnotationObject. Overriding would require
086// instanceof AppliedOnClassAnnotationObject, which breaks comparison with declarative annotations (JDK proxies),
087// causing MarshallingContext/PropertyStore cache misses and schema validation failures (see XmlAnnotation_Test, FormData_Test).
088@SuppressWarnings({
089   "java:S2160" // Inherits equals/hashCode from parent; annotation identity based on type and attributes
090})
091public class AppliedOnClassAnnotationObject extends AppliedAnnotationObject {
092
093   private final Class<?>[] onClass;
094
095   /**
096    * Constructor.
097    *
098    * @param b The builder used to instantiate the fields of this class.  Must not be <jk>null</jk>.
099    */
100   public AppliedOnClassAnnotationObject(BuilderT b) {
101      super(b);
102      this.onClass = cp(b.onClass);
103   }
104
105   /**
106    * The targets this annotation applies to.
107    *
108    * @return The targets this annotation applies to.
109    */
110   public Class<?>[] onClass() {
111      return cp(onClass);
112   }
113}