/**
* Logback: the reliable, generic, fast and flexible logging framework.
* Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
package ch.qos.logback.core.joran.util;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* The Introspector class provides a standard way for tools to learn about the
* properties, events, and methods supported by a target class.
*
* @author Anthony K. Trinh
*/
public class Introspector {
/**
* Converts a name string's first letter to lowercase
*
* @param name
* name string to evaluate
* @return the name with its first letter in lowercase
*/
static public String decapitalize(String name) {
if (name == null || name.length() == 0) {
return name;
} else {
String nm = name.substring(0, 1).toLowerCase();
if (name.length() > 1) {
nm += name.substring(1);
}
return nm;
}
}
/**
* Gets a class's method descriptors
*
* @param clazz
* class to be evaluated
* @return method descriptors
*/
static public MethodDescriptor[] getMethodDescriptors(Class<?> clazz) {
ArrayList<MethodDescriptor> methods = new ArrayList<MethodDescriptor>();
for (Method m : clazz.getMethods()) {
methods.add(new MethodDescriptor(m.getName(), m));
}
return methods.toArray(new MethodDescriptor[0]);
}
/**
* Gets a class's property descriptors. All properties have methods whose name
* begins with "set" or "get". The setters must have a single parameter and
* getters must have none.
*
* @param clazz
* class to be evaluated
* @return property descriptors
*/
static public PropertyDescriptor[] getPropertyDescriptors(Class<?> clazz) {
final String SETTER_PREFIX = "set";
final String GETTER_PREFIX = "get";
final int LEN_PREFIX = SETTER_PREFIX.length();
Map<String, PropertyDescriptor> map = new HashMap<String, PropertyDescriptor>();
for (Method m : clazz.getMethods()) {
PropertyDescriptor pd = null;
String mName = m.getName();
boolean isGet = mName.startsWith(GETTER_PREFIX) && (mName.length() > LEN_PREFIX);
boolean isSet = mName.startsWith(SETTER_PREFIX) && (mName.length() > LEN_PREFIX);
if (isGet || isSet) {
String propName = decapitalize(mName.substring(LEN_PREFIX));
pd = map.get(propName);
if (pd == null) {
pd = new PropertyDescriptor(propName);
map.put(propName, pd);
}
Class<?>[] parmTypes = m.getParameterTypes();
if (isSet) {
if (parmTypes.length == 1) { // we only want the single-parm setter
pd.setWriteMethod(m);
pd.setPropertyType(parmTypes[0]);
}
} else if (isGet) {
if (parmTypes.length == 0) { // we only want the zero-parm getter
pd.setReadMethod(m);
// let setter's type take priority
if (pd.getPropertyType() == null) {
pd.setPropertyType(m.getReturnType());
}
}
}
}
}
return map.values().toArray(new PropertyDescriptor[0]);
}
}