Java tutorial
/* * Copyright 2004, 2005, 2006 Odysseus Software GmbH * * 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. */ import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * Property access utility methods. * * @author Christoph Beck */ public class PropertyUtils { private static HashMap descriptorCache = new HashMap(); /** * Get map with property descriptors for the specified bean class */ private static Map getPropertyDescriptors(Class clazz) { HashMap map = (HashMap) descriptorCache.get(clazz); if (map == null) { BeanInfo beanInfo = null; try { beanInfo = Introspector.getBeanInfo(clazz); } catch (IntrospectionException e) { return Collections.EMPTY_MAP; } PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors(); if (descriptors == null) descriptors = new PropertyDescriptor[0]; map = new HashMap(descriptors.length); for (int i = 0; i < descriptors.length; i++) map.put(descriptors[i].getName(), descriptors[i]); descriptorCache.put(clazz, map); } return map; } /** * Get property names of the specified bean class */ public static Iterator getPropertyNames(Class clazz) { return getPropertyDescriptors(clazz).keySet().iterator(); } /** * Get specified property descriptor */ public static PropertyDescriptor getPropertyDescriptor(Class clazz, String property) { return (PropertyDescriptor) getPropertyDescriptors(clazz).get(property); } /** * Get specified property value */ public static Object getProperty(Object bean, String property) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { PropertyDescriptor descriptor = getPropertyDescriptor(bean.getClass(), property); if (descriptor == null) throw new NoSuchMethodException("Cannot find property " + bean.getClass().getName() + "." + property); Method method = descriptor.getReadMethod(); if (method == null) throw new NoSuchMethodException("Cannot find getter for " + bean.getClass().getName() + "." + property); return method.invoke(bean, null); } /** * Get specified nested property value */ public static Object getNestedProperty(Object bean, String property) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { if (property.indexOf('.') > 0) { String[] path = property.split("\\."); for (int i = 0; i < path.length && bean != null; i++) { bean = getProperty(bean, path[i]); } return bean; } else { return getProperty(bean, property); } } /** * Set specified property value */ public static void setProperty(Object bean, String property, Object value) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { PropertyDescriptor descriptor = getPropertyDescriptor(bean.getClass(), property); if (descriptor == null) throw new NoSuchMethodException("Cannot find property " + bean.getClass().getName() + "." + property); Method method = descriptor.getWriteMethod(); if (method == null) throw new NoSuchMethodException("Cannot find setter for " + bean.getClass().getName() + "." + property); method.invoke(bean, new Object[] { value }); } /** * Set nested property given by property path, starting at specified * index. Dynamically create beans if necessary. Take care not to * leave the bean changed if an exception occurs. */ private static void setNestedPropertyWithCreate(Object bean, String[] path, int start, Object value) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { for (int i = start; i < path.length - 1; i++) { Object object = getProperty(bean, path[i]); if (object == null) { PropertyDescriptor descr = getPropertyDescriptor(bean.getClass(), path[i]); object = descr.getPropertyType().newInstance(); setNestedPropertyWithCreate(object, path, i + 1, value); setProperty(bean, path[i], object); return; } bean = object; } setProperty(bean, path[path.length - 1], value); } /** * Set specified nested property value */ public static void setNestedProperty(Object bean, String property, Object value) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { int lastDot = property.lastIndexOf('.'); if (lastDot > 0) { setNestedPropertyWithCreate(bean, property.split("\\."), 0, value); } else { setProperty(bean, property, value); } } }