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