Hi,
I wrote a small patch for axis 1.2 RC3 to allow me to take advantage
DIME record chunking. This allows people who generate dynamic content
who don't know the size of their data beforehand to stream out.
I've been streaming 2GB+ attachments out with no problem.
Using it is very simple
for example:
DynamicContentDataHandler datahandler = null;
URL url = new URL("http",host,port,QUERY_STRING);
URLDataSource dataSource = new URLDataSource(url);
datahandler = new DynamicContentDataHandler(dataSource);
datahandler.setChunkSize(10 * 1024 * 1024);
This will make dime record chunks of 10MB, and only buffer 20MB of data
at any one time.
Marc Dumontier
Bioinformatics Software Developer
Blueprint Initiative
http://www.blueprint.org
diff -Naur
../../axis/axis-1_2RC3/src/org/apache/axis/attachments/DimeBodyPart.java
./src/org/apache/axis/attachments/DimeBodyPart.java
--- ../../axis/axis-1_2RC3/src/org/apache/axis/attachments/DimeBodyPart.java
2005-02-28 22:41:19.000000000 -0500
+++ ./src/org/apache/axis/attachments/DimeBodyPart.java 2005-03-11
14:30:30.644650882 -0500
@@ -21,14 +21,16 @@
package org.apache.axis.attachments;
-import org.apache.axis.components.logger.LogFactory;
-import org.apache.axis.utils.Messages;
-import org.apache.commons.logging.Log;
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.util.StringTokenizer;
import javax.activation.DataHandler;
import javax.activation.DataSource;
-import java.util.StringTokenizer;
-import java.io.IOException;
+
+import org.apache.axis.components.logger.LogFactory;
+import org.apache.axis.utils.Messages;
+import org.apache.commons.logging.Log;
/**
@@ -220,10 +222,12 @@
Messages.getMessage("attach.dimeMaxChunkSize0", "" +
maxchunk));
if (maxchunk > MAX_DWORD) throw new IllegalArgumentException(
Messages.getMessage("attach.dimeMaxChunkSize1", "" +
maxchunk));
- if (data instanceof byte[]) send(os, position, (byte[]) data,
- maxchunk);
- if (data instanceof DataHandler) send(os, position,
- (DataHandler) data, maxchunk);
+ if (data instanceof byte[])
+ send(os, position, (byte[]) data, maxchunk);
+ else if (data instanceof DynamicContentDataHandler) send(os, position,
+ (DynamicContentDataHandler) data, maxchunk);
+ else if (data instanceof DataHandler) send(os, position,
+ (DataHandler) data, maxchunk);
}
/**
@@ -300,6 +304,57 @@
}
// END FIX: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=17001
}
+
+ /**
+ * Special case for dynamically generated content.
+ * maxchunk is currently ignored since the default is 2GB.
+ * The chunk size is retrieved from the DynamicContentDataHandler
+ *
+ * @param os
+ * @param position
+ * @param dh
+ * @param maxchunk
+ * @throws java.io.IOException
+ */
+ void send(java.io.OutputStream os, byte position,
DynamicContentDataHandler dh,
+ final long maxchunk)
+ throws java.io.IOException {
+
+ BufferedInputStream in = new
BufferedInputStream(dh.getInputStream());
+
+ final int myChunkSize = dh.getChunkSize();
+
+ byte[] buffer1 = new byte[myChunkSize];
+ byte[] buffer2 = new byte[myChunkSize];
+
+ int bytesRead1 = 0 , bytesRead2 = 0;
+ byte chunknext = 0;
+
+ bytesRead1 = in.read(buffer1);
+
+ if(bytesRead1 < 0) {
+ //no data all.should we be sending an empty dime record?
+ throw new IOException("No data found to send in DIME
message");
+ }
+
+ do {
+ bytesRead2 = in.read(buffer2);
+
+ if(bytesRead2 < 0) {
+ //last record...do not set the chunk bit.
+ //buffer1 contains the last chunked record!
+ sendChunk(os, position, buffer1, 0, bytesRead1,
(byte)0);
+ break;
+ }
+
+ sendChunk(os, position, buffer1, 0, bytesRead1,
(byte)CHUNK);
+
+ //now that we have written out buffer1, copy buffer2
into to buffer1
+ System.arraycopy(buffer2,0,buffer1,0,myChunkSize);
+ bytesRead1 = bytesRead2;
+
+ }while(bytesRead2 > 0);
+ }
protected void sendChunk(java.io.OutputStream os,
final byte position,
diff -Naur
../../axis/axis-1_2RC3/src/org/apache/axis/attachments/DynamicContentDataHandler.java
./src/org/apache/axis/attachments/DynamicContentDataHandler.java
---
../../axis/axis-1_2RC3/src/org/apache/axis/attachments/DynamicContentDataHandler.java
1969-12-31 19:00:00.000000000 -0500
+++ ./src/org/apache/axis/attachments/DynamicContentDataHandler.java
2005-03-11 14:30:24.974794757 -0500
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.axis.attachments;
+
+import java.net.URL;
+
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+
+/**
+ * To be used with writing out DIME Attachments.
+ *
+ * AXIS will use DIME record chunking.
+ *
+ * @author Marc Dumontier ([EMAIL PROTECTED])
+ *
+ */
+public class DynamicContentDataHandler extends DataHandler {
+
+ int chunkSize = 1*1024*1024;
+
+ /**
+ * @param arg0
+ */
+ public DynamicContentDataHandler(DataSource arg0) {
+ super(arg0);
+ }
+
+ /**
+ * @param arg0
+ * @param arg1
+ */
+ public DynamicContentDataHandler(Object arg0, String arg1) {
+ super(arg0, arg1);
+ }
+
+ /**
+ * @param arg0
+ */
+ public DynamicContentDataHandler(URL arg0) {
+ super(arg0);
+ }
+
+ /**
+ * Get the DIME record chunk size
+ * @return The value
+ */
+ public int getChunkSize() {
+ return chunkSize;
+ }
+
+ /**
+ * Set the DIME record chunk size
+ * @param chunkSize The value.
+ */
+ public void setChunkSize(int chunkSize) {
+ this.chunkSize = chunkSize;
+ }
+}