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.j2ee.deployment;
018    
019    import java.io.File;
020    import java.io.IOException;
021    import java.net.MalformedURLException;
022    import java.net.URI;
023    import java.net.URL;
024    import java.util.ArrayList;
025    import java.util.Collection;
026    import java.util.Collections;
027    import java.util.Enumeration;
028    import java.util.HashMap;
029    import java.util.HashSet;
030    import java.util.LinkedHashMap;
031    import java.util.LinkedHashSet;
032    import java.util.LinkedList;
033    import java.util.List;
034    import java.util.Map;
035    import java.util.Set;
036    import java.util.jar.JarEntry;
037    import java.util.jar.JarFile;
038    import java.util.jar.Manifest;
039    import java.util.jar.Attributes;
040    import java.util.zip.ZipEntry;
041    
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.deployment.ConfigurationBuilder;
048    import org.apache.geronimo.deployment.DeploymentContext;
049    import org.apache.geronimo.deployment.ModuleIDBuilder;
050    import org.apache.geronimo.deployment.NamespaceDrivenBuilder;
051    import org.apache.geronimo.deployment.NamespaceDrivenBuilderCollection;
052    import org.apache.geronimo.deployment.ClassPathList;
053    import org.apache.geronimo.deployment.ModuleList;
054    import org.apache.geronimo.deployment.service.EnvironmentBuilder;
055    import org.apache.geronimo.deployment.service.GBeanBuilder;
056    import org.apache.geronimo.deployment.util.DeploymentUtil;
057    import org.apache.geronimo.deployment.util.NestedJarFile;
058    import org.apache.geronimo.deployment.xbeans.ArtifactType;
059    import org.apache.geronimo.deployment.xbeans.EnvironmentType;
060    import org.apache.geronimo.deployment.xbeans.PatternType;
061    import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
062    import org.apache.geronimo.gbean.AbstractName;
063    import org.apache.geronimo.gbean.AbstractNameQuery;
064    import org.apache.geronimo.gbean.GBeanData;
065    import org.apache.geronimo.gbean.GBeanInfo;
066    import org.apache.geronimo.gbean.GBeanInfoBuilder;
067    import org.apache.geronimo.gbean.ReferencePatterns;
068    import org.apache.geronimo.gbean.SingleElementCollection;
069    import org.apache.geronimo.j2ee.ApplicationInfo;
070    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
071    import org.apache.geronimo.j2ee.management.impl.J2EEApplicationImpl;
072    import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
073    import org.apache.geronimo.kernel.Kernel;
074    import org.apache.geronimo.kernel.Naming;
075    import org.apache.geronimo.kernel.config.ConfigurationAlreadyExistsException;
076    import org.apache.geronimo.kernel.config.ConfigurationData;
077    import org.apache.geronimo.kernel.config.ConfigurationManager;
078    import org.apache.geronimo.kernel.config.ConfigurationModuleType;
079    import org.apache.geronimo.kernel.config.ConfigurationStore;
080    import org.apache.geronimo.kernel.config.ConfigurationUtil;
081    import org.apache.geronimo.kernel.config.SimpleConfigurationManager;
082    import org.apache.geronimo.kernel.repository.Artifact;
083    import org.apache.geronimo.kernel.repository.ArtifactResolver;
084    import org.apache.geronimo.kernel.repository.Environment;
085    import org.apache.geronimo.kernel.repository.Repository;
086    import org.apache.geronimo.kernel.repository.MissingDependencyException;
087    import org.apache.geronimo.management.J2EEResource;
088    import org.apache.geronimo.management.J2EEServer;
089    import org.apache.geronimo.schema.SchemaConversionUtils;
090    import org.apache.geronimo.xbeans.geronimo.j2ee.GerApplicationDocument;
091    import org.apache.geronimo.xbeans.geronimo.j2ee.GerApplicationType;
092    import org.apache.geronimo.xbeans.geronimo.j2ee.GerExtModuleType;
093    import org.apache.geronimo.xbeans.geronimo.j2ee.GerModuleType;
094    import org.apache.geronimo.xbeans.geronimo.j2ee.GerSecurityDocument;
095    import org.apache.geronimo.xbeans.javaee.ApplicationDocument;
096    import org.apache.geronimo.xbeans.javaee.ApplicationType;
097    import org.apache.geronimo.xbeans.javaee.ModuleType;
098    import org.apache.xmlbeans.XmlCursor;
099    import org.apache.xmlbeans.XmlException;
100    import org.apache.xmlbeans.XmlObject;
101    
102    /**
103     * @version $Rev: 561286 $ $Date: 2007-07-31 05:39:53 -0400 (Tue, 31 Jul 2007) $
104     */
105    public class EARConfigBuilder implements ConfigurationBuilder, CorbaGBeanNameSource {
106    
107        private static final Log log = LogFactory.getLog(EARConfigBuilder.class);
108        private static final String LINE_SEP = System.getProperty("line.separator");
109    
110        private final static QName APPLICATION_QNAME = GerApplicationDocument.type.getDocumentElementName();
111    
112        private final ConfigurationManager configurationManager;
113        private final Collection<Repository> repositories;
114        private final SingleElementCollection ejbConfigBuilder;
115        private final SingleElementCollection webConfigBuilder;
116        private final SingleElementCollection connectorConfigBuilder;
117        private final SingleElementCollection appClientConfigBuilder;
118        private final SingleElementCollection resourceReferenceBuilder;
119        private final NamespaceDrivenBuilderCollection securityBuilders;
120        private final NamespaceDrivenBuilderCollection serviceBuilders;
121        private final Collection<ModuleBuilderExtension> persistenceUnitBuilders;
122    
123        private final Environment defaultEnvironment;
124        private final AbstractNameQuery serverName;
125        private final AbstractNameQuery transactionManagerObjectName;
126        private final AbstractNameQuery connectionTrackerObjectName;
127        private final AbstractNameQuery transactionalTimerObjectName;
128        private final AbstractNameQuery nonTransactionalTimerObjectName;
129        private final AbstractNameQuery corbaGBeanObjectName;
130        private final Naming naming;
131        private final Collection<ArtifactResolver> artifactResolvers;
132    
133        public EARConfigBuilder(Environment defaultEnvironment,
134                AbstractNameQuery transactionManagerAbstractName,
135                AbstractNameQuery connectionTrackerAbstractName,
136                AbstractNameQuery transactionalTimerAbstractName,
137                AbstractNameQuery nonTransactionalTimerAbstractName,
138                AbstractNameQuery corbaGBeanAbstractName,
139                AbstractNameQuery serverName,
140                Collection<Repository> repositories,
141                Collection ejbConfigBuilder,
142                Collection webConfigBuilder,
143                Collection connectorConfigBuilder,
144                Collection resourceReferenceBuilder,
145                Collection appClientConfigBuilder,
146                Collection securityBuilders,
147                Collection serviceBuilders,
148                Collection<ModuleBuilderExtension> persistenceUnitBuilders,
149                Collection<ArtifactResolver> artifactResolvers,
150                Kernel kernel) {
151            this(defaultEnvironment,
152                    transactionManagerAbstractName,
153                    connectionTrackerAbstractName,
154                    transactionalTimerAbstractName,
155                    nonTransactionalTimerAbstractName,
156                    corbaGBeanAbstractName,
157                    serverName,
158                    ConfigurationUtil.getConfigurationManager(kernel),
159                    repositories,
160                    new SingleElementCollection(ejbConfigBuilder),
161                    new SingleElementCollection(webConfigBuilder),
162                    new SingleElementCollection(connectorConfigBuilder),
163                    new SingleElementCollection(resourceReferenceBuilder),
164                    new SingleElementCollection(appClientConfigBuilder),
165                    securityBuilders,
166                    serviceBuilders,
167                    persistenceUnitBuilders,
168                    kernel.getNaming(), artifactResolvers);
169        }
170    
171        public EARConfigBuilder(Environment defaultEnvironment,
172                AbstractNameQuery transactionManagerAbstractName,
173                AbstractNameQuery connectionTrackerAbstractName,
174                AbstractNameQuery transactionalTimerAbstractName,
175                AbstractNameQuery nonTransactionalTimerAbstractName,
176                AbstractNameQuery corbaGBeanAbstractName,
177                AbstractNameQuery serverName,
178                Collection<Repository> repositories,
179                ModuleBuilder ejbConfigBuilder,
180                ModuleBuilder webConfigBuilder,
181                ModuleBuilder connectorConfigBuilder,
182                ActivationSpecInfoLocator activationSpecInfoLocator,
183                ModuleBuilder appClientConfigBuilder,
184                NamespaceDrivenBuilder securityBuilder,
185                NamespaceDrivenBuilder serviceBuilder,
186                ModuleBuilderExtension persistenceUnitBuilder,
187                Naming naming,
188                Collection<ArtifactResolver> artifactResolvers) {
189            this(defaultEnvironment,
190                    transactionManagerAbstractName,
191                    connectionTrackerAbstractName,
192                    transactionalTimerAbstractName,
193                    nonTransactionalTimerAbstractName,
194                    corbaGBeanAbstractName,
195                    serverName,
196                    null,
197                    repositories,
198                    new SingleElementCollection(ejbConfigBuilder),
199                    new SingleElementCollection(webConfigBuilder),
200                    new SingleElementCollection(connectorConfigBuilder),
201                    new SingleElementCollection(activationSpecInfoLocator),
202                    new SingleElementCollection(appClientConfigBuilder),
203                    securityBuilder == null ? Collections.EMPTY_SET : Collections.singleton(securityBuilder),
204                    serviceBuilder == null ? Collections.EMPTY_SET : Collections.singleton(serviceBuilder),
205                    persistenceUnitBuilder == null ? Collections.EMPTY_SET : Collections.singleton(persistenceUnitBuilder),
206                    naming,
207                    artifactResolvers);
208        }
209    
210        private EARConfigBuilder(Environment defaultEnvironment,
211                 AbstractNameQuery transactionManagerAbstractName,
212                 AbstractNameQuery connectionTrackerAbstractName,
213                 AbstractNameQuery transactionalTimerAbstractName,
214                 AbstractNameQuery nonTransactionalTimerAbstractName,
215                 AbstractNameQuery corbaGBeanAbstractName,
216                 AbstractNameQuery serverName,
217                 ConfigurationManager configurationManager,
218                 Collection<Repository> repositories,
219                 SingleElementCollection ejbConfigBuilder,
220                 SingleElementCollection webConfigBuilder,
221                 SingleElementCollection connectorConfigBuilder,
222                 SingleElementCollection resourceReferenceBuilder,
223                 SingleElementCollection appClientConfigBuilder,
224                 Collection securityBuilders,
225                 Collection serviceBuilders,
226                 Collection<ModuleBuilderExtension> persistenceUnitBuilders,
227                 Naming naming,
228                 Collection<ArtifactResolver> artifactResolvers) {
229            this.configurationManager = configurationManager;
230            this.repositories = repositories;
231            this.defaultEnvironment = defaultEnvironment;
232    
233            this.ejbConfigBuilder = ejbConfigBuilder;
234            this.resourceReferenceBuilder = resourceReferenceBuilder;
235            this.webConfigBuilder = webConfigBuilder;
236            this.connectorConfigBuilder = connectorConfigBuilder;
237            this.appClientConfigBuilder = appClientConfigBuilder;
238            this.securityBuilders = new NamespaceDrivenBuilderCollection(securityBuilders, GerSecurityDocument.type.getDocumentElementName());
239            this.serviceBuilders = new NamespaceDrivenBuilderCollection(serviceBuilders, GBeanBuilder.SERVICE_QNAME);
240            this.persistenceUnitBuilders = persistenceUnitBuilders;
241            
242            this.transactionManagerObjectName = transactionManagerAbstractName;
243            this.connectionTrackerObjectName = connectionTrackerAbstractName;
244            this.transactionalTimerObjectName = transactionalTimerAbstractName;
245            this.nonTransactionalTimerObjectName = nonTransactionalTimerAbstractName;
246            this.corbaGBeanObjectName = corbaGBeanAbstractName;
247            this.serverName = serverName;
248            this.naming = naming;
249            this.artifactResolvers = artifactResolvers;
250        }
251    
252    
253        public AbstractNameQuery getCorbaGBeanName() {
254            return corbaGBeanObjectName;
255        }
256    
257        private ModuleBuilder getEjbConfigBuilder() {
258            return (ModuleBuilder) ejbConfigBuilder.getElement();
259        }
260    
261        private ModuleBuilder getWebConfigBuilder() {
262            return (ModuleBuilder) webConfigBuilder.getElement();
263        }
264    
265        private ModuleBuilder getConnectorConfigBuilder() {
266            return (ModuleBuilder) connectorConfigBuilder.getElement();
267        }
268    
269        private ModuleBuilder getAppClientConfigBuilder() {
270            return (ModuleBuilder) appClientConfigBuilder.getElement();
271        }
272    
273        public Object getDeploymentPlan(File planFile, JarFile jarFile, ModuleIDBuilder idBuilder) throws DeploymentException {
274            if (planFile == null && jarFile == null) {
275                return null;
276            }
277            ApplicationInfo plan = getEarPlan(planFile, jarFile, idBuilder);
278            if (plan != null) {
279                return plan;
280            }
281            //Only "synthetic" ears with only external modules can have no jar file.
282            if (jarFile == null) {
283                return null;
284            }
285    
286            // get the modules either the application plan or for a stand alone module from the specific deployer
287            Module module = null;
288            if (getWebConfigBuilder() != null) {
289                module = getWebConfigBuilder().createModule(planFile, jarFile, naming, idBuilder);
290            }
291            if (module == null && getEjbConfigBuilder() != null) {
292                module = getEjbConfigBuilder().createModule(planFile, jarFile, naming, idBuilder);
293            }
294            if (module == null && getConnectorConfigBuilder() != null) {
295                module = getConnectorConfigBuilder().createModule(planFile, jarFile, naming, idBuilder);
296            }
297            if (module == null && getAppClientConfigBuilder() != null) {
298                module = getAppClientConfigBuilder().createModule(planFile, jarFile, naming, idBuilder);
299            }
300            if (module == null) {
301                return null;
302            }
303    
304            if (module instanceof ApplicationInfo) {
305                return module;
306            }
307            
308            return new ApplicationInfo(module.getType(),
309                    module.getEnvironment(),
310                    module.getModuleName(),
311                    jarFile,
312                    null,
313                    null,
314                    new LinkedHashSet<Module>(Collections.singleton(module)),
315                    new ModuleList(),
316                    null);
317        }
318    
319        private ApplicationInfo getEarPlan(File planFile, JarFile earFile, ModuleIDBuilder idBuilder) throws DeploymentException {
320            String specDD;
321            ApplicationType application = null;
322            if (earFile != null) {
323                try {
324                    URL applicationXmlUrl = DeploymentUtil.createJarURL(earFile, "META-INF/application.xml");
325                    specDD = DeploymentUtil.readAll(applicationXmlUrl);
326                    //we found something called application.xml in the right place, if we can't parse it it's an error
327                    XmlObject xmlObject = XmlBeansUtil.parse(specDD);
328                    application = convertToApplicationSchema(xmlObject).getApplication();
329                } catch (XmlException e) {
330                    throw new DeploymentException("Could not parse application.xml", e);
331                } catch (Exception e) {
332                    //ee5 spec allows optional application.xml, continue with application == null
333                    if (!earFile.getName().endsWith(".ear")) {
334                        return null;
335                    }
336                    //TODO return application.xml that we can make metadata complete?
337                }
338            }
339    
340            GerApplicationType gerApplication = null;
341            try {
342                // load the geronimo-application.xml from either the supplied plan or from the earFile
343                XmlObject rawPlan;
344                try {
345                    if (planFile != null) {
346                        rawPlan = XmlBeansUtil.parse(planFile.toURL(), getClass().getClassLoader());
347                        gerApplication = (GerApplicationType) SchemaConversionUtils.fixGeronimoSchema(rawPlan, APPLICATION_QNAME, GerApplicationType.type);
348                        if (gerApplication == null) {
349                            return null;
350                        }
351                    } else {
352                        URL path = DeploymentUtil.createJarURL(earFile, "META-INF/geronimo-application.xml");
353                        rawPlan = XmlBeansUtil.parse(path, getClass().getClassLoader());
354                        gerApplication = (GerApplicationType) SchemaConversionUtils.fixGeronimoSchema(rawPlan, APPLICATION_QNAME, GerApplicationType.type);
355                    }
356                } catch (IOException e) {
357                    //TODO isn't this an error?
358                }
359    
360                // if we got one extract the validate it otherwise create a default one
361                if (gerApplication == null) {
362                    gerApplication = createDefaultPlan(application, earFile);
363                }
364            } catch (XmlException e) {
365                throw new DeploymentException(e);
366            }
367    
368            EnvironmentType environmentType = gerApplication.getEnvironment();
369            Environment environment = EnvironmentBuilder.buildEnvironment(environmentType, defaultEnvironment);
370            idBuilder.resolve(environment, earFile == null ? planFile.getName() : new File(earFile.getName()).getName(), "ear");
371            // Make this EAR's settings the default for child modules
372            idBuilder.setDefaultGroup(environment.getConfigId().getGroupId());
373            idBuilder.setDefaultVersion(environment.getConfigId().getVersion());
374    
375            Artifact artifact = environment.getConfigId();
376            AbstractName earName = naming.createRootName(artifact, artifact.toString(), NameFactory.J2EE_APPLICATION);
377    
378            // get the modules either the application plan or for a stand alone module from the specific deployer
379            // todo change module so you can extract the real module path back out.. then we can eliminate
380            // the moduleLocations and have addModules return the modules
381            ModuleList moduleLocations = new ModuleList();
382            LinkedHashSet<Module> modules = new LinkedHashSet<Module>();
383            try {
384                addModules(earFile, application, gerApplication, moduleLocations, modules, environment, earName, idBuilder);
385                if (application == null && modules.isEmpty()) {
386                    //if no application.xml and no modules detected, return null for stand-alone module processing
387                    return null;
388                }
389            } catch (Throwable e) {
390                // close all the modules
391                for (Module module : modules) {
392                    module.close();
393                }
394    
395                if (e instanceof DeploymentException) {
396                    throw (DeploymentException) e;
397                } else if (e instanceof RuntimeException) {
398                    throw (RuntimeException) e;
399                } else if (e instanceof Error) {
400                    throw (Error) e;
401                }
402                throw new DeploymentException(e);
403            }
404    
405            return new ApplicationInfo(ConfigurationModuleType.EAR,
406                    environment,
407                    earName,
408                    earFile,
409                    application,
410                    gerApplication,
411                    modules,
412                    moduleLocations,
413                    application == null ? null : application.toString());
414        }
415    
416    
417        private GerApplicationType createDefaultPlan(ApplicationType application, JarFile module) {
418            // construct the empty geronimo-application.xml
419            GerApplicationType gerApplication = GerApplicationType.Factory.newInstance();
420            EnvironmentType environmentType = gerApplication.addNewEnvironment();
421            ArtifactType artifactType = environmentType.addNewModuleId();
422    
423            artifactType.setGroupId(Artifact.DEFAULT_GROUP_ID);
424    
425            // set the configId
426            String id = application != null ? application.getId() : null;
427            if (id == null) {
428                File fileName = new File(module.getName());
429                id = fileName.getName();
430                if (id.endsWith(".ear")) {
431                    id = id.substring(0, id.length() - 4);
432                }
433                if (id.endsWith("/")) {
434                    id = id.substring(0, id.length() - 1);
435                }
436            }
437    
438            artifactType.setArtifactId(id);
439            artifactType.setVersion("" + System.currentTimeMillis());
440            artifactType.setType("car");
441            return gerApplication;
442        }
443    
444        static ApplicationDocument convertToApplicationSchema(XmlObject xmlObject) throws XmlException {
445            if (ApplicationDocument.type.equals(xmlObject.schemaType())) {
446                XmlBeansUtil.validateDD(xmlObject);
447                return (ApplicationDocument) xmlObject;
448            }
449            XmlCursor cursor = xmlObject.newCursor();
450            XmlCursor moveable = xmlObject.newCursor();
451            String schemaLocationURL = "http://java.sun.com/xml/ns/javaee/application_5.xsd";
452            String version = "5";
453            try {
454                cursor.toStartDoc();
455                cursor.toFirstChild();
456                if ("http://java.sun.com/xml/ns/j2ee".equals(cursor.getName().getNamespaceURI())) {
457                    SchemaConversionUtils.convertSchemaVersion(cursor, SchemaConversionUtils.JAVAEE_NAMESPACE, schemaLocationURL, version);
458                    XmlObject result = xmlObject.changeType(ApplicationDocument.type);
459                    XmlBeansUtil.validateDD(result);
460                    return (ApplicationDocument) result;
461                }
462    
463                // otherwise assume DTD
464                SchemaConversionUtils.convertToSchema(cursor, SchemaConversionUtils.JAVAEE_NAMESPACE, schemaLocationURL, version);
465                cursor.toStartDoc();
466                cursor.toChild(SchemaConversionUtils.JAVAEE_NAMESPACE, "application");
467                cursor.toFirstChild();
468                SchemaConversionUtils.convertToDescriptionGroup(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable);
469            } finally {
470                cursor.dispose();
471                moveable.dispose();
472            }
473            XmlObject result = xmlObject.changeType(ApplicationDocument.type);
474            if (result != null) {
475                XmlBeansUtil.validateDD(result);
476                return (ApplicationDocument) result;
477            }
478            XmlBeansUtil.validateDD(xmlObject);
479            return (ApplicationDocument) xmlObject;
480        }
481    
482        public Artifact getConfigurationID(Object plan, JarFile module, ModuleIDBuilder idBuilder) throws IOException, DeploymentException {
483            ApplicationInfo applicationInfo = (ApplicationInfo) plan;
484            Artifact test = applicationInfo.getEnvironment().getConfigId();
485            if (!test.isResolved()) {
486                throw new IllegalStateException("Module ID should be fully resolved by now (not " + test + ")");
487            }
488            return test;
489        }
490    
491        public DeploymentContext buildConfiguration(boolean inPlaceDeployment, Artifact configId, Object plan, JarFile earFile, Collection configurationStores, ArtifactResolver artifactResolver, ConfigurationStore targetConfigurationStore) throws IOException, DeploymentException {
492            assert plan != null;
493            ApplicationInfo applicationInfo = (ApplicationInfo) plan;
494    
495            EARContext earContext = null;
496            ConfigurationModuleType applicationType = applicationInfo.getType();
497            applicationInfo.getEnvironment().setConfigId(configId);
498            File configurationDir;
499            try {
500                configurationDir = targetConfigurationStore.createNewConfigurationDir(configId);
501            } catch (ConfigurationAlreadyExistsException e) {
502                throw new DeploymentException(e);
503            }
504    
505            ConfigurationManager configurationManager = this.configurationManager;
506            if (configurationManager == null) {
507                configurationManager = new SimpleConfigurationManager(configurationStores, artifactResolver, repositories);
508            }
509            try {
510                // Create the output ear context
511                earContext = new EARContext(configurationDir,
512                        inPlaceDeployment ? DeploymentUtil.toFile(earFile) : null,
513                        applicationInfo.getEnvironment(),
514                        applicationType,
515                        naming,
516                        configurationManager,
517                        repositories,
518                        serverName,
519                        applicationInfo.getModuleName(),
520                        transactionManagerObjectName,
521                        connectionTrackerObjectName,
522                        transactionalTimerObjectName,
523                        nonTransactionalTimerObjectName,
524                        corbaGBeanObjectName
525                );
526                applicationInfo.setEarContext(earContext);
527                applicationInfo.setRootEarContext(earContext);
528                earContext.getGeneralData().put(ModuleList.class, applicationInfo.getModuleLocations());
529    
530                // Copy over all files that are _NOT_ modules (e.g. META-INF and APP-INF files)
531                Set moduleLocations = applicationInfo.getModuleLocations();
532                ClassPathList libClasspath = new ClassPathList();
533                if (ConfigurationModuleType.EAR == applicationType && earFile != null) {
534                    //get the value of the library-directory element in spec DD
535                    ApplicationType specDD = (ApplicationType) applicationInfo.getSpecDD();
536                    String libDir = getLibraryDirectory(specDD);
537                    for (Enumeration<JarEntry> e = earFile.entries(); e.hasMoreElements();) {
538                        ZipEntry entry = e.nextElement();
539                        String entryName = entry.getName();
540                        boolean addEntry = true;
541                        for (Object moduleLocation : moduleLocations) {
542                            String location = (String) moduleLocation;
543                            if (entryName.startsWith(location)) {
544                                addEntry = false;
545                                break;
546                            }
547                        }
548                        if (libDir != null && entry.getName().startsWith(libDir) && entry.getName().endsWith(".jar")) {
549                            NestedJarFile library = new NestedJarFile(earFile, entry.getName());
550                            earContext.addIncludeAsPackedJar(URI.create(entry.getName()), library);
551                            libClasspath.add(entry.getName());
552                        } else if (addEntry) {
553                            earContext.addFile(URI.create(entry.getName()), earFile, entry);
554                        }
555                    }
556                    if (!libClasspath.isEmpty()) {
557                        earContext.getGeneralData().put(ClassPathList.class, libClasspath);
558                    }
559                }
560    
561                GerApplicationType geronimoApplication = (GerApplicationType) applicationInfo.getVendorDD();
562    
563                // each module installs it's files into the output context.. this is different for each module type
564                LinkedHashSet modules = applicationInfo.getModules();
565                for (Object module2 : modules) {
566                    Module module = (Module) module2;
567                    getBuilder(module).installModule(earFile, earContext, module, configurationStores, targetConfigurationStore, repositories);
568                }
569    
570                earContext.flush();
571    
572                // give each module a chance to populate the earContext now that a classloader is available
573                ClassLoader cl = earContext.getClassLoader();
574                for (Object module3 : modules) {
575                    Module module = (Module) module3;
576                    getBuilder(module).initContext(earContext, module, cl);
577                }
578    
579                // add gbeans declared in the geronimo-application.xml
580                if (geronimoApplication != null) {
581                    securityBuilders.build(geronimoApplication, earContext, earContext);
582                    serviceBuilders.build(geronimoApplication, earContext, earContext);
583                }
584                
585                if (ConfigurationModuleType.EAR == applicationType) {
586                    // process persistence unit in EAR library directory
587                    earContext.getGeneralData().put(ClassPathList.class, libClasspath);
588                    for (ModuleBuilderExtension mbe: persistenceUnitBuilders) {
589                        mbe.initContext(earContext, applicationInfo, earContext.getClassLoader());
590                    }
591                    
592                    // Create the J2EEApplication managed object
593                    GBeanData gbeanData = new GBeanData(earContext.getModuleName(), J2EEApplicationImpl.GBEAN_INFO);
594                    try {
595                        String originalSpecDD = applicationInfo.getOriginalSpecDD();
596                        if (originalSpecDD == null) {
597                            originalSpecDD = "Synthetic EAR";
598                        }
599                        gbeanData.setAttribute("deploymentDescriptor", originalSpecDD);
600                    } catch (Exception e) {
601                        throw new DeploymentException("Error initializing J2EEApplication managed object", e);
602                    }
603                    gbeanData.setReferencePatterns("Server", new ReferencePatterns(new AbstractNameQuery(J2EEServer.class.getName())));
604    
605                    Map<String, String> thisApp = Collections.singletonMap(NameFactory.J2EE_APPLICATION, earContext.getModuleName().getNameProperty(NameFactory.J2EE_NAME));
606                    LinkedHashSet<AbstractNameQuery> resourcePatterns = new LinkedHashSet<AbstractNameQuery>();
607                    resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.JAVA_MAIL_RESOURCE), J2EEResource.class.getName()));
608                    resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.JCA_CONNECTION_FACTORY), J2EEResource.class.getName()));
609                    resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.JDBC_RESOURCE), J2EEResource.class.getName()));
610                    resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.JDBC_DRIVER), J2EEResource.class.getName()));
611                    resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.JMS_RESOURCE), J2EEResource.class.getName()));
612                    resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.JNDI_RESOURCE), J2EEResource.class.getName()));
613                    resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.JTA_RESOURCE), J2EEResource.class.getName()));
614                    resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.RMI_IIOP_RESOURCE), J2EEResource.class.getName()));
615                    resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.URL_RESOURCE), J2EEResource.class.getName()));
616                    gbeanData.setReferencePatterns("Resources", resourcePatterns);
617    
618                    gbeanData.setReferencePatterns("AppClientModules", new ReferencePatterns(new AbstractNameQuery(null, thisApp, org.apache.geronimo.management.AppClientModule.class.getName())));
619                    gbeanData.setReferencePatterns("EJBModules", new ReferencePatterns(new AbstractNameQuery(null, thisApp, org.apache.geronimo.management.EJBModule.class.getName())));
620                    gbeanData.setReferencePatterns("ResourceAdapterModules", new ReferencePatterns(new AbstractNameQuery(null, thisApp, org.apache.geronimo.management.geronimo.ResourceAdapterModule.class.getName())));
621                    gbeanData.setReferencePatterns("WebModules", new ReferencePatterns(new AbstractNameQuery(null, thisApp, org.apache.geronimo.management.geronimo.WebModule.class.getName())));
622                    earContext.addGBean(gbeanData);
623                }
624    
625                // each module can now add it's GBeans
626                for (Object module1 : modules) {
627                    Module module = (Module) module1;
628                    getBuilder(module).addGBeans(earContext, module, cl, repositories);
629                }
630    
631                // it's the caller's responsibility to close the context...
632                return earContext;
633            } catch (GBeanAlreadyExistsException e) {
634                cleanupContext(earContext, configurationDir);
635                throw new DeploymentException(e);
636            } catch (IOException e) {
637                cleanupContext(earContext, configurationDir);
638                throw e;
639            } catch (DeploymentException e) {
640                cleanupContext(earContext, configurationDir);
641                throw e;
642            } catch (RuntimeException e) {
643                cleanupContext(earContext, configurationDir);
644                throw e;
645            } catch (Error e) {
646                cleanupContext(earContext, configurationDir);
647                throw e;
648            } finally {
649                for (Object module1 : applicationInfo.getModules()) {
650                    Module module = (Module) module1;
651                    module.close();
652                }
653            }
654        }
655    
656        private String getLibraryDirectory(ApplicationType specDD) {
657            if (specDD == null || !specDD.isSetLibraryDirectory()) {
658                //value 'lib' is used if element not set or ear does not contain a dd
659                return "lib";
660            }
661    
662            //only set if not empty value, empty value implies no library directory
663            String value = specDD.getLibraryDirectory().getStringValue();
664            return value.trim().length() > 0 ? value : null;
665        }
666    
667        private void cleanupContext(EARContext earContext, File configurationDir) {
668            List<ConfigurationData> configurations = new ArrayList<ConfigurationData>();
669            if (earContext != null) {
670                configurations.addAll(earContext.getAdditionalDeployment());
671                try {
672                    earContext.close();
673                } catch (IOException ioe) {
674                    // ignore any cleanup problems
675                } catch (DeploymentException de) {
676                    // ignore any cleanup problems
677                }
678            }
679            // configurationDir is created before we create an EARContext
680            if (configurationDir != null) {
681                cleanupConfigurationDir(configurationDir);
682            }
683            // cleanup any other configurations generated (e.g. AppClient config dirs)
684            for (ConfigurationData configurationData : configurations) {
685                cleanupConfigurationDir(configurationData.getConfigurationDir());
686            }
687        }
688    
689        private boolean cleanupConfigurationDir(File configurationDir) {
690            LinkedList<String> cannotBeDeletedList = new LinkedList<String>();
691    
692            if (!DeploymentUtil.recursiveDelete(configurationDir, cannotBeDeletedList)) {
693                // Output a message to help user track down file problem
694                log.warn("Unable to delete " + cannotBeDeletedList.size() +
695                        " files while recursively deleting directory "
696                        + configurationDir.getAbsolutePath() + LINE_SEP +
697                        "The first file that could not be deleted was:" + LINE_SEP + "  " +
698                        (!cannotBeDeletedList.isEmpty() ? cannotBeDeletedList.getFirst() : ""));
699                return false;
700            }
701            return true;
702        }
703    
704        private static Map<String, String> filter(Map<String, String> original, String key, String value) {
705            LinkedHashMap<String, String> filter = new LinkedHashMap<String, String>(original);
706            filter.put(key, value);
707            return filter;
708        }
709    
710        private void addModules(JarFile earFile, ApplicationType application, GerApplicationType gerApplication, ModuleList moduleLocations, LinkedHashSet<Module> modules, Environment environment, AbstractName earName, ModuleIDBuilder idBuilder) throws DeploymentException {
711            Map<String, Object> altVendorDDs = new HashMap<String, Object>();
712            try {
713                mapVendorPlans(gerApplication, altVendorDDs, earFile);
714                if (earFile != null) {
715                    if (application != null) {
716                        ModuleType[] moduleTypes = application.getModuleArray();
717    
718                        //get a set containing all of the files in the ear that are actually modules
719                        for (ModuleType moduleXml : moduleTypes) {
720                            String modulePath;
721                            ModuleBuilder builder;
722    
723                            Object moduleContextInfo = null;
724                            String moduleTypeName;
725                            if (moduleXml.isSetEjb()) {
726                                modulePath = moduleXml.getEjb().getStringValue();
727                                builder = getEjbConfigBuilder();
728                                if (builder == null) {
729                                    throw new DeploymentException("Cannot deploy ejb application; No ejb deployer defined: " + modulePath);
730                                }
731                                moduleTypeName = "an EJB";
732                            } else if (moduleXml.isSetWeb()) {
733                                modulePath = moduleXml.getWeb().getWebUri().getStringValue();
734                                if (getWebConfigBuilder() == null) {
735                                    throw new DeploymentException("Cannot deploy web application; No war deployer defined: " + modulePath);
736                                }
737                                builder = getWebConfigBuilder();
738                                moduleTypeName = "a war";
739                                moduleContextInfo = moduleXml.getWeb().getContextRoot().getStringValue().trim();
740                            } else if (moduleXml.isSetConnector()) {
741                                modulePath = moduleXml.getConnector().getStringValue();
742                                if (getConnectorConfigBuilder() == null) {
743                                    throw new DeploymentException("Cannot deploy resource adapter; No rar deployer defined: " + modulePath);
744                                }
745                                builder = getConnectorConfigBuilder();
746                                moduleTypeName = "a connector";
747                            } else if (moduleXml.isSetJava()) {
748                                modulePath = moduleXml.getJava().getStringValue();
749                                if (getAppClientConfigBuilder() == null) {
750                                    throw new DeploymentException("Cannot deploy app client; No app client deployer defined: " + modulePath);
751                                }
752                                builder = getAppClientConfigBuilder();
753                                moduleTypeName = "an application client";
754                            } else {
755                                throw new DeploymentException("Could not find a module builder for module: " + moduleXml);
756                            }
757    
758                            moduleLocations.add(modulePath);
759    
760                            NestedJarFile moduleFile;
761                            try {
762                                moduleFile = new NestedJarFile(earFile, modulePath);
763                            } catch (IOException e) {
764                                throw new DeploymentException("Invalid moduleFile: " + modulePath, e);
765                            }
766    
767                            Module module = builder.createModule(altVendorDDs.get(modulePath),
768                                    moduleFile,
769                                    modulePath,
770                                    getAltSpecDDURL(earFile, moduleXml),
771                                    environment,
772                                    moduleContextInfo,
773                                    earName,
774                                    naming, idBuilder);
775    
776                            if (module == null) {
777                                throw new DeploymentException("Module was not " + moduleTypeName + ": " + modulePath);
778                            }
779    
780                            modules.add(module);
781                        }
782                    } else {
783                        //no application.xml available, must inspect ear to locate and process modules
784                        Enumeration<JarEntry> entries = earFile.entries();
785                        while (entries.hasMoreElements()) {
786                            ModuleBuilder builder;
787                            Object moduleContextInfo = null;
788                            String moduleTypeName;
789                            ZipEntry entry = entries.nextElement();
790                            if (entry.getName().endsWith(".war")) {
791                                if (getWebConfigBuilder() == null) {
792                                    throw new DeploymentException("Cannot deploy web application; No war deployer defined: " + entry.getName());
793                                }
794                                builder = getWebConfigBuilder();
795                                moduleTypeName = "a war";
796                                moduleContextInfo = entry.getName().split(".war")[0];
797                            } else if (entry.getName().endsWith(".rar")) {
798                                if (getConnectorConfigBuilder() == null) {
799                                    throw new DeploymentException("Cannot deploy resource adapter; No rar deployer defined: " + entry.getName());
800                                }
801                                builder = getConnectorConfigBuilder();
802                                moduleTypeName = "a connector";
803                            } else if (entry.getName().endsWith(".jar") && !isLibraryEntry(application, entry)) {
804                                try {
805                                    NestedJarFile moduleFile = new NestedJarFile(earFile, entry.getName());
806                                    Manifest mf = moduleFile.getManifest();
807    
808                                    if (mf.getMainAttributes().getValue(Attributes.Name.MAIN_CLASS) != null) {
809                                        if (getAppClientConfigBuilder() == null) {
810                                            throw new DeploymentException("Cannot deploy app client; No app client deployer defined: " + entry.getName());
811                                        }
812                                        builder = getAppClientConfigBuilder();
813                                        moduleTypeName = "an application client";
814                                    } else {
815                                        //ask the ejb builder if its an ejb module
816                                        builder = getEjbConfigBuilder();
817                                        if (builder == null) {
818    //                                        throw new DeploymentException("Cannot deploy ejb application; No ejb deployer defined: " + entry.getName());
819                                            continue;
820                                        }
821    
822                                        Module module = builder.createModule(altVendorDDs.get(entry.getName()),
823                                                moduleFile,
824                                                entry.getName(),
825                                                null,
826                                                environment,
827                                                moduleContextInfo,
828                                                earName,
829                                                naming, idBuilder);
830    
831                                        if (module != null) {
832                                            moduleLocations.add(entry.getName());
833                                            modules.add(module);
834                                        }
835                                        continue;
836                                    }
837                                    //TODO if no ejb-jar.xml inspect classes for EJB component annotations to identify as EJBJar module
838                                } catch (IOException e) {
839                                    throw new DeploymentException("Invalid moduleFile: " + entry.getName(), e);
840                                }
841                            } else {
842                                continue;
843                            }
844    
845                            moduleLocations.add(entry.getName());
846    
847                            NestedJarFile moduleFile;
848                            try {
849                                moduleFile = new NestedJarFile(earFile, entry.getName());
850                            } catch (IOException e) {
851                                throw new DeploymentException("Invalid moduleFile: " + entry.getName(), e);
852                            }
853    
854                            Module module = builder.createModule(altVendorDDs.get(entry.getName()),
855                                    moduleFile,
856                                    entry.getName(),
857                                    null,
858                                    environment,
859                                    moduleContextInfo,
860                                    earName,
861                                    naming, idBuilder);
862    
863                            if (module == null) {
864                                throw new DeploymentException("Module was not " + moduleTypeName + ": " + entry.getName());
865                            }
866    
867                            modules.add(module);
868                        }
869                    }
870                }
871    
872                //all the modules in the geronimo plan should have been found by now.
873                if (!moduleLocations.containsAll(altVendorDDs.keySet())) {
874                    throw new DeploymentException("Geronimo ear plan contains modules that aren't in the ear: " + new HashSet<String>(moduleLocations).removeAll(altVendorDDs.keySet()));
875                }
876                //deploy the extension modules
877                for (GerExtModuleType gerExtModule : gerApplication.getExtModuleArray()) {
878                    String moduleName;
879                    ModuleBuilder builder;
880                    Object moduleContextInfo = null;
881                    String moduleTypeName;
882    
883                    if (gerExtModule.isSetEjb()) {
884                        moduleName = gerExtModule.getEjb().getStringValue();
885                        builder = getEjbConfigBuilder();
886                        if (builder == null) {
887                            throw new DeploymentException("Cannot deploy ejb application; No ejb deployer defined: " + moduleName);
888                        }
889                        moduleTypeName = "an EJB";
890                    } else if (gerExtModule.isSetWeb()) {
891                        moduleName = gerExtModule.getWeb().getStringValue();
892                        if (getWebConfigBuilder() == null) {
893                            throw new DeploymentException("Cannot deploy web application; No war deployer defined: " + moduleName);
894                        }
895                        builder = getWebConfigBuilder();
896                        moduleTypeName = "a war";
897                        //ext modules must use vendor plan to set context-root
898                    } else if (gerExtModule.isSetConnector()) {
899                        moduleName = gerExtModule.getConnector().getStringValue();
900                        if (getConnectorConfigBuilder() == null) {
901                            throw new DeploymentException("Cannot deploy resource adapter; No rar deployer defined: " + moduleName);
902                        }
903                        builder = getConnectorConfigBuilder();
904                        moduleTypeName = "a connector";
905                    } else if (gerExtModule.isSetJava()) {
906                        moduleName = gerExtModule.getJava().getStringValue();
907                        if (getAppClientConfigBuilder() == null) {
908                            throw new DeploymentException("Cannot deploy app client; No app client deployer defined: " + moduleName);
909                        }
910                        builder = getAppClientConfigBuilder();
911                        moduleTypeName = "an application client";
912                    } else {
913                        throw new DeploymentException("Could not find a module builder for module: " + gerExtModule);
914                    }
915                    //dd is included explicitly
916                    XmlObject[] anys = gerExtModule.selectChildren(GerExtModuleType.type.qnameSetForWildcardElements());
917                    if (anys.length != 1) {
918                        throw new DeploymentException("Unexpected count of xs:any elements in embedded vendor plan " + anys.length + " qnameset: " + GerExtModuleType.type.qnameSetForWildcardElements());
919                    }
920                    Object vendorDD = anys[0];
921    
922                    JarFile moduleFile;
923                    if (gerExtModule.isSetInternalPath()) {
924                        String modulePath = gerExtModule.getInternalPath().trim();
925                        moduleLocations.add(modulePath);
926                        try {
927                            moduleFile = new NestedJarFile(earFile, modulePath);
928                        } catch (IOException e) {
929                            throw new DeploymentException("Invalid moduleFile: " + modulePath, e);
930                        }
931                    } else {
932                        PatternType patternType = gerExtModule.getExternalPath();
933                        String groupId = trim(patternType.getGroupId());
934                        String artifactId = trim(patternType.getArtifactId());
935                        String version = trim(patternType.getVersion());
936                        String type = trim(patternType.getType());
937                        Artifact artifact = new Artifact(groupId, artifactId, version, type);
938                        try {
939                            artifact = getArtifactResolver().resolveInClassLoader(artifact);
940                        } catch (MissingDependencyException e) {
941                            throw new DeploymentException("Could not resolve external rar location in repository: " + artifact, e);
942                        }
943                        File location = null;
944                        for (Repository repository : repositories) {
945                            if (repository.contains(artifact)) {
946                                location = repository.getLocation(artifact);
947                                break;
948                            }
949                        }
950                        if (location == null) {
951                            throw new DeploymentException(moduleTypeName + " is missing in repositories: " + artifact);
952                        }
953                        try {
954                            moduleFile = new JarFile(location);
955                        } catch (IOException e) {
956                            throw new DeploymentException("Could not access contents of " + moduleTypeName, e);
957                        }
958    
959                    }
960    
961                    Module module = builder.createModule(vendorDD,
962                            moduleFile,
963                            moduleName,
964                            null, //TODO implement an alt-spec-dd element
965                            environment,
966                            moduleContextInfo,
967                            earName,
968                            naming, idBuilder);
969    
970                    if (module == null) {
971                        throw new DeploymentException("Module was not " + moduleTypeName + ": " + moduleName);
972                    }
973    
974                    modules.add(module);
975                }
976            } finally {
977                // delete all the temp files created for alt vendor dds
978                for (Object altVendorDD : altVendorDDs.values()) {
979                    if (altVendorDD instanceof File) {
980                        ((File) altVendorDD).delete();
981                    }
982                }
983            }
984        }
985    
986        private ArtifactResolver getArtifactResolver() throws DeploymentException {
987            if (artifactResolvers == null || artifactResolvers.isEmpty()) {
988                throw new DeploymentException("No artifact resolver supplied to resolve external module");
989            }
990            return artifactResolvers.iterator().next();
991        }
992    
993        private String trim(String s) {
994            if (s == null) {
995                return null;
996            }
997            return s.trim();
998        }
999    
1000        private boolean isLibraryEntry(ApplicationType application, ZipEntry entry) {
1001            String libDir = getLibraryDirectory(application);
1002            if (libDir != null && entry.getName().startsWith(libDir)) {
1003                return true;
1004            }
1005            return false;
1006        }
1007    
1008        private void mapVendorPlans(GerApplicationType gerApplication, Map<String, Object> altVendorDDs, JarFile earFile) throws DeploymentException {
1009            //build map from module path to alt vendor dd
1010            for (GerModuleType gerModule : gerApplication.getModuleArray()) {
1011                String path = null;
1012                if (gerModule.isSetEjb()) {
1013                    path = gerModule.getEjb().getStringValue();
1014                } else if (gerModule.isSetWeb()) {
1015                    path = gerModule.getWeb().getStringValue();
1016                } else if (gerModule.isSetConnector()) {
1017                    path = gerModule.getConnector().getStringValue();
1018                } else if (gerModule.isSetJava()) {
1019                    path = gerModule.getJava().getStringValue();
1020                }
1021    //            if (!paths.contains(path)) {
1022    //                throw new DeploymentException("Geronimo deployment plan refers to module '" + path + "' but that was not defined in the META-INF/application.xml");
1023    //            }
1024    
1025                if (gerModule.isSetAltDd()) {
1026                    // the the url of the alt dd
1027                    try {
1028                        altVendorDDs.put(path, DeploymentUtil.toTempFile(earFile, gerModule.getAltDd().getStringValue()));
1029                    } catch (IOException e) {
1030                        throw new DeploymentException("Invalid alt vendor dd url: " + gerModule.getAltDd().getStringValue(), e);
1031                    }
1032                } else {
1033                    //dd is included explicitly
1034                    XmlObject[] anys = gerModule.selectChildren(GerModuleType.type.qnameSetForWildcardElements());
1035                    if (anys.length != 1) {
1036                        throw new DeploymentException("Unexpected count of xs:any elements in embedded vendor plan " + anys.length + " qnameset: " + GerModuleType.type.qnameSetForWildcardElements());
1037                    }
1038                    altVendorDDs.put(path, anys[0]);
1039                }
1040            }
1041        }
1042    
1043        private URL getAltSpecDDURL(JarFile earFile, ModuleType moduleXml) throws DeploymentException {
1044            if (moduleXml != null && moduleXml.isSetAltDd()) {
1045                try {
1046                    return DeploymentUtil.createJarURL(earFile, moduleXml.getAltDd().getStringValue());
1047                } catch (MalformedURLException e) {
1048                    throw new DeploymentException("Invalid alt sped dd url: " + moduleXml.getAltDd().getStringValue(), e);
1049                }
1050            }
1051            return null;
1052        }
1053    
1054        private ModuleBuilder getBuilder(Module module) throws DeploymentException {
1055            if (module instanceof EJBModule) {
1056                if (getEjbConfigBuilder() == null) {
1057                    throw new DeploymentException("Cannot deploy ejb application; No ejb deployer defined: " + module.getModuleURI());
1058                }
1059                return getEjbConfigBuilder();
1060            } else if (module instanceof WebModule) {
1061                if (getWebConfigBuilder() == null) {
1062                    throw new DeploymentException("Cannot deploy web application; No war deployer defined: " + module.getModuleURI());
1063                }
1064                return getWebConfigBuilder();
1065            } else if (module instanceof ConnectorModule) {
1066                if (getConnectorConfigBuilder() == null) {
1067                    throw new DeploymentException("Cannot deploy resource adapter; No rar deployer defined: " + module.getModuleURI());
1068                }
1069                return getConnectorConfigBuilder();
1070            } else if (module instanceof AppClientModule) {
1071                if (getAppClientConfigBuilder() == null) {
1072                    throw new DeploymentException("Cannot deploy app client; No app client deployer defined: " + module.getModuleURI());
1073                }
1074                return getAppClientConfigBuilder();
1075            }
1076            throw new IllegalArgumentException("Unknown module type: " + module.getClass().getName());
1077        }
1078    
1079        public static final GBeanInfo GBEAN_INFO;
1080    
1081        static {
1082            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(EARConfigBuilder.class, NameFactory.CONFIG_BUILDER);
1083            infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true);
1084            infoBuilder.addAttribute("transactionManagerAbstractName", AbstractNameQuery.class, true);
1085            infoBuilder.addAttribute("connectionTrackerAbstractName", AbstractNameQuery.class, true);
1086            infoBuilder.addAttribute("transactionalTimerAbstractName", AbstractNameQuery.class, true);
1087            infoBuilder.addAttribute("nonTransactionalTimerAbstractName", AbstractNameQuery.class, true);
1088            infoBuilder.addAttribute("corbaGBeanAbstractName", AbstractNameQuery.class, true);
1089            infoBuilder.addAttribute("serverName", AbstractNameQuery.class, true);
1090    
1091            infoBuilder.addReference("Repositories", Repository.class, "Repository");
1092            infoBuilder.addReference("EJBConfigBuilder", ModuleBuilder.class, NameFactory.MODULE_BUILDER);
1093            infoBuilder.addReference("WebConfigBuilder", ModuleBuilder.class, NameFactory.MODULE_BUILDER);
1094            infoBuilder.addReference("ConnectorConfigBuilder", ModuleBuilder.class, NameFactory.MODULE_BUILDER);
1095            infoBuilder.addReference("ActivationSpecInfoLocator", ActivationSpecInfoLocator.class, NameFactory.MODULE_BUILDER);
1096            infoBuilder.addReference("AppClientConfigBuilder", ModuleBuilder.class, NameFactory.MODULE_BUILDER);
1097            infoBuilder.addReference("SecurityBuilders", NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER);
1098            infoBuilder.addReference("ServiceBuilders", NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER);
1099            infoBuilder.addReference("PersistenceUnitBuilders", ModuleBuilderExtension.class, NameFactory.MODULE_BUILDER);
1100            infoBuilder.addReference("ArtifactResolvers", ArtifactResolver.class, "ArtifactResolver");
1101    
1102            infoBuilder.addAttribute("kernel", Kernel.class, false);
1103    
1104            infoBuilder.setConstructor(new String[]{
1105                    "defaultEnvironment",
1106                    "transactionManagerAbstractName",
1107                    "connectionTrackerAbstractName",
1108                    "transactionalTimerAbstractName",
1109                    "nonTransactionalTimerAbstractName",
1110                    "corbaGBeanAbstractName",
1111                    "serverName",
1112                    "Repositories",
1113                    "EJBConfigBuilder",
1114                    "WebConfigBuilder",
1115                    "ConnectorConfigBuilder",
1116                    "ActivationSpecInfoLocator",
1117                    "AppClientConfigBuilder",
1118                    "SecurityBuilders",
1119                    "ServiceBuilders",
1120                    "PersistenceUnitBuilders",
1121                    "ArtifactResolvers",
1122                    "kernel"
1123            });
1124    
1125            GBEAN_INFO = infoBuilder.getBeanInfo();
1126        }
1127    
1128        public static GBeanInfo getGBeanInfo() {
1129            return GBEAN_INFO;
1130        }
1131    
1132    }