1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.juneau.commons.reflect;
18
19 import static org.apache.juneau.commons.utils.AssertionUtils.*;
20 import static org.apache.juneau.commons.utils.ClassUtils.*;
21
22 import java.beans.beancontext.*;
23 import java.lang.reflect.*;
24
25 /**
26 * Defines class/field/method visibilities.
27 *
28 * <p>
29 * Used to specify minimum levels of visibility when detecting bean classes, methods, and fields.
30 *
31 * <p>
32 * Used in conjunction with the following bean context properties:
33 * <ul class='javatree'>
34 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanConstructorVisibility}
35 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanClassVisibility}
36 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanFieldVisibility}
37 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanMethodVisibility}
38 * </ul>
39 *
40 */
41 public enum Visibility {
42
43 /** Ignore all */
44 NONE,
45
46 /** Include only <jk>public</jk> classes/fields/methods. */
47 PUBLIC,
48
49 /** Include only <jk>public</jk> or <jk>protected</jk> classes/fields/methods. */
50 PROTECTED,
51
52 /** Include all but <jk>private</jk> classes/fields/methods. */
53 DEFAULT,
54
55 /** Include all classes/fields/methods. */
56 PRIVATE;
57
58 /**
59 * Shortcut for <c>isVisible(x.getModifiers());</c>
60 *
61 * @param x The class to check.
62 * @return <jk>true</jk> if the class is at least as visible as this object.
63 */
64 public boolean isVisible(Class<?> x) {
65 return isVisible(x.getModifiers());
66 }
67
68 /**
69 * Shortcut for <c>isVisible(x.getModifiers());</c>
70 *
71 * @param x The constructor to check.
72 * @return <jk>true</jk> if the constructor is at least as visible as this object.
73 */
74 public boolean isVisible(Executable x) {
75 return isVisible(x.getModifiers());
76 }
77
78 /**
79 * Shortcut for <c>isVisible(x.getModifiers());</c>
80 *
81 * @param x The field to check.
82 * @return <jk>true</jk> if the field is at least as visible as this object.
83 */
84 public boolean isVisible(Field x) {
85 return isVisible(x.getModifiers());
86 }
87
88 /**
89 * Identifies if the specified mod matches this visibility.
90 *
91 * <h5 class='section'>Example:</h5>
92 * <p class='bjava'>
93 * <jsf>PUBLIC</jsf>.isVisible(MyPublicClass.<jk>class</jk>.getModifiers()); <jc>//true</jc>
94 * <jsf>PUBLIC</jsf>.isVisible(MyPrivateClass.<jk>class</jk>.getModifiers()); <jc>//false</jc>
95 * <jsf>PRIVATE</jsf>.isVisible(MyPrivateClass.<jk>class</jk>.getModifiers()); <jc>//true</jc>
96 * <jsf>NONE</jsf>.isVisible(MyPublicClass.<jk>class</jk>.getModifiers()); <jc>//false</jc>
97 * </p>
98 *
99 * @param mod The modifier from the object being tested (e.g. results from {@link Class#getModifiers()}.
100 * @return <jk>true</jk> if this visibility matches the specified modifier attribute.
101 */
102 public boolean isVisible(int mod) {
103 return switch (this) {
104 case NONE -> false;
105 case PRIVATE -> true;
106 case DEFAULT -> ! Modifier.isPrivate(mod);
107 case PROTECTED -> Modifier.isProtected(mod) || Modifier.isPublic(mod);
108 default -> Modifier.isPublic(mod);
109 };
110 }
111
112 /**
113 * Makes constructor accessible if it matches the visibility requirements, or returns <jk>null</jk> if it doesn't.
114 *
115 * <p>
116 * Security exceptions thrown on the call to {@link Constructor#setAccessible(boolean)} are quietly ignored.
117 *
118 * @param <T> The class type.
119 * @param x The constructor. Must not be <jk>null</jk>.
120 * @return
121 * The same constructor if visibility requirements met, or <jk>null</jk> if visibility requirement not
122 * met or call to {@link Constructor#setAccessible(boolean)} throws a security exception.
123 * @throws IllegalArgumentException If <c>x</c> is <jk>null</jk>.
124 */
125 public <T> Constructor<T> transform(Constructor<T> x) {
126 assertArgNotNull("x", x);
127 if (isVisible(x))
128 if (! setAccessible(x))
129 return null; // HTT
130 return x;
131 }
132
133 /**
134 * Makes field accessible if it matches the visibility requirements, or returns <jk>null</jk> if it doesn't.
135 *
136 * <p>
137 * Security exceptions thrown on the call to {@link Field#setAccessible(boolean)} are quietly ignored.
138 *
139 * @param x The field. Must not be <jk>null</jk>.
140 * @return
141 * The same field if visibility requirements met, or <jk>null</jk> if visibility requirement not
142 * met or call to {@link Field#setAccessible(boolean)} throws a security exception.
143 * @throws IllegalArgumentException If <c>x</c> is <jk>null</jk>.
144 */
145 public Field transform(Field x) {
146 assertArgNotNull("x", x);
147 if (isVisible(x))
148 if (! setAccessible(x))
149 return null; // HTT
150 return x;
151 }
152
153 /**
154 * Makes method accessible if it matches the visibility requirements, or returns <jk>null</jk> if it doesn't.
155 *
156 * <p>
157 * Security exceptions thrown on the call to {@link Method#setAccessible(boolean)} are quietly ignored.
158 *
159 * @param x The method. Must not be <jk>null</jk>.
160 * @return
161 * The same method if visibility requirements met, or <jk>null</jk> if visibility requirement not
162 * met or call to {@link Method#setAccessible(boolean)} throws a security exception.
163 * @throws IllegalArgumentException If <c>x</c> is <jk>null</jk>.
164 */
165 public Method transform(Method x) {
166 assertArgNotNull("x", x);
167 if (isVisible(x))
168 if (! setAccessible(x))
169 return null; // HTT
170 return x;
171 }
172 }