001: /*
002: * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/naming/factory/BeanFactory.java,v 1.1 2001/09/02 01:17:47 remm Exp $
003: * $Revision: 1.1 $
004: * $Date: 2001/09/02 01:17:47 $
005: *
006: * ====================================================================
007: *
008: * The Apache Software License, Version 1.1
009: *
010: * Copyright (c) 1999-2001 The Apache Software Foundation. All rights
011: * reserved.
012: *
013: * Redistribution and use in source and binary forms, with or without
014: * modification, are permitted provided that the following conditions
015: * are met:
016: *
017: * 1. Redistributions of source code must retain the above copyright
018: * notice, this list of conditions and the following disclaimer.
019: *
020: * 2. Redistributions in binary form must reproduce the above copyright
021: * notice, this list of conditions and the following disclaimer in
022: * the documentation and/or other materials provided with the
023: * distribution.
024: *
025: * 3. The end-user documentation included with the redistribution, if
026: * any, must include the following acknowlegement:
027: * "This product includes software developed by the
028: * Apache Software Foundation (http://www.apache.org/)."
029: * Alternately, this acknowlegement may appear in the software itself,
030: * if and wherever such third-party acknowlegements normally appear.
031: *
032: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
033: * Foundation" must not be used to endorse or promote products derived
034: * from this software without prior written permission. For written
035: * permission, please contact apache@apache.org.
036: *
037: * 5. Products derived from this software may not be called "Apache"
038: * nor may "Apache" appear in their names without prior written
039: * permission of the Apache Group.
040: *
041: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
042: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
043: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
044: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
045: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
046: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
047: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
048: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
049: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
050: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
051: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
052: * SUCH DAMAGE.
053: * ====================================================================
054: *
055: * This software consists of voluntary contributions made by many
056: * individuals on behalf of the Apache Software Foundation. For more
057: * information on the Apache Software Foundation, please see
058: * <http://www.apache.org/>.
059: *
060: * [Additional notices, if required by prior licensing conditions]
061: *
062: */
063:
064: package org.apache.naming.factory;
065:
066: import java.util.Hashtable;
067: import java.util.Enumeration;
068: import javax.naming.Name;
069: import javax.naming.Context;
070: import javax.naming.NamingException;
071: import javax.naming.Reference;
072: import javax.naming.RefAddr;
073: import javax.naming.spi.ObjectFactory;
074: import org.apache.naming.ResourceRef;
075:
076: import java.beans.Introspector;
077: import java.beans.BeanInfo;
078: import java.beans.PropertyDescriptor;
079:
080: import java.lang.reflect.Method;
081:
082: /**
083: * Object factory for any Resource conforming to the JavaBean spec.
084: *
085: * <p>This factory can be configured in a <code><DefaultContext></code>
086: * or <code><Context></code> element in your <code>conf/server.xml</code>
087: * configuration file. An example of factory configuration is:</p>
088: * <pre>
089: * <Resource name="jdbc/myDataSource" auth="SERVLET"
090: * type="oracle.jdbc.pool.OracleConnectionCacheImpl"/>
091: * <ResourceParams name="jdbc/myDataSource">
092: * <parameter>
093: * <name>factory</name>
094: * <value>org.apache.naming.factory.BeanFactory</value>
095: * </parameter>
096: * <parameter>
097: * <name>driverType</name>
098: * <value>thin</value>
099: * </parameter>
100: * <parameter>
101: * <name>serverName</name>
102: * <value>hue</value>
103: * </parameter>
104: * <parameter>
105: * <name>networkProtocol</name>
106: * <value>tcp</value>
107: * </parameter>
108: * <parameter>
109: * <name>databaseName</name>
110: * <value>XXXX</value>
111: * </parameter>
112: * <parameter>
113: * <name>portNumber</name>
114: * <value>NNNN</value>
115: * </parameter>
116: * <parameter>
117: * <name>user</name>
118: * <value>XXXX</value>
119: * </parameter>
120: * <parameter>
121: * <name>password</name>
122: * <value>XXXX</value>
123: * </parameter>
124: * <parameter>
125: * <name>maxLimit</name>
126: * <value>5</value>
127: * </parameter>
128: * </ResourceParams>
129: * </pre>
130: *
131: * @author <a href="mailto:aner at ncstech.com">Aner Perez</a>
132: */
133: public class BeanFactory implements ObjectFactory {
134:
135: // ----------------------------------------------------------- Constructors
136:
137: // -------------------------------------------------------------- Constants
138:
139: // ----------------------------------------------------- Instance Variables
140:
141: // --------------------------------------------------------- Public Methods
142:
143: // -------------------------------------------------- ObjectFactory Methods
144:
145: /**
146: * Create a new Bean instance.
147: *
148: * @param obj The reference object describing the Bean
149: */
150: public Object getObjectInstance(Object obj, Name name,
151: Context nameCtx, Hashtable environment)
152: throws NamingException {
153:
154: if (obj instanceof ResourceRef) {
155:
156: try {
157:
158: Reference ref = (Reference) obj;
159: String beanClassName = ref.getClassName();
160: Class beanClass = null;
161: ClassLoader tcl = Thread.currentThread()
162: .getContextClassLoader();
163: if (tcl != null) {
164: try {
165: beanClass = tcl.loadClass(beanClassName);
166: } catch (ClassNotFoundException e) {
167: }
168: } else {
169: try {
170: beanClass = Class.forName(beanClassName);
171: } catch (ClassNotFoundException e) {
172: e.printStackTrace();
173: }
174: }
175: if (beanClass == null) {
176: throw new NamingException("Class not found: "
177: + beanClassName);
178: }
179:
180: BeanInfo bi = Introspector.getBeanInfo(beanClass);
181: PropertyDescriptor[] pda = bi.getPropertyDescriptors();
182:
183: Object bean = beanClass.newInstance();
184:
185: Enumeration e = ref.getAll();
186: while (e.hasMoreElements()) {
187:
188: RefAddr ra = (RefAddr) e.nextElement();
189: String propName = ra.getType();
190:
191: if (propName.equals(Constants.FACTORY)
192: || propName.equals("scope")
193: || propName.equals("auth")) {
194: continue;
195: }
196:
197: String value = (String) ra.getContent();
198:
199: Object[] valueArray = new Object[1];
200:
201: int i = 0;
202: for (i = 0; i < pda.length; i++) {
203:
204: if (pda[i].getName().equals(propName)) {
205:
206: Class propType = pda[i].getPropertyType();
207:
208: if (propType.equals(String.class)) {
209: valueArray[0] = value;
210: } else if (propType.equals(Character.class)
211: || propType.equals(char.class)) {
212: valueArray[0] = new Character(value
213: .charAt(0));
214: } else if (propType.equals(Byte.class)
215: || propType.equals(byte.class)) {
216: valueArray[0] = new Byte(value);
217: } else if (propType.equals(Short.class)
218: || propType.equals(short.class)) {
219: valueArray[0] = new Short(value);
220: } else if (propType.equals(Integer.class)
221: || propType.equals(int.class)) {
222: valueArray[0] = new Integer(value);
223: } else if (propType.equals(Long.class)
224: || propType.equals(long.class)) {
225: valueArray[0] = new Long(value);
226: } else if (propType.equals(Float.class)
227: || propType.equals(float.class)) {
228: valueArray[0] = new Float(value);
229: } else if (propType.equals(Double.class)
230: || propType.equals(double.class)) {
231: valueArray[0] = new Double(value);
232: } else {
233: throw new NamingException(
234: "String conversion for property type '"
235: + propType.getName()
236: + "' not available");
237: }
238:
239: Method setProp = pda[i].getWriteMethod();
240: if (setProp != null) {
241: setProp.invoke(bean, valueArray);
242: } else {
243: throw new NamingException(
244: "Write not allowed for property: "
245: + propName);
246: }
247:
248: break;
249:
250: }
251:
252: }
253:
254: if (i == pda.length) {
255: throw new NamingException(
256: "No set method found for property: "
257: + propName);
258: }
259:
260: }
261:
262: return bean;
263:
264: } catch (java.beans.IntrospectionException ie) {
265: throw new NamingException(ie.getMessage());
266: } catch (java.lang.IllegalAccessException iae) {
267: throw new NamingException(iae.getMessage());
268: } catch (java.lang.InstantiationException ie2) {
269: throw new NamingException(ie2.getMessage());
270: } catch (java.lang.reflect.InvocationTargetException ite) {
271: throw new NamingException(ite.getMessage());
272: }
273:
274: } else {
275: return null;
276: }
277:
278: }
279: }
|