View Javadoc

1   /*
2    * Copyright (c) 2005, Henri Yandell
3    * All rights reserved.
4    * 
5    * Redistribution and use in source and binary forms, with or 
6    * without modification, are permitted provided that the 
7    * following conditions are met:
8    * 
9    * + Redistributions of source code must retain the above copyright notice, 
10   *   this list of conditions and the following disclaimer.
11   * 
12   * + Redistributions in binary form must reproduce the above copyright notice, 
13   *   this list of conditions and the following disclaimer in the documentation 
14   *   and/or other materials provided with the distribution.
15   * 
16   * + Neither the name of Simple-JNDI nor the names of its contributors 
17   *   may be used to endorse or promote products derived from this software 
18   *   without specific prior written permission.
19   * 
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
23   * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
30   * POSSIBILITY OF SUCH DAMAGE.
31   */
32  
33  package org.osjava.sj.loader.convert;
34  
35  import java.util.Properties;
36  import java.util.Iterator;
37  import java.util.List;
38  
39  import java.lang.reflect.Method;
40  import java.lang.reflect.InvocationTargetException;
41  
42  /***
43   * Create an object using its empty constructor, then 
44   * call setXxx for each pseudo property. Only String 
45   * properties are supported.
46   *
47   * <pre>
48   * Foo.name=Arthur
49   * Foo.answer=42
50   * Foo.type=com.example.Person
51   * Foo.converter=org.osjava.sj.loader.convert.BeanConverter
52   * </pre>
53   */
54  public class BeanConverter implements Converter {
55  
56      public Object convert(Properties properties, String type) {
57          String value = properties.getProperty("");
58  
59          if(value != null) {
60              throw new RuntimeException("Specify the value as a pseudo property as Beans have empty constructors");
61          }
62  
63          String methodName = null;
64  
65          try {
66              Class c = Class.forName(type);
67              Object bean = c.newInstance();
68              Iterator itr = properties.keySet().iterator();
69              while(itr.hasNext()) {
70                  String key = (String) itr.next();
71                  if("converter".equals(key) || "type".equals(key)) {
72                      continue;
73                  }
74                  Object property = properties.get(key);
75                  if(property instanceof String) {
76                      methodName = "set" + Character.toTitleCase(key.charAt(0)) + key.substring(1);
77                      Method m = c.getMethod(methodName, new Class[] { String.class });
78                      m.invoke(bean, new Object[] { (String) property });
79                  } else
80                  if(property instanceof List) {
81                      List list = (List) property;
82                      int sz = list.size();
83                      key = "add" + Character.toTitleCase(key.charAt(0)) + key.substring(1);
84                      Method m = c.getMethod(key, new Class[] { Integer.TYPE, String.class });
85                      for(int i=0; i<sz; i++) {
86                          Object item = list.get(i);
87                          if(item instanceof String) {
88                              m.invoke(bean, new Object[] { new Integer(i), (String) item });
89                          } else {
90                              throw new RuntimeException("Only Strings and Lists of String are supported");
91                          }
92                      }
93                  } else {
94                      throw new RuntimeException("Only Strings and Lists of Strings are supported");
95                  }
96              }
97              return bean;
98          } catch(ClassNotFoundException cnfe) {
99              throw new RuntimeException("Unable to find class: "+type, cnfe);
100         } catch(NoSuchMethodException nsme) {
101             throw new RuntimeException("Unable to find method " + methodName + " on class: "+type, nsme);
102         } catch(InstantiationException ie) {
103             throw new RuntimeException("Unable to instantiate class: "+type, ie);
104         } catch(IllegalAccessException ie) {
105             throw new RuntimeException("Unable to access class: "+type, ie);
106         } catch(IllegalArgumentException iae) {
107             throw new RuntimeException("Unable to pass argument to class: "+type, iae);
108         } catch(InvocationTargetException ite) {
109             throw new RuntimeException("Unable to invoke (String) constructor on class: "+type, ite);
110         }
111 
112     }
113 
114 }