You are viewing a plain text version of this content. The canonical link for it is here.
Posted to pluto-scm@portals.apache.org by dd...@apache.org on 2005/07/30 06:15:12 UTC

svn commit: r226469 - /portals/pluto/branches/pluto-1.1/pluto-deploy/src/main/java/org/apache/pluto/deploy/impl/ArchivedFileAssembler.java

Author: ddewolf
Date: Fri Jul 29 21:15:07 2005
New Revision: 226469

URL: http://svn.apache.org/viewcvs?rev=226469&view=rev
Log:
Applying patch from Zhong ZHENG.  Thank you.  Completing the ArchivedFileAssembler.java implementation.

Modified:
    portals/pluto/branches/pluto-1.1/pluto-deploy/src/main/java/org/apache/pluto/deploy/impl/ArchivedFileAssembler.java

Modified: portals/pluto/branches/pluto-1.1/pluto-deploy/src/main/java/org/apache/pluto/deploy/impl/ArchivedFileAssembler.java
URL: http://svn.apache.org/viewcvs/portals/pluto/branches/pluto-1.1/pluto-deploy/src/main/java/org/apache/pluto/deploy/impl/ArchivedFileAssembler.java?rev=226469&r1=226468&r2=226469&view=diff
==============================================================================
--- portals/pluto/branches/pluto-1.1/pluto-deploy/src/main/java/org/apache/pluto/deploy/impl/ArchivedFileAssembler.java (original)
+++ portals/pluto/branches/pluto-1.1/pluto-deploy/src/main/java/org/apache/pluto/deploy/impl/ArchivedFileAssembler.java Fri Jul 29 21:15:07 2005
@@ -17,13 +17,8 @@
 
 import org.w3c.dom.Document;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.Map;
