View Javadoc

1   /*
2    * The SmartWeb Framework
3    * Copyright (C) 2004-2006
4    *
5    * This library is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU Lesser General Public
7    * License as published by the Free Software Foundation; either
8    * version 2.1 of the License, or (at your option) any later version.
9    *
10   * This library is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   * Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public
16   * License along with this library; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18   *
19   * For further informations on the SmartWeb Framework please visit
20   *
21   *                        http://smartweb.sourceforge.net
22   */
23  package net.smartlab.web.bean;
24  
25  import java.beans.PropertyDescriptor;
26  import java.lang.reflect.InvocationTargetException;
27  import java.util.Iterator;
28  import java.util.Locale;
29  import java.util.Map;
30  
31  import org.apache.commons.beanutils.DynaBean;
32  import org.apache.commons.beanutils.DynaClass;
33  import org.apache.commons.beanutils.DynaProperty;
34  import org.apache.commons.beanutils.PropertyUtils;
35  import org.apache.commons.logging.Log;
36  import org.apache.commons.logging.LogFactory;
37  
38  /**
39   * TODO class documentation
40   * 
41   * @author rlogiacco
42   * @uml.dependency supplier="net.smartlab.web.bean.ValorizationException"
43   */
44  public class Valorizer {
45  
46  	/* # net.smartlab.web.bean.ValorizationException Dependency_Link1 */
47  	/* # net.smartlab.web.bean.ValorizationException ve */
48  	private static Log logger = LogFactory.getLog(Valorizer.class);
49  
50  	private static ConverterManager converter = ConverterManager.getDefault();
51  
52  
53  	/**
54  	 * TODO documentation
55  	 * 
56  	 * @param bean
57  	 * @param name
58  	 * @param value
59  	 * @param locale
60  	 * @throws ValorizationException
61  	 * @throws ConversionException
62  	 */
63  	protected static void set(Object bean, String name, Object value, Locale locale) throws ValorizationException,
64  			ConversionException {
65  		if (logger.isTraceEnabled()) {
66  			logger.trace("setProperty(" + bean + ", " + name + ", " + value + ", " + locale + ")");
67  		}
68  		try {
69  			// Resolve any nested expression to get the actual target bean
70  			Object target = bean;
71  			int delim = name.lastIndexOf(PropertyUtils.NESTED_DELIM);
72  			if (delim >= 0) {
73  				try {
74  					target = PropertyUtils.getProperty(bean, name.substring(0, delim));
75  				} catch (NoSuchMethodException e) {
76  					// Skip this property setter
77  					return;
78  				}
79  				name = name.substring(delim + 1);
80  				if (logger.isTraceEnabled()) {
81  					logger.trace("   target bean = " + target);
82  					logger.trace("   target name = " + name);
83  				}
84  			}
85  			// Simple name of target property
86  			String property = null;
87  			// Java type of target property
88  			Class type = null;
89  			// Indexed subscript value (if any)
90  			int index = -1;
91  			// Mapped key value (if any)
92  			String key = null;
93  			// Calculate the target property name, index, and key values
94  			property = name;
95  			int i = property.indexOf(PropertyUtils.INDEXED_DELIM);
96  			if (i >= 0) {
97  				int k = property.indexOf(PropertyUtils.INDEXED_DELIM2);
98  				try {
99  					index = Integer.parseInt(property.substring(i + 1, k));
100 				} catch (NumberFormatException nfe) {
101 					logger.debug(nfe);
102 				}
103 				property = property.substring(0, i);
104 			}
105 			int j = property.indexOf(PropertyUtils.MAPPED_DELIM);
106 			if (j >= 0) {
107 				int k = property.indexOf(PropertyUtils.MAPPED_DELIM2);
108 				try {
109 					key = property.substring(j + 1, k);
110 				} catch (IndexOutOfBoundsException ioobe) {
111 					logger.debug(ioobe);
112 				}
113 				property = property.substring(0, j);
114 			}
115 			// Calculate the target property type
116 			if (target instanceof DynaBean) {
117 				DynaClass dynaClass = ((DynaBean)target).getDynaClass();
118 				DynaProperty dynaProperty = dynaClass.getDynaProperty(property);
119 				if (dynaProperty == null) {
120 					// Skip this property setter
121 					return;
122 				}
123 				type = dynaProperty.getType();
124 			} else {
125 				PropertyDescriptor descriptor = null;
126 				try {
127 					descriptor = PropertyUtils.getPropertyDescriptor(target, name);
128 					if (descriptor == null) {
129 						// Skip this property setter
130 						return;
131 					}
132 				} catch (NoSuchMethodException nsme) {
133 					// Skip this property setter
134 					return;
135 				}
136 				type = descriptor.getPropertyType();
137 				if (type == null) {
138 					// Most likely an indexed setter on a POJB only
139 					if (logger.isTraceEnabled()) {
140 						logger.trace("   target type for property '" + property + "' is null, so skipping this setter");
141 					}
142 					return;
143 				}
144 			}
145 			if (logger.isTraceEnabled()) {
146 				logger.trace("   target property = " + property + ", type = " + type + ", index = " + index
147 						+ ", key = " + key);
148 			}
149 			// Convert the specified value to the required type and store it
150 			if (index >= 0) {
151 				converter.convert(type, value, locale);
152 				try {
153 					PropertyUtils.setIndexedProperty(target, property, index, value);
154 				} catch (NoSuchMethodException e) {
155 					throw new InvocationTargetException(e, "Cannot set " + property);
156 				}
157 			} else if (key != null) {
158 				// Map based destination
159 				// Maps do not know what the preferred data type is,
160 				// so perform no conversions at all
161 				try {
162 					PropertyUtils.setMappedProperty(target, property, key, value);
163 				} catch (NoSuchMethodException e) {
164 					throw new InvocationTargetException(e, "Cannot set " + property);
165 				}
166 			} else {
167 				// Bean destination
168 				value = converter.convert(type, value, locale);
169 				try {
170 					PropertyUtils.setSimpleProperty(target, property, value);
171 				} catch (NoSuchMethodException e) {
172 					throw new InvocationTargetException(e, "Cannot set " + property);
173 				}
174 			}
175 		} catch (IllegalAccessException iae) {
176 			throw new ValorizationException(iae);
177 		} catch (InvocationTargetException ite) {
178 			throw new ValorizationException(ite.getTargetException());
179 		}
180 	}
181 
182 	/**
183 	 * TODO method documentation
184 	 * 
185 	 * @param src
186 	 * @param dst
187 	 * @param locale
188 	 * @throws ConversionException
189 	 * @throws ValorizationException
190 	 */
191 	public static void copy(Object src, Object dst, Locale locale) throws ConversionException, ValorizationException {
192 		if (dst == null) {
193 			throw new IllegalArgumentException("No destination specified");
194 		}
195 		if (src == null) {
196 			throw new IllegalArgumentException("No origin specified");
197 		}
198 		if (logger.isDebugEnabled()) {
199 			logger.debug("populate(" + dst + ", " + src + ")");
200 		}
201 		if (src instanceof DynaBean) {
202 			DynaProperty descriptors[] = ((DynaBean)src).getDynaClass().getDynaProperties();
203 			for (int i = 0; i < descriptors.length; i++) {
204 				String name = descriptors[i].getName();
205 				if (PropertyUtils.isWriteable(dst, name)) {
206 					Object value = ((DynaBean)src).get(name);
207 					Valorizer.set(dst, name, value, locale);
208 				}
209 			}
210 		} else if (src instanceof Map) {
211 			Iterator names = ((Map)src).keySet().iterator();
212 			while (names.hasNext()) {
213 				String name = (String)names.next();
214 				if (PropertyUtils.isWriteable(dst, name)) {
215 					Object value = ((Map)src).get(name);
216 					Valorizer.set(dst, name, value, locale);
217 				}
218 			}
219 		} else {
220 			PropertyDescriptor descriptors[] = PropertyUtils.getPropertyDescriptors(src);
221 			for (int i = 0; i < descriptors.length; i++) {
222 				String name = descriptors[i].getName();
223 				if (!"class".equals(name) && PropertyUtils.isReadable(src, name)
224 						&& PropertyUtils.isWriteable(dst, name)) {
225 					try {
226 						Object value = PropertyUtils.getSimpleProperty(src, name);
227 						Valorizer.set(dst, name, value, locale);
228 					} catch (NoSuchMethodException nsme) {
229 						logger.warn(nsme);
230 					} catch (IllegalAccessException iae) {
231 						logger.warn(iae);
232 					} catch (InvocationTargetException ite) {
233 						logger.warn(ite);
234 					}
235 				}
236 			}
237 		}
238 	}
239 }