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