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