001: /*
002: * Copyright 1999-2001,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.naming.factory;
018:
019: import java.util.Hashtable;
020: import java.util.Enumeration;
021: import javax.naming.Name;
022: import javax.naming.Context;
023: import javax.naming.NamingException;
024: import javax.naming.Reference;
025: import javax.naming.RefAddr;
026: import javax.naming.spi.ObjectFactory;
027: import org.apache.naming.ResourceRef;
028:
029: import java.beans.Introspector;
030: import java.beans.BeanInfo;
031: import java.beans.PropertyDescriptor;
032:
033: import java.lang.reflect.Method;
034:
035: /**
036: * Object factory for any Resource conforming to the JavaBean spec.
037: *
038: * <p>This factory can be configured in a <code><DefaultContext></code>
039: * or <code><Context></code> element in your <code>conf/server.xml</code>
040: * configuration file. An example of factory configuration is:</p>
041: * <pre>
042: * <Resource name="jdbc/myDataSource" auth="SERVLET"
043: * type="oracle.jdbc.pool.OracleConnectionCacheImpl"/>
044: * <ResourceParams name="jdbc/myDataSource">
045: * <parameter>
046: * <name>factory</name>
047: * <value>org.apache.naming.factory.BeanFactory</value>
048: * </parameter>
049: * <parameter>
050: * <name>driverType</name>
051: * <value>thin</value>
052: * </parameter>
053: * <parameter>
054: * <name>serverName</name>
055: * <value>hue</value>
056: * </parameter>
057: * <parameter>
058: * <name>networkProtocol</name>
059: * <value>tcp</value>
060: * </parameter>
061: * <parameter>
062: * <name>databaseName</name>
063: * <value>XXXX</value>
064: * </parameter>
065: * <parameter>
066: * <name>portNumber</name>
067: * <value>NNNN</value>
068: * </parameter>
069: * <parameter>
070: * <name>user</name>
071: * <value>XXXX</value>
072: * </parameter>
073: * <parameter>
074: * <name>password</name>
075: * <value>XXXX</value>
076: * </parameter>
077: * <parameter>
078: * <name>maxLimit</name>
079: * <value>5</value>
080: * </parameter>
081: * </ResourceParams>
082: * </pre>
083: *
084: * @author <a href="mailto:aner at ncstech.com">Aner Perez</a>
085: */
086: public class BeanFactory implements ObjectFactory {
087:
088: // ----------------------------------------------------------- Constructors
089:
090: // -------------------------------------------------------------- Constants
091:
092: // ----------------------------------------------------- Instance Variables
093:
094: // --------------------------------------------------------- Public Methods
095:
096: // -------------------------------------------------- ObjectFactory Methods
097:
098: /**
099: * Create a new Bean instance.
100: *
101: * @param obj The reference object describing the Bean
102: */
103: public Object getObjectInstance(Object obj, Name name,
104: Context nameCtx, Hashtable environment)
105: throws NamingException {
106:
107: if (obj instanceof ResourceRef) {
108:
109: try {
110:
111: Reference ref = (Reference) obj;
112: String beanClassName = ref.getClassName();
113: Class beanClass = null;
114: ClassLoader tcl = Thread.currentThread()
115: .getContextClassLoader();
116: if (tcl != null) {
117: try {
118: beanClass = tcl.loadClass(beanClassName);
119: } catch (ClassNotFoundException e) {
120: }
121: } else {
122: try {
123: beanClass = Class.forName(beanClassName);
124: } catch (ClassNotFoundException e) {
125: e.printStackTrace();
126: }
127: }
128: if (beanClass == null) {
129: throw new NamingException("Class not found: "
130: + beanClassName);
131: }
132:
133: BeanInfo bi = Introspector.getBeanInfo(beanClass);
134: PropertyDescriptor[] pda = bi.getPropertyDescriptors();
135:
136: Object bean = beanClass.newInstance();
137:
138: Enumeration e = ref.getAll();
139: while (e.hasMoreElements()) {
140:
141: RefAddr ra = (RefAddr) e.nextElement();
142: String propName = ra.getType();
143:
144: if (propName.equals(Constants.FACTORY)
145: || propName.equals("scope")
146: || propName.equals("auth")) {
147: continue;
148: }
149:
150: String value = (String) ra.getContent();
151:
152: Object[] valueArray = new Object[1];
153:
154: int i = 0;
155: for (i = 0; i < pda.length; i++) {
156:
157: if (pda[i].getName().equals(propName)) {
158:
159: Class propType = pda[i].getPropertyType();
160:
161: if (propType.equals(String.class)) {
162: valueArray[0] = value;
163: } else if (propType.equals(Character.class)
164: || propType.equals(char.class)) {
165: valueArray[0] = new Character(value
166: .charAt(0));
167: } else if (propType.equals(Byte.class)
168: || propType.equals(byte.class)) {
169: valueArray[0] = new Byte(value);
170: } else if (propType.equals(Short.class)
171: || propType.equals(short.class)) {
172: valueArray[0] = new Short(value);
173: } else if (propType.equals(Integer.class)
174: || propType.equals(int.class)) {
175: valueArray[0] = new Integer(value);
176: } else if (propType.equals(Long.class)
177: || propType.equals(long.class)) {
178: valueArray[0] = new Long(value);
179: } else if (propType.equals(Float.class)
180: || propType.equals(float.class)) {
181: valueArray[0] = new Float(value);
182: } else if (propType.equals(Double.class)
183: || propType.equals(double.class)) {
184: valueArray[0] = new Double(value);
185: } else if (propType.equals(Boolean.class)
186: || propType.equals(boolean.class)) {
187: valueArray[0] = new Boolean(value);
188: } else {
189: throw new NamingException(
190: "String conversion for property type '"
191: + propType.getName()
192: + "' not available");
193: }
194:
195: Method setProp = pda[i].getWriteMethod();
196: if (setProp != null) {
197: setProp.invoke(bean, valueArray);
198: } else {
199: throw new NamingException(
200: "Write not allowed for property: "
201: + propName);
202: }
203:
204: break;
205:
206: }
207:
208: }
209:
210: if (i == pda.length) {
211: throw new NamingException(
212: "No set method found for property: "
213: + propName);
214: }
215:
216: }
217:
218: return bean;
219:
220: } catch (java.beans.IntrospectionException ie) {
221: throw new NamingException(ie.getMessage());
222: } catch (java.lang.IllegalAccessException iae) {
223: throw new NamingException(iae.getMessage());
224: } catch (java.lang.InstantiationException ie2) {
225: throw new NamingException(ie2.getMessage());
226: } catch (java.lang.reflect.InvocationTargetException ite) {
227: throw new NamingException(ite.getMessage());
228: }
229:
230: } else {
231: return null;
232: }
233:
234: }
235: }
|