You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by th...@apache.org on 2005/06/20 05:42:49 UTC

svn commit: r191386 - in /webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments: ./ Base64.java ByteArrayDataSource.java IOUtils.java MIMEHelper.java MimeBodyPartInputStream.java PartOnFile.java

Author: thilina
Date: Sun Jun 19 20:42:48 2005
New Revision: 191386

URL: http://svn.apache.org/viewcvs?rev=191386&view=rev
Log:
attachments support helper files.

Added:
    webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/
    webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/Base64.java
    webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/ByteArrayDataSource.java
    webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/IOUtils.java
    webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/MIMEHelper.java
    webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/MimeBodyPartInputStream.java
    webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/PartOnFile.java

Added: webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/Base64.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/Base64.java?rev=191386&view=auto
==============================================================================
--- webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/Base64.java (added)
+++ webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/Base64.java Sun Jun 19 20:42:48 2005
@@ -0,0 +1,296 @@
+ /*
+ * 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.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+
+/**
+ * @author TAMURA Kent <kent@trl.ibm.co.jp>
+ */
+public class Base64 {
+    private static final char[] S_BASE64CHAR = { 'A', 'B', 'C', 'D', 'E', 'F',
+            'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
+            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
+            't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
+            '6', '7', '8', '9', '+', '/' };
+
+    private static final char S_BASE64PAD = '=';
+
+    private static final byte[] S_DECODETABLE = new byte[128];
+
+    static {
+        for (int i = 0; i < S_DECODETABLE.length; i++)
+            S_DECODETABLE[i] = Byte.MAX_VALUE; // 127
+        for (int i = 0; i < S_BASE64CHAR.length; i++)
+            // 0 to 63
+            S_DECODETABLE[S_BASE64CHAR[i]] = (byte) i;
+    }
+
+    private static int decode0(char[] ibuf, byte[] obuf, int wp) {
+        int outlen = 3;
+        if (ibuf[3] == S_BASE64PAD)
+            outlen = 2;
+        if (ibuf[2] == S_BASE64PAD)
+            outlen = 1;
+        int b0 = S_DECODETABLE[ibuf[0]];
+        int b1 = S_DECODETABLE[ibuf[1]];
+        int b2 = S_DECODETABLE[ibuf[2]];
+        int b3 = S_DECODETABLE[ibuf[3]];
+        switch (outlen) {
+        case 1:
+            obuf[wp] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3);
+            return 1;
+        case 2:
+            obuf[wp++] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3);
+            obuf[wp] = (byte) (b1 << 4 & 0xf0 | b2 >> 2 & 0xf);
+            return 2;
+        case 3:
+            obuf[wp++] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3);
+            obuf[wp++] = (byte) (b1 << 4 & 0xf0 | b2 >> 2 & 0xf);
+            obuf[wp] = (byte) (b2 << 6 & 0xc0 | b3 & 0x3f);
+            return 3;
+        default:
+            throw new RuntimeException("internalError00");
+        }
+    }
+
+    /**
+     *  
+     */
+    public static byte[] decode(char[] data, int off, int len) {
+        char[] ibuf = new char[4];
+        int ibufcount = 0;
+        byte[] obuf = new byte[len / 4 * 3 + 3];
+        int obufcount = 0;
+        for (int i = off; i < off + len; i++) {
+            char ch = data[i];
+            if (ch == S_BASE64PAD || ch < S_DECODETABLE.length
+                    && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
+                ibuf[ibufcount++] = ch;
+                if (ibufcount == ibuf.length) {
+                    ibufcount = 0;
+                    obufcount += decode0(ibuf, obuf, obufcount);
+                }
+            }
+        }
+        if (obufcount == obuf.length)
+            return obuf;
+        byte[] ret = new byte[obufcount];
+        System.arraycopy(obuf, 0, ret, 0, obufcount);
+        return ret;
+    }
+
+    /**
+     *  
+     */
+    public static byte[] decode(String data) {
+        char[] ibuf = new char[4];
+        int ibufcount = 0;
+        byte[] obuf = new byte[data.length() / 4 * 3 + 3];
+        int obufcount = 0;
+        for (int i = 0; i < data.length(); i++) {
+            char ch = data.charAt(i);
+            if (ch == S_BASE64PAD || ch < S_DECODETABLE.length
+                    && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
+                ibuf[ibufcount++] = ch;
+                if (ibufcount == ibuf.length) {
+                    ibufcount = 0;
+                    obufcount += decode0(ibuf, obuf, obufcount);
+                }
+            }
+        }
+        if (obufcount == obuf.length)
+            return obuf;
+        byte[] ret = new byte[obufcount];
+        System.arraycopy(obuf, 0, ret, 0, obufcount);
+        return ret;
+    }
+
+    /**
+     *  
+     */
+    public static void decode(char[] data, int off, int len,
+            OutputStream ostream) throws IOException {
+        char[] ibuf = new char[4];
+        int ibufcount = 0;
+        byte[] obuf = new byte[3];
+        for (int i = off; i < off + len; i++) {
+            char ch = data[i];
+            if (ch == S_BASE64PAD || ch < S_DECODETABLE.length
+                    && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
+                ibuf[ibufcount++] = ch;
+                if (ibufcount == ibuf.length) {
+                    ibufcount = 0;
+                    int obufcount = decode0(ibuf, obuf, 0);
+                    ostream.write(obuf, 0, obufcount);
+                }
+            }
+        }
+    }
+
+    /**
+     *  
+     */
+    public static void decode(String data, OutputStream ostream)
+            throws IOException {
+        char[] ibuf = new char[4];
+        int ibufcount = 0;
+        byte[] obuf = new byte[3];
+        for (int i = 0; i < data.length(); i++) {
+            char ch = data.charAt(i);
+            if (ch == S_BASE64PAD || ch < S_DECODETABLE.length
+                    && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
+                ibuf[ibufcount++] = ch;
+                if (ibufcount == ibuf.length) {
+                    ibufcount = 0;
+                    int obufcount = decode0(ibuf, obuf, 0);
+                    ostream.write(obuf, 0, obufcount);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns base64 representation of specified byte array.
+     */
+    public static String encode(byte[] data) {
+        return encode(data, 0, data.length);
+    }
+
+    /**
+     * Returns base64 representation of specified byte array.
+     */
+    public static String encode(byte[] data, int off, int len) {
+        if (len <= 0)
+            return "";
+        char[] out = new char[len / 3 * 4 + 4];
+        int rindex = off;
+        int windex = 0;
+        int rest = len - off;
+        while (rest >= 3) {
+            int i = ((data[rindex] & 0xff) << 16)
+                    + ((data[rindex + 1] & 0xff) << 8)
+                    + (data[rindex + 2] & 0xff);
+            out[windex++] = S_BASE64CHAR[i >> 18];
+            out[windex++] = S_BASE64CHAR[(i >> 12) & 0x3f];
+            out[windex++] = S_BASE64CHAR[(i >> 6) & 0x3f];
+            out[windex++] = S_BASE64CHAR[i & 0x3f];
+            rindex += 3;
+            rest -= 3;
+        }
+        if (rest == 1) {
+            int i = data[rindex] & 0xff;
+            out[windex++] = S_BASE64CHAR[i >> 2];
+            out[windex++] = S_BASE64CHAR[(i << 4) & 0x3f];
+            out[windex++] = S_BASE64PAD;
+            out[windex++] = S_BASE64PAD;
+        } else if (rest == 2) {
+            int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff);
+            out[windex++] = S_BASE64CHAR[i >> 10];
+            out[windex++] = S_BASE64CHAR[(i >> 4) & 0x3f];
+            out[windex++] = S_BASE64CHAR[(i << 2) & 0x3f];
+            out[windex++] = S_BASE64PAD;
+        }
+        return new String(out, 0, windex);
+    }
+
+    /**
+     * Outputs base64 representation of the specified byte array to a byte
+     * stream.
+     */
+    public static void encode(byte[] data, int off, int len,
+            OutputStream ostream) throws IOException {
+        if (len <= 0)
+            return;
+        byte[] out = new byte[4];
+        int rindex = off;
+        int rest = len - off;
+        while (rest >= 3) {
+            int i = ((data[rindex] & 0xff) << 16)
+                    + ((data[rindex + 1] & 0xff) << 8)
+                    + (data[rindex + 2] & 0xff);
+            out[0] = (byte) S_BASE64CHAR[i >> 18];
+            out[1] = (byte) S_BASE64CHAR[(i >> 12) & 0x3f];
+            out[2] = (byte) S_BASE64CHAR[(i >> 6) & 0x3f];
+            out[3] = (byte) S_BASE64CHAR[i & 0x3f];
+            ostream.write(out, 0, 4);
+            rindex += 3;
+            rest -= 3;
+        }
+        if (rest == 1) {
+            int i = data[rindex] & 0xff;
+            out[0] = (byte) S_BASE64CHAR[i >> 2];
+            out[1] = (byte) S_BASE64CHAR[(i << 4) & 0x3f];
+            out[2] = (byte) S_BASE64PAD;
+            out[3] = (byte) S_BASE64PAD;
+            ostream.write(out, 0, 4);
+        } else if (rest == 2) {
+            int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff);
+            out[0] = (byte) S_BASE64CHAR[i >> 10];
+            out[1] = (byte) S_BASE64CHAR[(i >> 4) & 0x3f];
+            out[2] = (byte) S_BASE64CHAR[(i << 2) & 0x3f];
+            out[3] = (byte) S_BASE64PAD;
+            ostream.write(out, 0, 4);
+        }
+    }
+
+    /**
+     * Outputs base64 representation of the specified byte array to a character
+     * stream.
+     */
+    public static void encode(byte[] data, int off, int len, Writer writer)
+            throws IOException {
+        if (len <= 0)
+            return;
+        char[] out = new char[4];
+        int rindex = off;
+        int rest = len - off;
+        int output = 0;
+        while (rest >= 3) {
+            int i = ((data[rindex] & 0xff) << 16)
+                    + ((data[rindex + 1] & 0xff) << 8)
+                    + (data[rindex + 2] & 0xff);
+            out[0] = S_BASE64CHAR[i >> 18];
+            out[1] = S_BASE64CHAR[(i >> 12) & 0x3f];
+            out[2] = S_BASE64CHAR[(i >> 6) & 0x3f];
+            out[3] = S_BASE64CHAR[i & 0x3f];
+            writer.write(out, 0, 4);
+            rindex += 3;
+            rest -= 3;
+            output += 4;
+            if (output % 76 == 0)
+                writer.write("\n");
+        }
+        if (rest == 1) {
+            int i = data[rindex] & 0xff;
+            out[0] = S_BASE64CHAR[i >> 2];
+            out[1] = S_BASE64CHAR[(i << 4) & 0x3f];
+            out[2] = S_BASE64PAD;
+            out[3] = S_BASE64PAD;
+            writer.write(out, 0, 4);
+        } else if (rest == 2) {
+            int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff);
+            out[0] = S_BASE64CHAR[i >> 10];
+            out[1] = S_BASE64CHAR[(i >> 4) & 0x3f];
+            out[2] = S_BASE64CHAR[(i << 2) & 0x3f];
+            out[3] = S_BASE64PAD;
+            writer.write(out, 0, 4);
+        }
+    }
+}
\ No newline at end of file

