portals-pluto-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From e..@apache.org
Subject svn commit: r539020 [1/2] - in /portals/pluto/branches/pluto-1.1.x: maven-pluto-plugin/src/main/java/org/apache/pluto/maven/ pluto-ant-tasks/src/main/java/org/apache/pluto/ant/ pluto-util/src/main/java/org/apache/pluto/util/assemble/ pluto-util/src/mai...
Date Thu, 17 May 2007 17:07:02 GMT
Author: esm
Date: Thu May 17 10:07:00 2007
New Revision: 539020

URL: http://svn.apache.org/viewvc?view=rev&rev=539020
Log:
[PLUTO-359]: adding ear assembly support to pluto-1.1.x branch.

Added:
    portals/pluto/branches/pluto-1.1.x/pluto-ant-tasks/src/main/java/org/apache/pluto/ant/ExamineArchiveTask.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/AbstractArchiveAssembler.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/AssemblySink.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/ByteArrayAssemblySink.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/EarAssembler.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/FileAssemblySink.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/io/
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/io/JarStreamingAssembly.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/io/WebXmlStreamingAssembly.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/test/java/org/apache/pluto/util/assemble/ArchiveBasedAssemblyTest.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/test/java/org/apache/pluto/util/assemble/ear/
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/test/java/org/apache/pluto/util/assemble/ear/ComplexEarAssemblerTest.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/test/java/org/apache/pluto/util/assemble/ear/EarAssemblerTest.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/test/java/org/apache/pluto/util/assemble/io/
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/test/java/org/apache/pluto/util/assemble/io/AssemblyStreamTest.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/test/resources/org/apache/pluto/util/assemble/ear/
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/test/resources/org/apache/pluto/util/assemble/ear/ComplexEarDeployerTest.ear   (with props)
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/test/resources/org/apache/pluto/util/assemble/ear/EarDeployerTest.ear   (with props)
Modified:
    portals/pluto/branches/pluto-1.1.x/maven-pluto-plugin/src/main/java/org/apache/pluto/maven/AssembleMojo.java
    portals/pluto/branches/pluto-1.1.x/pluto-ant-tasks/src/main/java/org/apache/pluto/ant/AssembleTask.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/AssemblerConfig.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/AssemblerFactory.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/WebXmlRewritingAssembler.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/war/WarAssembler.java
    portals/pluto/branches/pluto-1.1.x/pluto-util/src/test/java/org/apache/pluto/util/assemble/war/WarAssemblerTest.java

Modified: portals/pluto/branches/pluto-1.1.x/maven-pluto-plugin/src/main/java/org/apache/pluto/maven/AssembleMojo.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/pluto-1.1.x/maven-pluto-plugin/src/main/java/org/apache/pluto/maven/AssembleMojo.java?view=diff&rev=539020&r1=539019&r2=539020
==============================================================================
--- portals/pluto/branches/pluto-1.1.x/maven-pluto-plugin/src/main/java/org/apache/pluto/maven/AssembleMojo.java (original)
+++ portals/pluto/branches/pluto-1.1.x/maven-pluto-plugin/src/main/java/org/apache/pluto/maven/AssembleMojo.java Thu May 17 10:07:00 2007
@@ -17,22 +17,85 @@
 package org.apache.pluto.maven;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.logging.Log;
+import org.apache.pluto.util.UtilityException;
 import org.apache.pluto.util.assemble.Assembler;
 import org.apache.pluto.util.assemble.AssemblerConfig;
 import org.apache.pluto.util.assemble.AssemblerFactory;
 
 /**
- * TODO: Document
- * TODO: Refactor this and the assembler to model deployer and allow no arg constructor
- *
+ * The AssembleMojo is responsible for assembling a web application for deployment
+ * into the Pluto portlet container.  Assembly, in this context, is the process of
+ * updating a web application's WEB-INF/web.xml with Pluto specific parameters for 
+ * deployment in Pluto.   
+ * <p>
+ * This Mojo is able to operate on individual descriptors by specifying 
+ * <code>portletXml</code>, <code>webXml</code>, and <code>webXmlDestination</code>.
+ * If your project uses standard Maven 2 directory layouts, the defaults will
+ * provide proper values.
+ * <p/>
+ * Example Maven 2 <code>pom.xml</code> usage:
+ * <pre>
+ * &lt;project&gt;
+ *   ...
+ *   &lt;build&gt;
+ *      &lt;plugins&gt;
+ *          &lt;plugin&gt;
+ *              &lt;groupId&gt;org.apache.pluto&lt;/groupId&gt;
+ *              &lt;artifactId&gt;maven-pluto-plugin&lt;/artifactId&gt;
+ *          &lt;/plugin&gt;
+ *      &lt;/plugins&gt;
+ *   &lt;/build&gt;
+ *   ...
+ * &lt;/project&gt;
+ * </pre>
+ * <p>
+ * This Mojo can also operate on entire WAR or EAR archive files by specifying
+ * a list of archive path names in <code>archives</code>.
+ * <p/>
+ * Example Maven 2 <code>pom.xml</code> usage:
+ * <pre>
+ * &lt;project&gt;
+ *   ...
+ *   &lt;build&gt;
+ *      &lt;plugins&gt;
+ *          &lt;plugin&gt;
+ *              &lt;groupId&gt;org.apache.pluto&lt;/groupId&gt;
+ *              &lt;artifactId&gt;maven-pluto-plugin&lt;/artifactId&gt;
+ *              &lt;executions&gt;
+ *                  &lt;execution&gt;
+ *                      &lt;phase&gt;package&lt;/phase&gt;
+ *                      &lt;goals&gt;
+ *                          &lt;goal&gt;assemble&lt;/goal&gt;
+ *                      &lt;/goals&gt;
+ *                      &lt;configuration&gt;
+ *                          &lt;assemblyOutputDirectory&gt;${project.build.directory}/assembled-wars&lt;/assemblyOutputDirectory&gt;
+ *                          &lt;archives&gt;
+ *                              &lt;assembleArchive&gt;
+ *                                  ${project.build.directory}/wartoassemble.war
+ *                              &lt;/assembleArchive&gt;
+ *                              &lt;assembleArchive&gt;
+ *                                  ${project.build.directory}/anotherwartoassemble.war
+ *                              &lt;/assembleArchive&gt;
+ *                          &lt;/archives&gt;
+ *                      &lt;/configuration&gt;
+ *                  &lt;/execution&gt;
+ *              &lt;/executions&gt;
+ *          &lt;/plugin&gt;
+ *      &lt;/plugins&gt;
+ *   &lt;/build&gt;
+ *   ...
+ * &lt;/project&gt;
+ * </pre>
+ * 
  * @since Jul 30, 2005
- * @see org.apache.pluto.util.assemble.Assembler
- *
+ * @see org.apache.pluto.util.assemble.Assembler 
+ * 
  * @goal assemble
  * @description prepares a web application as a portlet application
  * @phase process-resources
@@ -68,86 +131,115 @@
     private String dispatchServletClass;
     
     /**
-     * A list of war files to assemble.  Mutually exclusive with portletXml, webXml, 
-     * and webXmlDestination parameters.
+     * A list of archive files to assemble.  Only EAR and WAR file
+     * types are supported.  
+     * <p/>
+     * Each value in the list is the absolute pathname to the 
+     * archive being assembled.
+     * <p/>
+     * This parameter is mutually exclusive with portletXml, webXml, 
+     * and webXmlDestination parameters.  
+     * 
+     * @parameter alias="warFiles"
+     */
+    private List archives;
+
+    /**
+     * @deprecated see archives parameter
      * @parameter
      */
     private List warFiles;
     
     /**
-     * Destination directory the assembled war files are written out to.
-     * @parameter expression="${project.build.directory}/pluto-assembled-wars"
+     * Destination directory the assembled files are written out to.
+     * @parameter alias="warFilesDestination" expression="${project.build.directory}/pluto-assembled-wars"
+     */
+    private File assemblyOutputDirectory;
+    
+    /**
+     * Destination directory the assembled files are written out to.
+     * @parameter
+     * @deprecated see assemblyOutputDirectory parameter
      */
     private File warFilesDestination;
 
     // AbstractPlutoMojo Impl --------------------------------------------------
 
