001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.resource.deployment;
023:
024: import java.beans.PropertyEditor;
025: import java.beans.PropertyEditorManager;
026: import java.lang.reflect.InvocationTargetException;
027: import java.lang.reflect.Method;
028: import java.util.Collection;
029: import java.util.Iterator;
030: import java.util.Map;
031: import java.util.Properties;
032:
033: import javax.management.ObjectName;
034:
035: import org.jboss.deployment.DeploymentException;
036: import org.jboss.logging.Logger;
037: import org.jboss.resource.metadata.AdminObjectMetaData;
038: import org.jboss.resource.metadata.ConfigPropertyMetaData;
039:
040: /**
041: * An admin object factory
042: *
043: * @author <a href="adrian@jboss.com">Adrian Brock</a>
044: * @version $Revision: 57189 $
045: */
046: public class AdminObjectFactory {
047: /** The logger */
048: private static final Logger log = Logger
049: .getLogger(AdminObjectFactory.class);
050:
051: public static Object createAdminObject(String jndiName,
052: ObjectName rarName, AdminObjectMetaData aomd,
053: Properties properties) throws Exception {
054: boolean trace = log.isTraceEnabled();
055:
056: // Get the current classloader
057: ClassLoader cl = Thread.currentThread().getContextClassLoader();
058:
059: if (trace)
060: log.trace("Creating AdminObject '" + jndiName
061: + "' metadata=" + aomd + " rar=" + rarName
062: + " properties=" + properties + " classloader="
063: + cl);
064:
065: // The interface class
066: String interfaceName = aomd.getAdminObjectInterfaceClass();
067: // Load the interface class class
068: if (trace)
069: log.trace("AdminObject '" + jndiName
070: + "' loading interface=" + interfaceName);
071: Class interfaceClass = cl.loadClass(interfaceName);
072:
073: // Determine the implementation class
074: String implName = aomd.getAdminObjectImplementationClass();
075: if (implName == null)
076: throw new DeploymentException(
077: "No implementation class for admin object '"
078: + interfaceClass + "' ra=" + rarName);
079:
080: // Load the implementation class
081: if (trace)
082: log.trace("AdminObject '" + jndiName
083: + "' loading implementation=" + implName);
084: Class implClass = cl.loadClass(implName);
085: if (interfaceClass.isAssignableFrom(implClass) == false)
086: throw new DeploymentException(implClass.getName()
087: + " is not a '" + interfaceClass + "' ra="
088: + rarName);
089:
090: Object result = implClass.newInstance();
091: if (trace)
092: log.trace("AdminObject '" + jndiName
093: + "' created instance=" + result);
094:
095: // Apply values from the ra.xml
096: Collection raProperties = aomd.getProperties();
097: if (raProperties != null && raProperties.size() != 0) {
098: for (Iterator i = raProperties.iterator(); i.hasNext();) {
099: ConfigPropertyMetaData cpmd = (ConfigPropertyMetaData) i
100: .next();
101: String name = cpmd.getName();
102: String value = cpmd.getValue();
103: if (value != null && value.length() > 0) {
104: if (properties.containsKey(name)) {
105: if (trace)
106: log
107: .trace("AdminObject '"
108: + jndiName
109: + "' property="
110: + name
111: + " IGNORING value="
112: + value
113: + " specified in MBean properties.");
114: } else {
115: // Load the property class as defined in the meta data
116: String typeName = cpmd.getType();
117: if (trace)
118: log.trace("AdminObject '" + jndiName
119: + "' property=" + name
120: + " loading class=" + typeName);
121: Class type = cl.loadClass(typeName);
122:
123: // Find the property editor for this class
124: PropertyEditor editor = PropertyEditorManager
125: .findEditor(type);
126: if (editor == null)
127: throw new DeploymentException(
128: "No property editor found for property '"
129: + name + " class='" + type
130: + "' for admin object '"
131: + interfaceClass + "' ra="
132: + rarName);
133: editor.setAsText(value);
134: Object object = editor.getValue();
135:
136: try {
137: String setter = "set"
138: + Character.toUpperCase(name
139: .charAt(0));
140: if (name.length() > 1)
141: setter = setter.concat(name
142: .substring(1));
143: Method method = implClass.getMethod(setter,
144: new Class[] { type });
145: if (trace)
146: log.trace("AdminObject '" + jndiName
147: + "' property=" + name
148: + " set=" + object);
149: method.invoke(result,
150: new Object[] { object });
151: } catch (InvocationTargetException e) {
152: DeploymentException
153: .rethrowAsDeploymentException(
154: "Error for property '"
155: + name
156: + "' class="
157: + implClass
158: + "' for admin object '"
159: + interfaceClass
160: + "' ra=" + rarName,
161: e.getTargetException());
162: } catch (Throwable t) {
163: DeploymentException
164: .rethrowAsDeploymentException(
165: "Error for property '"
166: + name
167: + "' class="
168: + implClass
169: + "' for admin object '"
170: + interfaceClass
171: + "' ra=" + rarName,
172: t);
173: }
174: }
175: }
176: }
177: }
178:
179: // Apply the properties
180: if (properties != null) {
181: for (Iterator i = properties.entrySet().iterator(); i
182: .hasNext();) {
183: Map.Entry property = (Map.Entry) i.next();
184: String name = (String) property.getKey();
185: String value = (String) property.getValue();
186: if (trace)
187: log.trace("AdminObject '" + jndiName
188: + "' property=" + name + " value=" + value);
189:
190: // Pick up the property metadata
191: ConfigPropertyMetaData cpmd = aomd.getProperty(name);
192: if (cpmd == null)
193: throw new DeploymentException("No property '"
194: + name + "' for admin object '"
195: + interfaceClass + "' ra=" + rarName);
196: if (trace)
197: log.trace("AdminObject '" + jndiName
198: + "' property=" + name + " metadata="
199: + cpmd);
200:
201: // Load the property class as defined in the meta data
202: String typeName = cpmd.getType();
203: if (trace)
204: log.trace("AdminObject '" + jndiName
205: + "' property=" + name + " loading class="
206: + typeName);
207: Class type = cl.loadClass(typeName);
208:
209: // Find the property editor for this class
210: PropertyEditor editor = PropertyEditorManager
211: .findEditor(type);
212: if (editor == null)
213: throw new DeploymentException(
214: "No property editor found for property '"
215: + name + " class='" + type
216: + "' for admin object '"
217: + interfaceClass + "' ra="
218: + rarName);
219: editor.setAsText(value);
220: Object object = editor.getValue();
221:
222: try {
223: String setter = "set"
224: + Character.toUpperCase(name.charAt(0));
225: if (name.length() > 1)
226: setter = setter.concat(name.substring(1));
227: Method method = implClass.getMethod(setter,
228: new Class[] { type });
229: if (trace)
230: log.trace("AdminObject '" + jndiName
231: + "' property=" + name + " set="
232: + object);
233: method.invoke(result, new Object[] { object });
234: } catch (InvocationTargetException e) {
235: DeploymentException.rethrowAsDeploymentException(
236: "Error for property '" + name + "' class="
237: + implClass
238: + "' for admin object '"
239: + interfaceClass + "' ra="
240: + rarName, e.getTargetException());
241: } catch (Throwable t) {
242: DeploymentException.rethrowAsDeploymentException(
243: "Error for property '" + name + "' class="
244: + implClass
245: + "' for admin object '"
246: + interfaceClass + "' ra="
247: + rarName, t);
248: }
249: }
250: }
251:
252: return result;
253: }
254: }
|