|
From: <kc...@us...> - 2003-06-17 04:28:04
|
Update of /cvsroot/ebxmlms/ebxmlms/src/hk/hku/cecid/phoenix/message/packaging
In directory sc8-pr-cvs1:/tmp/cvs-serv27446/src/hk/hku/cecid/phoenix/message/packaging
Modified Files:
EbxmlMessage.java
Log Message:
significant commit: we throw away the dependency on JAXM for serialization of
SOAP message. now, we control the MIME headers, content transfer encoding and
serialization of SOAP messages. The sole purpose is to support reading of
payload data ONLY when sending out. In the past, JAXM will load the payload
to memory for preparing data, which will limits the maximum size of the payload
to be sent.
Index: EbxmlMessage.java
===================================================================
RCS file: /cvsroot/ebxmlms/ebxmlms/src/hk/hku/cecid/phoenix/message/packaging/EbxmlMessage.java,v
retrieving revision 1.28
retrieving revision 1.29
diff -C2 -d -r1.28 -r1.29
*** EbxmlMessage.java 6 May 2003 06:17:42 -0000 1.28
--- EbxmlMessage.java 17 Jun 2003 04:28:01 -0000 1.29
***************
*** 77,82 ****
--- 77,84 ----
import java.util.Iterator;
import java.util.HashMap;
+ import java.util.Map;
import javax.xml.soap.*;
import javax.activation.DataHandler;
+ import javax.mail.internet.MimeUtility;
/**
***************
*** 150,154 ****
* ebXML message payloads as SOAP attachments.
*/
! private final ArrayList payloadContainers;
/**
--- 152,156 ----
* ebXML message payloads as SOAP attachments.
*/
! private ArrayList payloadContainers;
/**
***************
*** 157,160 ****
--- 159,167 ----
private String filename;
+ /**
+ * MIME boundary generated
+ */
+ private String mimeBoundary;
+
/** Constructs an <code>EbxmlMessage</code> using the default JAXM
<code>MessageFactory</code> implementation
***************
*** 948,952 ****
}
payloadContainers.add(payload);
! soapMessage.addAttachmentPart(attachment);
return payload;
--- 955,962 ----
}
payloadContainers.add(payload);
!
! // we now keep the SOAP message object away from attachment to avoid
! // it to load the payload to memory
! // soapMessage.addAttachmentPart(attachment);
return payload;
***************
*** 964,967 ****
--- 974,989 ----
/**
+ * Sets the <code>PayloadContainer</code>
+ *
+ * @param contentId
+ * @return The old payload container as an array list
+ */
+ public ArrayList setPayloadContainers(ArrayList payloads) {
+ ArrayList oldPayloads = this.payloadContainers;
+ this.payloadContainers = payloads;
+ return oldPayloads;
+ }
+
+ /**
* Gets the payload that is identified by the given content ID.
*
***************
*** 980,983 ****
--- 1002,1018 ----
}
+ /**
+ * Gets the number of payloads in this ebXML message
+ *
+ * @return the number of payloads
+ */
+ public int getPayloadCount() {
+ return payloadContainers.size();
+ }
+
+ /**
+ * Gets the Manifest element in this ebXML message
+ * @return Manifest element
+ */
public Manifest getManifest() {
return headerContainer.getManifest();
***************
*** 1005,1008 ****
--- 1040,1222 ----
}
+ /**
+ * Gets the MIME headers of this ebXML message
+ *
+ * @return the MIME headers of this ebXML message
+ */
+ public Map getMimeHeaders(String soapEncoding, String payloadEncoding)
+ throws IOException, SOAPException {
+ HashMap headers = new HashMap();
+
+ // fill in Content-Type
+ String contentType;
+ if (getPayloadCount() > 0) {
+ contentType = Constants.MULTIPART_RELATED_TYPE
+ + "\"" + getMimeBoundary() + "\"; "
+ + Constants.CHARACTER_SET + "=\""
+ + Constants.CHARACTER_ENCODING + "\"; "
+ + Constants.START + "=\"<"
+ + SOAP_PART_CONTENT_ID + ">\"";
+ }
+ else {
+ contentType = Constants.TEXT_XML_TYPE + "; "
+ + Constants.CHARACTER_SET + "=\""
+ + Constants.CHARACTER_ENCODING + "\"";
+ }
+ headers.put(Constants.CONTENT_TYPE, contentType);
+
+ // fill in Content-Length
+ headers.put(Constants.CONTENT_LENGTH,
+ String.valueOf(
+ serialize(null, soapEncoding, payloadEncoding, true)));
+
+ // fill in SOAPAction
+ headers.put(SOAP_ACTION, SOAP_ACTION_VALUE);
+
+ return headers;
+ }
+
+ /**
+ * Walks through the serialization process to get the content length.
+ * It can do the actually serialization also optionally
+ *
+ * @param out <code>OutputStream</code> to write the message to.
+ * @param encoding content transfer encoding to be applied to payload
+ * @param getLengthOnly get length only and do no actual serialization
+ * @return the content length of the serialization
+ * @throws IOException
+ * @throws SOAPException
+ */
+ private long serialize(OutputStream out, String soapEncoding,
+ String payloadEncoding, boolean getLengthOnly)
+ throws IOException, SOAPException {
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ OutputStream os;
+ try {
+ os = MimeUtility.encode(baos, soapEncoding);
+ }
+ catch (Exception e) {
+ throw new SOAPException(
+ "Content-Transfer-Encoding encode error: "
+ + e.getMessage());
+ }
+ soapMessage.writeTo(os);
+ long soapMessageLength = baos.toByteArray().length;
+ long totalLength = 0;
+
+ try {
+ os = MimeUtility.encode(out, soapEncoding);
+ }
+ catch (Exception e) {
+ throw new SOAPException(
+ "Content-Transfer-Encoding encode error: "
+ + e.getMessage());
+ }
+
+ Iterator i = getPayloadContainers();
+
+ // not multipart
+ if (!i.hasNext()) {
+ if (!getLengthOnly) {
+ soapMessage.writeTo(os);
+ os.flush();
+ }
+ return soapMessageLength;
+ }
+
+ String boundary = getMimeBoundary();
+ String buffer;
+ byte[] bytes;
+
+ // print SOAP part
+ buffer = Constants.MIME_BOUNDARY_PREFIX + boundary + Constants.CRLF;
+ buffer = buffer + Constants.CONTENT_TYPE + ": "
+ + Constants.TEXT_XML_TYPE + Constants.CRLF;
+ buffer = buffer + Constants.CONTENT_ID + ": "
+ + soapMessage.getSOAPPart().getContentId() + Constants.CRLF;
+ buffer = buffer + Constants.CONTENT_TRANSFER_ENCODING + ": "
+ + soapEncoding + Constants.CRLF;
+ buffer = buffer + Constants.CRLF;
+ bytes = buffer.getBytes(Constants.CHARACTER_ENCODING);
+ totalLength += bytes.length;
+ totalLength += soapMessageLength;
+ if (!getLengthOnly) {
+ out.write(bytes);
+ out.flush();
+ soapMessage.writeTo(os);
+ os.flush();
+ }
+ bytes = Constants.CRLF.getBytes(Constants.CHARACTER_ENCODING);
+ totalLength += bytes.length;
+ if (!getLengthOnly) {
+ out.write(bytes);
+ out.flush();
+ }
+
+ // print payloads
+ while (i.hasNext()) {
+ PayloadContainer pc = (PayloadContainer) i.next();
+
+ buffer = Constants.MIME_BOUNDARY_PREFIX + boundary + Constants.CRLF;
+ buffer = buffer + Constants.CONTENT_TYPE + ": "
+ + pc.getContentType() + Constants.CRLF;
+ buffer = buffer + Constants.CONTENT_ID + ": "
+ + (needPatch ? "<"+pc.getContentId()+">" : pc.getContentId())
+ + Constants.CRLF;
+ buffer = buffer + Constants.CONTENT_TRANSFER_ENCODING + ": "
+ + payloadEncoding + Constants.CRLF;
+ buffer = buffer + Constants.CRLF;
+ bytes = buffer.getBytes(Constants.CHARACTER_ENCODING);
+ totalLength += bytes.length;
+ if (!getLengthOnly) {
+ out.write(bytes);
+ out.flush();
+ }
+
+ long payloadLength = pc.getContentLength();
+ if (payloadLength == -1 || !getLengthOnly ||
+ !payloadEncoding.equalsIgnoreCase("binary")) {
+ InputStream in = pc.getDataHandler().getInputStream();
+ byte[] b = new byte[4096];
+ int bytesRead;
+ long totalBytes = 0;
+ try {
+ os = MimeUtility.encode(out, payloadEncoding);
+ }
+ catch (Exception e) {
+ throw new SOAPException(
+ "Content-Transfer-Encoding encode error: "
+ + e.getMessage());
+ }
+ while ((bytesRead = in.read(b)) > 0) {
+ totalBytes += bytesRead;
+ if (!getLengthOnly) {
+ os.write(b, 0, bytesRead);
+ os.flush();
+ }
+ }
+ payloadLength = totalBytes;
+ }
+ totalLength += payloadLength;
+
+ bytes = Constants.CRLF.getBytes(Constants.CHARACTER_ENCODING);
+ totalLength += bytes.length;
+ if (!getLengthOnly) {
+ out.write(bytes);
+ }
+ }
+
+ // print last boundary
+ buffer = Constants.MIME_BOUNDARY_PREFIX + boundary + "--"
+ + Constants.CRLF;
+ bytes = buffer.getBytes(Constants.CHARACTER_ENCODING);
+ totalLength += bytes.length;
+ if (!getLengthOnly) {
+ out.write(bytes);
+ }
+ return totalLength;
+ }
+
/** Writes the encapsulated <code>SOAPMessage</code> to the given
* output stream. The externalization format is as defined by the
***************
*** 1013,1017 ****
public void writeTo(OutputStream out)
throws IOException, SOAPException {
! soapMessage.writeTo(out);
}
--- 1227,1262 ----
public void writeTo(OutputStream out)
throws IOException, SOAPException {
!
! // we now keep the SOAP message object away from attachment to avoid
! // it to load the payload to memory, therefore we are doing our own
! // writeTo() here
! // soapMessage.writeTo(out);
! serialize(out, Constants.DEFAULT_CONTENT_TRANSFER_ENCODING,
! Constants.DEFAULT_CONTENT_TRANSFER_ENCODING, false);
! }
!
! /** Writes the encapsulated <code>SOAPMessage</code> to the given
! * output stream. The externalization format is as defined by the
! * SOAP 1.1 with Attachments Specification.
! *
! * @param out <code>OutputStream</code> to write the message to.
! * @param encoding the content transfer encoding to be applied to payload
! */
! public void writeTo(OutputStream out, String soapEncoding,
! String payloadEncoding)
! throws IOException, SOAPException {
!
! // we now keep the SOAP message object away from attachment to avoid
! // it to load the payload to memory, therefore we are doing our own
! // writeTo() here
! // soapMessage.writeTo(out);
! serialize(out, soapEncoding, payloadEncoding, false);
! }
!
! public String getMimeBoundary() {
! if (mimeBoundary == null) {
! mimeBoundary = "----=_BOUNDARY_01";
! }
! return mimeBoundary;
}
|