Author: scheu
Date: Sat May 17 14:10:52 2008
New Revision: 657463

URL: http://svn.apache.org/viewvc?rev=657463&view=rev
Log:
WSCOMMONS-347
Contributor:Rich Scheuerle
TextHelper utility method to help create an efficient OMText node from a binary 
byte[]
TextHelperTest validation testing

Modified:
    
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/TextHelper.java
    
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/util/TextHelperTest.java

Modified: 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/TextHelper.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/TextHelper.java?rev=657463&r1=657462&r2=657463&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/TextHelper.java
 (original)
+++ 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/TextHelper.java
 Sat May 17 14:10:52 2008
@@ -19,15 +19,27 @@
 
 package org.apache.axiom.om.util;
 
+import org.apache.axiom.attachments.impl.BufferUtils;
+import org.apache.axiom.attachments.lifecycle.LifecycleManager;
+import org.apache.axiom.attachments.lifecycle.impl.FileAccessor;
+import org.apache.axiom.attachments.lifecycle.impl.LifecycleManagerImpl;
+import org.apache.axiom.om.OMFactory;
 import org.apache.axiom.om.OMText;
 
 import javax.activation.DataHandler;
+import javax.mail.MessagingException;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 
 public class TextHelper {
     
+    private static int DEFAULT_FILE_THRESHOLD = 100 * 1024;
+    private static String DEFAULT_ATTACHMENT_DIR = "axiomTmp";
+    private static int DELETE_TIME = 60 * 60; // 1 Hour
+    
     /**
      * @param inStream InputStream
      * @return Base64 encoded string representint the data in inStream
@@ -91,4 +103,107 @@
         buffer.append(omText.getText());
         return;
     }
+    
+    
+    /**
+     * Create an OMText node from a byte array containing binary data
+     * If the byte array is large and the optimize flag is set, then 
+     * the data is stored in a temp file to reduce in-core memory
+     * @param is
+     * @param factory
+     * @param isOptimize
+     */
+    public static OMText toOMText(byte[] b, int off, int length, 
+                                  OMFactory factory, 
+                                  boolean isOptimize) throws IOException, 
MessagingException {
+        String attachmentDir = getAttachmentDir(factory);
+        return toOMText(b, off, length, factory, isOptimize, attachmentDir);
+    }
+    
+    /**
+     * Create an OMText node from a byte array containing binary data
+     * If the byte array is large and the optimize flag is set, then 
+     * the data is stored in a temp file to reduce in-core memory
+     * @param is
+     * @param factory
+     * @param isOptimize
+     */
+    public static OMText toOMText(byte[] b, int off, int length, 
+                                      OMFactory factory, 
+                                      boolean isOptimize,
+                                      String attachmentDir) throws 
IOException, MessagingException {
+        OMText omText = null;
+        if (isOptimize) {
+            LifecycleManager lm = getLifecycleManager(factory);
+            int threshold = getThreshold(factory);
+            
+            // TODO Consider lowering the threshold in low memory situations ?
+            //threshold = lm.getRuntimeThreshold(threshold);
+            
+            if (length >= threshold && attachmentDir != null) {
+                
+                // Get the file accessor
+                FileAccessor fileAccessor = lm.create(attachmentDir);
+                OutputStream fos = fileAccessor.getOutputStream();
+                
+                //Copy the bytes into the file
+                ByteArrayInputStream is = new ByteArrayInputStream(b, off, 
length);
+                BufferUtils.inputStream2OutputStream(is, fos);
+                fos.close();
+                
+                // Delete this temp file on exit
+                lm.deleteOnExit(fileAccessor.getFile());
+                lm.deleteOnTimeInterval(DELETE_TIME, fileAccessor.getFile());
+                
+                // Create the OMText node from the datahandler
+                DataHandler dh = fileAccessor.getDataHandler(null);
+                omText = factory.createOMText(dh, isOptimize);
+            }
+        }
+        if (omText == null) {
+            omText = factory.createOMText(Base64.encode(b, off, length));
+            omText.setOptimize(isOptimize);
+        }
+        return omText;
+    }
+   
+    private static LifecycleManager getLifecycleManager(OMFactory factory) {
+        LifecycleManager lm = null;
+        
+        /* TODO Support access to lifecycle manager from the factory
+        if (factory.getProperty(LIFECYCLE_MANAGER)) {
+            ...
+        }
+        */
+        if (lm == null) {
+            return new LifecycleManagerImpl();
+        }
+        return lm;
+        
+    }
+    
+    private static int getThreshold(OMFactory factory) {
+       
+        int threshold = DEFAULT_FILE_THRESHOLD;
+        /* TODO Support access to threshold from the factory
+        if (factory.getProperty(FILE_THRESHOLD)) {
+            ...
+        }
+        */
+        return threshold;
+        
+    }
+    
+    private static String getAttachmentDir(OMFactory factory) {
+        
+        String attachmentDir = DEFAULT_ATTACHMENT_DIR;
+        /* TODO Support access to threshold from the factory
+        if (factory.getProperty(FILE_THRESHOLD)) {
+            ...
+        }
+        */
+        return attachmentDir;
+        
+    }
+    
 }

Modified: 
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/util/TextHelperTest.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/util/TextHelperTest.java?rev=657463&r1=657462&r2=657463&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/util/TextHelperTest.java
 (original)
