001: package fr.aliacom.bean;
002:
003: import java.beans.Introspector;
004: import java.beans.PropertyChangeListener;
005: import java.beans.PropertyDescriptor;
006: import java.lang.reflect.Method;
007:
008: import org.apache.log4j.Logger;
009:
010: /**
011: * This class provides some utility methods
012: * to work with JavaBeans.
013: *
014: * Those methods provide read/write access to properties
015: * and allow property change listener management.
016: *
017: *
018: * @author tom
019: *
020: * (C) 2001, 2002 Thomas Cataldo
021: */
022: public final class BeanUtils {
023:
024: private static final Logger log = Logger.getLogger(BeanUtils.class);
025:
026: /**
027: * Try to add a property change listener to a JavaBean.
028: * The method returns silently when the bean does not support
029: * property change notifications.
030: *
031: * The listener is added through reflexivity. It checks the existance
032: * of an <code>addPropertyChangeListener(String, PropertyChangeListener)</code>
033: * method.
034: *
035: * @param javaBean the bean
036: * @param property
037: * @param pcl
038: */
039: public static void addPropertyChangeListener(Object javaBean,
040: String property, PropertyChangeListener pcl) {
041: try {
042: Method m = javaBean.getClass().getMethod(
043: "addPropertyChangeListener",
044: new Class[] { String.class,
045: PropertyChangeListener.class });
046: m.invoke(javaBean, new Object[] { property, pcl });
047: } catch (Exception e) {
048: log.warn("No property change support in class "
049: + javaBean.getClass().getName());
050: }
051: }
052:
053: private static PropertyDescriptor findPropertyDescriptor(
054: Object bean, String property) {
055: try {
056: PropertyDescriptor pd[] = Introspector.getBeanInfo(
057: bean.getClass()).getPropertyDescriptors();
058: boolean found = false;
059: int idx = 0;
060: for (idx = 0; idx < pd.length && !found; idx++) {
061: found = pd[idx].getName().equals(property);
062: }
063: if (found) {
064: return pd[idx - 1];
065: } else {
066: throw new RuntimeException(
067: "No descriptor for property '" + property
068: + "' in " + bean);
069: }
070: } catch (Exception e) {
071: log.fatal("Error finding descriptor for property '"
072: + property + "' in " + bean, e);
073: throw new RuntimeException(e);
074: }
075: }
076:
077: /**
078: * Returns the value of a property in a java bean.
079: * This will throw a runtime exception if the property does not exist.
080: *
081: * @param bean the java bean
082: * @param property the property to query
083: * @return the value of the property in the bean.
084: */
085: public static Object getValue(Object bean, String property) {
086: PropertyDescriptor pd = findPropertyDescriptor(bean, property);
087: Object ret = null;
088: try {
089: Method read = pd.getReadMethod();
090: ret = read.invoke(bean, new Object[0]);
091: } catch (Exception e) {
092: log.fatal("Error getting value of property '" + property
093: + "' in " + bean, e);
094: throw new RuntimeException(e);
095: }
096: return ret;
097: }
098:
099: /**
100: * Removes a propertyChangeListener from
101: * a JavaBean using reflexivity.
102: *
103: * @param javaBean
104: * @param property
105: * @param pcl
106: */
107: public static void removePropertyChangeListener(Object javaBean,
108: String property, PropertyChangeListener pcl) {
109: try {
110: Method m = javaBean.getClass().getMethod(
111: "removePropertyChangeListener",
112: new Class[] { String.class,
113: PropertyChangeListener.class });
114: m.invoke(javaBean, new Object[] { property, pcl });
115: } catch (Exception e) {
116: log.warn("No property change support.");
117: }
118: }
119:
120: /**
121: * Sets the value of a property in a JavaBean.
122: *
123: * Method setValue.
124: * @param bean
125: * @param property
126: * @param value
127: */
128: public static void setValue(Object bean, String property,
129: Object value) {
130: PropertyDescriptor pd = findPropertyDescriptor(bean, property);
131: try {
132: Method write = pd.getWriteMethod();
133: write.invoke(bean, new Object[] { value });
134: } catch (Exception e) {
135: throw new RuntimeException("Error writing '" + property
136: + "' to " + bean);
137: }
138: }
139:
140: /**
141: * @param javaBean
142: * @param pcl
143: */
144: public static void addPropertyChangeListener(Object javaBean,
145: PropertyChangeListener pcl) {
146: try {
147: Method m = javaBean.getClass().getMethod(
148: "addPropertyChangeListener",
149: new Class[] { PropertyChangeListener.class });
150: m.invoke(javaBean, new Object[] { pcl });
151: } catch (Exception e) {
152: log
153: .warn("No (or incorrect) property change support in class "
154: + javaBean.getClass().getName());
155: }
156: }
157:
158: /**
159: * @param javaBean
160: * @param pcl
161: */
162: public static void removePropertyChangeListener(Object javaBean,
163: PropertyChangeListener pcl) {
164: try {
165: Method m = javaBean.getClass().getMethod(
166: "removePropertyChangeListener",
167: new Class[] { PropertyChangeListener.class });
168: m.invoke(javaBean, new Object[] { pcl });
169: } catch (Exception e) {
170: log
171: .warn("No (or incorrect) property change support in class "
172: + javaBean.getClass().getName());
173: }
174: }
175: }
|