Added: webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/ByteArrayDataSource.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/ByteArrayDataSource.java?rev=191386&view=auto
==============================================================================
--- webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/ByteArrayDataSource.java (added)
+++ webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/ByteArrayDataSource.java Sun Jun 19 20:42:48 2005
@@ -0,0 +1,70 @@
+/**
+ * Copyright 2001-2004 The Apache Software Foundation.
+ * <p/>
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.
+ * <p/>
+ */
+package org.apache.axis.attachments;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.activation.DataSource;
+
+/**
+ * @author Thilina Gunarathne thilina@opensource.lk
+ */
+public class ByteArrayDataSource implements DataSource {
+
+    private byte[] data;
+
+    private String type;
+
+    public ByteArrayDataSource(byte[] data, String type) {
+        super();
+        this.data = data;
+        this.type = type;
+    }
+
+    public ByteArrayDataSource(byte[] data) {
+        super();
+        this.data = data;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getContentType() {
+        if (type == null)
+            return "application/octet-stream";
+        else
+            return type;
+    }
+
+    public InputStream getInputStream() throws IOException {
+        return new ByteArrayInputStream(data);
+    }
+
+    public String getName() {
+
+        return "ByteArrayDataSource";
+    }
+
+    public OutputStream getOutputStream() throws IOException {
+        throw new IOException("Not Supported");
+    }
+}
+

Added: webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/IOUtils.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/IOUtils.java?rev=191386&view=auto
==============================================================================
--- webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/IOUtils.java (added)
+++ webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/IOUtils.java Sun Jun 19 20:42:48 2005
@@ -0,0 +1,64 @@
+/*
+ * 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.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Utility class containing IO helper methods
+ */
+public class IOUtils
+{
+    private IOUtils() {
+    }
+
+    /**
+     * Read into a byte array; tries to ensure that the the
+     * full buffer is read.
+     *
+     * Helper method, just calls <tt>readFully(in, b, 0, b.length)</tt>
+     * @see #readFully(java.io.InputStream, byte[], int, int)
+     */
+    public static int readFully(InputStream in, byte[] b)
+    throws IOException
+    {
+        return readFully(in, b, 0, b.length);
+    }
+
+    /**
+     * Same as the normal <tt>in.read(b, off, len)</tt>, but tries to ensure that
+     * the entire len number of bytes is read.
+     * <p>
+     * @returns the number of bytes read, or -1 if the end of file is
+     *  reached before any bytes are read
+     */
+    public static int readFully(InputStream in, byte[] b, int off, int len)
+    throws IOException
+    {
+        int total = 0;
+        for (;;) {
+            int got = in.read(b, off + total, len - total);
+            if (got < 0) {
+                return (total == 0) ? -1 : total;
+            } else {
+                total += got;
+                if (total == len)
+                    return total;
+            }
+        }
+    }
+}
\ No newline at end of file

Added: webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/MIMEHelper.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/MIMEHelper.java?rev=191386&view=auto
==============================================================================
--- webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/MIMEHelper.java (added)
+++ webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/MIMEHelper.java Sun Jun 19 20:42:48 2005
@@ -0,0 +1,275 @@
+/**
+ * Copyright 2001-2004 The Apache Software Foundation.
+ * <p/>
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.
+ * <p/>
+ */
+package org.apache.axis.attachments;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.util.HashMap;
+
+import javax.activation.DataHandler;
+import javax.mail.MessagingException;
+import javax.mail.Part;
+import javax.mail.internet.ContentType;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.ParseException;
+
+import org.apache.axis.om.OMException;
+
+/**
+ * @author <a href="mailto:thilina@opensource.lk">Thilina Gunarathne </a>
+ */
+public class MIMEHelper {
+	/**
+	 * if the Message is MTOM optimised then <code>MTOM_TYPE</code>
+	 */
+	public static final String MTOM_TYPE = "application/xop+xml";
+	
+	/**
+	 * If the message is Soap with Attachments <code>SwA_TYPE</code>
+	 */
+	public static final String SWA_TYPE = "application/soap+xml";
+	
+	/**
+	 * <code>rootPart</code> is used as the key for the root BodyPart in the
+	 * Parts HashMap
+	 */
+	public static final String ROOT_PART = "SoapPart";
+	
+	/**
+	 * <code>ContentType</code> of the MIME message
+	 */
+	ContentType contentType;
+	
+	/**
+	 * Mime <code>boundary</code> which seperates mime parts
+	 */
+	byte[] boundary;
+	
+	/**
+	 * <code>applicationType</code> used to distinguish between MTOM & SWA If
+	 * the message is MTOM optimised type is application/xop+xml If the message
+	 * is SWA, type is ??have to find out
+	 */
+	String applicationType = null;
+	
+	/**
+	 * <code>pushbackInStream</code> stores the reference to the incoming
+	 * stream A PushbackStream has the ability to "push back" or "unread" one
+	 * byte.
+	 */
+	PushbackInputStream pushbackInStream;
+	
+	/**
+	 * <code>mimeBodyPartsMap</code> stores the already parsed Mime Body
+	 * Parts. This Map will be keyed using the content-ID's
+	 */
+	HashMap bodyPartsMap;
+	
+	/**
+	 * <code>partIndex</code>- Number of Mime parts parsed
+	 */
+	int partIndex = 0;
+	
+	public MIMEHelper(InputStream inStream, String contentTypeString)
+	throws OMException {
+		try {
+			contentType = new ContentType(contentTypeString);
+		} catch (ParseException e) {
+			throw new OMException(
+					"Invalid Content Type Field in the Mime Message"
+					+ e.toString());
+		}
+		// Boundary always have the prefix "--".
+		this.boundary = ("--" + contentType.getParameter("boundary"))
+		.getBytes();
+		
+		//TODO do we need to wrap InputStream from a BufferedInputStream before
+		// wrapping from PushbackStream
+		pushbackInStream = new PushbackInputStream(inStream,
+				(this.boundary.length + 2));
+		
+		// Move the read pointer to the begining of the first part
+		// read till the end of first boundary
+		while (true) {
+			int value;
+			try {
+				value = pushbackInStream.read();
+				if ((byte) value == boundary[0]) {
+					int boundaryIndex = 0;
+					while ((boundaryIndex < boundary.length)
+							&& ((byte) value == boundary[boundaryIndex])) {
+						value = pushbackInStream.read();
+						if (value == -1)
+							throw new OMException(
+							"Unexpected End of Stream while searching for first Mime Boundary");
+						boundaryIndex++;
+					}
+					if (boundaryIndex == boundary.length) { // boundary found
+						pushbackInStream.read();
+						break;
+					}
+				}
+			} catch (IOException e1) {
+				throw new OMException("Stream Error" + e1.toString());
+			}
+		}
+	}
+	
+	/**
+	 * @return whether Message Type is SOAP with Attachments or MTOM optimised
+	 *         by checking the application type parameter in the Contant Type
+	 */
+	public String getAttachmentSpecType() {
+		if (this.applicationType == null) {
+			applicationType = contentType.getParameter("type");
+			if (applicationType.equalsIgnoreCase(MTOM_TYPE)) {
+				this.applicationType = MTOM_TYPE;
+			} else if (applicationType.equalsIgnoreCase(SWA_TYPE)) {
+				this.applicationType = SWA_TYPE;
+			} else {
+				throw new OMException(
+				"Invalid Application type. Support available for MTOM & SwA only.");
+			}
+		}
+		return this.applicationType;
+	}
+	
+	/**
+	 * @return the InputStream which includes the SOAP Envelope
+	 */
+	public InputStream getSOAPPartInputStream() throws OMException{
+		//TODO Assumes that the First Mime part is the root part and it
+		// contains the SOAP Envelope. Check the start tag of the contant type
+		// when it comes to SWA
+		MimeBodyPart mimeBodyPart = getRootMimeBodyPart();
+		DataHandler dh;
+		try {
+			dh = mimeBodyPart.getDataHandler();
+			return dh.getInputStream();
+		} catch (IOException e) {
+			throw new OMException("Problem with DataHandler of the Root Mime Part. "+e);
+		} catch (MessagingException e) {
+			throw new OMException("Problem with getting DataHandler from the Root Mime Part. "+e);
+		}				
+		
+	}
+	
+	/**
+	 * @param blobContentID
+	 * @return The DataHandler of the mime part refered by the content-Id
+	 * @throws OMException
+	 *             First checks whether the MIME part is already parsed by
+	 *             checking the parts HashMap. If it is not parsed yet then call
+	 *             the getNextPart() till we find the required part.
+	 */
+	//TODO change parts list to a Hash Map
+	public DataHandler getDataHandler(String blobContentID) throws OMException {
+		
+		Part bodyPart;
+		
+		boolean attachmentFound = false;
+		
+		if (bodyPartsMap.containsKey(blobContentID)) {
+			bodyPart = (Part) bodyPartsMap.get(blobContentID);
+			attachmentFound = true;
+			DataHandler dh;
+			try {
+				dh = bodyPart.getDataHandler();
+			} catch (MessagingException e) {
+				throw new OMException("Problem with Mime Body Part No "+partIndex+".  "+e);
+			}
+			return dh;
+		} else {
+			try {
+				while (true) {
+					bodyPart = this.getNextMimeBodyPart();
+					if (bodyPart == null) {
+						return null;
+					}
+					if (bodyPartsMap.containsKey(blobContentID)) {
+						bodyPart = (Part) bodyPartsMap.get(blobContentID);
+						DataHandler dh = bodyPart.getDataHandler();
+	                    return dh;
+					}
+				}
+			} catch (MessagingException e) {
+				throw new OMException("Invalid Mime Message " + e.toString());
+			}
+		}
+		
+	}
+	
+	/**
+	 * @return The next MIME Body part in the stream Uses the MimeBodyPartStream
+	 *         to obtain streams delimited by boundaries.
+	 * @throws MessagingException
+	 */
+	// TODO do we need Locking for this
+	private MimeBodyPart getMimeBodyPart() throws OMException{
+		MimeBodyPart mimeBodyPart = null;
+		
+		//TODO A private methode to read a line
+		//String Line = pushbackInStream.readLine();
+		MimeBodyPartInputStream partStream = new MimeBodyPartInputStream(
+				pushbackInStream, boundary);
+		
+		try {
+			mimeBodyPart = new MimeBodyPart(partStream);
+		} catch (MessagingException e) {
+			throw new OMException("Problem reading Mime Part No "+(partIndex+1)+". "+e);
+		}
+		
+		partIndex++;
+		return mimeBodyPart;
+	}
+	
+	/**
+	 * @return The Mime body part which contains the SOAP Envelope In MTOM case
+	 *         it is the first part In SwA case we assumes it to be first
+	 *         part.Have to FIX This
+	 * @throws MessagingException
+	 */
+	private MimeBodyPart getRootMimeBodyPart() throws OMException {
+		MimeBodyPart rootMimeBodyPart;
+		if (bodyPartsMap.isEmpty()) {
+			rootMimeBodyPart = getMimeBodyPart();
+			bodyPartsMap.put(ROOT_PART, rootMimeBodyPart);
+		} else {
+			rootMimeBodyPart = (MimeBodyPart) bodyPartsMap.get(ROOT_PART);
+		}
+		return rootMimeBodyPart;
+	}
+	
+	private MimeBodyPart getNextMimeBodyPart() throws OMException {
+		MimeBodyPart nextMimeBodyPart;
+		nextMimeBodyPart = getMimeBodyPart();
+		if (nextMimeBodyPart != null) {
+			String partContentID;
+			try {
+				partContentID = nextMimeBodyPart.getContentID();
+			// TODO we might need to trim the surrounding "<"">" from content ID
+			bodyPartsMap.put(partContentID, nextMimeBodyPart);
+			return nextMimeBodyPart;
+			} catch (MessagingException e) {
+				throw new OMException("Error Reading Content-ID from Mime Part No "+partIndex+". "+e);
+			}
+		} else
+			return null;
+	}
+	
+}
\ No newline at end of file

Added: webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/MimeBodyPartInputStream.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/MimeBodyPartInputStream.java?rev=191386&view=auto
==============================================================================
--- webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/MimeBodyPartInputStream.java (added)
+++ webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/MimeBodyPartInputStream.java Sun Jun 19 20:42:48 2005
@@ -0,0 +1,70 @@
+/**
+ * Copyright 2001-2004 The Apache Software Foundation.
+ * <p/>
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.
+ * <p/>
+ */
+package org.apache.axis.attachments;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+
+/**
+ * @author <a href="mailto:thilina@opensource.lk">Thilina Gunarathne </a>
+ * This class provides input streams delimited by the mime boundaries.
+ */
+public class MimeBodyPartInputStream extends InputStream {
+	PushbackInputStream inStream;
+	
+	byte[] boundary;
+	
+	public MimeBodyPartInputStream(PushbackInputStream inStream, byte[] boundary) {
+		super();
+		this.inStream = inStream;
+		this.boundary = boundary;
+	}
+	
+	public int read() throws IOException {
+		
+		// read the next value from stream
+		int value = inStream.read();
+		
+		//read value is not the first byte of the boundary
+		if ((byte) value != boundary[0]) {
+			return value;
+		}
+		
+		// read value is the first byte of the boundary. Start matching the
+		// next characters to find a boundary
+		int boundaryIndex = 0; 
+		while ((boundaryIndex < boundary.length)
+				&& ((byte) value == boundary[boundaryIndex])) {
+			value = inStream.read();
+			boundaryIndex++;
+		}
+		
+		if (boundaryIndex == boundary.length) { // boundary found
+			return -1;
+		}
+		
+		// Boundary not found. Restoring bytes skipped.
+		// write first skipped byte, push back the rest
+		
+		if (value != -1) { // Stream might have ended
+			inStream.unread(value); 
+		}
+		inStream.unread(boundary, 1, boundaryIndex - 1);
+		return boundary[0];
+	}
+}
\ No newline at end of file

Added: webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/PartOnFile.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/PartOnFile.java?rev=191386&view=auto
==============================================================================
--- webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/PartOnFile.java (added)
+++ webservices/axis/trunk/java/modules/xml/src/org/apache/axis/attachments/PartOnFile.java Sun Jun 19 20:42:48 2005
@@ -0,0 +1,247 @@
+/**
+ * Copyright 2001-2004 The Apache Software Foundation.
+ * <p/>
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.
+ * <p/>
+ */
+package org.apache.axis.attachments;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.Enumeration;
+
+import javax.activation.DataHandler;
+import javax.mail.MessagingException;
+import javax.mail.Multipart;
+import javax.mail.Part;
+
+/**
+ * @author <a href="mailto:thilina@opensource.lk"> Thilina Gunarathne </a>
+ */
+public class PartOnFile implements Part {
+	
+	String fileName;
+	Part bodyPart;
+	public PartOnFile(Part bodyPart) throws Exception{
+		super();
+		fileName = (new Date()).getTime()+".tmp";
+		FileOutputStream outFileStream;
+		outFileStream = new FileOutputStream(fileName);
+		bodyPart.writeTo(outFileStream);
+		outFileStream.close();
+	}
+	
+	public int getSize() throws MessagingException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#getLineCount()
+	 */
+	public int getLineCount() throws MessagingException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#getContentType()
+	 */
+	public String getContentType() throws MessagingException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#isMimeType(java.lang.String)
+	 */
+	public boolean isMimeType(String arg0) throws MessagingException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#getDisposition()
+	 */
+	public String getDisposition() throws MessagingException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#setDisposition(java.lang.String)
+	 */
+	public void setDisposition(String arg0) throws MessagingException {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#getDescription()
+	 */
+	public String getDescription() throws MessagingException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#setDescription(java.lang.String)
+	 */
+	public void setDescription(String arg0) throws MessagingException {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#getFileName()
+	 */
+	public String getFileName() throws MessagingException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#setFileName(java.lang.String)
+	 */
+	public void setFileName(String arg0) throws MessagingException {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#getInputStream()
+	 */
+	public InputStream getInputStream() throws IOException, MessagingException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#getDataHandler()
+	 */
+	public DataHandler getDataHandler() throws MessagingException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#getContent()
+	 */
+	public Object getContent() throws IOException, MessagingException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#setDataHandler(javax.activation.DataHandler)
+	 */
+	public void setDataHandler(DataHandler arg0) throws MessagingException {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#setContent(java.lang.Object, java.lang.String)
+	 */
+	public void setContent(Object arg0, String arg1) throws MessagingException {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#setText(java.lang.String)
+	 */
+	public void setText(String arg0) throws MessagingException {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#setContent(javax.mail.Multipart)
+	 */
+	public void setContent(Multipart arg0) throws MessagingException {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#writeTo(java.io.OutputStream)
+	 */
+	public void writeTo(OutputStream arg0) throws IOException,
+	MessagingException {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#getHeader(java.lang.String)
+	 */
+	public String[] getHeader(String arg0) throws MessagingException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#setHeader(java.lang.String, java.lang.String)
+	 */
+	public void setHeader(String arg0, String arg1) throws MessagingException {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#addHeader(java.lang.String, java.lang.String)
+	 */
+	public void addHeader(String arg0, String arg1) throws MessagingException {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#removeHeader(java.lang.String)
+	 */
+	public void removeHeader(String arg0) throws MessagingException {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#getAllHeaders()
+	 */
+	public Enumeration getAllHeaders() throws MessagingException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#getMatchingHeaders(java.lang.String[])
+	 */
+	public Enumeration getMatchingHeaders(String[] arg0)
+	throws MessagingException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.mail.Part#getNonMatchingHeaders(java.lang.String[])
+	 */
+	public Enumeration getNonMatchingHeaders(String[] arg0)
+	throws MessagingException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+}