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.reflect;
018
019/**
020 * Defines traversal options for annotation searches.
021 *
022 * <p>
023 * These enums configure what elements to traverse and in what order when searching for annotations.
024 * They are used with {@link AnnotationProvider#find(Class, ClassInfo, AnnotationTraversal...)} 
025 * and related methods.
026 *
027 * <p>
028 * Each traversal type has an order of precedence that determines the search order.
029 * When multiple traversal types are specified, they are automatically sorted by their precedence
030 * to ensure consistent behavior regardless of the order they are specified.
031 *
032 * <h5 class='section'>Example:</h5>
033 * <p class='bjava'>
034 *    <jc>// These produce the same result (automatically sorted by precedence):</jc>
035 *    Stream&lt;AnnotationInfo&lt;MyAnnotation&gt;&gt; <jv>s1</jv> = 
036 *       annotationProvider.streamClassAnnotations(MyAnnotation.<jk>class</jk>, <jv>ci</jv>, PACKAGE, PARENTS, SELF);
037 *    Stream&lt;AnnotationInfo&lt;MyAnnotation&gt;&gt; <jv>s2</jv> = 
038 *       annotationProvider.streamClassAnnotations(MyAnnotation.<jk>class</jk>, <jv>ci</jv>, SELF, PARENTS, PACKAGE);
039 * </p>
040 *
041 * <h5 class='section'>See Also:</h5><ul>
042 *    <li class='jc'>{@link AnnotationProvider}
043 *    <li class='jm'>{@link AnnotationProvider#find(Class, ClassInfo, AnnotationTraversal...)}
044 *    <li class='jm'>{@link AnnotationProvider#find(Class, MethodInfo, AnnotationTraversal...)}
045 *    <li class='jm'>{@link AnnotationProvider#find(Class, ParameterInfo, AnnotationTraversal...)}
046 * </ul>
047 */
048public enum AnnotationTraversal {
049
050   /**
051    * Include the element itself (class, method, field, constructor, parameter).
052    *
053    * <p>
054    * This searches for annotations directly declared on the target element.
055    *
056    * <h5 class='section'>Applicable to:</h5>
057    * All element types (classes, methods, fields, constructors, parameters).
058    *
059    * <h5 class='section'>Order:</h5>
060    * Precedence: 10 (highest - searched first)
061    */
062   SELF(10),
063
064   /**
065    * Include parent classes and interfaces in the traversal.
066    *
067    * <p>
068    * For classes: Traverses the superclass hierarchy and all implemented interfaces,
069    * interleaved in child-to-parent order (using {@link ClassInfo#getParentsAndInterfaces()}).
070    * Default order is child-to-parent unless {@link #REVERSE} is specified.
071    *
072    * <h5 class='section'>Applicable to:</h5>
073    * Classes.
074    *
075    * <h5 class='section'>Example:</h5>
076    * <p class='bjava'>
077    *    <jc>// Given: class Child extends Parent implements Interface</jc>
078    *    <jc>// Traverses parents and interfaces interleaved: Parent → Interface → GrandParent → ...</jc>
079    * </p>
080    *
081    * <h5 class='section'>Order:</h5>
082    * Precedence: 20
083    */
084   PARENTS(20),
085
086   /**
087    * Include matching methods in the traversal.
088    *
089    * <p>
090    * For methods: Searches annotations on methods with the same signature in parent classes and interfaces.
091    * This finds annotations on overridden methods.
092    *
093    * <h5 class='section'>Applicable to:</h5>
094    * Methods.
095    *
096    * <h5 class='section'>Example:</h5>
097    * <p class='bjava'>
098    *    <jc>// Given:</jc>
099    *    <jk>class</jk> Parent {
100    *       <ja>@MyAnnotation</ja>
101    *       <jk>public void</jk> method() {}
102    *    }
103    *    <jk>class</jk> Child <jk>extends</jk> Parent {
104    *       <ja>@Override</ja>
105    *       <jk>public void</jk> method() {}  <jc>// Will find @MyAnnotation from Parent</jc>
106    *    }
107    * </p>
108    *
109    * <h5 class='section'>Order:</h5>
110    * Precedence: 20
111    */
112   MATCHING_METHODS(20),
113
114   /**
115    * Include matching parameters in the traversal.
116    *
117    * <p>
118    * For parameters: Searches annotations on parameters in matching parent methods or constructors.
119    * This finds annotations on parameters in overridden methods or parent constructors.
120    *
121    * <h5 class='section'>Applicable to:</h5>
122    * Parameters.
123    *
124    * <h5 class='section'>Example:</h5>
125    * <p class='bjava'>
126    *    <jc>// Given:</jc>
127    *    <jk>class</jk> Parent {
128    *       <jk>public void</jk> method(<ja>@MyAnnotation</ja> String <jv>param</jv>) {}
129    *    }
130    *    <jk>class</jk> Child <jk>extends</jk> Parent {
131    *       <ja>@Override</ja>
132    *       <jk>public void</jk> method(String <jv>param</jv>) {}  <jc>// Will find @MyAnnotation from Parent</jc>
133    *    }
134    * </p>
135    *
136    * <h5 class='section'>Order:</h5>
137    * Precedence: 20
138    */
139   MATCHING_PARAMETERS(20),
140
141   /**
142    * Include the return type in the traversal.
143    *
144    * <p>
145    * For methods: Searches annotations on the method's return type and its hierarchy.
146    * Automatically includes {@link #PARENTS} of the return type.
147    *
148    * <h5 class='section'>Applicable to:</h5>
149    * Methods.
150    *
151    * <h5 class='section'>Example:</h5>
152    * <p class='bjava'>
153    *    <jc>// Given: public MyClass myMethod() {...}</jc>
154    *    <jc>// Searches: MyClass hierarchy and its interfaces</jc>
155    * </p>
156    *
157    * <h5 class='section'>Order:</h5>
158    * Precedence: 30
159    */
160   RETURN_TYPE(30),
161
162   /**
163    * Include the declaring class hierarchy in the traversal.
164    *
165    * <p>
166    * For methods, fields, and constructors: Searches annotations on the declaring class and its parent hierarchy.
167    * Automatically includes the declaring class and all its parents and interfaces.
168    *
169    * <h5 class='section'>Applicable to:</h5>
170    * Methods, fields, and constructors.
171    *
172    * <h5 class='section'>Example:</h5>
173    * <p class='bjava'>
174    *    <jc>// Given: class Child extends Parent { void method() {...} }</jc>
175    *    <jc>// Searches: Child hierarchy (Child, Parent, interfaces, etc.)</jc>
176    * </p>
177    *
178    * <h5 class='section'>Order:</h5>
179    * Precedence: 35
180    */
181   DECLARING_CLASS(35),
182
183   /**
184    * Include the parameter type in the traversal.
185    *
186    * <p>
187    * For parameters: Searches annotations on the parameter's type and its hierarchy.
188    * Automatically includes {@link #PARENTS} and {@link #PACKAGE} of the parameter type.
189    *
190    * <h5 class='section'>Applicable to:</h5>
191    * Parameters.
192    *
193    * <h5 class='section'>Example:</h5>
194    * <p class='bjava'>
195    *    <jc>// Given: void method(MyClass param) {...}</jc>
196    *    <jc>// Searches: MyClass hierarchy, its interfaces, and package</jc>
197    * </p>
198    *
199    * <h5 class='section'>Order:</h5>
200    * Precedence: 30
201    */
202   PARAMETER_TYPE(30),
203
204   /**
205    * Include package annotations in the traversal.
206    *
207    * <p>
208    * Searches for annotations on the package-info class.
209    *
210    * <h5 class='section'>Applicable to:</h5>
211    * Classes and parameters (via {@link #PARAMETER_TYPE}).
212    *
213    * <h5 class='section'>Example:</h5>
214    * <p class='bjava'>
215    *    <jc>// Searches annotations in package-info.java</jc>
216    * </p>
217    *
218    * <h5 class='section'>Order:</h5>
219    * Precedence: 40 (lowest - searched last)
220    */
221   PACKAGE(40),
222
223   /**
224    * Reverse the order of the resulting stream.
225    *
226    * <p>
227    * When this flag is present, the final stream is wrapped in {@code rstream()} to reverse the order.
228    * This allows parent-first ordering (parent annotations before child annotations).
229    *
230    * <p>
231    * By default, traversals return results in child-to-parent order (child annotations first).
232    * Using {@code REVERSE} changes this to parent-to-child order (parent annotations first).
233    *
234    * <h5 class='section'>Applicable to:</h5>
235    * All stream-based traversal methods.
236    *
237    * <h5 class='section'>Example:</h5>
238    * <p class='bjava'>
239    *    <jc>// Default (child-first): Child → Parent → GrandParent</jc>
240    *    Stream&lt;AnnotationInfo&lt;MyAnnotation&gt;&gt; <jv>s1</jv> = 
241    *       streamClassAnnotations(MyAnnotation.<jk>class</jk>, <jv>ci</jv>, PARENTS);
242    *
243    *    <jc>// With REVERSE (parent-first): GrandParent → Parent → Child</jc>
244    *    Stream&lt;AnnotationInfo&lt;MyAnnotation&gt;&gt; <jv>s2</jv> = 
245    *       streamClassAnnotations(MyAnnotation.<jk>class</jk>, <jv>ci</jv>, PARENTS, REVERSE);
246    * </p>
247    *
248    * <h5 class='section'>Order:</h5>
249    * Precedence: 999 (modifier - does not affect traversal order)
250    */
251   REVERSE(999);
252
253   private final int order;
254
255   AnnotationTraversal(int order) {
256      this.order = order;
257   }
258
259   /**
260    * Returns the precedence order of this traversal type.
261    *
262    * <p>
263    * Lower values have higher precedence and are processed first.
264    *
265    * @return The order value.
266    */
267   public int getOrder() { return order; }
268}