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    }