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<AnnotationInfo<MyAnnotation>> <jv>s1</jv> = 036 * annotationProvider.streamClassAnnotations(MyAnnotation.<jk>class</jk>, <jv>ci</jv>, PACKAGE, PARENTS, SELF); 037 * Stream<AnnotationInfo<MyAnnotation>> <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<AnnotationInfo<MyAnnotation>> <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<AnnotationInfo<MyAnnotation>> <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}