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