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 019import static org.apache.juneau.commons.utils.ClassUtils.*; 020import static org.apache.juneau.commons.utils.Shorts.*; 021 022import java.lang.reflect.*; 023 024/** 025 * Defines class/field/method visibilities. 026 * 027 * <p> 028 * Used to specify minimum levels of visibility when detecting bean classes, methods, and fields. 029 * 030 * <p> 031 * Used in conjunction with the following bean context properties: 032 * <ul class='javatree'> 033 * <li class='jm'>MarshallingContext.Builder.beanConstructorVisibility 034 * <li class='jm'>MarshallingContext.Builder.beanClassVisibility 035 * <li class='jm'>MarshallingContext.Builder.beanFieldVisibility 036 * <li class='jm'>MarshallingContext.Builder.beanMethodVisibility 037 * </ul> 038 * 039 */ 040@SuppressWarnings({ 041 "java:S1192" // Duplicated literals (argument/property names) read more clearly inline than as constants 042}) 043public enum Visibility { 044 045 /** Ignore all */ 046 NONE, 047 048 /** Include only <jk>public</jk> classes/fields/methods. */ 049 PUBLIC, 050 051 /** Include only <jk>public</jk> or <jk>protected</jk> classes/fields/methods. */ 052 PROTECTED, 053 054 /** Include all but <jk>private</jk> classes/fields/methods. */ 055 DEFAULT, 056 057 /** Include all classes/fields/methods. */ 058 PRIVATE; 059 060 /** 061 * Shortcut for <c>isVisible(x.getModifiers());</c> 062 * 063 * @param x The class to check. Must not be <jk>null</jk>. 064 * @return <jk>true</jk> if the class is at least as visible as this object. 065 */ 066 public boolean isVisible(Class<?> x) { 067 return isVisible(x.getModifiers()); 068 } 069 070 /** 071 * Shortcut for <c>isVisible(x.getModifiers());</c> 072 * 073 * @param x The constructor to check. Must not be <jk>null</jk>. 074 * @return <jk>true</jk> if the constructor is at least as visible as this object. 075 */ 076 public boolean isVisible(Executable x) { 077 return isVisible(x.getModifiers()); 078 } 079 080 /** 081 * Shortcut for <c>isVisible(x.getModifiers());</c> 082 * 083 * @param x The field to check. Must not be <jk>null</jk>. 084 * @return <jk>true</jk> if the field is at least as visible as this object. 085 */ 086 public boolean isVisible(Field x) { 087 return isVisible(x.getModifiers()); 088 } 089 090 /** 091 * Identifies if the specified mod matches this visibility. 092 * 093 * <h5 class='section'>Example:</h5> 094 * <p class='bjava'> 095 * <jsf>PUBLIC</jsf>.isVisible(MyPublicClass.<jk>class</jk>.getModifiers()); <jc>//true</jc> 096 * <jsf>PUBLIC</jsf>.isVisible(MyPrivateClass.<jk>class</jk>.getModifiers()); <jc>//false</jc> 097 * <jsf>PRIVATE</jsf>.isVisible(MyPrivateClass.<jk>class</jk>.getModifiers()); <jc>//true</jc> 098 * <jsf>NONE</jsf>.isVisible(MyPublicClass.<jk>class</jk>.getModifiers()); <jc>//false</jc> 099 * </p> 100 * 101 * @param mod The modifier from the object being tested (e.g. results from {@link Class#getModifiers()}. 102 * @return <jk>true</jk> if this visibility matches the specified modifier attribute. 103 */ 104 public boolean isVisible(int mod) { 105 return switch (this) { 106 case NONE -> false; 107 case PRIVATE -> true; 108 case DEFAULT -> ! Modifier.isPrivate(mod); 109 case PROTECTED -> Modifier.isProtected(mod) || Modifier.isPublic(mod); 110 default -> Modifier.isPublic(mod); 111 }; 112 } 113 114 /** 115 * Makes constructor accessible if it matches the visibility requirements, or returns <jk>null</jk> if it doesn't. 116 * 117 * <p> 118 * Security exceptions thrown on the call to {@link Constructor#setAccessible(boolean)} are quietly ignored. 119 * 120 * @param <T> The class type. 121 * @param x The constructor. Must not be <jk>null</jk>. 122 * @return 123 * The same constructor if visibility requirements met, or <jk>null</jk> if visibility requirement not 124 * met or call to {@link Constructor#setAccessible(boolean)} throws a security exception. 125 * @throws IllegalArgumentException If <c>x</c> is <jk>null</jk>. 126 */ 127 public <T> Constructor<T> transform(Constructor<T> x) { 128 reqnn("x", x); 129 if (isVisible(x) && ! setAccessible(x)) 130 return null; // HTT 131 return x; 132 } 133 134 /** 135 * Makes field accessible if it matches the visibility requirements, or returns <jk>null</jk> if it doesn't. 136 * 137 * <p> 138 * Security exceptions thrown on the call to {@link Field#setAccessible(boolean)} are quietly ignored. 139 * 140 * @param x The field. Must not be <jk>null</jk>. 141 * @return 142 * The same field if visibility requirements met, or <jk>null</jk> if visibility requirement not 143 * met or call to {@link Field#setAccessible(boolean)} throws a security exception. 144 * @throws IllegalArgumentException If <c>x</c> is <jk>null</jk>. 145 */ 146 public Field transform(Field x) { 147 reqnn("x", x); 148 if (isVisible(x) && ! 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 reqnn("x", x); 167 if (isVisible(x) && ! setAccessible(x)) 168 return null; // HTT 169 return x; 170 } 171}