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    }