/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
*
* Licensed 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.jkiss.utils;
import java.lang.reflect.*;
import java.util.Collection;
import java.util.StringTokenizer;
/**
* BeanUtils
*/
public class BeanUtils {
public static boolean isGetterName(String name) {
return name.startsWith("get") || name.startsWith("is") || name.startsWith("has");
}
public static String getPropertyNameFromGetter(String getterName) {
if (getterName.startsWith("get")) {
return
Character.toLowerCase(getterName.charAt(3)) +
getterName.substring(4);
} else if (getterName.startsWith("is")) {
return
Character.toLowerCase(getterName.charAt(2)) +
getterName.substring(3);
} else if (getterName.startsWith("has")) {
return
Character.toLowerCase(getterName.charAt(3)) +
getterName.substring(4);
} else {
// Unrecognized getter name
return null;
}
}
public static String getSetterName(String getterName) {
if (getterName.startsWith("get")) {
return "set" + getterName.substring(3);
} else if (getterName.startsWith("is")) {
return "set" + getterName.substring(2);
} else if (getterName.startsWith("has")) {
return "set" + getterName.substring(3);
} else {
// Unrecognized getter name
return null;
}
}
/**
* Returns a set method matching the property name.
*/
public static Method getSetMethod(Class<?> cl, String propertyName) {
Method method = getSetMethod(cl, propertyName, false);
if (method != null) {
return method;
}
return getSetMethod(cl, propertyName, true);
}
/**
* Returns a set method matching the property name.
*/
public static Method getSetMethod(
Class<?> cl,
String propertyName,
boolean ignoreCase) {
String setName = "set" + propertyNameToMethodName(propertyName);
return getSetMethod(
cl.getMethods(),
setName,
ignoreCase);
}
/**
* Returns a get method matching the property name.
*/
public static Method getGetMethod(Class<?> cl, String propertyName) {
Method method = getGetMethod(cl, propertyName, false);
return method != null ?
method :
getGetMethod(cl, propertyName, true);
}
/**
* Returns a get method matching the property name.
*/
public static Method getGetMethod(
Class<?> cl,
String propertyName,
boolean ignoreCase) {
String methodName = propertyNameToMethodName(propertyName);
return getGetMethod(
cl.getMethods(),
"get" + methodName,
"is" + methodName,
ignoreCase);
}
/**
* Converts a user's property name to a bean method name.
*
* @param propertyName the user property name
* @return the equivalent bean method name
*/
public static String propertyNameToMethodName(String propertyName) {
char ch = propertyName.charAt(0);
if (Character.isLowerCase(ch))
propertyName = Character.toUpperCase(ch) + propertyName.substring(1);
return propertyName;
}
/**
* Converts a user's property name to a bean method name.
*
* @param methodName the method name
* @return the equivalent property name
*/
public static String methodNameToPropertyName(String methodName) {
if (methodName.startsWith("get"))
methodName = methodName.substring(3);
else if (methodName.startsWith("set"))
methodName = methodName.substring(3);
else if (methodName.startsWith("is"))
methodName = methodName.substring(2);
if (methodName.length() == 0)
return null;
char ch = methodName.charAt(0);
if (Character.isUpperCase(ch) && (methodName.length() == 1 || !Character.isUpperCase(methodName.charAt(1)))) {
methodName = Character.toLowerCase(ch) + methodName.substring(1);
}
return methodName;
}
public static boolean isArrayType(Type type) {
return (type instanceof Class && ((Class<?>) type).isArray());
}
public static boolean isCollectionType(Type type) {
if (type instanceof Class && Collection.class.isAssignableFrom((Class<?>) type)) {
/*
if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType)type;
if (pt.getActualTypeArguments().length == 1) {
return true;
}
}
*/
return true;
}
return isArrayType(type);
}
public static Class<?> getCollectionType(Type type) {
if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) type;
if (pt.getActualTypeArguments().length == 1) {
final Type argType = pt.getActualTypeArguments()[0];
if (argType instanceof Class) {
return (Class<?>) argType;
} else if (argType instanceof WildcardType) {
final Type[] upperBounds = ((WildcardType) argType).getUpperBounds();
if (upperBounds.length > 0 && upperBounds[0] instanceof Class) {
return (Class<?>) upperBounds[0];
}
final Type[] lowerBounds = ((WildcardType) argType).getLowerBounds();
if (lowerBounds.length > 0 && lowerBounds[0] instanceof Class) {
return (Class<?>) lowerBounds[0];
}
}
}
}
return null;
}
public static Object readObjectProperty(Object object, String propName)
throws IllegalAccessException, InvocationTargetException {
if (propName.indexOf('.') == -1) {
Method getter = getGetMethod(object.getClass(), propName);
return getter == null ? null : getter.invoke(object);
}
// Parse property path
StringTokenizer st = new StringTokenizer(propName, ".");
Object value = object;
while (value != null && st.hasMoreTokens()) {
String pathItem = st.nextToken();
Method getter = getGetMethod(value.getClass(), pathItem);
if (getter == null) {
return null;
}
value = getter.invoke(value);
}
return value;
}
/**
* Finds the matching set method
*/
private static Method getGetMethod(
Method[] methods,
String getName,
String isName,
boolean ignoreCase) {
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
// The method must be public
if (
(!Modifier.isPublic(method.getModifiers())) ||
(!Modifier.isPublic(method.getDeclaringClass().getModifiers())) ||
(method.getParameterTypes().length != 0) ||
(method.getReturnType().equals(void.class))) {
continue;
} else if (!ignoreCase && method.getName().equals(getName)) {
// If it matches the get name, it's the right method
return method;
} else if (ignoreCase && method.getName().equalsIgnoreCase(getName)) {
// If it matches the get name, it's the right method
return method;
} else if (!method.getReturnType().equals(boolean.class)) {
// The is methods must return boolean
continue;
} else if (!ignoreCase && method.getName().equals(isName)) {
// If it matches the is name, it must return boolean
return method;
} else if (ignoreCase && method.getName().equalsIgnoreCase(isName)) {
// If it matches the is name, it must return boolean
return method;
}
}
return null;
}
/**
* Finds the matching set method
*
* @param setName the method name
*/
private static Method getSetMethod(
Method[] methods,
String setName,
boolean ignoreCase) {
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
// The method name must match
if (
!(ignoreCase ? method.getName().equalsIgnoreCase(setName) : method.getName().equals(setName)) ||
!Modifier.isPublic(method.getModifiers()) ||
!Modifier.isPublic(method.getDeclaringClass().getModifiers()) ||
method.getParameterTypes().length != 1
)
continue;
return method;
}
return null;
}
public static final Short DEFAULT_SHORT = (short) 0;
public static final Integer DEFAULT_INTEGER = 0;
public static final Long DEFAULT_LONG = 0l;
public static final Float DEFAULT_FLOAT = new Float(0.0);
public static final Double DEFAULT_DOUBLE = 0.0;
public static final Byte DEFAULT_BYTE = (byte) 0;
public static final Character DEFAULT_CHAR = (char) 0;
public static boolean isBooleanType(Type paramClass) {
return paramClass == Boolean.class || paramClass == Boolean.TYPE;
}
public static Object getDefaultPrimitiveValue(Class<?> paramClass) {
if (paramClass == Boolean.TYPE) {
return Boolean.FALSE;
} else if (paramClass == Short.TYPE) {
return DEFAULT_SHORT;
} else if (paramClass == Integer.TYPE) {
return DEFAULT_INTEGER;
} else if (paramClass == Long.TYPE) {
return DEFAULT_LONG;
} else if (paramClass == Float.TYPE) {
return DEFAULT_FLOAT;
} else if (paramClass == Double.TYPE) {
return DEFAULT_DOUBLE;
} else if (paramClass == Byte.TYPE) {
return DEFAULT_BYTE;
} else if (paramClass == Character.TYPE) {
return DEFAULT_CHAR;
} else {
throw new IllegalArgumentException("Class " + paramClass.getName() + " is not primitive type");
}
}
public static boolean isNumericType(Class<?> paramClass) {
return
Number.class.isAssignableFrom(paramClass) ||
paramClass == Short.TYPE ||
paramClass == Integer.TYPE ||
paramClass == Long.TYPE ||
paramClass == Double.TYPE ||
paramClass == Float.TYPE ||
paramClass == Byte.TYPE;
}
public static Object invokeObjectMethod(Object object, String name, Class<?> paramTypes[], Object args[])
throws Throwable {
Method method = object.getClass().getMethod(name, paramTypes);
if (!method.isAccessible()) {
method.setAccessible(true);
}
try {
return method.invoke(object, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
public static Object invokeObjectMethod(Object object, String name)
throws Throwable {
Method method = object.getClass().getMethod(name);
if (!method.isAccessible()) {
method.setAccessible(true);
}
try {
return method.invoke(object);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
public static Object invokeStaticMethod(Class<?> objectType, String name, Class<?> paramTypes[], Object args[])
throws Throwable {
Method method = objectType.getMethod(name, paramTypes);
if (!method.isAccessible()) {
method.setAccessible(true);
}
try {
return method.invoke(null, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
}