You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ga...@apache.org on 2010/02/17 17:31:58 UTC

svn commit: r911057 - in /incubator/aries/trunk/web/web-urlhandler/src/main/java/org/apache/aries/web/converter/impl: CachedOutputStream.java WarToWabConverterImpl.java

Author: gawor
Date: Wed Feb 17 16:31:58 2010
New Revision: 911057

URL: http://svn.apache.org/viewvc?rev=911057&view=rev
Log:
ARIES-176: Store wab contents in a file if size of the source war exceeds certain threshold (64K now). Also, separate the process of creating the wab into two steps: 1) generating the manifest and 2) copying the war contents into wab

Added:
    incubator/aries/trunk/web/web-urlhandler/src/main/java/org/apache/aries/web/converter/impl/CachedOutputStream.java   (with props)
Modified:
    incubator/aries/trunk/web/web-urlhandler/src/main/java/org/apache/aries/web/converter/impl/WarToWabConverterImpl.java

Added: incubator/aries/trunk/web/web-urlhandler/src/main/java/org/apache/aries/web/converter/impl/CachedOutputStream.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/web/web-urlhandler/src/main/java/org/apache/aries/web/converter/impl/CachedOutputStream.java?rev=911057&view=auto
==============================================================================
--- incubator/aries/trunk/web/web-urlhandler/src/main/java/org/apache/aries/web/converter/impl/CachedOutputStream.java (added)
+++ incubator/aries/trunk/web/web-urlhandler/src/main/java/org/apache/aries/web/converter/impl/CachedOutputStream.java Wed Feb 17 16:31:58 2010
@@ -0,0 +1,140 @@
+/**
+ * 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.aries.web.converter.impl;
+
+import java.io.BufferedOutputStream;
+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.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+public class CachedOutputStream extends OutputStream {
+
+    private static final int DEFAULT_THRESHOLD = 64 * 1024;
+    
+    private OutputStream currentStream;
+    private long threshold;
+    private int totalLength;
+    private boolean inmem;
+    private List<InputStream> streams;
+    private File tempFile;
+    private File outputDir;
+
+    public CachedOutputStream() {
+        this(DEFAULT_THRESHOLD, null);
+    }
+
+    public CachedOutputStream(long threshold, File outputDir) {
+        this.threshold = threshold; 
+        this.outputDir = outputDir;
+        this.currentStream = new ByteArrayOutputStream(2048);
+        this.inmem = true;
+        this.streams = new ArrayList<InputStream>(1);
+    }
+
+    public void flush() throws IOException {
+        currentStream.flush();
+    }
+    
+    public void close() throws IOException {
+        currentStream.flush();       
+        currentStream.close();
+    }
+
+    public void write(byte[] b) throws IOException {
+        write(b, 0, b.length);
+    }
+    
+    public void write(byte[] b, int off, int len) throws IOException {
+        totalLength += len;
+        if (inmem && totalLength > threshold) {
+            createFileOutputStream();
+        }
+        currentStream.write(b, off, len);
+    }
+
+    public void write(int b) throws IOException {
+        totalLength++;
+        if (inmem && totalLength > threshold) {
+            createFileOutputStream();
+        }
+        currentStream.write(b);
+    }
+
+    private void createFileOutputStream() throws IOException {
+        ByteArrayOutputStream bout = (ByteArrayOutputStream) currentStream;
+        if (outputDir == null) {
+            tempFile = File.createTempFile("cos", "tmp");
+        } else {
+            tempFile = File.createTempFile("cos", "tmp", outputDir);
+        }
+        
+        currentStream = new BufferedOutputStream(new FileOutputStream(tempFile));
+        bout.writeTo(currentStream);
+        inmem = false;
+    }
+
+    public void destroy() {
+        streams.clear();
+        if (tempFile != null) {
+            tempFile.delete();
+        }
+    }
+    
+    public int size() {
+        return totalLength;
+    }
+    
+    public InputStream getInputStream() throws IOException {
+        close();
+        if (inmem) {
+            return new ByteArrayInputStream(((ByteArrayOutputStream) currentStream).toByteArray());
+        } else {
+            try {
+                FileInputStream fileInputStream = new FileInputStream(tempFile) {
+                    public void close() throws IOException {
+                        super.close();
+                        maybeDeleteTempFile(this);
+                    }
+                };
+                streams.add(fileInputStream);
+                return fileInputStream;
+            } catch (FileNotFoundException e) {
+                throw new IOException("Cached file was deleted, " + e.toString());
+            }
+        }
+    }
+    
+    private void maybeDeleteTempFile(Object stream) {
+        streams.remove(stream);
+        if (tempFile != null && streams.isEmpty()) {
+            tempFile.delete();
+            tempFile = null;
+        }
+    }
+
+}

Propchange: incubator/aries/trunk/web/web-urlhandler/src/main/java/org/apache/aries/web/converter/impl/CachedOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/aries/trunk/web/web-urlhandler/src/main/java/org/apache/aries/web/converter/impl/CachedOutputStream.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: incubator/aries/trunk/web/web-urlhandler/src/main/java/org/apache/aries/web/converter/impl/CachedOutputStream.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: incubator/aries/trunk/web/web-urlhandler/src/main/java/org/apache/aries/web/converter/impl/WarToWabConverterImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/web/web-urlhandler/src/main/java/org/apache/aries/web/converter/impl/WarToWabConverterImpl.java?rev=911057&r1=911056&r2=911057&view=diff
==============================================================================
--- incubator/aries/trunk/web/web-urlhandler/src/main/java/org/apache/aries/web/converter/impl/WarToWabConverterImpl.java (original)
+++ incubator/aries/trunk/web/web-urlhandler/src/main/java/org/apache/aries/web/converter/impl/WarToWabConverterImpl.java Wed Feb 17 16:31:58 2010
@@ -20,8 +20,6 @@
 
 import static org.apache.aries.web.converter.WarToWabConverter.WEB_CONTEXT_PATH;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -66,13 +64,11 @@
   private CaseInsensitiveMap properties;
 
   // InputStream for the new WAB file
-  private byte[] wabFile;
+  private CachedOutputStream wab;
   private Manifest wabManifest;
   private String warName;
   private InputStreamProvider input;
   
-  private boolean converted = false;
-
   // State used for updating the manifest
   private Set<String> importPackages;
   private Set<String> exemptPackages;
@@ -92,11 +88,13 @@
     this.warName = name;
   }
     
-  private void convert() throws IOException {
-
-    ZipEntry entry;
+  private void generateManifest() throws IOException {
+    if (wabManifest != null) {
+        // WAB manifest is already generated
+        return;
+    }
+    
     JarInputStream jarInput = null;
-
     try {
       jarInput = new JarInputStream(input.getInputStream());
       Manifest manifest = jarInput.getManifest();
@@ -111,11 +109,20 @@
     finally {
       try { if (jarInput != null) jarInput.close(); } catch (IOException e) { e.printStackTrace(); }
     }
+  }
 
-    // Create a new jar file in memory with the new manifest and the old data
-    ByteArrayOutputStream output = new ByteArrayOutputStream();
+  private void convert() throws IOException {
+    if (wab != null) {
+        // WAB is already converted
+        return;
+    }
+    
+    generateManifest();
+    
+    CachedOutputStream output = new CachedOutputStream();
     JarOutputStream jarOutput = null;
-    jarInput = null;
+    JarInputStream jarInput = null;
+    ZipEntry entry = null;
 
     // Copy across all entries from the original jar
     int val;
@@ -125,19 +132,21 @@
       byte[] buffer = new byte[2048];
       while ((entry = jarInput.getNextEntry()) != null) {
         jarOutput.putNextEntry(entry);        
-        while ((val = jarInput.read(buffer)) > 0)
+        while ((val = jarInput.read(buffer)) > 0) {
           jarOutput.write(buffer, 0, val);
+        }
       }
     }
     finally {
-      if (jarOutput != null)
+      if (jarOutput != null) {
         jarOutput.close();
-      if (jarInput != null)
+      }
+      if (jarInput != null) {
         jarInput.close();
+      }
     }
-
-    // Create a stream to the in-memory jar
-    wabFile = output.toByteArray();
+    
+    wab = output;
   }
 
   private boolean isBundle(Manifest manifest)  {
@@ -474,25 +483,18 @@
   }
   
   public InputStream getWAB() throws IOException {
-    ensureConverted();
-    return new ByteArrayInputStream(wabFile);
+    convert();
+    return wab.getInputStream();
   }
   
   public Manifest getWABManifest() throws IOException {
-    ensureConverted();
+    generateManifest();
     return wabManifest;
   }
 
   public int getWabLength() throws IOException {
-    ensureConverted();
-    return wabFile.length;
+    convert();
+    return wab.size();
   }
   
-  private void ensureConverted() throws IOException {
-    if (!!!converted) {
-      convert();
-      converted = true;
-    }
-  }
-
 }