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 package org.apache.geronimo.connector.deployment;
018
019 import java.beans.Introspector;
020 import java.beans.PropertyEditor;
021 import java.io.File;
022 import java.io.IOException;
023 import java.lang.reflect.Method;
024 import java.net.URI;
025 import java.net.URL;
026 import java.util.ArrayList;
027 import java.util.Collection;
028 import java.util.Date;
029 import java.util.Enumeration;
030 import java.util.HashMap;
031 import java.util.HashSet;
032 import java.util.Iterator;
033 import java.util.LinkedHashMap;
034 import java.util.List;
035 import java.util.Map;
036 import java.util.Set;
037 import java.util.TreeMap;
038 import java.util.jar.JarFile;
039 import java.util.zip.ZipEntry;
040
041 import javax.naming.Reference;
042 import javax.xml.namespace.QName;
043
044 import org.apache.commons.logging.Log;
045 import org.apache.commons.logging.LogFactory;
046 import org.apache.geronimo.common.DeploymentException;
047 import org.apache.geronimo.common.UnresolvedReferenceException;
048 import org.apache.geronimo.common.propertyeditor.PropertyEditors;
049 import org.apache.geronimo.connector.ActivationSpecWrapperGBean;
050 import org.apache.geronimo.connector.AdminObjectWrapper;
051 import org.apache.geronimo.connector.AdminObjectWrapperGBean;
052 import org.apache.geronimo.connector.JCAResourceImplGBean;
053 import org.apache.geronimo.connector.ResourceAdapterImplGBean;
054 import org.apache.geronimo.connector.ResourceAdapterModuleImplGBean;
055 import org.apache.geronimo.connector.ResourceAdapterWrapperGBean;
056 import org.apache.geronimo.connector.outbound.JCAConnectionFactoryImplGBean;
057 import org.apache.geronimo.connector.outbound.ManagedConnectionFactoryWrapper;
058 import org.apache.geronimo.connector.outbound.ManagedConnectionFactoryWrapperGBean;
059 import org.apache.geronimo.connector.outbound.connectionmanagerconfig.LocalTransactions;
060 import org.apache.geronimo.connector.outbound.connectionmanagerconfig.NoPool;
061 import org.apache.geronimo.connector.outbound.connectionmanagerconfig.NoTransactions;
062 import org.apache.geronimo.connector.outbound.connectionmanagerconfig.PartitionedPool;
063 import org.apache.geronimo.connector.outbound.connectionmanagerconfig.PoolingSupport;
064 import org.apache.geronimo.connector.outbound.connectionmanagerconfig.SinglePool;
065 import org.apache.geronimo.connector.outbound.connectionmanagerconfig.TransactionLog;
066 import org.apache.geronimo.connector.outbound.connectionmanagerconfig.TransactionSupport;
067 import org.apache.geronimo.connector.outbound.connectionmanagerconfig.XATransactions;
068 import org.apache.geronimo.deployment.ModuleIDBuilder;
069 import org.apache.geronimo.deployment.NamespaceDrivenBuilder;
070 import org.apache.geronimo.deployment.NamespaceDrivenBuilderCollection;
071 import org.apache.geronimo.deployment.service.EnvironmentBuilder;
072 import org.apache.geronimo.deployment.service.GBeanBuilder;
073 import org.apache.geronimo.deployment.util.DeploymentUtil;
074 import org.apache.geronimo.deployment.xbeans.EnvironmentType;
075 import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
076 import org.apache.geronimo.gbean.AbstractName;
077 import org.apache.geronimo.gbean.AbstractNameQuery;
078 import org.apache.geronimo.gbean.DynamicGAttributeInfo;
079 import org.apache.geronimo.gbean.GAttributeInfo;
080 import org.apache.geronimo.gbean.GBeanData;
081 import org.apache.geronimo.gbean.GBeanInfo;
082 import org.apache.geronimo.gbean.GBeanInfoBuilder;
083 import org.apache.geronimo.gbean.InvalidConfigurationException;
084 import org.apache.geronimo.j2ee.deployment.ActivationSpecInfoLocator;
085 import org.apache.geronimo.j2ee.deployment.ConnectorModule;
086 import org.apache.geronimo.j2ee.deployment.EARContext;
087 import org.apache.geronimo.j2ee.deployment.Module;
088 import org.apache.geronimo.j2ee.deployment.ModuleBuilder;
089 import org.apache.geronimo.j2ee.deployment.annotation.AnnotatedApp;
090 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
091 import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
092 import org.apache.geronimo.kernel.GBeanNotFoundException;
093 import org.apache.geronimo.kernel.Naming;
094 import org.apache.geronimo.kernel.config.Configuration;
095 import org.apache.geronimo.kernel.config.ConfigurationStore;
096 import org.apache.geronimo.kernel.repository.Environment;
097 import org.apache.geronimo.management.JCAConnectionFactory;
098 import org.apache.geronimo.management.geronimo.JCAAdminObject;
099 import org.apache.geronimo.management.geronimo.JCAResourceAdapter;
100 import org.apache.geronimo.management.geronimo.ResourceAdapterModule;
101 import org.apache.geronimo.naming.deployment.ENCConfigBuilder;
102 import org.apache.geronimo.naming.reference.ResourceReference;
103 import org.apache.geronimo.schema.SchemaConversionUtils;
104 import org.apache.geronimo.xbeans.geronimo.GerAdminobjectInstanceType;
105 import org.apache.geronimo.xbeans.geronimo.GerAdminobjectType;
106 import org.apache.geronimo.xbeans.geronimo.GerConfigPropertySettingType;
107 import org.apache.geronimo.xbeans.geronimo.GerConnectionDefinitionType;
108 import org.apache.geronimo.xbeans.geronimo.GerConnectiondefinitionInstanceType;
109 import org.apache.geronimo.xbeans.geronimo.GerConnectionmanagerType;
110 import org.apache.geronimo.xbeans.geronimo.GerConnectorDocument;
111 import org.apache.geronimo.xbeans.geronimo.GerConnectorType;
112 import org.apache.geronimo.xbeans.geronimo.GerPartitionedpoolType;
113 import org.apache.geronimo.xbeans.geronimo.GerResourceadapterType;
114 import org.apache.geronimo.xbeans.geronimo.GerSinglepoolType;
115 import org.apache.geronimo.xbeans.j2ee.ActivationspecType;
116 import org.apache.geronimo.xbeans.j2ee.AdminobjectType;
117 import org.apache.geronimo.xbeans.j2ee.ConfigPropertyType;
118 import org.apache.geronimo.xbeans.j2ee.ConnectionDefinitionType;
119 import org.apache.geronimo.xbeans.j2ee.ConnectorDocument;
120 import org.apache.geronimo.xbeans.j2ee.ConnectorType;
121 import org.apache.geronimo.xbeans.j2ee.MessagelistenerType;
122 import org.apache.geronimo.xbeans.j2ee.ResourceadapterType;
123 import org.apache.xmlbeans.XmlCursor;
124 import org.apache.xmlbeans.XmlDocumentProperties;
125 import org.apache.xmlbeans.XmlException;
126 import org.apache.xmlbeans.XmlObject;
127
128 /**
129 * @version $Rev:385659 $ $Date: 2007-06-25 12:52:11 -0400 (Mon, 25 Jun 2007) $
130 */
131 public class ConnectorModuleBuilder implements ModuleBuilder, ActivationSpecInfoLocator {
132 private final static Log log = LogFactory.getLog(ConnectorModuleBuilder.class);
133
134 private static QName CONNECTOR_QNAME = GerConnectorDocument.type.getDocumentElementName();
135 static final String GERCONNECTOR_NAMESPACE = CONNECTOR_QNAME.getNamespaceURI();
136
137 private final int defaultMaxSize;
138 private final int defaultMinSize;
139 private final int defaultBlockingTimeoutMilliseconds;
140 private final int defaultIdleTimeoutMinutes;
141 private final boolean defaultXATransactionCaching;
142 private final boolean defaultXAThreadCaching;
143 private final Environment defaultEnvironment;
144 private final NamespaceDrivenBuilderCollection serviceBuilders;
145 private static final QName RESOURCE_ADAPTER_VERSION = new QName(SchemaConversionUtils.J2EE_NAMESPACE, "resourceadapter-version");
146
147 public ConnectorModuleBuilder(Environment defaultEnvironment,
148 int defaultMaxSize,
149 int defaultMinSize,
150 int defaultBlockingTimeoutMilliseconds,
151 int defaultIdleTimeoutMinutes,
152 boolean defaultXATransactionCaching,
153 boolean defaultXAThreadCaching,
154 Collection serviceBuilders) {
155 this.defaultEnvironment = defaultEnvironment;
156
157 this.defaultMaxSize = defaultMaxSize;
158 this.defaultMinSize = defaultMinSize;
159 this.defaultBlockingTimeoutMilliseconds = defaultBlockingTimeoutMilliseconds;
160 this.defaultIdleTimeoutMinutes = defaultIdleTimeoutMinutes;
161 this.defaultXATransactionCaching = defaultXATransactionCaching;
162 this.defaultXAThreadCaching = defaultXAThreadCaching;
163 this.serviceBuilders = new NamespaceDrivenBuilderCollection(serviceBuilders, GBeanBuilder.SERVICE_QNAME);
164 }
165
166 public Module createModule(File plan, JarFile moduleFile, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException {
167 return createModule(plan, moduleFile, "rar", null, null, null, naming, idBuilder);
168 }
169
170 public Module createModule(Object plan, JarFile moduleFile, String targetPath, URL specDDUrl, Environment environment, Object moduleContextInfo, AbstractName earName, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException {
171 return createModule(plan, moduleFile, targetPath, specDDUrl, environment, earName, naming, idBuilder);
172 }
173
174 private Module createModule(Object plan, JarFile moduleFile, String targetPath, URL specDDUrl, Environment earEnvironment, AbstractName earName, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException {
175 assert moduleFile != null : "moduleFile is null";
176 assert targetPath != null : "targetPath is null";
177 assert !targetPath.endsWith("/") : "targetPath must not end with a '/'";
178
179 String specDD;
180 XmlObject connector;
181 try {
182 if (specDDUrl == null) {
183 specDDUrl = DeploymentUtil.createJarURL(moduleFile, "META-INF/ra.xml");
184 }
185
186 // read in the entire specDD as a string, we need this for getDeploymentDescriptor
187 // on the J2ee management object
188 specDD = DeploymentUtil.readAll(specDDUrl);
189 } catch (Exception e) {
190 //no ra.xml, not for us.
191 return null;
192 }
193 //we found ra.xml, if it won't parse it's an error.
194 try {
195 // parse it
196 XmlObject xmlObject = XmlBeansUtil.parse(specDD);
197 ConnectorDocument connectorDoc = convertToConnectorSchema(xmlObject);
198 connector = connectorDoc.getConnector();
199 } catch (XmlException e) {
200 throw new DeploymentException("Could not parse ra.xml descriptor", e);
201 }
202 GerConnectorType gerConnector = null;
203 try {
204 // load the geronimo connector plan from either the supplied plan or from the earFile
205 try {
206 if (plan instanceof XmlObject) {
207 gerConnector = (GerConnectorType) SchemaConversionUtils.getNestedObjectAsType((XmlObject) plan,
208 CONNECTOR_QNAME,
209 GerConnectorType.type);
210 } else {
211 GerConnectorDocument gerConnectorDoc;
212 ArrayList errors = new ArrayList();
213 if (plan != null) {
214 gerConnectorDoc = GerConnectorDocument.Factory.parse((File) plan, XmlBeansUtil.createXmlOptions(errors));
215 } else {
216 URL path = DeploymentUtil.createJarURL(moduleFile, "META-INF/geronimo-ra.xml");
217 gerConnectorDoc = GerConnectorDocument.Factory.parse(path, XmlBeansUtil.createXmlOptions(errors));
218 }
219 if (errors.size() > 0) {
220 throw new DeploymentException("Could not parse connector doc: " + errors);
221 }
222 if (gerConnectorDoc != null) {
223 gerConnector = gerConnectorDoc.getConnector();
224 }
225 }
226 } catch (IOException e) {
227 //do nothing
228 }
229
230 // if we got one extract the validate it otherwise create a default one
231 if (gerConnector == null) {
232 throw new DeploymentException("A connector module must be deployed using a Geronimo deployment plan" +
233 " (either META-INF/geronimo-ra.xml in the RAR file or a standalone deployment plan passed to the deployer).");
234 }
235 ConnectorPlanRectifier.rectifyPlan(gerConnector);
236 XmlCursor cursor = gerConnector.newCursor();
237 try {
238 SchemaConversionUtils.convertToGeronimoSubSchemas(cursor);
239 } finally {
240 cursor.dispose();
241 }
242
243 XmlBeansUtil.validateDD(gerConnector);
244 } catch (XmlException e) {
245 throw new DeploymentException("Could not parse module descriptor", e);
246 }
247
248 EnvironmentType environmentType = gerConnector.getEnvironment();
249 Environment environment = EnvironmentBuilder.buildEnvironment(environmentType, defaultEnvironment);
250 if (earEnvironment != null) {
251 EnvironmentBuilder.mergeEnvironments(earEnvironment, environment);
252 environment = earEnvironment;
253 if (!environment.getConfigId().isResolved()) {
254 throw new IllegalStateException("Connector module ID should be fully resolved (not " + environment.getConfigId() + ")");
255 }
256 } else {
257 idBuilder.resolve(environment, new File(moduleFile.getName()).getName(), "rar");
258 }
259
260 AbstractName moduleName;
261 if (earName == null) {
262 earName = naming.createRootName(environment.getConfigId(), NameFactory.NULL, NameFactory.J2EE_APPLICATION);
263 moduleName = naming.createChildName(earName, environment.getConfigId().toString(), NameFactory.RESOURCE_ADAPTER_MODULE);
264 } else {
265 moduleName = naming.createChildName(earName, targetPath, NameFactory.RESOURCE_ADAPTER_MODULE);
266 }
267
268 boolean standAlone = earEnvironment == null;
269 AnnotatedApp annotatedApp = null;
270 return new ConnectorModule(standAlone, moduleName, environment, moduleFile, targetPath, connector, gerConnector, specDD, annotatedApp);
271
272 }
273
274 static ConnectorDocument convertToConnectorSchema(XmlObject xmlObject) throws XmlException {
275 if (ConnectorDocument.type.equals(xmlObject.schemaType())) {
276 XmlBeansUtil.validateDD(xmlObject);
277 return (ConnectorDocument) xmlObject;
278 }
279 XmlCursor cursor = xmlObject.newCursor();
280 XmlDocumentProperties xmlDocumentProperties = cursor.documentProperties();
281 String publicId = xmlDocumentProperties.getDoctypePublicId();
282 try {
283 if ("-//Sun Microsystems, Inc.//DTD Connector 1.0//EN".equals(publicId)) {
284 XmlCursor moveable = xmlObject.newCursor();
285 try {
286 String schemaLocationURL = "http://java.sun.com/xml/ns/j2ee/connector_1_5.xsd";
287 String version = "1.5";
288 SchemaConversionUtils.convertToSchema(cursor, SchemaConversionUtils.J2EE_NAMESPACE, schemaLocationURL, version);
289 cursor.toStartDoc();
290 cursor.toChild(SchemaConversionUtils.J2EE_NAMESPACE, "connector");
291 cursor.toFirstChild();
292 SchemaConversionUtils.convertToDescriptionGroup(SchemaConversionUtils.J2EE_NAMESPACE, cursor, moveable);
293 cursor.toNextSibling(SchemaConversionUtils.J2EE_NAMESPACE, "spec-version");
294 cursor.removeXml();
295 cursor.toNextSibling(SchemaConversionUtils.J2EE_NAMESPACE, "version");
296 cursor.setName(RESOURCE_ADAPTER_VERSION);
297 cursor.toNextSibling(SchemaConversionUtils.J2EE_NAMESPACE, "resourceadapter");
298 moveable.toCursor(cursor);
299 cursor.toFirstChild();
300 cursor.beginElement("outbound-resourceadapter", SchemaConversionUtils.J2EE_NAMESPACE);
301 cursor.beginElement("connection-definition", SchemaConversionUtils.J2EE_NAMESPACE);
302 moveable.toChild(SchemaConversionUtils.J2EE_NAMESPACE, "managedconnectionfactory-class");
303 moveable.push();
304 //from moveable to cursor
305 moveable.moveXml(cursor);
306 while (moveable.toNextSibling(SchemaConversionUtils.J2EE_NAMESPACE, "config-property")) {
307 moveable.moveXml(cursor);
308 }
309 moveable.pop();
310 moveable.toNextSibling(SchemaConversionUtils.J2EE_NAMESPACE, "connectionfactory-interface");
311 moveable.moveXml(cursor);
312 moveable.toNextSibling(SchemaConversionUtils.J2EE_NAMESPACE, "connectionfactory-impl-class");
313 moveable.moveXml(cursor);
314 moveable.toNextSibling(SchemaConversionUtils.J2EE_NAMESPACE, "connection-interface");
315 moveable.moveXml(cursor);
316 moveable.toNextSibling(SchemaConversionUtils.J2EE_NAMESPACE, "connection-impl-class");
317 moveable.moveXml(cursor);
318 //get out of connection-definition element
319 cursor.toNextToken();
320 moveable.toNextSibling(SchemaConversionUtils.J2EE_NAMESPACE, "transaction-support");
321 moveable.moveXml(cursor);
322 while (moveable.toNextSibling(SchemaConversionUtils.J2EE_NAMESPACE, "authentication-mechanism")) {
323 moveable.moveXml(cursor);
324 }
325 moveable.toNextSibling(SchemaConversionUtils.J2EE_NAMESPACE, "reauthentication-support");
326 moveable.moveXml(cursor);
327 } finally {
328 moveable.dispose();
329 }
330
331 }
332 } finally {
333 cursor.dispose();
334 }
335 XmlObject result = xmlObject.changeType(ConnectorDocument.type);
336 if (result != null) {
337 XmlBeansUtil.validateDD(result);
338 return (ConnectorDocument) result;
339 }
340 XmlBeansUtil.validateDD(xmlObject);
341 return (ConnectorDocument) xmlObject;
342
343 }
344
345 public void installModule(JarFile earFile, EARContext earContext, Module module, Collection configurationStores, ConfigurationStore targetConfigurationStore, Collection repository) throws DeploymentException {
346 try {
347 JarFile moduleFile = module.getModuleFile();
348
349 // add the manifest classpath entries declared in the connector to the class loader
350 // we have to explicitly add these since we are unpacking the connector module
351 // and the url class loader will not pick up a manifiest from an unpacked dir
352 // N.B. If we ever introduce a separate configuration/module for a rar inside an ear
353 // this will need to be modified to use "../" instead of module.getTargetPath().
354 // See AbstractWebModuleBuilder.
355 earContext.addManifestClassPath(moduleFile, URI.create(module.getTargetPath()));
356
357 URI targetURI = URI.create(module.getTargetPath() + "/");
358 Enumeration entries = moduleFile.entries();
359 while (entries.hasMoreElements()) {
360 ZipEntry entry = (ZipEntry) entries.nextElement();
361 URI target = targetURI.resolve(entry.getName());
362 if (entry.getName().endsWith(".jar")) {
363 earContext.addInclude(target, moduleFile, entry);
364 } else {
365 earContext.addFile(target, moduleFile, entry);
366 }
367 }
368
369 } catch (IOException e) {
370 throw new DeploymentException("Problem deploying connector", e);
371 }
372 }
373
374 public void initContext(EARContext earContext, Module module, ClassLoader cl) throws DeploymentException {
375 ConnectorModule resourceModule = (ConnectorModule) module;
376
377 final ConnectorType connector = (ConnectorType) module.getSpecDD();
378
379 /*
380 The chain of idiotic jsr-77 meaningless objects is:
381 ResourceAdapterModule (1) >
382 ResourceAdapter (n, but there can only be 1 resource adapter in a rar, so we use 1) >
383 JCAResource (1) >
384 JCAConnectionFactory (n) >
385 JCAManagedConnectionFactory (1)
386 We also include:
387 JCAResourceAdapter (n) (from JCAResource) (actual instance of ResourceAdapter)
388 TODO include admin objects (n) from JCAResource presumably
389 */
390 AbstractName resourceAdapterModuleName = resourceModule.getModuleName();
391
392 AbstractName resourceAdapterjsr77Name = earContext.getNaming().createChildName(resourceAdapterModuleName, module.getName(), NameFactory.RESOURCE_ADAPTER);
393 AbstractName jcaResourcejsr77Name = earContext.getNaming().createChildName(resourceAdapterjsr77Name, module.getName(), NameFactory.JCA_RESOURCE);
394
395 //set up the metadata for the ResourceAdapterModule
396 GBeanData resourceAdapterModuleData = new GBeanData(resourceAdapterModuleName, ResourceAdapterModuleImplGBean.GBEAN_INFO);
397 // initalize the GBean
398 if (earContext.getServerName() != null) {
399 //app clients don't have a Server gbean
400 resourceAdapterModuleData.setReferencePattern(NameFactory.J2EE_SERVER, earContext.getServerName());
401 //app clients don't have an application name either
402 if (!earContext.getModuleName().equals(resourceAdapterModuleName)) {
403 resourceAdapterModuleData.setReferencePattern(NameFactory.J2EE_APPLICATION, earContext.getModuleName());
404 }
405 }
406 resourceAdapterModuleData.setReferencePattern("ResourceAdapter", resourceAdapterjsr77Name);
407
408 resourceAdapterModuleData.setAttribute("deploymentDescriptor", module.getOriginalSpecDD());
409 resourceAdapterModuleData.setAttribute("displayName", connector.getDisplayNameArray().length == 0 ? null : connector.getDisplayNameArray(0).getStringValue());
410 resourceAdapterModuleData.setAttribute("description", connector.getDescriptionArray().length == 0 ? null : connector.getDescriptionArray(0).getStringValue());
411 resourceAdapterModuleData.setAttribute("vendorName", connector.getVendorName().getStringValue());
412 resourceAdapterModuleData.setAttribute("EISType", connector.getEisType().getStringValue());
413 resourceAdapterModuleData.setAttribute("resourceAdapterVersion", connector.getResourceadapterVersion().getStringValue());
414
415 ResourceadapterType resourceadapter = connector.getResourceadapter();
416 // Create the resource adapter gbean
417 if (resourceadapter.isSetResourceadapterClass()) {
418 GBeanInfoBuilder resourceAdapterInfoBuilder = new GBeanInfoBuilder(ResourceAdapterWrapperGBean.class, ResourceAdapterWrapperGBean.GBEAN_INFO);
419 GBeanData resourceAdapterGBeanData = setUpDynamicGBean(resourceAdapterInfoBuilder, resourceadapter.getConfigPropertyArray(), cl);
420
421 resourceAdapterGBeanData.setAttribute("resourceAdapterClass", resourceadapter.getResourceadapterClass().getStringValue().trim());
422
423 // Add map from messageListenerInterface to activationSpec class
424 Map<String, String> messageListenerToActivationSpecMap = new TreeMap<String, String>();
425 if (resourceadapter.isSetInboundResourceadapter() && resourceadapter.getInboundResourceadapter().isSetMessageadapter()) {
426 for (MessagelistenerType messagelistenerType : resourceadapter.getInboundResourceadapter().getMessageadapter().getMessagelistenerArray()) {
427 String messageListenerInterface = messagelistenerType.getMessagelistenerType().getStringValue().trim();
428 ActivationspecType activationspec = messagelistenerType.getActivationspec();
429 String activationSpecClassName = activationspec.getActivationspecClass().getStringValue().trim();
430 messageListenerToActivationSpecMap.put(messageListenerInterface, activationSpecClassName);
431 resourceAdapterGBeanData.setAttribute("messageListenerToActivationSpecMap", messageListenerToActivationSpecMap);
432 resourceAdapterGBeanData.setReferencePattern("TransactionManager", earContext.getTransactionManagerName());
433 }
434 }
435
436 resourceAdapterModuleData.setAttribute("resourceAdapterGBeanData", resourceAdapterGBeanData);
437 }
438
439 if (resourceadapter.isSetInboundResourceadapter() && resourceadapter.getInboundResourceadapter().isSetMessageadapter()) {
440 Map activationSpecInfoMap = getActivationSpecInfoMap(resourceadapter.getInboundResourceadapter().getMessageadapter().getMessagelistenerArray(), cl);
441 resourceAdapterModuleData.setAttribute("activationSpecInfoMap", activationSpecInfoMap);
442 }
443 Map adminObjectInfoMap = getAdminObjectInfoMap(resourceadapter.getAdminobjectArray(), cl);
444 resourceAdapterModuleData.setAttribute("adminObjectInfoMap", adminObjectInfoMap);
445 if (resourceadapter.isSetOutboundResourceadapter()) {
446 Map managedConnectionFactoryInfoMap = getManagedConnectionFactoryInfoMap(resourceadapter.getOutboundResourceadapter().getConnectionDefinitionArray(), cl);
447 resourceAdapterModuleData.setAttribute("managedConnectionFactoryInfoMap", managedConnectionFactoryInfoMap);
448 }
449
450 try {
451 earContext.addGBean(resourceAdapterModuleData);
452 } catch (GBeanAlreadyExistsException e) {
453 throw new DeploymentException("Could not add resource adapter module gbean to context", e);
454 }
455
456 //construct the bogus resource adapter and jca resource placeholders
457 GBeanData resourceAdapterData = new GBeanData(resourceAdapterjsr77Name, ResourceAdapterImplGBean.GBEAN_INFO);
458 resourceAdapterData.setReferencePattern("JCAResource", jcaResourcejsr77Name);
459 try {
460 earContext.addGBean(resourceAdapterData);
461 } catch (GBeanAlreadyExistsException e) {
462 throw new DeploymentException("Could not add resource adapter gbean to context", e);
463 }
464
465 GBeanData jcaResourceData = new GBeanData(jcaResourcejsr77Name, JCAResourceImplGBean.GBEAN_INFO);
466 Map thisModule = new LinkedHashMap(2);
467 thisModule.put(NameFactory.J2EE_APPLICATION, resourceAdapterModuleName.getNameProperty(NameFactory.J2EE_APPLICATION));
468 thisModule.put(NameFactory.RESOURCE_ADAPTER_MODULE, resourceAdapterModuleName.getNameProperty(NameFactory.J2EE_NAME));
469 jcaResourceData.setReferencePattern("ConnectionFactories", new AbstractNameQuery(resourceAdapterModuleName.getArtifact(), thisModule, JCAConnectionFactory.class.getName()));
470 jcaResourceData.setReferencePattern("ResourceAdapters", new AbstractNameQuery(resourceAdapterModuleName.getArtifact(), thisModule, JCAResourceAdapter.class.getName()));
471 jcaResourceData.setReferencePattern("AdminObjects", new AbstractNameQuery(resourceAdapterModuleName.getArtifact(), thisModule, JCAAdminObject.class.getName()));
472
473 try {
474 earContext.addGBean(jcaResourceData);
475 } catch (GBeanAlreadyExistsException e) {
476 throw new DeploymentException("Could not add jca resource gbean to context", e);
477 }
478
479 GerConnectorType geronimoConnector = (GerConnectorType) module.getVendorDD();
480
481 serviceBuilders.build(geronimoConnector, earContext, earContext);
482
483 addConnectorGBeans(earContext, jcaResourcejsr77Name, resourceAdapterModuleData, connector, geronimoConnector, cl);
484
485 }
486
487 public void addGBeans(EARContext earContext, Module module, ClassLoader cl, Collection repository) throws DeploymentException {
488 //all our gbeans are added in the initContext step
489 }
490
491 public String getSchemaNamespace() {
492 return GERCONNECTOR_NAMESPACE;
493 }
494
495 private void addConnectorGBeans(EARContext earContext, AbstractName jcaResourceName, GBeanData resourceAdapterModuleData, ConnectorType connector, GerConnectorType geronimoConnector, ClassLoader cl) throws DeploymentException {
496 ResourceadapterType resourceadapter = connector.getResourceadapter();
497
498 GerResourceadapterType[] geronimoResourceAdapters = geronimoConnector.getResourceadapterArray();
499 for (int k = 0; k < geronimoResourceAdapters.length; k++) {
500 GerResourceadapterType geronimoResourceAdapter = geronimoResourceAdapters[k];
501
502 // Resource Adapter
503 AbstractName resourceAdapterAbstractName = null;
504 if (resourceadapter.isSetResourceadapterClass()) {
505 GBeanData resourceAdapterGBeanData = locateResourceAdapterGBeanData(resourceAdapterModuleData);
506 GBeanData resourceAdapterInstanceGBeanData = new GBeanData(resourceAdapterGBeanData);
507
508 setDynamicGBeanDataAttributes(resourceAdapterInstanceGBeanData, geronimoResourceAdapter.getResourceadapterInstance().getConfigPropertySettingArray(), cl);
509
510 // set the work manager name
511 AbstractNameQuery workManagerName = ENCConfigBuilder.getGBeanQuery(NameFactory.JCA_WORK_MANAGER, geronimoResourceAdapter.getResourceadapterInstance().getWorkmanager());
512 resourceAdapterInstanceGBeanData.setReferencePattern("WorkManager", workManagerName);
513
514 // set the xa terminator name which is the same as our transaction manager
515 resourceAdapterInstanceGBeanData.setReferencePattern("XATerminator", earContext.getTransactionManagerName());
516
517 String resourceAdapterName = geronimoResourceAdapter.getResourceadapterInstance().getResourceadapterName();
518 resourceAdapterAbstractName = earContext.getNaming().createChildName(jcaResourceName, resourceAdapterName, NameFactory.JCA_RESOURCE_ADAPTER);
519 resourceAdapterInstanceGBeanData.setAbstractName(resourceAdapterAbstractName);
520 try {
521 earContext.addGBean(resourceAdapterInstanceGBeanData);
522 } catch (GBeanAlreadyExistsException e) {
523 throw new DeploymentException("Could not add resource adapter instance gbean to context", e);
524 }
525 }
526
527 // Outbound Managed Connection Factories (think JDBC data source or JMS connection factory)
528
529 // ManagedConnectionFactory setup
530 if (geronimoResourceAdapter.isSetOutboundResourceadapter()) {
531 if (!resourceadapter.isSetOutboundResourceadapter()) {
532 throw new DeploymentException("Geronimo plan configures an outbound resource adapter but ra.xml does not describe any");
533 }
534 String transactionSupport = resourceadapter.getOutboundResourceadapter().getTransactionSupport().getStringValue().trim();
535 for (int i = 0; i < geronimoResourceAdapter.getOutboundResourceadapter().getConnectionDefinitionArray().length; i++)
536 {
537 GerConnectionDefinitionType geronimoConnectionDefinition = geronimoResourceAdapter.getOutboundResourceadapter().getConnectionDefinitionArray(i);
538 assert geronimoConnectionDefinition != null : "Null GeronimoConnectionDefinition";
539
540 String connectionFactoryInterfaceName = geronimoConnectionDefinition.getConnectionfactoryInterface().trim();
541 GBeanData connectionFactoryGBeanData = locateConnectionFactoryInfo(resourceAdapterModuleData, connectionFactoryInterfaceName);
542
543 if (connectionFactoryGBeanData == null) {
544 throw new DeploymentException("No connection definition for ConnectionFactory class: " + connectionFactoryInterfaceName);
545 }
546
547 for (int j = 0; j < geronimoConnectionDefinition.getConnectiondefinitionInstanceArray().length; j++)
548 {
549 GerConnectiondefinitionInstanceType connectionfactoryInstance = geronimoConnectionDefinition.getConnectiondefinitionInstanceArray()[j];
550
551 addOutboundGBeans(earContext, jcaResourceName, resourceAdapterAbstractName, connectionFactoryGBeanData, connectionfactoryInstance, transactionSupport, cl);
552 }
553 }
554 }
555 }
556 // admin objects (think message queues and topics)
557
558 // add configured admin objects
559 for (int i = 0; i < geronimoConnector.getAdminobjectArray().length; i++) {
560 GerAdminobjectType gerAdminObject = geronimoConnector.getAdminobjectArray()[i];
561
562 String adminObjectInterface = gerAdminObject.getAdminobjectInterface().trim();
563 GBeanData adminObjectGBeanData = locateAdminObjectInfo(resourceAdapterModuleData, adminObjectInterface);
564
565 if (adminObjectGBeanData == null) {
566 throw new DeploymentException("No admin object declared for interface: " + adminObjectInterface);
567 }
568
569 for (int j = 0; j < gerAdminObject.getAdminobjectInstanceArray().length; j++) {
570 GBeanData adminObjectInstanceGBeanData = new GBeanData(adminObjectGBeanData);
571 GerAdminobjectInstanceType gerAdminObjectInstance = gerAdminObject.getAdminobjectInstanceArray()[j];
572 setDynamicGBeanDataAttributes(adminObjectInstanceGBeanData, gerAdminObjectInstance.getConfigPropertySettingArray(), cl);
573 // add it
574 AbstractName adminObjectAbstractName = earContext.getNaming().createChildName(jcaResourceName, gerAdminObjectInstance.getMessageDestinationName().trim(), NameFactory.JCA_ADMIN_OBJECT);
575 adminObjectInstanceGBeanData.setAbstractName(adminObjectAbstractName);
576 try {
577 earContext.addGBean(adminObjectInstanceGBeanData);
578 } catch (GBeanAlreadyExistsException e) {
579 throw new DeploymentException("Could not add admin object gbean to context", e);
580 }
581 }
582 }
583 }
584
585 private Map getActivationSpecInfoMap(MessagelistenerType[] messagelistenerArray, ClassLoader cl) throws DeploymentException {
586 Map activationSpecInfos = new HashMap();
587 for (int i = 0; i < messagelistenerArray.length; i++) {
588 MessagelistenerType messagelistenerType = messagelistenerArray[i];
589 String messageListenerInterface = messagelistenerType.getMessagelistenerType().getStringValue().trim();
590 ActivationspecType activationspec = messagelistenerType.getActivationspec();
591 String activationSpecClassName = activationspec.getActivationspecClass().getStringValue().trim();
592 GBeanInfoBuilder infoBuilder = new GBeanInfoBuilder(ActivationSpecWrapperGBean.class, ActivationSpecWrapperGBean.GBEAN_INFO);
593
594 //add all javabean properties that have both getter and setter. Ignore the "required" flag from the dd.
595 Map getters = new HashMap();
596 Set setters = new HashSet();
597 Method[] methods;
598 try {
599 Class activationSpecClass = cl.loadClass(activationSpecClassName);
600 methods = activationSpecClass.getMethods();
601 } catch (ClassNotFoundException e) {
602 throw new DeploymentException("Can not load activation spec class", e);
603 }
604 for (int j = 0; j < methods.length; j++) {
605 Method method = methods[j];
606 String methodName = method.getName();
607 if ((methodName.startsWith("get") || methodName.startsWith("is")) && method.getParameterTypes().length == 0) {
608 String attributeName = (methodName.startsWith("get")) ? methodName.substring(3) : methodName.substring(2);
609 getters.put(Introspector.decapitalize(attributeName), method.getReturnType().getName());
610 } else if (methodName.startsWith("set") && method.getParameterTypes().length == 1) {
611 setters.add(Introspector.decapitalize(methodName.substring(3)));
612 }
613 }
614 getters.keySet().retainAll(setters);
615 getters.remove("resourceAdapter");
616
617 for (Iterator iterator = getters.entrySet().iterator(); iterator.hasNext();) {
618 Map.Entry entry = (Map.Entry) iterator.next();
619 infoBuilder.addAttribute(new DynamicGAttributeInfo((String) entry.getKey(), (String) entry.getValue(), true, true, true, true));
620 }
621
622 GBeanInfo gbeanInfo = infoBuilder.getBeanInfo();
623 try {
624 //make sure the class is available, but we don't use it.
625 cl.loadClass(activationSpecClassName);
626 } catch (ClassNotFoundException e) {
627 throw new DeploymentException("Could not load ActivationSpec class", e);
628 }
629 GBeanData activationSpecInfo = new GBeanData(gbeanInfo);
630 activationSpecInfo.setAttribute("activationSpecClass", activationSpecClassName);
631 activationSpecInfos.put(messageListenerInterface, activationSpecInfo);
632 }
633 return activationSpecInfos;
634 }
635
636 private Map getManagedConnectionFactoryInfoMap(ConnectionDefinitionType[] connectionDefinitionArray, ClassLoader cl) throws DeploymentException {
637 Map managedConnectionFactoryInfos = new HashMap();
638 for (int i = 0; i < connectionDefinitionArray.length; i++) {
639 ConnectionDefinitionType connectionDefinition = connectionDefinitionArray[i];
640
641 GBeanInfoBuilder managedConnectionFactoryInfoBuilder = new GBeanInfoBuilder(ManagedConnectionFactoryWrapper.class, ManagedConnectionFactoryWrapperGBean.GBEAN_INFO);
642 GBeanData managedConnectionFactoryGBeanData = setUpDynamicGBean(managedConnectionFactoryInfoBuilder, connectionDefinition.getConfigPropertyArray(), cl);
643
644 // set the standard properties
645 String connectionfactoryInterface = connectionDefinition.getConnectionfactoryInterface().getStringValue().trim();
646 managedConnectionFactoryGBeanData.setAttribute("managedConnectionFactoryClass", connectionDefinition.getManagedconnectionfactoryClass().getStringValue().trim());
647 managedConnectionFactoryGBeanData.setAttribute("connectionFactoryInterface", connectionfactoryInterface);
648 managedConnectionFactoryGBeanData.setAttribute("connectionFactoryImplClass", connectionDefinition.getConnectionfactoryImplClass().getStringValue().trim());
649 managedConnectionFactoryGBeanData.setAttribute("connectionInterface", connectionDefinition.getConnectionInterface().getStringValue().trim());
650 managedConnectionFactoryGBeanData.setAttribute("connectionImplClass", connectionDefinition.getConnectionImplClass().getStringValue().trim());
651 managedConnectionFactoryInfos.put(connectionfactoryInterface, managedConnectionFactoryGBeanData);
652 }
653 return managedConnectionFactoryInfos;
654 }
655
656 private Map getAdminObjectInfoMap(AdminobjectType[] adminobjectArray, ClassLoader cl) throws DeploymentException {
657 Map adminObjectInfos = new HashMap();
658 for (int i = 0; i < adminobjectArray.length; i++) {
659 AdminobjectType adminObject = adminobjectArray[i];
660
661 GBeanInfoBuilder adminObjectInfoBuilder = new GBeanInfoBuilder(AdminObjectWrapper.class, AdminObjectWrapperGBean.GBEAN_INFO);
662 GBeanData adminObjectGBeanData = setUpDynamicGBean(adminObjectInfoBuilder, adminObject.getConfigPropertyArray(), cl);
663
664 // set the standard properties
665 String adminObjectInterface = adminObject.getAdminobjectInterface().getStringValue().trim();
666 adminObjectGBeanData.setAttribute("adminObjectInterface", adminObjectInterface);
667 adminObjectGBeanData.setAttribute("adminObjectClass", adminObject.getAdminobjectClass().getStringValue().trim());
668 adminObjectInfos.put(adminObjectInterface, adminObjectGBeanData);
669 }
670 return adminObjectInfos;
671 }
672
673
674 private GBeanData setUpDynamicGBean(GBeanInfoBuilder infoBuilder, ConfigPropertyType[] configProperties, ClassLoader cl) throws DeploymentException {
675 for (int i = 0; i < configProperties.length; i++) {
676 infoBuilder.addAttribute(new DynamicGAttributeInfo(configProperties[i].getConfigPropertyName().getStringValue().trim(), configProperties[i].getConfigPropertyType().getStringValue().trim(), true, true, true, true));
677 }
678
679 GBeanInfo gbeanInfo = infoBuilder.getBeanInfo();
680 GBeanData gbeanData = new GBeanData(gbeanInfo);
681 for (int i = 0; i < configProperties.length; i++) {
682 if (configProperties[i].isSetConfigPropertyValue()) {
683 gbeanData.setAttribute(configProperties[i].getConfigPropertyName().getStringValue(),
684 getValue(configProperties[i].getConfigPropertyType().getStringValue(),
685 configProperties[i].getConfigPropertyValue().getStringValue(),
686 cl));
687 }
688 }
689 return gbeanData;
690 }
691
692 private void setDynamicGBeanDataAttributes(GBeanData gbeanData, GerConfigPropertySettingType[] configProperties, ClassLoader cl) throws DeploymentException {
693 List<String> unknownNames = new ArrayList<String>();
694 for (GerConfigPropertySettingType configProperty : configProperties) {
695 String name = configProperty.getName();
696 GAttributeInfo attributeInfo = gbeanData.getGBeanInfo().getAttribute(name);
697 if (attributeInfo == null) {
698 unknownNames.add(name);
699 // throw new DeploymentException("The plan is trying to set attribute: " + name + " which does not exist. Known attributes are: " + gbeanData.getGBeanInfo().getAttributes());
700 } else {
701 String type = attributeInfo.getType();
702 gbeanData.setAttribute(name, getValue(type, configProperty.getStringValue().trim(), cl));
703 }
704 }
705 if (unknownNames.size() > 0) {
706 StringBuffer buf = new StringBuffer("The plan is trying to set attributes: ").append(unknownNames).append("\n");
707 buf.append("Known attributes: \n");
708 for (GAttributeInfo attributeInfo: gbeanData.getGBeanInfo().getAttributes()) {
709 buf.append(attributeInfo).append("\n");
710 }
711 throw new DeploymentException(buf.toString());
712 }
713 }
714
715 private Object getValue(String type, String value, ClassLoader cl) throws DeploymentException {
716 if (value == null) {
717 return null;
718 }
719
720 Class clazz;
721 try {
722 clazz = cl.loadClass(type);
723 } catch (ClassNotFoundException e) {
724 throw new DeploymentException("Could not load attribute class: type: " + type, e);
725 }
726
727 // Handle numeric fields with no value set
728 if (value.equals("")) {
729 if (Number.class.isAssignableFrom(clazz) || Date.class.isAssignableFrom(clazz)) {
730 return null;
731 }
732 }
733
734 PropertyEditor editor = PropertyEditors.getEditor(clazz);
735 editor.setAsText(value);
736 return editor.getValue();
737 }
738
739 private AbstractName configureConnectionManager(EARContext earContext, AbstractName jcaResourceName, String ddTransactionSupport, GerConnectiondefinitionInstanceType connectionfactoryInstance, ClassLoader cl) throws DeploymentException {
740 // if (connectionfactoryInstance.getConnectionmanagerRef() != null) {
741 //we don't configure anything, just use the supplied gbean
742 // try {
743 // return AbstractName.getInstance(connectionfactoryInstance.getConnectionmanagerRef());
744 // } catch (MalformedAbstractNameException e) {
745 // throw new DeploymentException("Invalid AbstractName string supplied for ConnectionManager reference", e);
746 // }
747 // }
748
749 // create the object name for our connection manager
750 AbstractName connectionManagerAbstractName = earContext.getNaming().createChildName(jcaResourceName, connectionfactoryInstance.getName().trim(), NameFactory.JCA_CONNECTION_MANAGER);
751
752 // create the data holder for our connection manager
753 GBeanInfo gbeanInfo;
754 try {
755 gbeanInfo = GBeanInfo.getGBeanInfo("org.apache.geronimo.connector.outbound.GenericConnectionManagerGBean", cl);
756 } catch (InvalidConfigurationException e) {
757 throw new DeploymentException("Unable to create GMBean", e);
758 }
759 GBeanData connectionManagerGBean = new GBeanData(connectionManagerAbstractName, gbeanInfo);
760
761 //we configure our connection manager
762 GerConnectionmanagerType connectionManager = connectionfactoryInstance.getConnectionmanager();
763 TransactionSupport transactionSupport;
764 if (connectionManager.isSetNoTransaction()) {
765 transactionSupport = NoTransactions.INSTANCE;
766 } else if (connectionManager.isSetLocalTransaction()) {
767 if ("NoTransaction".equals(ddTransactionSupport)) {
768 throw new DeploymentException("You are requesting local transaction support for a connector that does not support transactions: named: " + connectionfactoryInstance.getName().trim());
769 }
770 transactionSupport = LocalTransactions.INSTANCE;
771 } else if (connectionManager.isSetTransactionLog()) {
772 if ("NoTransaction".equals(ddTransactionSupport)) {
773 throw new DeploymentException("You are requesting local transaction support for a connector that does not support transactions: named: " + connectionfactoryInstance.getName().trim());
774 }
775 transactionSupport = TransactionLog.INSTANCE;
776 } else if (connectionManager.isSetXaTransaction()) {
777 if ("NoTransaction".equals(ddTransactionSupport)) {
778 throw new DeploymentException("You are requesting xa transaction support for a connector that does not support transactions: named: " + connectionfactoryInstance.getName().trim());
779 }
780 if ("LocalTransaction".equals(ddTransactionSupport)) {
781 throw new DeploymentException("You are requesting xa transaction support for a connector that supports only local transactions: named: " + connectionfactoryInstance.getName().trim());
782 }
783 transactionSupport = new XATransactions(connectionManager.getXaTransaction().isSetTransactionCaching(),
784 connectionManager.getXaTransaction().isSetThreadCaching());
785 } else if ("NoTransaction".equals(ddTransactionSupport)) {
786 transactionSupport = NoTransactions.INSTANCE;
787 } else if ("LocalTransaction".equals(ddTransactionSupport)) {
788 transactionSupport = LocalTransactions.INSTANCE;
789 } else if ("XATransaction".equals(ddTransactionSupport)) {
790 transactionSupport = new XATransactions(defaultXATransactionCaching, defaultXAThreadCaching);
791 } else {
792 //this should not happen
793 throw new DeploymentException("Unexpected transaction support element in connector named: " + connectionfactoryInstance.getName().trim());
794 }
795 PoolingSupport pooling;
796 if (connectionManager.getSinglePool() != null) {
797 GerSinglepoolType pool = connectionManager.getSinglePool();
798
799 pooling = new SinglePool(pool.isSetMaxSize() ? pool.getMaxSize() : defaultMaxSize,
800 pool.isSetMinSize() ? pool.getMinSize() : defaultMinSize,
801 pool.isSetBlockingTimeoutMilliseconds() ? pool.getBlockingTimeoutMilliseconds() : defaultBlockingTimeoutMilliseconds,
802 pool.isSetIdleTimeoutMinutes() ? pool.getIdleTimeoutMinutes() : defaultIdleTimeoutMinutes,
803 pool.getMatchOne() != null,
804 pool.getMatchAll() != null,
805 pool.getSelectOneAssumeMatch() != null);
806 } else if (connectionManager.getPartitionedPool() != null) {
807 GerPartitionedpoolType pool = connectionManager.getPartitionedPool();
808 pooling = new PartitionedPool(pool.isSetMaxSize() ? pool.getMaxSize() : defaultMaxSize,
809 pool.isSetMinSize() ? pool.getMinSize() : defaultMinSize,
810 pool.isSetBlockingTimeoutMilliseconds() ? pool.getBlockingTimeoutMilliseconds() : defaultBlockingTimeoutMilliseconds,
811 pool.isSetIdleTimeoutMinutes() ? pool.getIdleTimeoutMinutes() : defaultIdleTimeoutMinutes,
812 pool.getMatchOne() != null,
813 pool.getMatchAll() != null,
814 pool.getSelectOneAssumeMatch() != null,
815 pool.isSetPartitionByConnectionrequestinfo(),
816 pool.isSetPartitionBySubject());
817 } else if (connectionManager.getNoPool() != null) {
818 pooling = new NoPool();
819 } else {
820 throw new DeploymentException("Unexpected pooling support element in connector named " + connectionfactoryInstance.getName().trim());
821 }
822 try {
823 connectionManagerGBean.setAttribute("transactionSupport", transactionSupport);
824 connectionManagerGBean.setAttribute("pooling", pooling);
825 connectionManagerGBean.setReferencePattern("ConnectionTracker", earContext.getConnectionTrackerName());
826 connectionManagerGBean.setAttribute("containerManagedSecurity", Boolean.valueOf(connectionManager.isSetContainerManagedSecurity()));
827 connectionManagerGBean.setReferencePattern("TransactionManager", earContext.getTransactionManagerName());
828 } catch (Exception e) {
829 throw new DeploymentException("Problem setting up ConnectionManager named " + connectionfactoryInstance.getName().trim(), e);
830 }
831
832 try {
833 earContext.addGBean(connectionManagerGBean);
834 } catch (GBeanAlreadyExistsException e) {
835 throw new DeploymentException("Could not add connection manager gbean to context: name: " + connectionfactoryInstance.getName().trim(), e);
836 }
837 return connectionManagerAbstractName;
838 }
839
840 private void addOutboundGBeans(EARContext earContext, AbstractName jcaResourceName, AbstractName resourceAdapterAbstractName, GBeanData managedConnectionFactoryPrototypeGBeanData, GerConnectiondefinitionInstanceType connectiondefinitionInstance, String transactionSupport, ClassLoader cl) throws DeploymentException {
841 GBeanData managedConnectionFactoryInstanceGBeanData = new GBeanData(managedConnectionFactoryPrototypeGBeanData);
842 AbstractName connectionFactoryAbstractName = earContext.getNaming().createChildName(jcaResourceName, connectiondefinitionInstance.getName().trim(), NameFactory.JCA_CONNECTION_FACTORY);
843 AbstractName managedConnectionFactoryAbstractName = earContext.getNaming().createChildName(connectionFactoryAbstractName, connectiondefinitionInstance.getName().trim(), NameFactory.JCA_MANAGED_CONNECTION_FACTORY);
844 // ConnectionManager
845 AbstractName connectionManagerAbstractName = configureConnectionManager(earContext, managedConnectionFactoryAbstractName, transactionSupport, connectiondefinitionInstance, cl);
846
847 // ManagedConnectionFactory
848 setDynamicGBeanDataAttributes(managedConnectionFactoryInstanceGBeanData, connectiondefinitionInstance.getConfigPropertySettingArray(), cl);
849
850 //Check if Driver class is available here. This should be available in cl. If not log a warning as
851 //the plan gets deployed and while starting GBean an error is thrown
852
853 Object driver = managedConnectionFactoryInstanceGBeanData.getAttribute("Driver");
854 if (driver != null && driver instanceof String) {
855 try {
856 cl.loadClass((String) driver);
857 } catch (ClassNotFoundException e1) {
858 log.warn("Problem loading driver class '" + driver + "', possibly due to a missing dependency on the driver jar!!", e1);
859 }
860 }
861
862 try {
863 if (resourceAdapterAbstractName != null) {
864 managedConnectionFactoryInstanceGBeanData.setReferencePattern("ResourceAdapterWrapper", resourceAdapterAbstractName);
865 }
866 managedConnectionFactoryInstanceGBeanData.setReferencePattern("ConnectionManagerContainer", connectionManagerAbstractName);
867 //additional interfaces implemented by connection factory
868 String[] implementedInterfaces = connectiondefinitionInstance.getImplementedInterfaceArray();
869 if (implementedInterfaces != null) {
870 for (int i = 0; i < implementedInterfaces.length; i++) {
871 implementedInterfaces[i] = implementedInterfaces[i].trim();
872 }
873 } else {
874 implementedInterfaces = new String[0];
875 }
876 managedConnectionFactoryInstanceGBeanData.setAttribute("implementedInterfaces", implementedInterfaces);
877
878 } catch (Exception e) {
879 throw new DeploymentException(e);
880 }
881
882 managedConnectionFactoryInstanceGBeanData.setAbstractName(managedConnectionFactoryAbstractName);
883 try {
884 earContext.addGBean(managedConnectionFactoryInstanceGBeanData);
885 } catch (GBeanAlreadyExistsException e) {
886 throw new DeploymentException("Could not add managed connection factory gbean to context", e);
887 }
888
889 // ConnectionFactory
890 GBeanData connectionFactoryGBeanData = new GBeanData(connectionFactoryAbstractName, JCAConnectionFactoryImplGBean.GBEAN_INFO);
891 connectionFactoryGBeanData.setReferencePattern("JCAManagedConnectionFactory", managedConnectionFactoryAbstractName);
892
893 try {
894 earContext.addGBean(connectionFactoryGBeanData);
895 } catch (GBeanAlreadyExistsException e) {
896 throw new DeploymentException("Could not add connection factory gbean to context", e);
897 }
898 }
899
900 public GBeanData locateActivationSpecInfo(AbstractNameQuery resourceAdapterInstanceQuery, String messageListenerInterface, Configuration configuration) throws DeploymentException {
901 //First, locate the module gbean from the JCAResourceAdapter instance
902 AbstractName instanceName;
903 try {
904 instanceName = configuration.findGBean(resourceAdapterInstanceQuery);
905 } catch (GBeanNotFoundException e) {
906 throw new DeploymentException("No resource adapter instance gbean found matching " + resourceAdapterInstanceQuery + " from configuration " + configuration.getId(), e);
907 }
908 String moduleName = (String) instanceName.getName().get(NameFactory.RESOURCE_ADAPTER_MODULE);
909 Map moduleNameMap = new HashMap(instanceName.getName());
910 moduleNameMap.remove(NameFactory.JCA_RESOURCE);
911 moduleNameMap.remove(NameFactory.RESOURCE_ADAPTER);
912 moduleNameMap.remove(NameFactory.RESOURCE_ADAPTER_MODULE);
913 moduleNameMap.put(NameFactory.J2EE_TYPE, NameFactory.RESOURCE_ADAPTER_MODULE);
914 moduleNameMap.put(NameFactory.J2EE_NAME, moduleName);
915 AbstractNameQuery nameQuery = new AbstractNameQuery(instanceName.getArtifact(), moduleNameMap, ResourceAdapterModule.class.getName());
916 //now find the gbeandata and extract the activation spec info.
917 GBeanData resourceModuleData;
918 try {
919 resourceModuleData = configuration.findGBeanData(nameQuery);
920 } catch (GBeanNotFoundException e) {
921 throw new DeploymentException("No resource module gbean found matching " + nameQuery + " from configuration " + configuration.getId(), e);
922 }
923 Map activationSpecInfos = (Map) resourceModuleData.getAttribute("activationSpecInfoMap");
924 if (activationSpecInfos == null) {
925 throw new DeploymentException("No activation spec info map found in resource adapter module: " + resourceModuleData.getAbstractName());
926 }
927 return (GBeanData) activationSpecInfos.get(messageListenerInterface);
928 }
929
930 private GBeanData locateResourceAdapterGBeanData(GBeanData resourceAdapterModuleData) throws DeploymentException {
931 GBeanData data = (GBeanData) resourceAdapterModuleData.getAttribute("resourceAdapterGBeanData");
932 if (data == null) {
933 throw new DeploymentException("No resource adapter info found for resource adapter module: " + resourceAdapterModuleData.getAbstractName());
934 }
935 return data;
936 }
937
938 private GBeanData locateAdminObjectInfo(GBeanData resourceAdapterModuleData, String adminObjectInterfaceName) throws DeploymentException {
939 Map adminObjectInfos = (Map) resourceAdapterModuleData.getAttribute("adminObjectInfoMap");
940 if (adminObjectInfos == null) {
941 throw new DeploymentException("No admin object infos found for resource adapter module: " + resourceAdapterModuleData.getAbstractName());
942 }
943 return (GBeanData) adminObjectInfos.get(adminObjectInterfaceName);
944 }
945
946 private GBeanData locateConnectionFactoryInfo(GBeanData resourceAdapterModuleData, String connectionFactoryInterfaceName) throws DeploymentException {
947 Map managedConnectionFactoryInfos = (Map) resourceAdapterModuleData.getAttribute("managedConnectionFactoryInfoMap");
948 if (managedConnectionFactoryInfos == null) {
949 throw new DeploymentException("No managed connection factory infos found for resource adapter module: " + resourceAdapterModuleData.getAbstractName());
950 }
951 return (GBeanData) managedConnectionFactoryInfos.get(connectionFactoryInterfaceName);
952 }
953
954 public static final GBeanInfo GBEAN_INFO;
955
956 static {
957 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(ConnectorModuleBuilder.class, NameFactory.MODULE_BUILDER);
958
959 infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true);
960 infoBuilder.addAttribute("defaultMaxSize", int.class, true, true);
961 infoBuilder.addAttribute("defaultMinSize", int.class, true, true);
962 infoBuilder.addAttribute("defaultBlockingTimeoutMilliseconds", int.class, true, true);
963 infoBuilder.addAttribute("defaultIdleTimeoutMinutes", int.class, true, true);
964 infoBuilder.addAttribute("defaultXATransactionCaching", boolean.class, true, true);
965 infoBuilder.addAttribute("defaultXAThreadCaching", boolean.class, true, true);
966
967 infoBuilder.addReference("ServiceBuilders", NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER);
968
969 infoBuilder.addInterface(ModuleBuilder.class);
970 infoBuilder.addInterface(ActivationSpecInfoLocator.class);
971
972 infoBuilder.setConstructor(new String[]{"defaultEnvironment",
973 "defaultMaxSize",
974 "defaultMinSize",
975 "defaultBlockingTimeoutMilliseconds",
976 "defaultIdleTimeoutMinutes",
977 "defaultXATransactionCaching",
978 "defaultXAThreadCaching",
979 "ServiceBuilders"});
980 GBEAN_INFO = infoBuilder.getBeanInfo();
981 }
982
983 public static GBeanInfo getGBeanInfo() {
984 return GBEAN_INFO;
985 }
986
987 }