+++ 
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/util/TextHelperTest.java
 Sat May 17 14:10:52 2008
@@ -18,6 +18,7 @@
  */
 package org.apache.axiom.om.util;
 
+import org.apache.axiom.attachments.impl.BufferUtils;
 import org.apache.axiom.om.AbstractTestCase;
 import org.apache.axiom.om.OMAbstractFactory;
 import org.apache.axiom.om.OMFactory;
@@ -27,9 +28,11 @@
 import javax.activation.FileDataSource;
 
 import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.InputStream;
 
 /**
  * Validate TextHelper code
@@ -38,7 +41,10 @@
 
     private File file;
     private FileInputStream fis;
-    private static final long SIZE = 10 * 1024;
+    private static final long SIZE = 101 * 1024; // More than the threshold
+    private static final long EXPECTED_BASE64_SIZE = 137900;
+    private static final String EXPECTED_STARTS_WITH = 
+        "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJC";
     
     
     public TextHelperTest(String testName) {
@@ -53,7 +59,8 @@
         for (long i = 0; i < SIZE; i++) {
             bos.write((byte)(i % 256));
         }
-        fos.close();
+        bos.flush();
+        bos.close();
         fis = new FileInputStream(file);
         file.deleteOnExit();
     }
@@ -65,17 +72,36 @@
         }
     }
     
+    /**
+     * Test the InputStream - > BASE64 String 
+     * code.
+     * 
+     * @throws Exception
+     */
     public void test_toString() throws Exception {
         String text = TextHelper.toString(fis);
         assertTrue(text.length() > SIZE);
+        assertTrue(text.length() == EXPECTED_BASE64_SIZE);
+        assertTrue(text.startsWith(EXPECTED_STARTS_WITH));
     }
     
+    /**
+     * Test the InputStream -> BASE64 StringBuffer code
+     * @throws Exception
+     */
     public void test_toStringBuffer() throws Exception {
         StringBuffer buffer = new StringBuffer();
         TextHelper.toStringBuffer(fis, buffer);
         assertTrue(buffer.length() > SIZE);
+        String text = buffer.toString();
+        assertTrue(text.length() == EXPECTED_BASE64_SIZE);
+        assertTrue(text.startsWith(EXPECTED_STARTS_WITH));
     }
     
+    /**
+     * Test the OMText -> StringBuffer code
+     * @throws Exception
+     */
     public void test_fromOMText() throws Exception {
         
         OMFactory factory = OMAbstractFactory.getOMFactory();
@@ -85,6 +111,71 @@
         StringBuffer buffer = new StringBuffer();
         TextHelper.toStringBuffer(omText, buffer);
         assertTrue(buffer.length() > SIZE);
+        String text = buffer.toString();
+        assertTrue(text.length() == EXPECTED_BASE64_SIZE);
+        assertTrue(text.startsWith(EXPECTED_STARTS_WITH));
+    }
+        
+    /**
+     * Test binary bytes -> OMText code
+     * @throws Exception
+     */
+    public void test_toOMText_fromBytes_optimized() throws Exception {
+        // Start with a binary bytes stream
+        InputStream is = new FileInputStream(file);
+        
+        // Get bytes
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        BufferUtils.inputStream2OutputStream(is, baos);
+        byte[] b = baos.toByteArray();
+        
+        // Create an OMText node from the binary bytes
+        OMFactory factory = OMAbstractFactory.getOMFactory();
+        OMText omText = TextHelper.toOMText(b, 0, b.length, 
+                                            factory, true,
+                                            this.tempDir);
+        
+        // Ensure text is optimized
+        assertTrue(omText != null);
+        assertTrue(omText.isOptimized());
+        
+        // Now check the text
+        StringBuffer buffer = new StringBuffer();
+        TextHelper.toStringBuffer(omText, buffer);
+        assertTrue(buffer.length() > SIZE);
+        String text = buffer.toString();
+        assertTrue(text.length() == EXPECTED_BASE64_SIZE);
+        assertTrue(text.startsWith(EXPECTED_STARTS_WITH));
     }
     
+    /**
+     * Test binary bytes -> OMText code
+     * @throws Exception
+     */
+    public void test_toOMText_fromBytes_notOptimized() throws Exception {
+        // Start with a binary bytes stream
+        InputStream is = new FileInputStream(file);
+        
+        // Get bytes
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        BufferUtils.inputStream2OutputStream(is, baos);
+        byte[] b = baos.toByteArray();
+        
+        // Create an OMText node from the binary bytes
+        OMFactory factory = OMAbstractFactory.getOMFactory();
+        OMText omText = TextHelper.toOMText(b, 0, b.length, factory, false);
+        
+        // Ensure text is optimized
+        assertTrue(omText != null);
+        assertTrue(!omText.isOptimized());
+        
+        // Now check the text
+        StringBuffer buffer = new StringBuffer();
+        TextHelper.toStringBuffer(omText, buffer);
+        assertTrue(buffer.length() > SIZE);
+        String text = buffer.toString();
+        assertTrue(text.length() == EXPECTED_BASE64_SIZE);
+        assertTrue(text.startsWith(EXPECTED_STARTS_WITH));
+        
+    }
 }
\ No newline at end of file


Reply via email to