1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.catalina.util;
import java.beans.Introspector;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedAction;
import org.apache.catalina.Context;
import org.apache.catalina.Globals;
import org.apache.juli.logging.Log;
import org.apache.tomcat.util.ExceptionUtils;
import org.apache.tomcat.util.res.StringManager;
/**
* Provides introspection utilities that either require knowledge of Tomcat internals or are solely used by Tomcat
* internals.
*/
public class Introspection {
private static final StringManager sm = StringManager.getManager("org.apache.catalina.util");
/**
* Extract the Java Bean property name from the setter name. Note: This method assumes that the method name has
* already been checked for correctness.
*
* @param setter The setter method
*
* @return the bean property name
*/
public static String getPropertyName(Method setter) {
return Introspector.decapitalize(setter.getName().substring(3));
}
/**
* Determines if a method has a valid name and signature for a Java Bean setter.
*
* @param method The method to test
*
* @return <code>true</code> if the method does have a valid name and signature, else <code>false</code>
*/
public static boolean isValidSetter(Method method) {
return method.getName().startsWith("set") && method.getName().length() > 3 &&
method.getParameterTypes().length == 1 && method.getReturnType().getName().equals("void");
}
/**
* Determines if a method is a valid lifecycle callback method.
*
* @param method The method to test
*
* @return <code>true</code> if the method is a valid lifecycle callback method, else <code>false</code>
*/
public static boolean isValidLifecycleCallback(Method method) {
return method.getParameterTypes().length == 0 && !Modifier.isStatic(method.getModifiers()) &&
method.getExceptionTypes().length == 0 && method.getReturnType().getName().equals("void");
}
/**
* Obtain the declared fields for a class taking account of any security manager that may be configured.
*
* @param clazz The class to introspect
*
* @return the class fields as an array
*/
public static Field[] getDeclaredFields(final Class<?> clazz) {
Field[] fields = null;
if (Globals.IS_SECURITY_ENABLED) {
fields = AccessController.doPrivileged((PrivilegedAction<Field[]>) clazz::getDeclaredFields);
} else {
fields = clazz.getDeclaredFields();
}
return fields;
}
/**
* Obtain the declared methods for a class taking account of any security manager that may be configured.
*
* @param clazz The class to introspect
*
* @return the class methods as an array
*/
public static Method[] getDeclaredMethods(final Class<?> clazz) {
Method[] methods = null;
if (Globals.IS_SECURITY_ENABLED) {
methods = AccessController.doPrivileged((PrivilegedAction<Method[]>) clazz::getDeclaredMethods);
} else {
methods = clazz.getDeclaredMethods();
}
return methods;
}
/**
* Attempt to load a class using the given Container's class loader. If the class cannot be loaded, a debug level
* log message will be written to the Container's log and null will be returned.
*
* @param context The class loader of this context will be used to attempt to load the class
* @param className The class name
*
* @return the loaded class or <code>null</code> if loading failed
*/
public static Class<?> loadClass(Context context, String className) {
ClassLoader cl = context.getLoader().getClassLoader();
Log log = context.getLogger();
Class<?> clazz = null;
try {
clazz = cl.loadClass(className);
} catch (ClassNotFoundException | NoClassDefFoundError | ClassFormatError e) {
log.debug(sm.getString("introspection.classLoadFailed", className), e);
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
log.debug(sm.getString("introspection.classLoadFailed", className), t);
}
return clazz;
}
/**
* Converts the primitive type to its corresponding wrapper.
*
* @param clazz Class that will be evaluated
*
* @return if the parameter is a primitive type returns its wrapper; otherwise returns the same class
*/
public static Class<?> convertPrimitiveType(Class<?> clazz) {
if (clazz.equals(char.class)) {
return Character.class;
} else if (clazz.equals(int.class)) {
return Integer.class;
} else if (clazz.equals(boolean.class)) {
return Boolean.class;
} else if (clazz.equals(double.class)) {
return Double.class;
} else if (clazz.equals(byte.class)) {
return Byte.class;
} else if (clazz.equals(short.class)) {
return Short.class;
} else if (clazz.equals(long.class)) {
return Long.class;
} else if (clazz.equals(float.class)) {
return Float.class;
} else {
return clazz;
}
}
}
|