001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau; 014 015import java.lang.reflect.*; 016 017/** 018 * Defines class/field/method visibilities. 019 * 020 * <p> 021 * Used to specify minimum levels of visibility when detecting bean classes, methods, and fields. 022 * 023 * <p> 024 * Used in conjunction with the following bean context properties: 025 * <ul> 026 * <li class='jf'>{@link BeanContext#BEAN_beanConstructorVisibility} 027 * <li class='jf'>{@link BeanContext#BEAN_beanClassVisibility} 028 * <li class='jf'>{@link BeanContext#BEAN_beanFieldVisibility} 029 * <li class='jf'>{@link BeanContext#BEAN_beanMethodVisibility} 030 * </ul> 031 */ 032public enum Visibility { 033 034 /** Ignore all */ 035 NONE, 036 037 /** Include only <jk>public</jk> classes/fields/methods. */ 038 PUBLIC, 039 040 /** Include only <jk>public</jk> or <jk>protected</jk> classes/fields/methods. */ 041 PROTECTED, 042 043 /** Include all but <jk>private</jk> classes/fields/methods. */ 044 DEFAULT, 045 046 /** Include all classes/fields/methods. */ 047 PRIVATE; 048 049 /** 050 * Identifies if the specified mod matches this visibility. 051 * 052 * <h5 class='section'>Example:</h5> 053 * <p class='bcode'> 054 * <jsf>PUBLIC</jsf>.isVisible(MyPublicClass.<jk>class</jk>.getModifiers()); <jc>//true</jc> 055 * <jsf>PUBLIC</jsf>.isVisible(MyPrivateClass.<jk>class</jk>.getModifiers()); <jc>//false</jc> 056 * <jsf>PRIVATE</jsf>.isVisible(MyPrivateClass.<jk>class</jk>.getModifiers()); <jc>//true</jc> 057 * <jsf>NONE</jsf>.isVisible(MyPublicClass.<jk>class</jk>.getModifiers()); <jc>//false</jc> 058 * </p> 059 * 060 * @param mod The modifier from the object being tested (e.g. results from {@link Class#getModifiers()}. 061 * @return <jk>true</jk> if this visibility matches the specified modifier attribute. 062 */ 063 public boolean isVisible(int mod) { 064 switch(this) { 065 case NONE: return false; 066 case PRIVATE: return true; 067 case DEFAULT: return ! Modifier.isPrivate(mod); 068 case PROTECTED: return Modifier.isProtected(mod) || Modifier.isPublic(mod); 069 default: return Modifier.isPublic(mod); 070 } 071 } 072 073 /** 074 * Shortcut for <code>isVisible(x.getModifiers());</code> 075 * 076 * @param x The constructor to check. 077 * @return <jk>true</jk> if the constructor is at least as visible as this object. 078 */ 079 public boolean isVisible(Constructor<?> x) { 080 return isVisible(x.getModifiers()); 081 } 082 083 /** 084 * Shortcut for <code>isVisible(x.getModifiers());</code> 085 * 086 * @param x The method to check. 087 * @return <jk>true</jk> if the method is at least as visible as this object. 088 */ 089 public boolean isVisible(Method x) { 090 return isVisible(x.getModifiers()); 091 } 092 093 /** 094 * Shortcut for <code>isVisible(x.getModifiers());</code> 095 * 096 * @param x The field to check. 097 * @return <jk>true</jk> if the field is at least as visible as this object. 098 */ 099 public boolean isVisible(Field x) { 100 return isVisible(x.getModifiers()); 101 } 102 103 /** 104 * Makes constructor accessible if it matches the visibility requirements, or returns <jk>null</jk> if it doesn't. 105 * 106 * <p> 107 * Security exceptions thrown on the call to {@link Constructor#setAccessible(boolean)} are quietly ignored. 108 * 109 * @param x The constructor. 110 * @return 111 * The same constructor if visibility requirements met, or <jk>null</jk> if visibility requirement not 112 * met or call to {@link Constructor#setAccessible(boolean)} throws a security exception. 113 */ 114 public <T> Constructor<T> transform(Constructor<T> x) { 115 if (x == null) 116 return null; 117 if (isVisible(x)) 118 if (! setAccessible(x)) 119 return null; 120 return x; 121 } 122 123 /** 124 * Makes method accessible if it matches the visibility requirements, or returns <jk>null</jk> if it doesn't. 125 * 126 * <p> 127 * Security exceptions thrown on the call to {@link Method#setAccessible(boolean)} are quietly ignored. 128 * 129 * @param x The method. 130 * @return 131 * The same method if visibility requirements met, or <jk>null</jk> if visibility requirement not 132 * met or call to {@link Method#setAccessible(boolean)} throws a security exception. 133 */ 134 public Method transform(Method x) { 135 if (x == null) 136 return null; 137 if (isVisible(x)) 138 if (! setAccessible(x)) 139 return null; 140 return x; 141 } 142 143 /** 144 * Makes field accessible if it matches the visibility requirements, or returns <jk>null</jk> if it doesn't. 145 * 146 * <p> 147 * Security exceptions thrown on the call to {@link Field#setAccessible(boolean)} are quietly ignored. 148 * 149 * @param x The field. 150 * @return 151 * The same field if visibility requirements met, or <jk>null</jk> if visibility requirement not 152 * met or call to {@link Field#setAccessible(boolean)} throws a security exception. 153 */ 154 public Field transform(Field x) { 155 if (x == null) 156 return null; 157 if (isVisible(x)) 158 if (! setAccessible(x)) 159 return null; 160 return x; 161 } 162 163 /** 164 * Attempts to call <code>x.setAccessible(<jk>true</jk>)</code> and quietly ignores security exceptions. 165 * 166 * @param x The constructor. 167 * @return <jk>true</jk> if call was successful. 168 */ 169 public static boolean setAccessible(Constructor<?> x) { 170 try { 171 if (! (x == null || x.isAccessible())) 172 x.setAccessible(true); 173 return true; 174 } catch (SecurityException e) { 175 return false; 176 } 177 } 178 179 /** 180 * Attempts to call <code>x.setAccessible(<jk>true</jk>)</code> and quietly ignores security exceptions. 181 * 182 * @param x The method. 183 * @return <jk>true</jk> if call was successful. 184 */ 185 public static boolean setAccessible(Method x) { 186 try { 187 if (! (x == null || x.isAccessible())) 188 x.setAccessible(true); 189 return true; 190 } catch (SecurityException e) { 191 return false; 192 } 193 } 194 195 /** 196 * Attempts to call <code>x.setAccessible(<jk>true</jk>)</code> and quietly ignores security exceptions. 197 * 198 * @param x The field. 199 * @return <jk>true</jk> if call was successful. 200 */ 201 public static boolean setAccessible(Field x) { 202 try { 203 if (! (x == null || x.isAccessible())) 204 x.setAccessible(true); 205 return true; 206 } catch (SecurityException e) { 207 return false; 208 } 209 } 210}