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
017import org.apache.juneau.internal.*;
018
019/**
020 * Defines class/field/method visibilities.
021 *
022 * <p>
023 * Used to specify minimum levels of visibility when detecting bean classes, methods, and fields.
024 *
025 * <p>
026 * Used in conjunction with the following bean context properties:
027 * <ul>
028 *    <li class='jf'>{@link BeanContext#BEAN_beanConstructorVisibility}
029 *    <li class='jf'>{@link BeanContext#BEAN_beanClassVisibility}
030 *    <li class='jf'>{@link BeanContext#BEAN_beanFieldVisibility}
031 *    <li class='jf'>{@link BeanContext#BEAN_beanMethodVisibility}
032 * </ul>
033 */
034public enum Visibility {
035
036   /** Ignore all */
037   NONE,
038
039   /** Include only <jk>public</jk> classes/fields/methods. */
040   PUBLIC,
041
042   /** Include only <jk>public</jk> or <jk>protected</jk> classes/fields/methods. */
043   PROTECTED,
044
045   /** Include all but <jk>private</jk> classes/fields/methods. */
046   DEFAULT,
047
048   /** Include all classes/fields/methods. */
049   PRIVATE;
050
051   /**
052    * Identifies if the specified mod matches this visibility.
053    *
054    * <h5 class='section'>Example:</h5>
055    * <p class='bcode w800'>
056    *    <jsf>PUBLIC</jsf>.isVisible(MyPublicClass.<jk>class</jk>.getModifiers()); <jc>//true</jc>
057    *    <jsf>PUBLIC</jsf>.isVisible(MyPrivateClass.<jk>class</jk>.getModifiers()); <jc>//false</jc>
058    *    <jsf>PRIVATE</jsf>.isVisible(MyPrivateClass.<jk>class</jk>.getModifiers()); <jc>//true</jc>
059    *    <jsf>NONE</jsf>.isVisible(MyPublicClass.<jk>class</jk>.getModifiers()); <jc>//false</jc>
060    * </p>
061    *
062    * @param mod The modifier from the object being tested (e.g. results from {@link Class#getModifiers()}.
063    * @return <jk>true</jk> if this visibility matches the specified modifier attribute.
064    */
065   public boolean isVisible(int mod) {
066      switch(this) {
067         case NONE: return false;
068         case PRIVATE: return true;
069         case DEFAULT: return ! Modifier.isPrivate(mod);
070         case PROTECTED: return Modifier.isProtected(mod) || Modifier.isPublic(mod);
071         default: return Modifier.isPublic(mod);
072      }
073   }
074
075   /**
076    * Shortcut for <code>isVisible(x.getModifiers());</code>
077    *
078    * @param x The constructor to check.
079    * @return <jk>true</jk> if the constructor is at least as visible as this object.
080    */
081   public boolean isVisible(Constructor<?> x) {
082      return isVisible(x.getModifiers());
083   }
084
085   /**
086    * Shortcut for <code>isVisible(x.getModifiers());</code>
087    *
088    * @param x The method to check.
089    * @return <jk>true</jk> if the method is at least as visible as this object.
090    */
091   public boolean isVisible(Method x) {
092      return isVisible(x.getModifiers());
093   }
094
095   /**
096    * Shortcut for <code>isVisible(x.getModifiers());</code>
097    *
098    * @param x The field to check.
099    * @return <jk>true</jk> if the field is at least as visible as this object.
100    */
101   public boolean isVisible(Field x) {
102      return isVisible(x.getModifiers());
103   }
104
105   /**
106    * Makes constructor accessible if it matches the visibility requirements, or returns <jk>null</jk> if it doesn't.
107    *
108    * <p>
109    * Security exceptions thrown on the call to {@link Constructor#setAccessible(boolean)} are quietly ignored.
110    *
111    * @param x The constructor.
112    * @return
113    *    The same constructor if visibility requirements met, or <jk>null</jk> if visibility requirement not
114    *    met or call to {@link Constructor#setAccessible(boolean)} throws a security exception.
115    */
116   public <T> Constructor<T> transform(Constructor<T> x) {
117      if (x == null)
118         return null;
119      if (isVisible(x))
120         if (! ClassUtils.setAccessible(x, true))
121            return null;
122      return x;
123   }
124
125   /**
126    * Makes method accessible if it matches the visibility requirements, or returns <jk>null</jk> if it doesn't.
127    *
128    * <p>
129    * Security exceptions thrown on the call to {@link Method#setAccessible(boolean)} are quietly ignored.
130    *
131    * @param x The method.
132    * @return
133    *    The same method if visibility requirements met, or <jk>null</jk> if visibility requirement not
134    *    met or call to {@link Method#setAccessible(boolean)} throws a security exception.
135    */
136   public Method transform(Method x) {
137      if (x == null)
138         return null;
139      if (isVisible(x))
140         if (! ClassUtils.setAccessible(x, true))
141            return null;
142      return x;
143   }
144
145   /**
146    * Makes field accessible if it matches the visibility requirements, or returns <jk>null</jk> if it doesn't.
147    *
148    * <p>
149    * Security exceptions thrown on the call to {@link Field#setAccessible(boolean)} are quietly ignored.
150    *
151    * @param x The field.
152    * @return
153    *    The same field if visibility requirements met, or <jk>null</jk> if visibility requirement not
154    *    met or call to {@link Field#setAccessible(boolean)} throws a security exception.
155    */
156   public Field transform(Field x) {
157      if (x == null)
158         return null;
159      if (isVisible(x))
160         if (! ClassUtils.setAccessible(x, true))
161            return null;
162      return x;
163   }
164
165   /**
166    * @deprecated Use {@link ClassUtils#setAccessible(Constructor, boolean)}
167    */
168   @SuppressWarnings("javadoc")
169   @Deprecated
170   public static boolean setAccessible(Constructor<?> x) {
171      return ClassUtils.setAccessible(x, true);
172   }
173
174   /**
175    * @deprecated Use {@link ClassUtils#setAccessible(Method, boolean)}
176    */
177   @SuppressWarnings("javadoc")
178   @Deprecated
179   public static boolean setAccessible(Method x) {
180      return ClassUtils.setAccessible(x, true);
181   }
182
183   /**
184    * @deprecated Use {@link ClassUtils#setAccessible(Field, boolean)}
185    */
186   @SuppressWarnings("javadoc")
187   @Deprecated
188   public static boolean setAccessible(Field x) {
189      return ClassUtils.setAccessible(x, true);
190   }
191}