gdamour 2004/07/22 23:06:19
Modified: modules/j2ee/src/test/org/apache/geronimo/j2ee/deployment MockConnectorConfigBuilder.java MockWARConfigBuilder.java modules/deployment/src/java/org/apache/geronimo/deployment DeploymentContext.java modules/j2ee/src/java/org/apache/geronimo/j2ee/deployment EARConfigBuilder.java modules/connector/src/java/org/apache/geronimo/connector/deployment ConnectorModuleBuilder.java modules/jetty/src/java/org/apache/geronimo/jetty/deployment JettyModuleBuilder.java modules/deployment/src/java/org/apache/geronimo/deployment/util FileUtil.java modules/connector/src/test/org/apache/geronimo/connector/deployment RAR_1_5ConfigBuilderTest.java RAR_1_0ConfigBuilderTest.java Added: modules/j2ee/src/java/org/apache/geronimo/j2ee/deployment ModuleBuilderWithUnpack.java Log: Supports the deployment of unpacked RAR and WAR. A "temporary" interface, namely ModuleBuilderWithUnpack, has been created in order to capture the ability of a ModuleBuilder to deploy unpacked modules. When the OpenEJB ModuleBuilder will be able to deploy unpacked EJB, this interface will be merged with ModuleBuilder. Revision Changes Path 1.3 +13 -2 incubator-geronimo/modules/j2ee/src/test/org/apache/geronimo/j2ee/deployment/MockConnectorConfigBuilder.java Index: MockConnectorConfigBuilder.java =================================================================== RCS file: /home/cvs/incubator-geronimo/modules/j2ee/src/test/org/apache/geronimo/j2ee/deployment/MockConnectorConfigBuilder.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- MockConnectorConfigBuilder.java 18 Jul 2004 22:04:27 -0000 1.2 +++ MockConnectorConfigBuilder.java 23 Jul 2004 06:06:19 -0000 1.3 @@ -16,18 +16,21 @@ */ package org.apache.geronimo.j2ee.deployment; +import java.io.File; import java.net.URI; import java.net.URL; import java.util.jar.JarFile; import junit.framework.Assert; + +import org.apache.geronimo.deployment.DeploymentException; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.SchemaTypeLoader; /** * @version $Revision$ $Date$ */ -public class MockConnectorConfigBuilder extends Assert implements ModuleBuilder { +public class MockConnectorConfigBuilder extends Assert implements ModuleBuilderWithUnpack { public EARContext earContext; public Module connectorModule; public ClassLoader cl; @@ -52,6 +55,14 @@ return null; } + public void installModule(File earFolder, EARContext earContext, + Module module) throws DeploymentException { + assertNotNull(earFolder); + assertNotNull(earContext); + this.earContext = earContext; + assertEquals(this.connectorModule, connectorModule); + } + public void installModule(JarFile earFile, EARContext earContext, Module connectorModule) { assertNotNull(earFile); assertNotNull(earContext); 1.3 +11 -2 incubator-geronimo/modules/j2ee/src/test/org/apache/geronimo/j2ee/deployment/MockWARConfigBuilder.java Index: MockWARConfigBuilder.java =================================================================== RCS file: /home/cvs/incubator-geronimo/modules/j2ee/src/test/org/apache/geronimo/j2ee/deployment/MockWARConfigBuilder.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- MockWARConfigBuilder.java 18 Jul 2004 22:04:27 -0000 1.2 +++ MockWARConfigBuilder.java 23 Jul 2004 06:06:19 -0000 1.3 @@ -16,6 +16,7 @@ */ package org.apache.geronimo.j2ee.deployment; +import java.io.File; import java.net.URI; import java.net.URL; import java.util.jar.JarFile; @@ -28,7 +29,7 @@ /** * @version $Revision$ $Date$ */ -public class MockWARConfigBuilder extends Assert implements ModuleBuilder { +public class MockWARConfigBuilder extends Assert implements ModuleBuilderWithUnpack { public EARContext earContext; public WebModule webModule; public ClassLoader cl; @@ -54,6 +55,14 @@ return null; } + public void installModule(File earFolder, EARContext earContext, + Module module) throws DeploymentException { + assertNotNull(earFolder); + assertNotNull(earContext); + this.earContext = earContext; + assertEquals(this.webModule, webModule); + } + public void installModule(JarFile earFile, EARContext earContext, Module webModule) throws DeploymentException { assertNotNull(earFile); assertNotNull(earContext); 1.15 +12 -5 incubator-geronimo/modules/deployment/src/java/org/apache/geronimo/deployment/DeploymentContext.java Index: DeploymentContext.java =================================================================== RCS file: /home/cvs/incubator-geronimo/modules/deployment/src/java/org/apache/geronimo/deployment/DeploymentContext.java,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- DeploymentContext.java 22 Jul 2004 03:22:53 -0000 1.14 +++ DeploymentContext.java 23 Jul 2004 06:06:19 -0000 1.15 @@ -18,6 +18,7 @@ package org.apache.geronimo.deployment; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectOutputStream; @@ -170,10 +171,7 @@ } } - //This method was once public. It appears to be useless in most cases so I made it private. - //Deploying from a stream (usual jsr 88 case) there is no URL to map unless the stream - //contents are copied to a temp file. - private void addToClassPath(URI path, URL url) { + protected void addToClassPath(URI path, URL url) { classPath.add(path); includes.put(path, url); } @@ -225,6 +223,15 @@ } } + public void addFile(URI path, File source) throws IOException { + InputStream in = new FileInputStream(source); + try { + addFile(path, in); + } finally { + in.close(); + } + } + public void addFile(URI path, InputStream source) throws IOException { JarOutputStream jos = getJos(); jos.putNextEntry(new ZipEntry(path.getPath())); 1.15 +115 -38 incubator-geronimo/modules/j2ee/src/java/org/apache/geronimo/j2ee/deployment/EARConfigBuilder.java Index: EARConfigBuilder.java =================================================================== RCS file: /home/cvs/incubator-geronimo/modules/j2ee/src/java/org/apache/geronimo/j2ee/deployment/EARConfigBuilder.java,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- EARConfigBuilder.java 22 Jul 2004 03:22:53 -0000 1.14 +++ EARConfigBuilder.java 23 Jul 2004 06:06:19 -0000 1.15 @@ -18,6 +18,7 @@ import java.io.BufferedOutputStream; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -25,6 +26,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; @@ -82,8 +84,8 @@ private final Kernel kernel; private final Repository repository; private final ModuleBuilder ejbConfigBuilder; - private final ModuleBuilder webConfigBuilder; - private final ModuleBuilder connectorConfigBuilder; + private final ModuleBuilderWithUnpack webConfigBuilder; + private final ModuleBuilderWithUnpack connectorConfigBuilder; private final String j2eeServerName; private final String j2eeDomainName; private final ObjectName j2eeServer; @@ -94,7 +96,7 @@ public EARConfigBuilder( - ObjectName j2eeServer, ObjectName transactionContextManagerObjectName, ObjectName connectionTrackerObjectName, ObjectName transactionalTimerObjectName, ObjectName nonTransactionalTimerObjectName, Repository repository, ModuleBuilder ejbConfigBuilder, ModuleBuilder webConfigBuilder, ModuleBuilder connectorConfigBuilder, Kernel kernel + ObjectName j2eeServer, ObjectName transactionContextManagerObjectName, ObjectName connectionTrackerObjectName, ObjectName transactionalTimerObjectName, ObjectName nonTransactionalTimerObjectName, Repository repository, ModuleBuilder ejbConfigBuilder, ModuleBuilderWithUnpack webConfigBuilder, ModuleBuilderWithUnpack connectorConfigBuilder, Kernel kernel ) { this.kernel = kernel; this.repository = repository; @@ -223,21 +225,94 @@ gerApplication.setConfigId(id); return gerApplicationDocument; } - - + public void buildConfiguration(File outfile, Manifest manifest, InputStream is, XmlObject plan) throws IOException, DeploymentException { File tmp = FileUtil.toTempFile(is); buildConfiguration(outfile, manifest, new JarFile(tmp), plan); } - public void buildConfiguration(File outfile, Manifest manifest, File module, XmlObject plan) throws IOException, DeploymentException { - if (module.isDirectory()) { - throw new DeploymentException("Unpacked ear files are not currently supported"); - } - buildConfiguration(outfile, manifest, new JarFile(module), plan); + public void buildConfiguration(File outfile, Manifest manifest, final File earFolder, final XmlObject plan) throws IOException, DeploymentException { + if ( !earFolder.isDirectory() ) { + buildConfiguration(outfile, manifest, new JarFile(earFolder), plan); + return; + } + BuildConfigurationCallback callback = new BuildConfigurationCallback() { + public ApplicationType addModules(URI configID, Set moduleLocations, Set modules) throws IOException, DeploymentException { + ApplicationTypeLocator locator = new ApplicationTypeLocator() { + public InputStream getApplication() throws DeploymentException, IOException { + File appXMLFile = new File(earFolder, "META-INF/application.xml"); + if ( !appXMLFile.isFile() ) { + throw new DeploymentException("Did not find META-INF/application.xml in earFile"); + } + return new FileInputStream(appXMLFile); + } + }; + return EARConfigBuilder.this.addModules(configID, plan, locator, moduleLocations, modules); + } + public void copyOverContent(EARContext earContext, Set moduleLocations) throws IOException, DeploymentException { + URI baseURI = earFolder.toURI(); + Collection files = new ArrayList(); + FileUtil.listRecursiveFiles(earFolder, files); + for (Iterator iter = files.iterator(); iter.hasNext();) { + File file = (File) iter.next(); + URI path = baseURI.relativize(file.toURI()); + if ( moduleLocations.contains(path.toString()) ) { + continue; + } + earContext.addFile(path, file); + } + } + public void installModule(ModuleBuilder moduleBuilder, EARContext earContext, Module module) throws IOException, DeploymentException { + if ( false == module instanceof ConnectorModule && + false == module instanceof WebModule ) { + throw new DeploymentException("Only unpacked RAR are suppored."); + } + // TODO gets rid of this cast when all the ModuleBuilder will + // support unpacked deployments. + ((ModuleBuilderWithUnpack) moduleBuilder).installModule(earFolder, earContext, module); + } + public void release() {} + }; + buildConfiguration(outfile, manifest, callback, plan); + } + + public void buildConfiguration(File outfile, Manifest manifest, final JarFile earFile, final XmlObject plan) throws IOException, DeploymentException { + BuildConfigurationCallback callback = new BuildConfigurationCallback() { + public ApplicationType addModules(URI configID, Set moduleLocations, Set modules) throws IOException, DeploymentException { + ApplicationTypeLocator locator = new ApplicationTypeLocator() { + public InputStream getApplication() throws DeploymentException, IOException { + JarEntry appXMLEntry = earFile.getJarEntry("META-INF/application.xml"); + if (appXMLEntry == null) { + throw new DeploymentException("Did not find META-INF/application.xml in earFile"); + } + return earFile.getInputStream(appXMLEntry); + } + }; + return EARConfigBuilder.this.addModules(configID, plan, locator, moduleLocations, modules); + } + public void copyOverContent(EARContext earContext, Set moduleLocations) throws IOException, DeploymentException { + for (Enumeration e = earFile.entries(); e.hasMoreElements();) { + ZipEntry entry = (ZipEntry) e.nextElement(); + if (!moduleLocations.contains(entry.getName())) { + earContext.addFile(URI.create(entry.getName()), earFile.getInputStream(entry)); + } + } + } + public void installModule(ModuleBuilder moduleBuilder, EARContext earContext, Module module) throws IOException, DeploymentException { + moduleBuilder.installModule(earFile, earContext, module); + } + public void release() { + if ( null != earFile ) { + try { + earFile.close(); + } catch (IOException e) {} + } + } + }; + buildConfiguration(outfile, manifest, callback, plan); } - - public void buildConfiguration(File outfile, Manifest manifest, JarFile earFile, XmlObject plan) throws IOException, DeploymentException { + + private void buildConfiguration(File outfile, Manifest manifest, BuildConfigurationCallback callback, XmlObject plan) throws IOException, DeploymentException { FileOutputStream fos = new FileOutputStream(outfile); try { // get the ids from either the application plan or for a stand alone module from the specific deployer @@ -248,7 +323,7 @@ // get the modules either the application plan or for a stand alone module from the specific deployer Set moduleLocations = new HashSet(); Set modules = new LinkedHashSet(); - ApplicationType application = addModules(configId, plan, earFile, moduleLocations, modules); + ApplicationType application = callback.addModules(configId, moduleLocations, modules); // if this is an ear, the application name is the configId; otherwise application name is "null" String applicationName; if (application != null) { @@ -279,12 +354,7 @@ // Copy over all files that are _NOT_ modules if (application != null) { - for (Enumeration e = earFile.entries(); e.hasMoreElements();) { - ZipEntry entry = (ZipEntry) e.nextElement(); - if (!moduleLocations.contains(entry.getName())) { - earContext.addFile(URI.create(entry.getName()), earFile.getInputStream(entry)); - } - } + callback.copyOverContent(earContext, moduleLocations); } // add dependencies declared in the geronimo-application.xml @@ -300,7 +370,7 @@ // each module installs it's files into the output context.. this is differenct for each module type for (Iterator iterator = modules.iterator(); iterator.hasNext();) { Module module = (Module) iterator.next(); - getBuilder(module).installModule(earFile, earContext, module); + callback.installModule(getBuilder(module), earContext, module); } // give each module a chance to populate the earContext now that a classloader is available @@ -340,31 +410,21 @@ earContext.close(); os.flush(); } finally { - if (earFile != null) { - try { - earFile.close(); - } catch (IOException e) { - // ignore - } - } + callback.release(); fos.close(); } } - - private ApplicationType addModules(URI configId, XmlObject plan, JarFile earFile, Set moduleLocations, Set modules) throws DeploymentException, IOException { + + private ApplicationType addModules(URI configId, XmlObject plan, ApplicationTypeLocator appLocator, Set moduleLocations, Set modules) throws DeploymentException, IOException { ApplicationType application; if (plan instanceof GerApplicationDocument) { try { - JarEntry appXMLEntry = earFile.getJarEntry("META-INF/application.xml"); - if (appXMLEntry == null) { - throw new DeploymentException("Did not find META-INF/application.xml in earFile"); - } - ApplicationDocument doc = (ApplicationDocument) XmlBeansUtil.parse(earFile.getInputStream(appXMLEntry), ApplicationDocument.type); + ApplicationDocument doc = (ApplicationDocument) XmlBeansUtil.parse(appLocator.getApplication(), ApplicationDocument.type); application = doc.getApplication(); } catch (XmlException e) { throw new DeploymentException("Unable to parse application.xml"); } - + // get a set containing all of the files in the ear that are actually modules ModuleType[] moduleTypes = application.getModuleArray(); Set ejbModules = new HashSet(); @@ -544,6 +604,23 @@ return uri; } + private interface BuildConfigurationCallback { + + public ApplicationType addModules(URI configID, Set moduleLocations, Set modules) throws IOException, DeploymentException ; + + public void copyOverContent(EARContext earContext, Set moduleLocations) throws IOException, DeploymentException; + + public void installModule(ModuleBuilder moduleBuilder, EARContext earContext, Module module) throws IOException, DeploymentException; + + public void release(); + } + + private interface ApplicationTypeLocator { + + public InputStream getApplication() throws DeploymentException, IOException; + + } + public static final GBeanInfo GBEAN_INFO; static { @@ -556,8 +633,8 @@ infoFactory.addReference("Repository", Repository.class); infoFactory.addReference("EJBConfigBuilder", ModuleBuilder.class); - infoFactory.addReference("WebConfigBuilder", ModuleBuilder.class); - infoFactory.addReference("ConnectorConfigBuilder", ModuleBuilder.class); + infoFactory.addReference("WebConfigBuilder", ModuleBuilderWithUnpack.class); + infoFactory.addReference("ConnectorConfigBuilder", ModuleBuilderWithUnpack.class); infoFactory.addAttribute("kernel", Kernel.class, false); 1.1 incubator-geronimo/modules/j2ee/src/java/org/apache/geronimo/j2ee/deployment/ModuleBuilderWithUnpack.java Index: ModuleBuilderWithUnpack.java =================================================================== /** * * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.geronimo.j2ee.deployment; import java.io.File; import org.apache.geronimo.deployment.DeploymentException; /** * Temporary interface. The method defined to this interface should be added to * ModuleBuilder. However, as long as all the ModuleBuilders do not implement * it one can not do that. * * @version $Revision: 1.1 $ $Date: 2004/07/23 06:06:19 $ */ public interface ModuleBuilderWithUnpack extends ModuleBuilder { public void installModule(File earFolder, EARContext earContext, Module module) throws DeploymentException; } 1.10 +81 -3 incubator-geronimo/modules/connector/src/java/org/apache/geronimo/connector/deployment/ConnectorModuleBuilder.java Index: ConnectorModuleBuilder.java =================================================================== RCS file: /home/cvs/incubator-geronimo/modules/connector/src/java/org/apache/geronimo/connector/deployment/ConnectorModuleBuilder.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- ConnectorModuleBuilder.java 18 Jul 2004 22:04:26 -0000 1.9 +++ ConnectorModuleBuilder.java 23 Jul 2004 06:06:19 -0000 1.10 @@ -19,6 +19,7 @@ import java.beans.PropertyEditor; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; @@ -30,6 +31,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.jar.JarEntry; @@ -57,6 +59,7 @@ import org.apache.geronimo.connector.outbound.security.PasswordCredentialRealm; import org.apache.geronimo.deployment.DeploymentException; import org.apache.geronimo.deployment.service.GBeanHelper; +import org.apache.geronimo.deployment.util.FileUtil; import org.apache.geronimo.gbean.DynamicGAttributeInfo; import org.apache.geronimo.gbean.GBeanInfo; import org.apache.geronimo.gbean.GBeanInfoFactory; @@ -66,6 +69,7 @@ import org.apache.geronimo.j2ee.deployment.EARContext; import org.apache.geronimo.j2ee.deployment.Module; import org.apache.geronimo.j2ee.deployment.ModuleBuilder; +import org.apache.geronimo.j2ee.deployment.ModuleBuilderWithUnpack; import org.apache.geronimo.xbeans.geronimo.GerAdminobjectInstanceType; import org.apache.geronimo.xbeans.geronimo.GerAdminobjectType; import org.apache.geronimo.xbeans.geronimo.GerConfigPropertySettingType; @@ -93,14 +97,13 @@ import org.apache.geronimo.schema.SchemaConversionUtils; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.XmlOptions; import org.apache.xmlbeans.SchemaTypeLoader; import org.apache.xmlbeans.XmlBeans; /** * @version $Revision$ $Date$ */ -public class ConnectorModuleBuilder implements ModuleBuilder { +public class ConnectorModuleBuilder implements ModuleBuilderWithUnpack { private static final SchemaTypeLoader SCHEMA_TYPE_LOADER = XmlBeans.typeLoaderUnion(new SchemaTypeLoader[]{ XmlBeans.typeLoaderForClassLoader(org.apache.geronimo.xbeans.j2ee.String.class.getClassLoader()), @@ -169,6 +172,80 @@ return configID; } + public void installModule(File earFolder, EARContext earContext, Module module) throws DeploymentException { + try { + File connectorFolder = new File(earFolder, module.getURI().toString()); + URI connectorFolderURI = connectorFolder.toURI(); + URI moduleBase; + if ( !module.getURI().equals(URI.create("/")) ) { + moduleBase = URI.create(module.getURI().toString() + "/"); + } else { + moduleBase = URI.create("connector/"); + } + + XmlObject specConnnector = null; + GerConnectorType vendorConnector = (GerConnectorType) module.getVendorDD(); + + Collection files = new ArrayList(); + FileUtil.listRecursiveFiles(connectorFolder, files); + for (Iterator iter = files.iterator(); iter.hasNext();) { + File file = (File) iter.next(); + URI fileURI = connectorFolderURI.relativize(file.toURI()); + URI target = moduleBase.resolve(fileURI); + if ( fileURI.toString().equals("META-INF/ra.xml") ) { + earContext.addFile(target, file); + try { + // try 1.0 + ConnectorDocument10 connectorDoc = ConnectorDocument10.Factory.parse(new FileInputStream(file)); + SchemaConversionUtils.validateDD(connectorDoc); + specConnnector = connectorDoc.getConnector(); + } catch (XmlException ignore) { + // that didn't work try 1.5 + try { + ConnectorDocument connectorDoc = ConnectorDocument.Factory.parse(new FileInputStream(file)); + SchemaConversionUtils.validateDD(connectorDoc); + specConnnector = connectorDoc.getConnector(); + } catch (XmlException alsoIgnore) { + throw new DeploymentException("Could not parse META-INF/ra.xml"); + } + } + } else if (module.getVendorDD() == null && fileURI.toString().equals("META-INF/geronimo-ra.xml") ) { + earContext.addFile(target, file); + GerConnectorDocument vendorConnectorDoc; + try { + vendorConnectorDoc = GerConnectorDocument.Factory.parse(new FileInputStream(file)); + SchemaConversionUtils.validateDD(vendorConnectorDoc); + } catch (XmlException e) { + throw new DeploymentException("Unable to parse geronimo-ra.xml"); + } + vendorConnector = vendorConnectorDoc.getConnector(); + } else if (file.getName().endsWith(".jar")) { + earContext.addInclude(target, file.toURL()); + } else { + earContext.addFile(target, file); + } + } + + if (specConnnector == null) { + throw new DeploymentException("Did not find META-INF/ra.xml in module"); + } + module.setSpecDD(specConnnector); + if (vendorConnector == null) { + throw new DeploymentException("Did not find META-INF/geronimo-ra.xml in module"); + } + module.setVendorDD(vendorConnector); + + if (vendorConnector != null) { + GerDependencyType[] dependencies = vendorConnector.getDependencyArray(); + for (int i = 0; i < dependencies.length; i++) { + earContext.addDependency(getDependencyURI(dependencies[i])); + } + } + } catch (IOException e) { + throw new DeploymentException("Problem deploying connector", e); + } + } + public void installModule(JarFile earFile, EARContext earContext, Module module) throws DeploymentException { try { URI moduleBase = null; @@ -808,6 +885,7 @@ static { GBeanInfoFactory infoFactory = new GBeanInfoFactory(ConnectorModuleBuilder.class); infoFactory.addInterface(ModuleBuilder.class); + infoFactory.addInterface(ModuleBuilderWithUnpack.class); GBEAN_INFO = infoFactory.getBeanInfo(); } 1.16 +73 -3 incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/deployment/JettyModuleBuilder.java Index: JettyModuleBuilder.java =================================================================== RCS file: /home/cvs/incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/deployment/JettyModuleBuilder.java,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- JettyModuleBuilder.java 18 Jul 2004 22:04:27 -0000 1.15 +++ JettyModuleBuilder.java 23 Jul 2004 06:06:19 -0000 1.16 @@ -19,6 +19,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; @@ -26,9 +27,11 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import java.util.Collections; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.Set; @@ -45,12 +48,14 @@ import org.apache.geronimo.common.xml.XmlBeansUtil; import org.apache.geronimo.deployment.DeploymentException; import org.apache.geronimo.deployment.service.GBeanHelper; +import org.apache.geronimo.deployment.util.FileUtil; import org.apache.geronimo.gbean.GBeanInfo; import org.apache.geronimo.gbean.GBeanInfoFactory; import org.apache.geronimo.gbean.jmx.GBeanMBean; import org.apache.geronimo.j2ee.deployment.EARContext; import org.apache.geronimo.j2ee.deployment.Module; import org.apache.geronimo.j2ee.deployment.ModuleBuilder; +import org.apache.geronimo.j2ee.deployment.ModuleBuilderWithUnpack; import org.apache.geronimo.j2ee.deployment.WebModule; import org.apache.geronimo.jetty.JettyWebAppContext; import org.apache.geronimo.jetty.JettyWebAppJACCContext; @@ -91,7 +96,7 @@ /** * @version $Revision$ $Date$ */ -public class JettyModuleBuilder implements ModuleBuilder { +public class JettyModuleBuilder implements ModuleBuilderWithUnpack { static final SchemaTypeLoader SCHEMA_TYPE_LOADER = XmlBeans.typeLoaderUnion(new SchemaTypeLoader[] { XmlBeans.typeLoaderForClassLoader(org.apache.geronimo.xbeans.j2ee.String.class.getClassLoader()), XmlBeans.typeLoaderForClassLoader(JettyWebAppDocument.class.getClassLoader()) @@ -188,6 +193,70 @@ return module; } + public void installModule(File earFolder, EARContext earContext, + Module webModule) throws DeploymentException { + try { + File webFolder = new File(earFolder, webModule.getURI().toString()); + URI warRoot = webFolder.toURI(); + URI moduleBase; + if ( !webModule.getURI().equals(URI.create("/")) ) { + moduleBase = URI.create(webModule.getURI().toString() + "/"); + } else { + moduleBase = URI.create("war/"); + } + + WebAppType webApp = null; + JettyWebAppType jettyWebApp = (JettyWebAppType) webModule.getVendorDD(); + + // add the warfile's content to the configuration + Collection files = new ArrayList(); + FileUtil.listRecursiveFiles(webFolder, files); + for (Iterator iter = files.iterator(); iter.hasNext();) { + File file = (File) iter.next(); + URI fileURI = warRoot.relativize(file.toURI()); + URI target = moduleBase.resolve(fileURI); + if (fileURI.toString().equals("WEB-INF/web.xml")) { + earContext.addFile(target, file); + try { + XmlObject dd = SchemaConversionUtils.parse(new FileInputStream(file)); + WebAppDocument doc = SchemaConversionUtils.convertToServletSchema(dd); + webApp = doc.getWebApp(); + } catch (XmlException e) { + throw new DeploymentException("Unable to parse web.xml", e); + } + } else if (jettyWebApp == null && fileURI.toString().equals("WEB-INF/geronimo-jetty.xml")) { + earContext.addFile(target, file); + try { + JettyWebAppDocument doc = (JettyWebAppDocument) XmlBeansUtil.parse(new FileInputStream(file), JettyWebAppDocument.type); + jettyWebApp = doc.getWebApp(); + } catch (XmlException e) { + throw new DeploymentException("Unable to parse geronimo-jetty.xml", e); + } + } else { + earContext.addFile(target, file); + } + } + + if (webApp == null) { + throw new DeploymentException("Did not find WEB-INF/web.xml in module"); + } + webModule.setSpecDD(webApp); + + if (jettyWebApp == null) { + throw new DeploymentException("No plan or WEB-INF/jetty-web.xml found"); + } + webModule.setVendorDD(jettyWebApp); + + // add the dependencies declared in the geronimo-jetty.xml file + JettyDependencyType[] dependencies = jettyWebApp.getDependencyArray(); + for (int i = 0; i < dependencies.length; i++) { + earContext.addDependency(getDependencyURI(dependencies[i])); + } + } catch (IOException e) { + throw new DeploymentException("Problem deploying war", e); + } + } + public void installModule(JarFile earFile, EARContext earContext, Module webModule) throws DeploymentException { try { URI warRoot = null; @@ -590,6 +659,7 @@ static { GBeanInfoFactory infoFactory = new GBeanInfoFactory(JettyModuleBuilder.class); infoFactory.addInterface(ModuleBuilder.class); + infoFactory.addInterface(ModuleBuilderWithUnpack.class); GBEAN_INFO = infoFactory.getBeanInfo(); } 1.5 +13 -1 incubator-geronimo/modules/deployment/src/java/org/apache/geronimo/deployment/util/FileUtil.java Index: FileUtil.java =================================================================== RCS file: /home/cvs/incubator-geronimo/modules/deployment/src/java/org/apache/geronimo/deployment/util/FileUtil.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- FileUtil.java 10 Mar 2004 09:58:49 -0000 1.4 +++ FileUtil.java 23 Jul 2004 06:06:19 -0000 1.5 @@ -21,6 +21,7 @@ import java.io.InputStream; import java.io.IOException; import java.io.FileOutputStream; +import java.util.Collection; /** * @@ -62,5 +63,16 @@ } } root.delete(); + } + + public static void listRecursiveFiles(File aFile, Collection aColl) { + File[] files = aFile.listFiles(); + for (int i = 0; i < files.length; i++) { + if ( files[i].isFile() ) { + aColl.add(files[i]); + } else { + listRecursiveFiles(files[i], aColl); + } + } } } 1.17 +39 -4 incubator-geronimo/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_5ConfigBuilderTest.java Index: RAR_1_5ConfigBuilderTest.java =================================================================== RCS file: /home/cvs/incubator-geronimo/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_5ConfigBuilderTest.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- RAR_1_5ConfigBuilderTest.java 22 Jul 2004 03:22:53 -0000 1.16 +++ RAR_1_5ConfigBuilderTest.java 23 Jul 2004 06:06:19 -0000 1.17 @@ -86,7 +86,36 @@ } } - public void testBuildModule() throws Exception { + public void testBuildUnpackedModule() throws Exception { + InstallAction action = new InstallAction() { + private File rarFile = new File("target/test-rar-15"); + public File getRARFile() { + return rarFile; + } + public void install(ModuleBuilder moduleBuilder, EARContext earContext, Module module) throws Exception { + // TODO gets rid of this cast when all the ModuleBuilder + // will implement this method. + ((ConnectorModuleBuilder) moduleBuilder).installModule(rarFile, earContext, module); + } + }; + executeTestBuildModule(action); + } + + + public void testBuildPackedModule() throws Exception { + InstallAction action = new InstallAction() { + private File rarFile = new File("target/test-rar-15.rar"); + public File getRARFile() { + return rarFile; + } + public void install(ModuleBuilder moduleBuilder, EARContext earContext, Module module) throws Exception { + moduleBuilder.installModule(new JarFile(rarFile), earContext, module); + } + }; + executeTestBuildModule(action); + } + + private void executeTestBuildModule(InstallAction action) throws Exception { String j2eeDomainName = "geronimo.server"; String j2eeServerName = "TestGeronimoServer"; String j2eeApplicationName = "null"; @@ -95,7 +124,7 @@ ObjectName connectionTrackerName = new ObjectName("geronimo.connector:service=ConnectionTracker"); ModuleBuilder moduleBuilder = new ConnectorModuleBuilder(); - File rarFile = new File("target/test-rar-15.rar"); + File rarFile = action.getRARFile(); ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); ClassLoader cl = new URLClassLoader(new URL[]{rarFile.toURL()}, oldCl); @@ -124,7 +153,7 @@ null, null); - moduleBuilder.installModule(new JarFile(rarFile), earContext, module); + action.install(moduleBuilder, earContext, module); earContext.getClassLoader(null); moduleBuilder.initContext(earContext, module, cl); moduleBuilder.addGBeans(earContext, module, cl); @@ -347,4 +376,10 @@ errors = new ArrayList(); xmlOptions.setErrorListener(errors); } + + private interface InstallAction { + public File getRARFile(); + public void install(ModuleBuilder moduleBuilder, EARContext earContext, Module module) throws Exception; + } + } 1.12 +41 -5 incubator-geronimo/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_0ConfigBuilderTest.java Index: RAR_1_0ConfigBuilderTest.java =================================================================== RCS file: /home/cvs/incubator-geronimo/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_0ConfigBuilderTest.java,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- RAR_1_0ConfigBuilderTest.java 22 Jul 2004 03:22:53 -0000 1.11 +++ RAR_1_0ConfigBuilderTest.java 23 Jul 2004 06:06:19 -0000 1.12 @@ -38,6 +38,7 @@ import javax.sql.DataSource; import junit.framework.TestCase; + import org.apache.geronimo.gbean.GBeanInfo; import org.apache.geronimo.gbean.jmx.GBeanMBean; import org.apache.geronimo.j2ee.deployment.EARContext; @@ -84,7 +85,36 @@ } - public void testBuildModule() throws Exception { + public void testBuildUnpackedModule() throws Exception { + InstallAction action = new InstallAction() { + private File rarFile = new File("target/test-rar-10"); + public File getRARFile() { + return rarFile; + } + public void install(ModuleBuilder moduleBuilder, EARContext earContext, Module module) throws Exception { + // TODO gets rid of this cast when all the ModuleBuilder + // will implement this method. + ((ConnectorModuleBuilder) moduleBuilder).installModule(rarFile, earContext, module); + } + }; + executeTestBuildModule(action); + } + + + public void testBuildPackedModule() throws Exception { + InstallAction action = new InstallAction() { + private File rarFile = new File("target/test-rar-10.rar"); + public File getRARFile() { + return rarFile; + } + public void install(ModuleBuilder moduleBuilder, EARContext earContext, Module module) throws Exception { + moduleBuilder.installModule(new JarFile(rarFile), earContext, module); + } + }; + executeTestBuildModule(action); + } + + private void executeTestBuildModule(InstallAction action) throws Exception { String j2eeDomainName = "geronimo.server"; String j2eeServerName = "TestGeronimoServer"; String j2eeApplicationName = "null"; @@ -92,7 +122,7 @@ ObjectName connectionTrackerName = new ObjectName("geronimo.connector:service=ConnectionTracker"); ModuleBuilder moduleBuilder = new ConnectorModuleBuilder(); - File rarFile = new File("target/test-rar-10.rar"); + File rarFile = action.getRARFile(); ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); ClassLoader cl = new URLClassLoader(new URL[]{rarFile.toURL()}, oldCl); @@ -121,7 +151,7 @@ null, null); - moduleBuilder.installModule(new JarFile(rarFile), earContext, module); + action.install(moduleBuilder, earContext, module); earContext.getClassLoader(null); moduleBuilder.initContext(earContext, module, cl); moduleBuilder.addGBeans(earContext, module, cl); @@ -136,7 +166,7 @@ carFile.delete(); } } - + private void verifyDeployment(File unpackedDir, ClassLoader cl, String j2eeDomainName, String j2eeServerName, String j2eeApplicationName, String j2eeModuleName) throws Exception { DataSource ds = null; Kernel kernel = null; @@ -295,4 +325,10 @@ errors = new ArrayList(); xmlOptions.setErrorListener(errors); } + + private interface InstallAction { + public File getRARFile(); + public void install(ModuleBuilder moduleBuilder, EARContext earContext, Module module) throws Exception; + } + }