+import java.io.*;
+import java.util.*;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 import java.util.jar.JarOutputStream;
@@ -31,16 +26,22 @@
 /**
  * Used to assemble a web application into a portlet application.
  *
- * @author <a href="ddewolf@apache.org">David H. DeWolf</a>
+ * @author <a href="mailto:ddewolf@apache.org">David H. DeWolf</a>
+ * @author <a href="mailto:heavyzheng@gmail.com">Zhong ZHENG</a>
  * @version 1.0
  * @since Oct 15, 2004
  */
 public class ArchivedFileAssembler extends AbstractAssembler {
 
+    private static final String SUFFIX = ".tmp";
+    private static final int BUFFER_SIZE = 2048;
+
     private JarFile war;
     private File destination;
 
-    private Map entries  = new java.util.HashMap();
+    private Map documents = new HashMap();
+    private Map streams = new HashMap();
+
 
     public ArchivedFileAssembler(JarFile war, File destination) {
         this.war = war;
@@ -59,46 +60,148 @@
 
     protected void setWebResource(String name, InputStream in)
     throws IOException {
-
+        streams.put(name, in);
     }
 
     protected void setWebResource(String name, Document doc)
     throws IOException {
-
+    	documents.put(name, doc);
     }
 
 
     protected void close() throws IOException  {
-        File file = new File(destination+".tmp");
-        FileOutputStream fout = new FileOutputStream(file);
-        JarOutputStream out = new JarOutputStream(fout);
-
-        Enumeration enumeration = war.entries();
-        while(enumeration.hasMoreElements()) {
-            JarEntry entry = (JarEntry)enumeration.nextElement();
-            entry = new JarEntry(entry.getName());
-            InputStream is = null;
-            if(!entries.containsKey(entry.getName())) {
-                is = war.getInputStream(entry);
-                out.putNextEntry(new JarEntry(entry));
-                save(is, out);
+
+    	// ensure temporary directory.
+        File tempDir = new File(destination + SUFFIX);
+        long tempId = 0;
+        while (tempDir.exists()) {
+        	tempDir = new File(destination + SUFFIX + String.valueOf(tempId));
+        	tempId++;
+        }
+        tempDir.mkdirs();
+
+        // copy files from original WAR.
+        for (Enumeration en = war.entries(); en.hasMoreElements(); ) {
+            JarEntry entry = (JarEntry) en.nextElement();
+            if (entry.isDirectory()) {
+            	File dir = new File(tempDir, entry.getName());
+            	dir.mkdirs();
+            } else if (!documents.containsKey(entry.getName()) &&
+            		!streams.containsKey(entry.getName())) {
+                File destFile = new File(tempDir, entry.getName());
+                destFile.getParentFile().mkdirs();
+                FileOutputStream fout = new FileOutputStream(destFile);
+            	InputStream is = war.getInputStream(entry);
+            	save(is, fout);
             }
         }
 
-        Iterator it = entries.keySet().iterator();
-        while(it.hasNext()) {
+        // copy updated files.
+        for (Iterator it = documents.keySet().iterator(); it.hasNext(); ) {
             String name = it.next().toString();
-            InputStream in = (InputStream)entries.get(name);
-            out.putNextEntry(new JarEntry(name));
-            save(in, out);
+            Document doc = (Document) documents.get(name);
+            File destFile = new File(tempDir, name);
+            destFile.getParentFile().mkdirs();
+            OutputStream out = new FileOutputStream(destFile);
+            save(doc, out);
         }
-        out.flush();
-        out.close();
 
-        destination.delete();
-        file.renameTo(destination);
-        file.delete();
+        for (Iterator it = streams.keySet().iterator(); it.hasNext(); ) {
+            String name = it.next().toString();
+            InputStream is = (InputStream) streams.get(name);
+            File destFile = new File(tempDir, name);
+            destFile.getParentFile().mkdirs();
+            OutputStream out = new FileOutputStream(destFile);
+            save(is, out);
+        }
+
+        // archive contents of the temporary directory to destination war.
+        jar(tempDir, destination);
+        deleteRecursive(tempDir);
     }
+
+    /**
+     * Archive the source directory to a WAR file.
+     *
+     * @param sourceDir  source directory to archive
+     * @param warFile  destination WAR file
+     * @throws IOException
+     */
+    private void jar(File sourceDir, File warFile)
+    throws IOException {
+    	if (warFile.exists()) {
+    		deleteRecursive(warFile);
+    	}
+    	JarOutputStream jout = new JarOutputStream(new BufferedOutputStream(
+    			new FileOutputStream(warFile)));
+    	List fileList = listRecursive(sourceDir);
+    	String[] fileNames = (String[]) fileList.toArray(
+    			new String[fileList.size()]);
+
+    	byte[] data = new byte[BUFFER_SIZE];
+    	for (int i = 0; i < fileNames.length; i++) {
+    		File sourceFile = new File(sourceDir, fileNames[i]);
+    		if (sourceFile.isFile()) {
+    			JarEntry entry = new JarEntry(fileNames[i]);
+        		jout.putNextEntry(entry);
+    			BufferedInputStream is = new BufferedInputStream(
+    					new FileInputStream(sourceFile));
+    			int count;
+    			while ((count = is.read(data, 0, BUFFER_SIZE)) != -1) {
+    				jout.write(data, 0, count);
+    			}
+    			is.close();
+    		}
+    	}
+    	jout.close();
+    }
+
+    /**
+     * List all files under the given directory recursively. This method's
+     * behavior is different from <code>File.list()</list> in two aspects:
+     * 1. All files are listed recursively; 2. sub directories are ignored.
+     *
+     * @param dir  directory whose files are to be listed
+     * @return a list of String containing relative file paths to the directory
+     */
+    private List listRecursive(File dir) {
+    	return listRecursive(dir, "");
+    }
+
+
+    private List listRecursive(File dir, String prefix) {
+    	List fileNameList = new ArrayList();
+    	String[] fileNames = dir.list();
+    	for (int i = 0; i < fileNames.length; i++) {
+    		File file = new File(dir, fileNames[i]);
+    		if (file.isFile()) {
+    			fileNameList.add(prefix + fileNames[i]);
+    		} else {
+    			String subDirName = file.getName();
+    			List subList = listRecursive(file,
+    					prefix + subDirName + File.separator);
+    			fileNameList.addAll(subList);
+    		}
+    	}
+    	return fileNameList;
+    }
+
+    /**
+     * Delete file. If given file is a regular file, it is deleted. If it is
+     * a directory, its all contents and itself are deleted recursively.
+     *
+     * @param file  file to delete
+     */
+    private void deleteRecursive(File file) {
+    	if (file.isDirectory()) {
+    		File[] files = file.listFiles();
+    		for (int i = 0; i < files.length; i++) {
+    			deleteRecursive(files[i]);
+    		}
+    	}
+    	file.delete();
+    }
+
 }