View Javadoc
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 }