001: /**
002: * $Id: BeanSupport.java,v 1.6 2005/09/21 10:50:21 dg154973 Exp $
003: * Copyright 2002 Sun Microsystems, Inc. All
004: * rights reserved. Use of this product is subject
005: * to license terms. Federal Acquisitions:
006: * Commercial Software -- Government Users
007: * Subject to Standard License Terms and
008: * Conditions.
009: *
010: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
011: * are trademarks or registered trademarks of Sun Microsystems,
012: * Inc. in the United States and other countries.
013: */package com.sun.portal.wireless.taglibs.base;
014:
015: import com.sun.portal.log.common.PortalLogger;
016:
017: import java.util.*;
018: import java.util.logging.Logger;
019: import java.beans.*;
020: import java.lang.reflect.*;
021: import javax.servlet.jsp.*;
022: import javax.servlet.jsp.tagext.*;
023:
024: /**
025: * BeanSupport - a support class for bean tags
026: *
027: * This class provides common functionality for the
028: * BeanGetTag and BeanSetTag classes.
029: *
030: * Attributes:
031: *
032: * property
033: * bean property name
034: * name
035: * name to save or restore the bean in the page context
036: *
037: * @author Robert O'Brien
038: * @version 1.0
039: * @see BeanGetTag
040: * @see BeanSetTag
041: */
042: public class BeanSupport extends BaseTagSupport {
043:
044: // Create a logger for this class
045: private static Logger debugLogger = PortalLogger
046: .getLogger(BeanSupport.class);
047:
048: /**
049: * The bean property name
050: */
051: protected String property;
052:
053: /**
054: * Get the bean property name
055: *
056: * @return the property name
057: */
058: public String getProperty() {
059: return property;
060: }
061:
062: /**
063: * Set the bean property name
064: *
065: * @param property the property name
066: */
067: public void setProperty(String property) {
068: this .property = property;
069: }
070:
071: /**
072: * The bean that this tag is operating on
073: */
074: protected Object bean;
075:
076: /**
077: * Get the bean to operate on
078: *
079: * @return the bean
080: */
081: public Object getBean() {
082: if (bean == null)
083: bean = findBean();
084: return bean;
085: }
086:
087: /**
088: * Set the bean to operate on
089: *
090: * @param bean the bean
091: */
092: public void setBean(Object bean) {
093: this .bean = bean;
094: }
095:
096: /**
097: * Find the bean on the page context using name.
098: *
099: * @return the bean
100: */
101: public Object findBean() {
102:
103: if (name != null) {
104: ScopeBean scope = null;
105: if (name.equals(ScopeBean.PAGE_SCOPE_RESERVED_NAME)) {
106: return PageScopeBean.getScopeBean(pageContext);
107: } else if (name
108: .equals(ScopeBean.REQUEST_SCOPE_RESERVED_NAME)) {
109: return RequestScopeBean.getScopeBean(pageContext);
110: } else { // TODO: implement session & app scope beans
111: return pageContext.getAttribute(getName());
112: }
113: }
114:
115: BeanHolder beanholder;
116: beanholder = (BeanHolder) TagSupport.findAncestorWithClass(
117: this , BeanHolder.class);
118:
119: if (beanholder != null)
120: return beanholder.getBean();
121: else
122: return null;
123: }
124:
125: /**
126: * Skip over the body
127: *
128: * @return SKIP_BODY
129: * @exception JspException
130: */
131: public int doStartTag() throws JspException {
132: return SKIP_BODY;
133: }
134:
135: /**
136: * Continue evaluting the page
137: *
138: * @return EVAL_PAGE
139: * @exception JspException
140: */
141: public int doEndTag() throws JspException {
142: return EVAL_PAGE;
143: }
144:
145: /**
146: * Cleanup
147: */
148: public void release() {
149: super .release();
150: id = null;
151: name = null;
152: bean = null;
153: property = null;
154: }
155:
156: /**
157: * Get a descriptor for the bean property
158: *
159: * @return the property descriptor
160: * @exception IntrospectionException
161: */
162: public static PropertyDescriptor getPropertyDescriptor(Object bean,
163: String property) throws IntrospectionException {
164: Class beanclass = bean.getClass();
165: BeanInfo beaninfo = Introspector.getBeanInfo(beanclass);
166: PropertyDescriptor pd[] = beaninfo.getPropertyDescriptors();
167:
168: for (int i = 0; i < pd.length; i++) {
169: PropertyDescriptor descriptor = pd[i];
170:
171: if (descriptor.getName().equals(property))
172: return descriptor;
173: }
174: throw new IntrospectionException("Class " + beanclass
175: + " doesn't have property " + property);
176: }
177:
178: /**
179: * Get the bean properties and values
180: *
181: * Returns a HashMap of the properties
182: * and corresponding descriptors for the bean.
183: *
184: * @return map of properties and descriptors
185: * @exception IntrospectionException
186: */
187: public static HashMap getBeanProperties(Object bean)
188: throws IntrospectionException {
189: Class beanclass = bean.getClass();
190: BeanInfo beaninfo = Introspector.getBeanInfo(beanclass);
191: PropertyDescriptor pd[] = beaninfo.getPropertyDescriptors();
192: HashMap properties = new HashMap(pd.length);
193:
194: for (int i = 0; i < pd.length; i++) {
195: PropertyDescriptor descriptor = pd[i];
196: properties.put(descriptor.getName(), descriptor);
197: }
198:
199: return properties;
200: }
201:
202: /**
203: * Invoke a bean property access method
204: *
205: * @param bean the bean object to access
206: * @param property the bean property to access
207: * @param method the read or write method for a property
208: * @param args arguments to the method; null for read
209: * @return the object returned by the method
210: * @exception IntrospectionException
211: */
212: public static Object accessProperty(Object bean, String property,
213: Method method, Object args[]) throws IntrospectionException {
214: try {
215: return method.invoke(bean, args);
216: } catch (Exception e) {
217: throw new IntrospectionException("Couldn't access "
218: + property + " property of " + bean.getClass());
219: }
220: }
221:
222: /**
223: * Invoke a bean property access method
224: *
225: * @param bean the bean object to access
226: * @param method the read or write method for a property
227: * @param args arguments to the method; null for read
228: * @return the object returned by the method
229: * @exception IntrospectionException
230: */
231: public Object accessProperty(Object bean, Method method,
232: Object args[]) throws IntrospectionException {
233: return accessProperty(bean, property, method, args);
234: }
235:
236: /**
237: * Read the property from the bean
238: *
239: * @param bean the bean object to access
240: * @param property the property name
241: * @return the property value
242: * @exception JspException
243: * @exception IntrospectionException
244: */
245: public static Object readProperty(Object bean, String property)
246: throws JspException, IntrospectionException {
247:
248: if (bean instanceof ScopeBean) {
249: return ((ScopeBean) bean).readProperty(property);
250: }
251:
252: PropertyDescriptor descriptor = getPropertyDescriptor(bean,
253: property);
254: Method method = descriptor.getReadMethod();
255:
256: if (method == null) {
257: throw new JspException("No read method for " + property
258: + " property found");
259: }
260:
261: return accessProperty(bean, property, method, null);
262: }
263:
264: /**
265: * Read the property from the bean
266: *
267: * @param bean the bean object to access
268: * @param property the property name
269: * @return the property value
270: * @exception JspException
271: * @exception IntrospectionException
272: */
273: public Object readProperty(Object bean) throws JspException,
274: IntrospectionException {
275: if (bean instanceof ScopeBean) {
276: return ((ScopeBean) bean).readProperty(property);
277: } else {
278: return readProperty(bean, property);
279: }
280: }
281:
282: /**
283: * Write the property value into the bean
284: *
285: * @param bean the bean object to access
286: * @param property the property name
287: * @param value the property value
288: * @exception JspException
289: * @exception IntrospectionException
290: */
291: public static void writeProperty(Object bean, String property,
292: Object value) throws JspException, IntrospectionException {
293: PropertyDescriptor descriptor = getPropertyDescriptor(bean,
294: property);
295: Method method = descriptor.getWriteMethod();
296:
297: if (method == null) {
298: throw new JspException("No write method for " + property
299: + " property found");
300: }
301:
302: if (value != null) {
303: try {
304: value = getInstanceOf(value, descriptor
305: .getPropertyType());
306: } catch (Exception e) {
307: throw new JspException("Couldn't convert " + property
308: + " value to " + descriptor.getPropertyType());
309: }
310: }
311:
312: Object args[] = { value };
313: accessProperty(bean, property, method, args);
314: }
315:
316: /**
317: * Write the property value into the bean using the property tag attribute
318: *
319: * @param bean the bean object to access
320: * @param value the property value
321: * @exception JspException
322: * @exception IntrospectionException
323: */
324: public void writeProperty(Object bean, Object value)
325: throws JspException, IntrospectionException {
326: if (bean instanceof ScopeBean) {
327: ((ScopeBean) bean).writeProperty(property, value);
328: } else {
329: writeProperty(bean, property, value);
330: debugLogger.finest("Just wrote: bean=" + bean + ", prop="
331: + property + ", val=" + value);
332: }
333: }
334:
335: /**
336: * Return the bean as an instance of the target class.
337: * If possible create a new instance of the target
338: * using the bean object as a parameter.
339: *
340: * @param obj the object to transform
341: * @param target the target class to transform to
342: * @return the bean as an instance of the target class
343: * @exception InstantiationException
344: */
345: public static Object getInstanceOf(Object obj, Class target)
346: throws InstantiationException {
347: target = mapPrimitive(target);
348:
349: if (obj.getClass().equals(target)) {
350: return obj;
351: }
352:
353: if (target.isInstance(obj)) {
354: return obj;
355: }
356:
357: try {
358: Class[] paramClass = { obj.getClass() };
359: Object[] params = { obj };
360: Constructor constructor;
361:
362: constructor = target.getConstructor(paramClass);
363:
364: return constructor.newInstance(params);
365:
366: } catch (Exception e) {
367: throw new InstantiationException(
368: "Couldn't convert bean to " + target + "["
369: + e.getMessage() + "]");
370: }
371: }
372:
373: /**
374: * Map from a primitive type to corresponding class
375: *
376: * @param target
377: * @return
378: */
379: private static Class mapPrimitive(Class target) {
380:
381: if (!target.isPrimitive()) {
382: return target;
383: }
384:
385: Class map = (Class) primitives.get(target);
386:
387: return (map != null) ? map : target;
388: }
389:
390: /**
391: * Mapping of primitive type to corresponding class
392: */
393: static HashMap primitives;
394:
395: static {
396: primitives = new HashMap(9);
397: primitives.put(Boolean.TYPE, Boolean.class);
398: primitives.put(Integer.TYPE, Integer.class);
399: primitives.put(Short.TYPE, Short.class);
400: primitives.put(Long.TYPE, Long.class);
401: primitives.put(Float.TYPE, Float.class);
402: primitives.put(Double.TYPE, Double.class);
403: primitives.put(Character.TYPE, Character.class);
404: primitives.put(Byte.TYPE, Byte.class);
405: primitives.put(Void.TYPE, Void.class);
406: }
407: }
|