-    protected void doExecute() throws Exception {
+    protected void doExecute() throws MojoExecutionException {       
+        
         // Log parameter values.
     	Log log = getLog();
         if (log.isInfoEnabled()) {
-            if (warFiles == null || warFiles.isEmpty()) {
+            if (archives == null || archives.isEmpty()) {
                 log.info("Reading web.xml from :" + webXml.getAbsolutePath());
                 log.info("Reading portlet.xml from: " + portletXml.getAbsolutePath());
                 log.info("Writing web.xml to: " + webXmlDestination.getAbsolutePath());
-            } else {
-                final String nl = System.getProperty("line.separator");
-                StringBuffer buf = new StringBuffer("Attempting to assemble the following war files to destination directory " +
-                        warFilesDestination.getAbsolutePath() + " : " + nl);
-                for (Iterator i = warFiles.iterator(); i.hasNext();) {
-                    File f = new File(i.next().toString());
-                    buf.append("  " + f.getAbsolutePath());
-                    if (i.hasNext()) {
-                        buf.append(nl);
-                    }
-                }
-                buf.append(nl);
-                log.info(buf.toString());
-            }              
+            }               
         }
-            
-        // Assemble portlet app by updating web.xml.
-        if (warFiles == null || warFiles.isEmpty()) {        
-            AssemblerConfig config = createAssemblerConfig();
-            Assembler assembler = AssemblerFactory.getFactory()
-        		    .createAssembler(config);
-            assembler.assemble(config);
-        } else {
-            for (Iterator i = warFiles.iterator(); i.hasNext();) {
-                File warFile = new File(i.next().toString());
-                if (log.isInfoEnabled()) {
-                    log.info("Assembling war file " + warFile.getAbsolutePath() + " to directory " + warFilesDestination.getAbsolutePath());
-                }                
-                AssemblerConfig config = createWarFileAssemblerConfig(warFile, warFilesDestination);
+        
+        try {
+            // Assemble portlet app by updating web.xml.
+            if (archives == null || archives.isEmpty()) {        
+                AssemblerConfig config = createAssemblerConfig();
                 Assembler assembler = AssemblerFactory.getFactory()
-                    .createAssembler(config);
+            		    .createAssembler(config);
                 assembler.assemble(config);
+            } else {
+                for (Iterator i = archives.iterator(); i.hasNext();) {
+                    File archive = new File(i.next().toString());
+                    if (log.isInfoEnabled()) {
+                        log.info("Assembling archive file " + archive.getAbsolutePath() + 
+                                " to directory " + assemblyOutputDirectory.getAbsolutePath());
+                    }                
+                    AssemblerConfig config = createArchiveAssemblerConfig(archive, assemblyOutputDirectory);
+                    Assembler assembler = AssemblerFactory.getFactory()
+                        .createAssembler(config);
+                    assembler.assemble(config);
+                }
             }
+        } catch (UtilityException e) {
+            log.error("Assembly failed: " + e.getMessage(), e);
         }
     }
 
     protected void doValidate() throws MojoExecutionException {
         Log log = getLog();
-
+        
+        // Support for the old 'warFiles' mojo parameter.  Apparently
+        // the alias for the 'archives' parameter doesn't work properly.
+        if (! (warFiles == null || warFiles.isEmpty()) ) {
+            log.warn( "'warFiles' parameter is deprecated.  Use 'archives' parameter instead." );
+            if ( archives == null ) {
+                archives = new ArrayList();
+            }
+            archives.addAll( warFiles );
+        }
+        
+        // Warn if the old 'warFilesDestination' mojo parameter is used
+        if ( warFilesDestination != null ) {
+            log.warn( "'warFilesDestination' parameter is deprecated.  Use 'assemblyOutputDirectory' instead." );
+            assemblyOutputDirectory = warFilesDestination;
+        }
+        
         // If a list of war files are supplied:
         //   1) webXml, portletXml, and webXmlDestination parameters are ignored
         //   2) verify the files in the List exist.
         //   3) verify the destination is a directory, or create it if it doesn't exist.
         
         // A list of files was supplied so we ignore other parameters. 
-        if (warFiles != null && !warFiles.isEmpty()) {
+        if (archives != null && !archives.isEmpty()) {
             if (webXml != null) {
-                log.debug("warFiles parameter and webXml parameter are mutually exclusive.  Ignoring webXml parameter.");
+                log.debug("archives parameter and webXml parameter are mutually exclusive.  Ignoring webXml parameter.");
             }
             if (portletXml != null) {
-                log.debug("warFiles parameter and portletXml parameter are mutually exclusive.  Ignoring portletXml parameter.");
+                log.debug("archives parameter and portletXml parameter are mutually exclusive.  Ignoring portletXml parameter.");
             }
             if (webXmlDestination != null) {
-                log.debug("warFiles parameter and webXmlDestination parameter are mutually exclusive.  Ignoring webXmlDestination parameter.");
+                log.debug("archives parameter and webXmlDestination parameter are mutually exclusive.  Ignoring webXmlDestination parameter.");
             }
             
             // verify each file can be found
-            for (Iterator i = warFiles.iterator(); i.hasNext();) {
+            for (Iterator i = archives.iterator(); i.hasNext();) {
                 File f = new File(i.next().toString());
                 if (!f.exists()) {
                     log.warn("File " + f.getAbsolutePath() + " does not exist.");
@@ -162,35 +254,35 @@
             }
             
             // check to see if the warFiles list is now empty
-            if (warFiles.isEmpty()) {
+            if (archives.isEmpty()) {
                 throw new MojoExecutionException("No war files could be installed due errors.");
             }
              
             // check to see if the dest dir exists or create it.
-            if (!warFilesDestination.exists()) {
+            if (!assemblyOutputDirectory.exists()) {
                 if (log.isDebugEnabled()) {
-                    log.debug("Creating destination directory for assembled war files: " + warFilesDestination.getAbsolutePath());
+                    log.debug("Creating destination directory for assembled war files: " + assemblyOutputDirectory.getAbsolutePath());
                 }
                 try {                    
-                    if(!warFilesDestination.mkdirs()) {
+                    if(!assemblyOutputDirectory.mkdirs()) {
                         throw new MojoExecutionException("Unable to create destination directory for assembled war files: " + 
-                                warFilesDestination.getAbsolutePath());
+                                assemblyOutputDirectory.getAbsolutePath());
                     }                        
                 } catch (SecurityException e) {
                     throw new MojoExecutionException("Unable to create destination directory for assembled war files: " + e.getMessage(), e);
                 }
             } else {
-                if (!warFilesDestination.isDirectory()) {
+                if (!assemblyOutputDirectory.isDirectory()) {
                     throw new MojoExecutionException("Specified destination for assembled war files " +
-                            warFilesDestination.getAbsolutePath() + " is not a directory!");
+                            assemblyOutputDirectory.getAbsolutePath() + " is not a directory!");
                 }
-                if (!warFilesDestination.canRead()||!warFilesDestination.canWrite()) {
+                if (!assemblyOutputDirectory.canRead()||!assemblyOutputDirectory.canWrite()) {
                     throw new MojoExecutionException("Unable to read or write to destination directory for assembed war files.  " +
-                            "Check permissions on the directory " + warFilesDestination.getAbsolutePath());
+                            "Check permissions on the directory " + assemblyOutputDirectory.getAbsolutePath());
                 }
             }
             
-        // A list of war files was not provided, so use the other parameters instead.
+        // A list of archive files was not provided, so use the other parameters instead.
             
         } else {            
             if (webXml == null || !webXml.exists()) {
@@ -213,10 +305,10 @@
         return config;
     }
     
-    private AssemblerConfig createWarFileAssemblerConfig(File warFile, File destinationDirectory) {
+    private AssemblerConfig createArchiveAssemblerConfig(File archiveToAssemble, File destinationDirectory) {
         AssemblerConfig config = new AssemblerConfig();
         config.setDispatchServletClass(dispatchServletClass);
-        config.setWarSource(warFile);
+        config.setSource(archiveToAssemble);
         config.setDestination(destinationDirectory);
         return config;
     }

Modified: portals/pluto/branches/pluto-1.1.x/pluto-ant-tasks/src/main/java/org/apache/pluto/ant/AssembleTask.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/pluto-1.1.x/pluto-ant-tasks/src/main/java/org/apache/pluto/ant/AssembleTask.java?view=diff&rev=539020&r1=539019&r2=539020
==============================================================================
--- portals/pluto/branches/pluto-1.1.x/pluto-ant-tasks/src/main/java/org/apache/pluto/ant/AssembleTask.java (original)
+++ portals/pluto/branches/pluto-1.1.x/pluto-ant-tasks/src/main/java/org/apache/pluto/ant/AssembleTask.java Thu May 17 10:07:00 2007
@@ -37,20 +37,51 @@
  * @since Nov 23, 2005
  */
 public class AssembleTask extends Task {
-
+    
+    /**
+     * Path to the portlet descriptor 
+     * (normally <code>WEB-INF/portlet.xml</code>)
+     * <p/>
+     * If <code>webapp</code> is specified, this File will
+     * be resolved relative to <code>webapp</code>
+     */
     private File portletxml;
 
+    /**
+     * Path to the unassembled servlet descriptor 
+     * (normally <code>WEB-INF/web.xml</code>)
+     * <p/>
+     * If <code>webapp</code> is specified, this File will
+     * be resolved relative to <code>webapp</code>
+     */
     private File webxml;
 
+    /**
+     * Path the assembled servlet descriptor will
+     * be written to.
+     */
     private File destfile;
 
+    /** 
+     * The base directory of the exploded web application to assemble.
+     * If set, <code>webXml</code> and <code>portletXml</code>
+     * will be resolved relative to this directory.
+     */
     private File webapp;
 
-    private File war;
-
+    /**
+     * Path to the archive to assemble.  EAR and WAR 
+     * packaging formats are supported.
+     */
+    private File archive;
+
+    /**
+     * Destination directory the assembled archives
+     * are written out to.
+     */
     private File destdir;
 
-    private final Collection warFileSets = new LinkedList();
+    private final Collection archiveFileSets = new LinkedList();
 
     public File getPortletxml() {
         if(webapp != null)
@@ -90,17 +121,38 @@
         this.webapp = webapp;
     }
 
+    /**
+     * Note this methods remains to support
+     * backwards compatiblity.
+     * 
+     * @deprecated see <code>getArchive()</code>
+     */
     public File getWar() {
-        return this.war;
+        return this.archive;
     }
 
+    /**
+     * Note this methods remains to support
+     * backwards compatiblity.
+     * 
+     * @param war
+     * @deprecated see <code>setArchive(File)</code>
+     */
     public void setWar(File war) {
-        this.war = war;
+        this.archive = war;
+    }
+    
+    public File getArchive() {
+        return this.archive;
+    }
+    
+    public void setArchive(File archive) {
+        this.archive = archive;
     }
 
     public File getDestdir() {
         if (destdir == null) {
-            return (war != null ? war.getParentFile() : null);
+            return (archive != null ? archive.getParentFile() : null);
         }
         return this.destdir;
     }
@@ -109,8 +161,19 @@
         this.destdir = destDir;
     }
 
+    /**
+     * Note this method remains to support 
+     * backwards compatiblity.
+     * 
+     * @param fileSet
+     * @deprecated use addArchives instead
+     */
     public void addWars(FileSet fileSet) {
-        this.warFileSets.add(fileSet);
+        this.archiveFileSets.add(fileSet);
+    }
+    
+    public void addArchives(FileSet fileSet) {
+        this.archiveFileSets.add(fileSet);
     }
 
     public void execute() throws BuildException {
@@ -118,8 +181,8 @@
         validateArgs();
 
         try {
-            if (this.warFileSets.size() > 0) {
-                for (final Iterator fileSetItr = this.warFileSets.iterator(); fileSetItr.hasNext();) {
+            if (this.archiveFileSets.size() > 0) {
+                for (final Iterator fileSetItr = this.archiveFileSets.iterator(); fileSetItr.hasNext();) {
                     final FileSet fileSet = (FileSet)fileSetItr.next();
                     final DirectoryScanner directoryScanner = fileSet.getDirectoryScanner(this.getProject());
 
@@ -129,11 +192,11 @@
                     for (int index = 0; index < includedFiles.length; index++) {
                         AssemblerConfig config = new AssemblerConfig();
 
-                        final File warSource = new File(basedir, includedFiles[index]);
-                        config.setWarSource(warSource);
+                        final File archiveSource = new File(basedir, includedFiles[index]);
+                        config.setSource(archiveSource);
                         config.setDestination(getDestdir());
 
-                        this.log("Assembling '" + warSource + "' to '" + getDestdir() + "'");
+                        this.log("Assembling '" + archiveSource + "' to '" + getDestdir() + "'");
                         Assembler assembler = AssemblerFactory.getFactory().createAssembler(config);
                         assembler.assemble(config);
                     }
@@ -142,11 +205,11 @@
             else {
                 AssemblerConfig config = new AssemblerConfig();
 
-                final File warSource = getWar();
-                if (warSource != null) {
-                    config.setWarSource(warSource);
+                final File archiveSource = getArchive();
+                if (archiveSource != null) {
+                    config.setSource(archiveSource);
                     config.setDestination(getDestdir());
-                    this.log("Assembling '" + warSource + "' to '" + getDestdir() + "'");
+                    this.log("Assembling '" + archiveSource + "' to '" + getDestdir() + "'");
                 }
                 else {
                     config.setPortletDescriptor(getPortletxml());
@@ -155,7 +218,6 @@
                     this.log("Assembling '" + getWebxml() + "' to '" + getDestfile() + "'");
                 }
 
-
                 Assembler assembler = AssemblerFactory.getFactory().createAssembler(config);
                 assembler.assemble(config);
             }
@@ -173,12 +235,13 @@
                throw new BuildException("webapp "+webapp.getAbsolutePath()+ " does not exist");
             }
 
-            if (war != null) {
-                throw new BuildException("war should not be specified if webapp is specified");
+            if (archive != null) {
+                throw new BuildException("archive (or war) should not be specified if webapp is specified");
             }
-            if (this.warFileSets.size() > 0) {
-                throw new BuildException("wars should not be specified if webapp is specified");
+            if (this.archiveFileSets.size() > 0) {
+                throw new BuildException("archive (or wars) should not be specified if webapp is specified");
             }
+            // TODO check this
             if (destdir != null) {
                 throw new BuildException("destfile should not be specified if webapp is specified");
             }
@@ -187,46 +250,46 @@
         }
 
         //Check if running with war arg
-        if (war != null) {
-            if(!war.exists()) {
-                throw new BuildException("WAR "+war.getAbsolutePath()+ " does not exist");
+        if (archive != null) {
+            if(!archive.exists()) {
+                throw new BuildException("Archive file "+archive.getAbsolutePath()+ " does not exist");
             }
 
-            if (this.warFileSets.size() > 0) {
-                throw new BuildException("wars should not be specified if war is specified");
+            if (this.archiveFileSets.size() > 0) {
+                throw new BuildException("archives (or wars) should not be specified if archive (or war) is specified");
             }
             if (webapp != null) {
-                throw new BuildException("webapp should not be specified if war is specified");
+                throw new BuildException("webapp should not be specified if archive (or war) is specified");
             }
             if (destfile != null) {
-                throw new BuildException("destfile should not be specified if war is specified");
+                throw new BuildException("destfile should not be specified if archive (or war) is specified");
             }
             if (portletxml != null) {
-                throw new BuildException("portletxml should not be specified if war is specified");
+                throw new BuildException("portletxml should not be specified if archive (or war) is specified");
             }
             if (webxml != null) {
-                throw new BuildException("webxml should not be specified if war is specified");
+                throw new BuildException("webxml should not be specified if archive (or war) is specified");
             }
 
             return;
         }
 
-        //Check if running with war arg
-        if (this.warFileSets.size() > 0) {
-            if (war != null) {
-                throw new BuildException("wars should not be specified if war is specified");
+        //Check if running with archives or wars arg
+        if (this.archiveFileSets.size() > 0) {
+            if (archive != null) {
+                throw new BuildException("archives (or wars) should not be specified if archive (or war) is specified");
             }
             if (webapp != null) {
-                throw new BuildException("webapp should not be specified if war is specified");
+                throw new BuildException("webapp should not be specified if archives (or wars) is specified");
             }
             if (destfile != null) {
-                throw new BuildException("destfile should not be specified if war is specified");
+                throw new BuildException("destfile should not be specified if archives (or wars) is specified");
             }
             if (portletxml != null) {
-                throw new BuildException("portletxml should not be specified if war is specified");
+                throw new BuildException("portletxml should not be specified if archive (or wars) is specified");
             }
             if (webxml != null) {
-                throw new BuildException("webxml should not be specified if war is specified");
+                throw new BuildException("webxml should not be specified if archives (or wars) is specified");
             }
 
             return;
@@ -239,13 +302,14 @@
         if(webxml == null || !webxml.exists()) {
             throw new BuildException("webxml "+webxml + " does not exist");
         }
-        if (war != null) {
-            throw new BuildException("war should not be specified if portletxml and webxml are aspecified");
+        if (archive != null) {
+            throw new BuildException("archive (or war) should not be specified if portletxml and webxml are specified");
         }
-        if (this.warFileSets.size() > 0) {
-            throw new BuildException("wars should not be specified if portletxml and webxml are aspecified");
+        if (this.archiveFileSets.size() > 0) {
+            throw new BuildException("archives (or wars) should not be specified if portletxml and webxml are specified");
         }
         if (destdir != null) {
+            // TODO check this
             throw new BuildException("destfile should not be specified if portletxml and webxml are aspecified");
         }
     }

Added: portals/pluto/branches/pluto-1.1.x/pluto-ant-tasks/src/main/java/org/apache/pluto/ant/ExamineArchiveTask.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/pluto-1.1.x/pluto-ant-tasks/src/main/java/org/apache/pluto/ant/ExamineArchiveTask.java?view=auto&rev=539020
==============================================================================
--- portals/pluto/branches/pluto-1.1.x/pluto-ant-tasks/src/main/java/org/apache/pluto/ant/ExamineArchiveTask.java (added)
+++ portals/pluto/branches/pluto-1.1.x/pluto-ant-tasks/src/main/java/org/apache/pluto/ant/ExamineArchiveTask.java Thu May 17 10:07:00 2007
@@ -0,0 +1,57 @@
+package org.apache.pluto.ant;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+public class ExamineArchiveTask extends Task {
+    
+    private File archive = null;
+    
+    public void execute() throws BuildException {
+        try {
+        
+            JarInputStream jarIn = new JarInputStream( new FileInputStream( archive ) );
+            JarEntry entry;
+            while ( ( entry = jarIn.getNextJarEntry() ) != null ) {
+                String name = entry.getName();
+                long crc = entry.getCrc();
+                long size = entry.getSize();
+                long compressedSize = entry.getCompressedSize();
+                int compressMethod = entry.getMethod();
+                long timeStamp = entry.getTime();
+                int hashCode = entry.hashCode();
+                
+                StringBuffer out = new StringBuffer();
+                
+                out.append( "Name: " + name + "\n" );
+                out.append( "  Size: "                  + Long.toHexString( size ) + " " );
+                out.append( "  Compressed Size: "       + Long.toHexString( compressedSize ) + " " );
+                out.append( "  Compression Method: "    + compressMethod + " " );
+                out.append( "  Timestamp: "             + Long.toHexString( timeStamp ) + " " );
+                out.append( "  HashCode: "              + Integer.toHexString( hashCode ) + " " );
+                out.append( "  CRC: "                   + Long.toHexString( crc ) + " " );
+                
+                System.out.println( out.toString() );
+                
+            }
+        
+        } catch ( Exception e ) {
+            throw new BuildException( e.getMessage(), e );
+        }
+        
+    }
+    
+    public void setArchive( File archive ) {
+        this.archive = archive;
+    }
+    
+    public File getArchive( ) {
+        return this.archive;
+    }
+
+}

Added: portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/AbstractArchiveAssembler.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/AbstractArchiveAssembler.java?view=auto&rev=539020
==============================================================================
--- portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/AbstractArchiveAssembler.java (added)
+++ portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/AbstractArchiveAssembler.java Thu May 17 10:07:00 2007
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.pluto.util.assemble;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pluto.util.UtilityException;
+
+/**
+ * A base class that assembler implementations should extend.  
+ * 
+ * The purpose of this class is to ensure consistent behavior
+ * when performing assembly.
+ */
+public abstract class AbstractArchiveAssembler extends WebXmlRewritingAssembler {
+
+    private static final Log LOG = LogFactory.getLog( AbstractArchiveAssembler.class );
+    
+    /**
+     * This implementation throws <code>UtilityException</code> if the source
+     * archive doesn't exist or is a directory.  If the destination archive is
+     * null, it assumes that in-place assembly is dessired.  It determines
+     * if the source archive should be replaced with the destination archive
+     * and provisions temporary files as needed.
+     */
+    public void assemble( AssemblerConfig config ) throws UtilityException {
+        File source = config.getSource();
+        File dest = config.getDestination();
+        
+        try {        
+            
+            if ( source == null || !source.exists() ) {
+                throw new UtilityException( "Source archive doesn't exist." );
+            }
+            
+            if ( source.isDirectory() ) {
+                throw new UtilityException( "Source archive is a directory." );
+            }
+
+            if ( performInPlaceAssembly( config ) ) {
+                    if ( LOG.isDebugEnabled() ) {
+                        LOG.debug( "Performing in-place assembly of " + config.getSource().getAbsolutePath() );
+                    }
+                    dest = File.createTempFile( source.getName(), ".tmp" );
+                    config.setDestination( dest );
+                    assembleInternal( config );
+                    dest.renameTo( source );          
+            } else {
+                if ( LOG.isDebugEnabled() ) {
+                    LOG.debug( "Performing assembly of " + config.getSource().getAbsolutePath() + " to " + 
+                            config.getDestination().getAbsolutePath() );
+                }
+                File destFile = dest;
+                
+                // if the destination is a directory, ensure that parent
+                // directories have been created and set the destination
+                // file to the file in the direcotory.
+                if ( dest.isDirectory() ) {                                
+                    dest.mkdirs();
+                    destFile = new File( dest, source.getName() );
+                }
+                
+                config.setDestination( destFile );
+                assembleInternal( config );
+            }
+            
+        } catch ( IOException e ) {
+            LOG.error( "Assembly failed: "+ e.getMessage() );
+            throw new UtilityException( e.getMessage(), e );
+        }        
+    }
+    
+    /**
+     * Performs a series of checks to determine whether or not the assembly should 
+     * occur "in-place" - that is, if the source archive will be assembled and then
+     * replaced by the destination archive.
+     * <p/>
+     * <ul>
+     *  <li>If the destination is null, then perform in place assembly.</li>
+     *  <li>If the destination is equal to the source, then perform in place assembly.</li>
+     * </ul>
+     * @param config the AssemblerConfig
+     * @return true if in-place configuration should occur
+     */    
+    protected boolean performInPlaceAssembly( final AssemblerConfig config ) {
+        // If the destination wasn't provided, in-place assembly is inferred
+        if ( config.getDestination() == null ) {
+            return true;
+        }
+        
+        // If the source and the destination are the same, in-place
+        // assembly has been explicitly requested by the caller
+        if ( config.getDestination().equals( config.getSource() ) ) {
+            return true;
+        }
+        
+        // If the destination is the parent directory of the source, then
+        // in-place assembly is inferred.
+        if ( config.getDestination().equals( config.getSource().getParentFile() ) ) {
+            return true;
+        }
+        
+        return false;
+    }
+    
+    /**
+     * Assemble the source file to the destination file.  The superclass is responsible for ensuring
+     * correct and not-null values for the source and destination, and for temporary file handling 
+     * used during in-place assembly.
+     * 
+     * @param config the assembler configuration object
+     * @throws UtilityException
+     * @throws IOException
+     */
+    protected abstract void assembleInternal( AssemblerConfig config ) 
+        throws UtilityException, IOException;
+
+}

Modified: portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/AssemblerConfig.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/AssemblerConfig.java?view=diff&rev=539020&r1=539019&r2=539020
==============================================================================
--- portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/AssemblerConfig.java (original)
+++ portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/AssemblerConfig.java Thu May 17 10:07:00 2007
@@ -19,7 +19,8 @@
 import java.io.File;
 
 /**
- * The pluto assembler configuration.
+ * The Pluto Assembler configuration encapsulates the configuration
+ * used by assembler implementations.
  */
 public class AssemblerConfig {
 
@@ -28,7 +29,7 @@
 	/** The portlet app descriptor, which is usually WEB-INF/portlet.xml. */
     private File portletDescriptor;
 
-    /** The webapp descriptor, which is usually WEB-INF/web.xml. */
+    /** The webapp descriptor to assemble, which is usually WEB-INF/web.xml. */
     private File webappDescriptor;
 
     /** The assemble destination, which points to the assembled WAR file. */
@@ -37,8 +38,11 @@
     /** The class of the servlet that will handle portlet requests */
     private String dispatchServletClass;
 
-    /** A source WAR archive to assemble */
-    private File warSource;
+    /** The source archive to assemble */
+    private File source;
+    
+    /** Assembler sink buffer size.  Defaults to 4096 bytes. */
+    private int assemblerSinkBuflen = 1024 * 4; // 4kb
 
     // Public Methods ----------------------------------------------------------
 
@@ -74,11 +78,33 @@
         this.dispatchServletClass = dispatchServletClass;
     }
 
+    /**
+     * @deprecated use <code>setSource(File)</code> instead.
+     */
+    public void setWarSource(File source) {
+        this.source = source;
+    }
+    
+    public void setSource(File source) {
+        this.source = source;
+    }
+    
+    /**
+     * @deprecated use <code>getSource()</code> instead.
+     */
     public File getWarSource() {
-        return this.warSource;
+        return source;
     }
-
-    public void setWarSource(File warSource) {
-        this.warSource = warSource;
+    
+    public File getSource() {
+        return source;
+    }
+    
+    public int getAssemblerSinkBuflen() {
+        return assemblerSinkBuflen;
+    }
+    
+    public void setAssemblerSinkBuflen(int buflen) {
+        this.assemblerSinkBuflen = buflen;
     }
 }

Modified: portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/AssemblerFactory.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/AssemblerFactory.java?view=diff&rev=539020&r1=539019&r2=539020
==============================================================================
--- portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/AssemblerFactory.java (original)
+++ portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/AssemblerFactory.java Thu May 17 10:07:00 2007
@@ -16,6 +16,9 @@
  */
 package org.apache.pluto.util.assemble;
 
+import java.io.File;
+
+import org.apache.pluto.util.assemble.ear.EarAssembler;
 import org.apache.pluto.util.assemble.file.FileAssembler;
 import org.apache.pluto.util.assemble.war.WarAssembler;
 
@@ -54,12 +57,21 @@
      * @return an assembler instance.
      */
     public Assembler createAssembler(AssemblerConfig config) {
-        if (config.getWarSource() != null) {
+        File source = config.getSource();
+        
+        if ( source == null ) {
+            return new FileAssembler();
+        }
+
+        if ( source.getName().toLowerCase().endsWith( ".war" ) ) {
             return new WarAssembler();
         }
-        else {
-            return new FileAssembler();
+        
+        if ( source.getName().toLowerCase().endsWith( ".ear" ) ) {
+            return new EarAssembler();
         }
+        
+        return new FileAssembler();
     }
 
 }

Modified: portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/WebXmlRewritingAssembler.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/WebXmlRewritingAssembler.java?view=diff&rev=539020&r1=539019&r2=539020
==============================================================================
--- portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/WebXmlRewritingAssembler.java (original)
+++ portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/WebXmlRewritingAssembler.java Thu May 17 10:07:00 2007
@@ -19,25 +19,18 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.Iterator;
 
-import org.apache.pluto.descriptors.common.InitParamDD;
-import org.apache.pluto.descriptors.portlet.PortletAppDD;
-import org.apache.pluto.descriptors.portlet.PortletDD;
-import org.apache.pluto.descriptors.services.PortletAppDescriptorService;
-import org.apache.pluto.descriptors.services.WebAppDescriptorService;
-import org.apache.pluto.descriptors.services.castor.PortletAppDescriptorServiceImpl;
-import org.apache.pluto.descriptors.services.castor.WebAppDescriptorServiceImpl;
-import org.apache.pluto.descriptors.servlet.LoadOnStartupDD;
-import org.apache.pluto.descriptors.servlet.ServletDD;
-import org.apache.pluto.descriptors.servlet.ServletMappingDD;
-import org.apache.pluto.descriptors.servlet.WebAppDD;
+import org.apache.pluto.util.assemble.io.JarStreamingAssembly;
+import org.apache.pluto.util.assemble.io.WebXmlStreamingAssembly;
 
 /**
  * @version $Revision$
  * @todo fix direct dependency on pluto-descriptor-impl
  */
 public abstract class WebXmlRewritingAssembler implements Assembler {
+    
+    //protected final JarStreamingAssembly jarAssembler = new JarStreamingAssembly();
+    //protected final WebXmlStreamingAssembly webXmlAssembler = new WebXmlStreamingAssembly();
 
     /**
      * Updates the webapp descriptor by injecting portlet wrapper servlet
@@ -56,50 +49,7 @@
                                               String dispatchServletClass)
     throws IOException {
 
-        if (dispatchServletClass == null ||
-            dispatchServletClass.length() == 0 ||
-            dispatchServletClass.trim().length() == 0) {
-            dispatchServletClass = DISPATCH_SERVLET_CLASS;
-        }
-
-        WebAppDescriptorService descriptorSvc = new WebAppDescriptorServiceImpl();
-        WebAppDD webAppDDIn = descriptorSvc.read(webXmlIn);
-
-        PortletAppDescriptorService portletAppDescriptorService =
-                new PortletAppDescriptorServiceImpl();
-        PortletAppDD portletAppDD = portletAppDescriptorService.read(portletXmlIn);
-        portletXmlIn.close();
-
-        for (Iterator it = portletAppDD.getPortlets().iterator();
-                it.hasNext(); ) {
-
-            // Read portlet definition.
-            PortletDD portlet = (PortletDD) it.next();
-            String name = portlet.getPortletName();
-
-            ServletDD servlet = new ServletDD();
-            servlet.setServletName(name);
-
-            servlet.setServletClass(dispatchServletClass);
-
-            InitParamDD initParam = new InitParamDD();
-            initParam.setParamName("portlet-name");
-            initParam.setParamValue(name);
-            servlet.getInitParams().add(initParam);
-
-            LoadOnStartupDD onStartup = new LoadOnStartupDD();
-            onStartup.setPriority(1);
-            servlet.setLoadOnStartup(onStartup);
-
-            ServletMappingDD servletMapping = new ServletMappingDD();
-            servletMapping.setServletName(name);
-            servletMapping.setUrlPattern("/PlutoInvoker/" + name);
-
-            webAppDDIn.getServlets().add(servlet);
-            webAppDDIn.getServletMappings().add(servletMapping);
-
-        }
-
-        descriptorSvc.write(webAppDDIn, webXmlOut);
+        WebXmlStreamingAssembly.assembleStream(webXmlIn, portletXmlIn, webXmlOut, dispatchServletClass);
+        
     }
 }

Added: portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/AssemblySink.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/AssemblySink.java?view=auto&rev=539020
==============================================================================
--- portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/AssemblySink.java (added)
+++ portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/AssemblySink.java Thu May 17 10:07:00 2007
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.pluto.util.assemble.ear;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.zip.CRC32;
+import java.util.zip.Checksum;
+
+/**
+ * Used as a temporary container for assembled bytes, and for tracking 
+ * metadata specific to <code>JarEntry</code> objects, especially the
+ * size of the <code>JarEntry</code> and its checksum.
+ */
+abstract class AssemblySink extends FilterOutputStream {
+    
+    /**
+     * The default buffer length used when reading and
+     * writing to the sink.  By default the value is
+     * 4096 bytes.
+     */
+    protected static int DEFAULT_BUFLEN = 4 * 1024; // 4kb
+    
+    /**
+     * The CRC-32 calculator.
+     */
+    protected final Checksum CRC = new CRC32();
+    
+    /**
+     * The number of bytes written to the sink.
+     */
+    protected long count = 0;
+    
+    /**
+     * Constructs a sink with <i>null</i> as an
+     * underlying output stream.
+     */
+    AssemblySink( ) {
+        super(null);
+    }
+    
+    /**
+     * Constructs a sink with <i>out</i> as the
+     * underlying output stream.  Method calls
+     * on the sink are delegated to the underlying
+     * output stream.
+     * 
+     * @param out the underlying output stream.
+     */
+    AssemblySink( OutputStream out ) {
+        super(out);
+    }
+    
+    /**
+     * Obtain the number of bytes written to the sink.
+     * 
+     * @return the number of bytes written to the sink
+     */
+    long getByteCount() {
+        return count;
+    }
+
+    /**
+     * Obtain the checksum of the bytes written to 
+     * the sink to this point.
+     * 
+     * @return the CRC-32 checksum of the bytes in the sink 
+     */
+    long getCrc() {
+        return CRC.getValue();
+    }
+
+    /**
+     * Write out the bytes in the sink to the supplied
+     * output stream, using the default buffer length.
+     * 
+     * @param out the OutputStream the sink should be copied to.
+     * @throws IOException
+     */
+    void writeTo( OutputStream out ) throws IOException {
+        writeTo( out, DEFAULT_BUFLEN );     
+    }
+    
+    /**
+     * Write out the bytes in the sink to the supplied
+     * output stream, using the supplied buffer length.
+     * 
+     * @param out the OutputStream the sink should be copied to.
+     * @param buflen the buffer length used when copying bytes
+     * @throws IOException
+     */
+    abstract void writeTo( OutputStream out, int buflen ) throws IOException;
+
+    public synchronized void write(byte[] b) throws IOException {
+        try {
+            out.write(b);
+            count++;
+            CRC.update( b, 0, b.length );
+        } catch (IOException e) {
+            count = 0;
+            CRC.reset();
+            throw e;
+        }
+    }
+    
+    public synchronized void write(byte[] b, int off, int len) throws IOException {
+        try {
+            out.write(b, off, len);
+            count += len;
+            CRC.update(b, off, len);
+        } catch (IOException e) {
+            count = 0;
+            CRC.reset();
+            throw e;
+        }
+    }
+
+    public synchronized void write(int b) throws IOException {
+        try {
+            out.write(b);
+            count++;
+            CRC.update(b);
+        } catch (IOException e) {
+            count = 0;
+            CRC.reset();
+            throw e;
+        }
+    }
+    
+    /**
+     * Closes the underlying output stream, resets the
+     * checksum calculator, and clears the byte count.
+     */
+    public void close() throws IOException {
+        try {
+            out.close();
+        } finally {
+            CRC.reset();
+            count = 0;
+        }
+    }
+
+}

Added: portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/ByteArrayAssemblySink.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/ByteArrayAssemblySink.java?view=auto&rev=539020
==============================================================================
--- portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/ByteArrayAssemblySink.java (added)
+++ portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/ByteArrayAssemblySink.java Thu May 17 10:07:00 2007
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.pluto.util.assemble.ear;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Stores assembled bytes in an underlying <code>ByteArrayOutputStream</code>
+ */
+class ByteArrayAssemblySink extends AssemblySink {
+    
+    private static final Log LOG = LogFactory.getLog( ByteArrayAssemblySink.class );
+    
+    ByteArrayAssemblySink(ByteArrayOutputStream out) {
+        super(out);
+    }
+    
+    ByteArrayAssemblySink(ByteArrayOutputStream out, int buflen) {
+        this.out = new ByteArrayOutputStream( buflen );
+    }
+    
+    public void writeTo(OutputStream out, int buflen) throws IOException {
+        byte[] buf = new byte[buflen];
+        int read = 0;
+        InputStream sinkReader = new BufferedInputStream( 
+                new ByteArrayInputStream( ((ByteArrayOutputStream)this.out).toByteArray()), buflen);
+        while ( ( read = sinkReader.read(buf) ) != -1 ) {
+            out.write(buf, 0, read);
+        }
+    }
+    
+}

Added: portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/EarAssembler.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/EarAssembler.java?view=auto&rev=539020
==============================================================================
--- portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/EarAssembler.java (added)
+++ portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/EarAssembler.java Thu May 17 10:07:00 2007
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.pluto.util.assemble.ear;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pluto.util.UtilityException;
+import org.apache.pluto.util.assemble.AbstractArchiveAssembler;
+import org.apache.pluto.util.assemble.AssemblerConfig;
+import org.apache.pluto.util.assemble.io.JarStreamingAssembly;
+
+/**
+ * Assembles war files contained inside of an EAR.  War files that do
+ * not contain a portlet.xml are not assembled.  All files are copied
+ * into the destination archive.
+ */
+public class EarAssembler extends AbstractArchiveAssembler {
+
+    private static final Log LOG = LogFactory.getLog( EarAssembler.class );
+    private static final int BUFLEN = 1024 * 8; // 8kb
+    
+    public void assembleInternal( AssemblerConfig config ) throws UtilityException, IOException {
+
+        File source = config.getSource();
+        File dest = config.getDestination();
+
+        JarInputStream earIn = new JarInputStream( new FileInputStream( source ) );
+        JarOutputStream earOut = new JarOutputStream(
+                new BufferedOutputStream( new FileOutputStream( dest ), BUFLEN ) );
+        
+        try {
+            
+            JarEntry entry;
+            
+            // Iterate over entries in the EAR archive
+            while ( ( entry = earIn.getNextJarEntry() ) != null ) {
+                
+                // If a war file is encountered, assemble it into a
+                // ByteArrayOutputStream and write the assembled bytes
+                // back to the EAR archive.
+                if ( entry.getName().toLowerCase().endsWith( ".war" ) ) {                                        
+                    
+                    if ( LOG.isDebugEnabled() ) {
+                        LOG.debug( "Assembling war file " + entry.getName() );
+                    }
+                    
+                    // keep a handle to the AssemblySink so we can write out
+                    // JarEntry metadata and the bytes later.
+                    AssemblySink warBytesOut = getAssemblySink( config, entry );
+                    JarOutputStream warOut = new JarOutputStream( warBytesOut );
+                    
+                    JarStreamingAssembly.assembleStream( new JarInputStream( earIn ), warOut,
+                            config.getDispatchServletClass() );
+                    
+                    JarEntry warEntry = new JarEntry( entry );
+                    
+                    // Write out the assembled JarEntry metadata
+                    warEntry.setSize( warBytesOut.getByteCount() );
+                    warEntry.setCrc( warBytesOut.getCrc() );
+                    warEntry.setCompressedSize( -1 );                    
+                    earOut.putNextEntry( warEntry );
+
+                    // Write out the assembled WAR file to the EAR
+                    warBytesOut.writeTo( earOut );
+
+                    earOut.flush();
+                    earOut.closeEntry();
+                    earIn.closeEntry();
+                    
+                } else {
+                    
+                    earOut.putNextEntry( entry );
+                    IOUtils.copy( earIn, earOut );
+                    
+                    earOut.flush();
+                    earOut.closeEntry();
+                    earIn.closeEntry();
+                    
+                }
+            }            
+            
+        } finally {
+            
+            earOut.close();
+            earIn.close();
+            
+        }
+    }
+    
+    /**
+     * Obtain a sink used as a temporary container for assembled war bytes.  By default a
+     * filesystem based sink is used.
+     * 
+     * @param config the AssemblerConfig
+     * @param entry the JarEntry
+     * @return the AssemblySink
+     * @throws IOException
+     */
+    protected AssemblySink getAssemblySink( AssemblerConfig config, JarEntry entry ) throws IOException {
+        File f = File.createTempFile( "earAssemblySink", "tmp" );
+        f.deleteOnExit();
+        return getFileAssemblySink( entry, f );
+    }
+    
+    private AssemblySink getByteArrayAssemblySink( JarEntry entry ) {
+        // Create a buffer the size of the warfile, plus a little extra, to 
+        // account for the additional bytes added to web.xml as a result of
+        // assembly.
+        
+        ByteArrayAssemblySink warBytesOut = null;
+        int defaultBuflen = 1024 * 1024 * 10; // 10Mb
+        int assemblyBuflen = 1024 * 32; // 32kb additional bytes for assembly
+        
+        
+        // ByteArrayOutputStream grows the buffer by a left bitshift each time
+        // its internal buffer would overflow.  The goal is to prevent the
+        // buffer from overflowing, otherwise the exponential growth of
+        // the internal buffer can cause OOM errors.
+        
+        // note that we can only optimize the buffer for file sizes less than 
+        // Integer.MAX_VALUE - assemblyBuf
+        if ( entry.getSize() > ( Integer.MAX_VALUE - assemblyBuflen ) || entry.getSize() < 1 ) {
+            warBytesOut = new ByteArrayAssemblySink( new ByteArrayOutputStream( defaultBuflen ) );
+        } else {
+            int buflen = (int) entry.getSize() + assemblyBuflen;
+            warBytesOut = new ByteArrayAssemblySink( new ByteArrayOutputStream( buflen ) );
+        }
+        
+        return warBytesOut;
+    }
+    
+    private AssemblySink getFileAssemblySink( JarEntry e, File f ) {
+        AssemblySink sink = null;    
+        try {
+            sink = new FileAssemblySink( f );
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+        return sink;
+    }
+
+}

Added: portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/FileAssemblySink.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/FileAssemblySink.java?view=auto&rev=539020
==============================================================================
--- portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/FileAssemblySink.java (added)
+++ portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/ear/FileAssemblySink.java Thu May 17 10:07:00 2007
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.pluto.util.assemble.ear;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Stores assembled bytes in an underlying <code>File</code>.
+ */
+class FileAssemblySink extends AssemblySink {
+    
+    private static final Log LOG = LogFactory.getLog( FileAssemblySink.class );
+    private File sink = null;
+    
+    FileAssemblySink(File file) throws FileNotFoundException {
+        super(new FileOutputStream(file));
+        this.sink = file;        
+    }
+    
+    public void writeTo(OutputStream out, int buflen) throws IOException {
+        byte[] buf = new byte[buflen];
+        int read = 0;
+        InputStream sinkReader = new BufferedInputStream( 
+                new FileInputStream(sink), buflen );
+        while ( ( read = sinkReader.read(buf) ) != -1 ) {
+            out.write(buf, 0, read);
+        }
+    }
+    
+}

Added: portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/io/JarStreamingAssembly.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/io/JarStreamingAssembly.java?view=auto&rev=539020
==============================================================================
--- portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/io/JarStreamingAssembly.java (added)
+++ portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/io/JarStreamingAssembly.java Thu May 17 10:07:00 2007
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.pluto.util.assemble.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+import java.util.zip.CRC32;
+import java.util.zip.ZipEntry;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pluto.util.assemble.Assembler;
+
+/** 
+ * Utility class responsible for accepting a JarInputStream representing a web application archive,
+ * iterating over each JarEntry in the input stream and assembling the WAR web.xml for portlet
+ * deployment.
+ */
+public class JarStreamingAssembly {
+    
+    private static final Log LOG = LogFactory.getLog( JarStreamingAssembly.class );
+
+    /**
+     * Reads the source JarInputStream, copying entries to the destination JarOutputStream. 
+     * The web.xml and portlet.xml are cached, and after the entire archive is copied 
+     * (minus the web.xml) a re-written web.xml is generated and written to the 
+     * destination JAR.
+     * 
+     * @param source the WAR source input stream
+     * @param dest the WAR destination output stream
+     * @param dispatchServletClass the name of the dispatch class
+     * @throws IOException
+     */
+    public static void assembleStream(JarInputStream source, JarOutputStream dest, String dispatchServletClass) throws IOException {
+        
+        try {
+            //Need to buffer the web.xml and portlet.xml files for the rewritting
+            JarEntry servletXmlEntry = null;
+            byte[] servletXmlBuffer = null;
+            byte[] portletXmlBuffer = null;
+
+            JarEntry originalJarEntry;                         
+            
+            //Read the source archive entry by entry
+            while ((originalJarEntry = source.getNextJarEntry()) != null) {
+
+                final JarEntry newJarEntry = smartClone(originalJarEntry);
+                originalJarEntry = null;
+
+                //Capture the web.xml JarEntry and contents as a byte[], don't write it out now or
+                //update the CRC or length of the destEntry.
+                if (Assembler.SERVLET_XML.equals(newJarEntry.getName())) {
+                    servletXmlEntry = newJarEntry;
+                    servletXmlBuffer = IOUtils.toByteArray(source);
+                }
+                
+                //Capture the portlet.xml contents as a byte[]
+                else if (Assembler.PORTLET_XML.equals(newJarEntry.getName())) {
+                    portletXmlBuffer = IOUtils.toByteArray(source);
+                    dest.putNextEntry(newJarEntry);
+                    IOUtils.write(portletXmlBuffer, dest);
+                }
+                
+                //Copy all other entries directly to the output archive
+                else {
+                    dest.putNextEntry(newJarEntry);
+                    IOUtils.copy(source, dest);                    
+                }      
+                    
+                dest.closeEntry();
+                dest.flush();
+
+            }
+
+            // If no portlet.xml was found in the archive, skip the assembly step.
+            if (portletXmlBuffer != null) {
+                // container for assembled web.xml bytes
+                final byte[] webXmlBytes;
+                
+                // Checks to make sure the web.xml was found in the archive
+                if (servletXmlBuffer == null) {
+                    throw new FileNotFoundException("File '" + Assembler.SERVLET_XML + "' could not be found in the source input stream.");
+                }
+
+                //Create streams of the byte[] data for the updater method
+                final InputStream webXmlIn = new ByteArrayInputStream(servletXmlBuffer);
+                final InputStream portletXmlIn = new ByteArrayInputStream(portletXmlBuffer);
+                final ByteArrayOutputStream webXmlOut = new ByteArrayOutputStream(servletXmlBuffer.length);
+
+                //Update the web.xml
+                WebXmlStreamingAssembly.assembleStream(webXmlIn, portletXmlIn, webXmlOut, dispatchServletClass);
+                IOUtils.copy( webXmlIn, webXmlOut );
+                webXmlBytes = webXmlOut.toByteArray();
+                
+                //If no compression is being used (STORED) we have to manually update the size and crc
+                if (servletXmlEntry.getMethod() == ZipEntry.STORED) {
+                    servletXmlEntry.setSize(webXmlBytes.length);
+                    final CRC32 webXmlCrc = new CRC32();
+                    webXmlCrc.update(webXmlBytes);
+                    servletXmlEntry.setCrc(webXmlCrc.getValue());
+                }
+
+                //write out the assembled web.xml entry and contents
+                dest.putNextEntry(servletXmlEntry);
+                IOUtils.write(webXmlBytes, dest);
+                
+                if ( LOG.isDebugEnabled() ) {
+                    LOG.debug( "Jar stream " + source + " successfully assembled." );
+                }
+            } else {                
+                if ( LOG.isDebugEnabled() ) {
+                    LOG.debug( "No portlet XML file was found, assembly was not required." );
+                }                
+
+                //copy the original, unmodified web.xml entry to the destination
+                dest.putNextEntry(servletXmlEntry);
+                IOUtils.write(servletXmlBuffer, dest);
+                
+                if ( LOG.isDebugEnabled() ) {
+                    LOG.debug( "Jar stream " + source + " successfully assembled." );
+                }
+            }            
+            
+        } finally {
+            
+            dest.flush();
+            dest.close();
+            
+        }
+    }
+    
+    private static JarEntry smartClone(JarEntry originalJarEntry) {
+        final JarEntry newJarEntry = new JarEntry(originalJarEntry.getName());
+        newJarEntry.setComment(originalJarEntry.getComment());
+        newJarEntry.setExtra(originalJarEntry.getExtra());
+        newJarEntry.setMethod(originalJarEntry.getMethod());
+        newJarEntry.setTime(originalJarEntry.getTime());
+
+        //Must set size and CRC for STORED entries
+        if (newJarEntry.getMethod() == ZipEntry.STORED) {
+            newJarEntry.setSize(originalJarEntry.getSize());
+            newJarEntry.setCrc(originalJarEntry.getCrc());
+        }
+
+        return newJarEntry;
+    }
+
+}

Added: portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/io/WebXmlStreamingAssembly.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/io/WebXmlStreamingAssembly.java?view=auto&rev=539020
==============================================================================
--- portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/io/WebXmlStreamingAssembly.java (added)
+++ portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/io/WebXmlStreamingAssembly.java Thu May 17 10:07:00 2007
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.pluto.util.assemble.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Iterator;
+
+import org.apache.pluto.descriptors.common.InitParamDD;
+import org.apache.pluto.descriptors.portlet.PortletAppDD;
+import org.apache.pluto.descriptors.portlet.PortletDD;
+import org.apache.pluto.descriptors.services.PortletAppDescriptorService;
+import org.apache.pluto.descriptors.services.WebAppDescriptorService;
+import org.apache.pluto.descriptors.services.castor.PortletAppDescriptorServiceImpl;
+import org.apache.pluto.descriptors.services.castor.WebAppDescriptorServiceImpl;
+import org.apache.pluto.descriptors.servlet.LoadOnStartupDD;
+import org.apache.pluto.descriptors.servlet.ServletDD;
+import org.apache.pluto.descriptors.servlet.ServletMappingDD;
+import org.apache.pluto.descriptors.servlet.WebAppDD;
+import org.apache.pluto.util.assemble.Assembler;
+
+/** 
+ * Utility class responsible for accepting web.xml and portlet.xml as InputStreams, and assembling
+ * the web.xml to an OutputStream.
+ */
+public class WebXmlStreamingAssembly {
+    
+    /**
+     * Assembles the web.xml represented by the <code>InputStream</code>.
+     * 
+     * @param webXmlIn the unassembled web.xml file
+     * @param portletXmlIn the corresponding portlet.xml file
+     * @param assembledWebXmlOut the assembled web.xml file
+     * @param dispatchServletClass the dispatch servlet
+     * @throws IOException
+     */
+    public static void assembleStream(InputStream webXmlIn,
+                                InputStream portletXmlIn, 
+                                OutputStream assembledWebXmlOut, 
+                                String dispatchServletClass) 
+    throws IOException {
+        if (dispatchServletClass == null ||
+                dispatchServletClass.length() == 0 ||
+                dispatchServletClass.trim().length() == 0) {
+            dispatchServletClass = Assembler.DISPATCH_SERVLET_CLASS;
+        }
+
+      WebAppDescriptorService descriptorSvc = new WebAppDescriptorServiceImpl();  
+      PortletAppDescriptorService portletAppDescriptorSvc = new PortletAppDescriptorServiceImpl();
+        
+        WebAppDD webAppDDIn = descriptorSvc.read(webXmlIn);
+        PortletAppDD portletAppDD = portletAppDescriptorSvc.read(portletXmlIn);
+        portletXmlIn.close();
+
+        for (Iterator it = portletAppDD.getPortlets().iterator();
+                it.hasNext(); ) {
+
+            // Read portlet definition.
+            PortletDD portlet = (PortletDD) it.next();
+            String name = portlet.getPortletName();
+
+            ServletDD servlet = new ServletDD();
+            servlet.setServletName(name);
+
+            servlet.setServletClass(dispatchServletClass);
+
+            InitParamDD initParam = new InitParamDD();
+            initParam.setParamName("portlet-name");
+            initParam.setParamValue(name);
+            servlet.getInitParams().add(initParam);
+
+            LoadOnStartupDD onStartup = new LoadOnStartupDD();
+            onStartup.setPriority(1);
+            servlet.setLoadOnStartup(onStartup);
+
+            ServletMappingDD servletMapping = new ServletMappingDD();
+            servletMapping.setServletName(name);
+            servletMapping.setUrlPattern("/PlutoInvoker/" + name);
+
+            webAppDDIn.getServlets().add(servlet);
+            webAppDDIn.getServletMappings().add(servletMapping);
+
+        }
+
+        descriptorSvc.write(webAppDDIn, assembledWebXmlOut);
+        
+    }
+}

Modified: portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/war/WarAssembler.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/war/WarAssembler.java?view=diff&rev=539020&r1=539019&r2=539020
==============================================================================
--- portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/war/WarAssembler.java (original)
+++ portals/pluto/branches/pluto-1.1.x/pluto-util/src/main/java/org/apache/pluto/util/assemble/war/WarAssembler.java Thu May 17 10:07:00 2007
@@ -16,33 +16,25 @@
  */
 package org.apache.pluto.util.assemble.war;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.util.jar.JarEntry;
 import java.util.jar.JarInputStream;
 import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
-import java.util.zip.CRC32;
-import java.util.zip.ZipEntry;
 
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
 import org.apache.pluto.util.UtilityException;
+import org.apache.pluto.util.assemble.AbstractArchiveAssembler;
 import org.apache.pluto.util.assemble.AssemblerConfig;
-import org.apache.pluto.util.assemble.WebXmlRewritingAssembler;
+import org.apache.pluto.util.assemble.io.JarStreamingAssembly;
 
 /**
  *
  * @version 1.0
  * @since Nov 8, 2004
  */
-public class WarAssembler extends WebXmlRewritingAssembler {
+public class WarAssembler extends AbstractArchiveAssembler {
     // Constructor -------------------------------------------------------------
 
     /**
@@ -55,28 +47,11 @@
 
     // Assembler Impl ----------------------------------------------------------
 
-    public void assemble(AssemblerConfig config) throws UtilityException {
-        try {
-            final File sourceArchive = config.getWarSource();
-            final File destinationFolder = config.getDestination();
-            final File destinationArchive = new File(destinationFolder, sourceArchive.getName());
-
-            //If the source and dest are the same a temp location is needed
-            if (sourceArchive.equals(destinationArchive)) {
-                final File tempArchive = File.createTempFile(sourceArchive.getName() + ".", ".tmp");
-                this.assembleWar(sourceArchive, tempArchive, config.getDispatchServletClass());
-
-                //Move the temp file to the destination location
-                destinationArchive.delete();
-                tempArchive.renameTo(destinationArchive);
-            }
-            else {
-                this.assembleWar(sourceArchive, destinationArchive, config.getDispatchServletClass());
-            }
-
-        } catch (IOException ex) {
-            throw new UtilityException(ex.getMessage(), ex, null);
-        }
+    public void assembleInternal(AssemblerConfig config) 
+        throws UtilityException, IOException {
+        
+        this.assembleWar(config.getSource(), config.getDestination(), config.getDispatchServletClass());
+        
     }
 
     /**
@@ -86,98 +61,18 @@
      */
     protected void assembleWar(File source, File dest, String dispatchServletClass) throws IOException {
         final JarInputStream jarIn = new JarInputStream(new FileInputStream(source));
-
-        try {
-            //Create the output JAR stream, copying the Manifest
-            final Manifest manifest = jarIn.getManifest();
-            //TODO add pluto notes to the Manifest?
-            FileUtils.forceMkdir(dest.getParentFile());
-            final JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(dest), manifest);
-
-            try {
-                //Need to buffer the web.xml and portlet.xml files for the rewritting
-                JarEntry servletXmlEntry = null;
-                byte[] servletXmlBuffer = null;
-                byte[] portletXmlBuffer = null;
-
-                //Read the source archive entry by entry
-                JarEntry originalJarEntry;
-                while ((originalJarEntry = jarIn.getNextJarEntry()) != null) {
-                    final JarEntry newJarEntry = this.smartClone(originalJarEntry);
-
-                    //Capture the web.xml JarEntry and contents as a byte[], don't write it out now
-                    if (SERVLET_XML.equals(newJarEntry.getName())) {
-                        servletXmlEntry = newJarEntry;
-                        servletXmlBuffer = IOUtils.toByteArray(jarIn);
-                    }
-                    //Capture the portlet.xml contents as a byte[]
-                    else if (PORTLET_XML.equals(newJarEntry.getName())) {
-                        portletXmlBuffer = IOUtils.toByteArray(jarIn);
-                        jarOut.putNextEntry(newJarEntry);
-                        IOUtils.write(portletXmlBuffer, jarOut);
-                    }
-                    //Copy all other entries directly to the output archive
-                    else {
-                        jarOut.putNextEntry(newJarEntry);
-                        IOUtils.copy(jarIn, jarOut);
-                    }
-                }
-
-                //Checks to make sure the web.xml and portlet.xml were found
-                if (servletXmlBuffer == null) {
-                    throw new FileNotFoundException("File '" + SERVLET_XML + "' could not be found in the archive '" + source + "'");
-                }
-                if (portletXmlBuffer == null) {
-                    throw new FileNotFoundException("File '" + PORTLET_XML + "' could not be found in the archive '" + source + "'");
-                }
-
-                //Create streams of the byte[] data for the updater method
-                final InputStream webXmlIn = new ByteArrayInputStream(servletXmlBuffer);
-                final InputStream portletXmlIn = new ByteArrayInputStream(portletXmlBuffer);
-                final ByteArrayOutputStream webXmlOut = new ByteArrayOutputStream(servletXmlBuffer.length);
-
-                //Update the web.xml
-                this.updateWebappDescriptor(webXmlIn, portletXmlIn, webXmlOut, dispatchServletClass);
-                final byte[] webXmlBytes = webXmlOut.toByteArray();
-
-                //If no compression is being used (STORED) we have to manually update the size and crc
-                if (servletXmlEntry.getMethod() == ZipEntry.STORED) {
-                    servletXmlEntry.setSize(webXmlBytes.length);
-
-                    final CRC32 webXmlCrc = new CRC32();
-                    webXmlCrc.update(webXmlBytes);
-                    servletXmlEntry.setCrc(webXmlCrc.getValue());
-                }
-
-                //write out the web.xml entry and contents
-                jarOut.putNextEntry(servletXmlEntry);
-                IOUtils.write(webXmlBytes, jarOut);
-            }
-            finally {
-                jarOut.flush();
-                jarOut.close();
-            }
-        }
-        finally {
+        //Create the output JAR stream, copying the Manifest
+        final Manifest manifest = jarIn.getManifest();
+        //TODO add pluto notes to the Manifest?
+        final JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(dest), manifest);
+        
+        try {            
+            JarStreamingAssembly.assembleStream(jarIn, jarOut, dispatchServletClass);
+        } finally {
             jarIn.close();
+            jarOut.close();
         }
     }
 
-
-    private JarEntry smartClone(JarEntry originalJarEntry) {
-        final JarEntry newJarEntry = new JarEntry(originalJarEntry.getName());
-        newJarEntry.setComment(originalJarEntry.getComment());
-        newJarEntry.setExtra(originalJarEntry.getExtra());
-        newJarEntry.setMethod(originalJarEntry.getMethod());
-        newJarEntry.setTime(originalJarEntry.getTime());
-
-        //Must set size and CRC for STORED entries
-        if (newJarEntry.getMethod() == ZipEntry.STORED) {
-            newJarEntry.setSize(originalJarEntry.getSize());
-            newJarEntry.setCrc(originalJarEntry.getCrc());
-        }
-
-        return newJarEntry;
-    }
 }
 



Mime
View raw message