geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From xuhaih...@apache.org
Subject svn commit: r1134200 - in /geronimo/bundles/trunk/axiom-all: ./ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/axiom/ src/main/java/org/apache/axiom/attachments/
Date Fri, 10 Jun 2011 06:07:12 GMT
Author: xuhaihong
Date: Fri Jun 10 06:07:11 2011
New Revision: 1134200

URL: http://svn.apache.org/viewvc?rev=1134200&view=rev
Log:
Fix (AXIOM-364) Unnecessary byte case while reading the attachments from Geronimo side

Added:
    geronimo/bundles/trunk/axiom-all/src/main/java/
    geronimo/bundles/trunk/axiom-all/src/main/java/org/
    geronimo/bundles/trunk/axiom-all/src/main/java/org/apache/
    geronimo/bundles/trunk/axiom-all/src/main/java/org/apache/axiom/
    geronimo/bundles/trunk/axiom-all/src/main/java/org/apache/axiom/attachments/
    geronimo/bundles/trunk/axiom-all/src/main/java/org/apache/axiom/attachments/Attachments.java
  (with props)
Modified:
    geronimo/bundles/trunk/axiom-all/pom.xml

Modified: geronimo/bundles/trunk/axiom-all/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axiom-all/pom.xml?rev=1134200&r1=1134199&r2=1134200&view=diff
==============================================================================
--- geronimo/bundles/trunk/axiom-all/pom.xml (original)
+++ geronimo/bundles/trunk/axiom-all/pom.xml Fri Jun 10 06:07:11 2011
@@ -173,7 +173,10 @@
                     <instructions>
                         <Export-Package>org.apache.axiom*;version="${pkgVersion}";-split-package:=merge-first</Export-Package>
                         <Import-Package>org.jaxen*;resolution:=optional,*</Import-Package>
-                        <!--<_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy>-->
+                        <Include-Resource>
+                           {maven-resources},
+                           org/apache/axiom/attachments/Attachments.class=target/classes/org/apache/axiom/attachments/attachments.class
+                        </Include-Resource>
                     </instructions>
                 </configuration>
             </plugin>

Added: geronimo/bundles/trunk/axiom-all/src/main/java/org/apache/axiom/attachments/Attachments.java
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axiom-all/src/main/java/org/apache/axiom/attachments/Attachments.java?rev=1134200&view=auto
==============================================================================
--- geronimo/bundles/trunk/axiom-all/src/main/java/org/apache/axiom/attachments/Attachments.java
(added)
+++ geronimo/bundles/trunk/axiom-all/src/main/java/org/apache/axiom/attachments/Attachments.java
Fri Jun 10 06:07:11 2011
@@ -0,0 +1,756 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.axiom.attachments;
+
+import org.apache.axiom.attachments.impl.PartFactory;
+import org.apache.axiom.attachments.lifecycle.LifecycleManager;
+import org.apache.axiom.attachments.lifecycle.impl.LifecycleManagerImpl;
+import org.apache.axiom.om.OMAttachmentAccessor;
+import org.apache.axiom.om.OMException;
+import org.apache.axiom.om.impl.MTOMConstants;
+import org.apache.axiom.om.util.DetachableInputStream;
+import org.apache.axiom.util.UIDGenerator;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.activation.DataHandler;
+import javax.mail.MessagingException;
+import javax.mail.internet.ContentType;
+import javax.mail.internet.ParseException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.Map;
+import java.util.Collections;
+
+public class Attachments implements OMAttachmentAccessor {
+
+    /** <code>ContentType</code> of the MIME message */
+    ContentType contentType;
+    
+    int contentLength; // Content Length
+
+    /** Mime <code>boundary</code> which separates 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;
+
+    /**
+     * <code>pushbackInStream</code> stores the reference to the incoming stream
A PushbackStream
+     * has the ability to "push back" or "unread" one byte.
+     */
+    PushbackInputStream pushbackInStream;
+    int PUSHBACK_SIZE = 4 * 1024;
+    DetachableInputStream filterIS = null;
+
+    /**
+     * <code>attachmentsMap</code> stores the Data Handlers of the already parsed
Mime Body Parts.
+     * This ordered Map is keyed using the content-ID's.
+     */
+    TreeMap attachmentsMap;
+    
+    /**
+     * <code>cids</code> stores the content ids in the order that the attachments
+     * occur in the message
+     */
+    ArrayList cids = new ArrayList(); 
+
+    /** <code>partIndex</code>- Number of Mime parts parsed */
+    int partIndex = 0;
+
+    /** Container to hold streams for direct access */
+    IncomingAttachmentStreams streams = null;
+
+    /** <code>boolean</code> Indicating if any streams have been directly requested
*/
+    private boolean streamsRequested = false;
+
+    /** <code>boolean</code> Indicating if any data handlers have been directly
requested */
+    private boolean partsRequested = false;
+
+    /**
+     * <code>endOfStreamReached</code> flag which is to be set by MIMEBodyPartStream
when MIME
+     * message terminator is found.
+     */
+    private boolean endOfStreamReached;
+
+
+    /**
+     * <code>noStreams</code> flag which is to be set when this class is instantiated
by the SwA API
+     * to handle programatic added attachements. An InputStream with attachments is not present
at
+     * that occation.
+     */
+    private boolean noStreams = false;
+
+    private String firstPartId;
+
+    private boolean fileCacheEnable;
+
+    private String attachmentRepoDir;
+
+    private int fileStorageThreshold;
+    
+    private LifecycleManager manager;
+    
+    protected static Log log = LogFactory.getLog(Attachments.class);
+   
+    public LifecycleManager getLifecycleManager() {
+        if(manager == null) {
+            manager = new LifecycleManagerImpl();   
+        }
+        return manager;
+    }
+
+    public void setLifecycleManager(LifecycleManager manager) {
+        this.manager = manager;
+    }
+
+    /**
+     * Moves the pointer to the beginning of the first MIME part. Reads till first MIME boundary
is
+     * found or end of stream is reached.
+     *
+     * @param inStream
+     * @param contentTypeString
+     * @param fileCacheEnable
+     * @param attachmentRepoDir
+     * @throws OMException
+     */
+    public Attachments(LifecycleManager manager, InputStream inStream, String contentTypeString,
+                       boolean fileCacheEnable, String attachmentRepoDir,
+                       String fileThreshold) throws OMException {
+        this(manager, inStream, contentTypeString, fileCacheEnable, attachmentRepoDir, fileThreshold,
0);
+    }
+        
+        /**
+     * Moves the pointer to the beginning of the first MIME part. Reads
+     * till first MIME boundary is found or end of stream is reached.
+     *
+     * @param inStream
+     * @param contentTypeString
+     * @param fileCacheEnable
+     * @param attachmentRepoDir
+     * @param fileThreshold
+     * @param contentLength
+     * @throws OMException
+     */
+    public Attachments(LifecycleManager manager, InputStream inStream, String contentTypeString,
boolean fileCacheEnable,
+            String attachmentRepoDir, String fileThreshold, int contentLength) throws OMException
{
+        this.manager = manager;
+        this.contentLength = contentLength;
+        this.attachmentRepoDir = attachmentRepoDir;
+        this.fileCacheEnable = fileCacheEnable;
+        if (log.isDebugEnabled()) {
+            log.debug("Attachments contentLength=" + contentLength + ", contentTypeString="
+ contentTypeString);
+        }
+        if (fileThreshold != null && (!"".equals(fileThreshold))) {
+            this.fileStorageThreshold = Integer.parseInt(fileThreshold);
+        } else {
+            this.fileStorageThreshold = 1;
+        }
+        attachmentsMap = new TreeMap();
+        try {
+            contentType = new ContentType(contentTypeString);
+        } catch (ParseException e) {
+            throw new OMException(
+                    "Invalid Content Type Field in the Mime Message"
+                    , e);
+        }
+        // REVIEW: This conversion is hard-coded to UTF-8.
+        // The complete solution is to respect the charset setting of the message.
+        // However this may cause problems in BoundaryDelimittedStream and other
+        // lower level classes.
+
+        // Boundary always have the prefix "--".
+        try {
+            String encoding = contentType.getParameter("charset");
+            if(encoding == null || encoding.length()==0){
+                encoding = "UTF-8";
+            }
+            String boundaryParam = contentType.getParameter("boundary");
+            if (boundaryParam == null) {
+                throw new OMException("Content-type has no 'boundary' parameter");
+            }
+            this.boundary = ("--" + boundaryParam).getBytes(encoding);
+            if (log.isDebugEnabled()) {
+                log.debug("boundary=" + new String(this.boundary));
+            }
+        } catch (UnsupportedEncodingException e) {
+            throw new OMException(e);
+        }
+
+        // If the length is not known, install a TeeInputStream
+        // so that we can retrieve it later.
+        InputStream is = inStream;
+        if (contentLength <= 0) {
+            filterIS = new DetachableInputStream(inStream);
+            is = filterIS;
+        }
+        pushbackInStream = new PushbackInputStream(is,
+                                                   PUSHBACK_SIZE);
+
+        // Move the read pointer to the beginning 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;
+                    }
+                } else if (value == -1) {
+                    throw new OMException(
+                            "Mime parts not found. Stream ended while searching for the boundary");
+                }
+            } catch (IOException e1) {
+                throw new OMException("Stream Error" + e1.toString(), e1);
+            }
+        }
+
+        // Read the SOAP part and cache it
+        getDataHandler(getSOAPPartContentID());
+
+        // Now reset partsRequested. SOAP part is a special case which is always 
+        // read beforehand, regardless of request.
+        partsRequested = false;
+    }
+
+    /**
+     * Moves the pointer to the beginning of the first MIME part. Reads till first MIME boundary
is
+     * found or end of stream is reached.
+     *
+     * @param inStream
+     * @param contentTypeString
+     * @param fileCacheEnable
+     * @param attachmentRepoDir
+     * @throws OMException
+     */
+    public Attachments(InputStream inStream, String contentTypeString,
+                       boolean fileCacheEnable, String attachmentRepoDir,
+                       String fileThreshold) throws OMException {
+        this(null, inStream, contentTypeString, fileCacheEnable, attachmentRepoDir, fileThreshold,
0);
+    }
+        
+        /**
+     * Moves the pointer to the beginning of the first MIME part. Reads
+     * till first MIME boundary is found or end of stream is reached.
+     *
+     * @param inStream
+     * @param contentTypeString
+     * @param fileCacheEnable
+     * @param attachmentRepoDir
+     * @param fileThreshold
+     * @param contentLength
+     * @throws OMException
+     */
+    public Attachments(InputStream inStream, String contentTypeString, boolean fileCacheEnable,
+            String attachmentRepoDir, String fileThreshold, int contentLength) throws OMException
{
+            this(null, inStream, contentTypeString, fileCacheEnable,
+            attachmentRepoDir, fileThreshold, contentLength);
+    }
+    /**
+     * Sets file cache to false.
+     *
+     * @param inStream
+     * @param contentTypeString
+     * @throws OMException
+     */
+    public Attachments(InputStream inStream, String contentTypeString)
+            throws OMException {
+        this(null, inStream, contentTypeString, false, null, null);
+    }
+
+    /**
+     * Use this constructor when instantiating this to store the attachments set programatically
+     * through the SwA API.
+     */
+    public Attachments() {
+        attachmentsMap = new TreeMap();
+        noStreams = true;
+    }
+
+    /**
+     * Identify the type of message (MTOM or SOAP with attachments) represented by this
+     * object.
+     * 
+     * @return One of the {@link MTOMConstants#MTOM_TYPE}, {@link MTOMConstants#SWA_TYPE}
+     *         or {@link MTOMConstants#SWA_TYPE_12} constants.
+     * @throws OMException if the message doesn't have one of the supported types, i.e. is
+     *         neither MTOM nor SOAP with attachments
+     */
+    public String getAttachmentSpecType() {
+        if (this.applicationType == null) {
+            applicationType = contentType.getParameter("type");
+            if ((MTOMConstants.MTOM_TYPE).equalsIgnoreCase(applicationType)) {
+                this.applicationType = MTOMConstants.MTOM_TYPE;
+            } else if ((MTOMConstants.SWA_TYPE).equalsIgnoreCase(applicationType)) {
+                this.applicationType = MTOMConstants.SWA_TYPE;
+            } else if ((MTOMConstants.SWA_TYPE_12).equalsIgnoreCase(applicationType)) {
+                this.applicationType = MTOMConstants.SWA_TYPE_12;
+            } else {
+                throw new OMException(
+                        "Invalid Application type. Support available for MTOM & SwA only.");
+            }
+        }
+        return this.applicationType;
+    }
+
+    /**
+     * Get the {@link DataHandler} object for the MIME part with a given content ID.
+     * 
+     * @param contentID
+     *            the raw content ID (without the surrounding angle brackets and <tt>cid:</tt>
+     *            prefix) of the MIME part
+     * @return the {@link DataHandler} of the MIME part referred by the content ID or
+     *         <code>null</code> if the MIME part referred by the content ID
does not exist
+     */
+    public DataHandler getDataHandler(String contentID) {
+        // Check whether the MIME part is already parsed by checking the attachments HashMap.
If it is
+        // not parsed yet then call the getNextPart() till the required part is found.
+        DataHandler dataHandler;
+        if (attachmentsMap.containsKey(contentID)) {
+            dataHandler = (DataHandler) attachmentsMap.get(contentID);
+            return dataHandler;
+        } else if (!noStreams) {
+            //This loop will be terminated by the Exceptions thrown if the Mime
+            // part searching was not found
+            while ((dataHandler = this.getNextPartDataHandler()) != null) {
+                if (attachmentsMap.containsKey(contentID)) {
+                    dataHandler = (DataHandler) attachmentsMap.get(contentID);
+                    return dataHandler;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Programatically adding an SOAP with Attachments(SwA) Attachment. These attachments
will get
+     * serialized only if SOAP with Attachments is enabled.
+     *
+     * @param contentID
+     * @param dataHandler
+     */
+    public void addDataHandler(String contentID, DataHandler dataHandler) {
+        attachmentsMap.put(contentID, dataHandler);
+        if (!cids.contains(contentID)) {
+            cids.add(contentID);
+        }
+    }
+
+    /**
+     * Removes the DataHandler corresponding to the given contenID. If it is not present,
then
+     * trying to find it calling the getNextPart() till the required part is found.
+     *
+     * @param blobContentID
+     */
+    public void removeDataHandler(String blobContentID) {
+        if (attachmentsMap.containsKey(blobContentID)) {
+            attachmentsMap.remove(blobContentID);
+        } else if (!noStreams) {
+            //This loop will be terminated by the Exceptions thrown if the Mime
+            // part searching was not found
+            while (this.getNextPartDataHandler() != null) {
+                if (attachmentsMap.containsKey(blobContentID)) {
+                    attachmentsMap.remove(blobContentID);
+                }
+            }
+        }
+        if (cids.contains(blobContentID)) {
+            cids.remove(blobContentID);
+        }
+    }
+
+    /**
+     * @return the InputStream which includes the SOAP Envelope. It assumes that the root
mime part
+     *         is always pointed by "start" parameter in content-type.
+     */
+    public InputStream getSOAPPartInputStream() throws OMException {
+        DataHandler dh;
+        if (noStreams) {
+            throw new OMException("Invalid operation. Attachments are created programatically.");
+        }
+        try {
+            dh = getDataHandler(getSOAPPartContentID());
+            if (dh == null) {
+                throw new OMException(
+                        "Mandatory Root MIME part containing the SOAP Envelope is missing");
+            }
+            return dh.getInputStream();
+        } catch (IOException e) {
+            throw new OMException(
+                    "Problem with DataHandler of the Root Mime Part. ", e);
+        }
+    }
+
+    /**
+     * Get the content ID of the SOAP part or the MIME message. This content ID is determined
as
+     * follows:
+     * <ul>
+     * <li>If the content type of the MIME message has a <tt>start</tt>
parameter, then the content
+     * ID will be extracted from that parameter.
+     * <li>Otherwise the content ID of the first MIME part of the MIME message is returned.
+     * </ul>
+     * 
+     * @return the content ID of the SOAP part (without the surrounding angle brackets)
+     */
+    public String getSOAPPartContentID() {
+        if(contentType == null) {
+            return null;
+        }
+        String rootContentID = contentType.getParameter("start");
+        if (log.isDebugEnabled()) {
+            log.debug("getSOAPPartContentID rootContentID=" + rootContentID);
+        }
+
+        // to handle the Start parameter not mentioned situation
+        if (rootContentID == null) {
+            if (partIndex == 0) {
+                getNextPartDataHandler();
+            }
+            rootContentID = firstPartId;
+        } else {
+            rootContentID = rootContentID.trim();
+
+            if ((rootContentID.indexOf("<") > -1)
+                    & (rootContentID.indexOf(">") > -1)) {
+                rootContentID = rootContentID.substring(1, (rootContentID
+                        .length() - 1));
+            }
+        }
+        // Strips off the "cid:" part from content-id
+        if (rootContentID.length() > 4
+                && "cid:".equalsIgnoreCase(rootContentID.substring(0, 4))) {
+            rootContentID = rootContentID.substring(4);
+        }
+        return rootContentID;
+    }
+
+    /**
+     * Get the content type of the SOAP part of the MIME message.
+     * 
+     * @return the content type of the SOAP part
+     * @throws OMException
+     *             if the content type could not be determined
+     */
+    public String getSOAPPartContentType() {
+        if (!noStreams) {
+            String soapPartContentID = getSOAPPartContentID();
+            if (soapPartContentID == null) {
+                throw new OMException("Unable to determine the content ID of the SOAP part");
+            }
+            DataHandler soapPart = getDataHandler(soapPartContentID);
+            if (soapPart == null) {
+                throw new OMException("Unable to locate the SOAP part; content ID was " +
soapPartContentID);
+            }
+            return soapPart.getContentType();
+        } else {
+            throw new OMException(
+                    "The attachments map was created programatically. Unsupported operation.");
+        }
+    }
+
+    /**
+     * Stream based access
+     *
+     * @return The stream container of type <code>IncomingAttachmentStreams</code>
+     * @throws IllegalStateException if application has alreadt started using Part's directly
+     */
+    public IncomingAttachmentStreams getIncomingAttachmentStreams()
+            throws IllegalStateException {
+        if (partsRequested) {
+            throw new IllegalStateException(
+                    "The attachments stream can only be accessed once; either by using the
IncomingAttachmentStreams class or by getting a " +
+                            "collection of AttachmentPart objects. They cannot both be called
within the life time of the same service request.");
+        }
+        if (noStreams) {
+            throw new IllegalStateException(
+                    "The attachments map was created programatically. No streams are available.");
+        }
+
+        streamsRequested = true;
+
+        if (this.streams == null) {
+            BoundaryDelimitedStream boundaryDelimitedStream =
+                    new BoundaryDelimitedStream(pushbackInStream,
+                                                boundary, 1024);
+
+            this.streams = new MultipartAttachmentStreams(boundaryDelimitedStream);
+        }
+
+        return this.streams;
+    }
+
+    /**
+     * Force reading of all attachments.
+     */
+    private void fetchAllParts() {
+        DataHandler dataHandler;
+        while (!noStreams) {
+            dataHandler = this.getNextPartDataHandler();
+            if (dataHandler == null) {
+                break;
+            }
+        }
+    }
+
+    /**
+     * Get the content IDs of all MIME parts in the message. This includes the content ID
of the
+     * SOAP part as well as the content IDs of the attachments. Note that if this object
has been
+     * created from a stream, a call to this method will force reading of all MIME parts
that
+     * have not been fetched from the stream yet.
+     * 
+     * @return an array with the content IDs in order of appearance in the message
+     */
+    public String[] getAllContentIDs() {
+        fetchAllParts();
+        return (String[]) cids.toArray(new String[cids.size()]);
+    }
+
+    /**
+     * Get the content IDs of all MIME parts in the message. This includes the content ID
of the
+     * SOAP part as well as the content IDs of the attachments. Note that if this object
has been
+     * created from a stream, a call to this method will force reading of all MIME parts
that
+     * have not been fetched from the stream yet.
+     * 
+     * @return the set of content IDs
+     */
+    public Set getContentIDSet() {
+        fetchAllParts();
+        return attachmentsMap.keySet();
+    }
+    
+    /**
+     * Get a map of all MIME parts in the message. This includes the SOAP part as well as
the
+     * attachments. Note that if this object has been created from a stream, a call to this
+     * method will force reading of all MIME parts that have not been fetched from the stream
yet.
+     * 
+     * @return A map of all MIME parts in the message, with content IDs as keys and
+     *         {@link DataHandler} objects as values.
+     */
+    public Map getMap() {
+        fetchAllParts();
+        return Collections.unmodifiableMap(attachmentsMap);
+    }
+
+    /**
+     * Get the content IDs of the already loaded MIME parts in the message. This includes
the
+     * content ID of the SOAP part as well as the content IDs of the attachments. If this
+     * object has been created from a stream, only the content IDs of the MIME parts that
+     * have already been fetched from the stream are returned. If this is not the desired
+     * behavior, {@link #getAllContentIDs()} or {@link #getContentIDSet()} should be used
+     * instead.
+     * 
+     * @return List of content IDs in order of appearance in message
+     */
+    public List getContentIDList() {
+        return cids;
+    }
+    
+    /**
+     * If the Attachments is backed by an InputStream, then this
+     * method returns the length of the message contents
+     * (Length of the entire message - Length of the Transport Headers)
+     * @return length of message content or -1 if Attachments is not
+     * backed by an InputStream
+     */
+    public long getContentLength() throws IOException {
+        if (contentLength > 0) {
+            return contentLength;
+        } else if (filterIS != null) {
+            // Ensure all parts are read
+            this.getContentIDSet();
+            // Now get the count from the filter
+            return filterIS.length();
+        } else {
+            return -1; // not backed by an input stream
+        }
+    }
+    
+    /**
+     * endOfStreamReached will be set to true if the message ended in MIME Style having "--"
suffix
+     * with the last mime boundary
+     *
+     * @param value
+     */
+    protected void setEndOfStream(boolean value) {
+        this.endOfStreamReached = value;
+    }
+
+    /**
+     * Returns the rest of mime stream. It will contain all attachments without
+     * soappart (first attachment) with headers and mime boundary. Raw content! 
+     */
+    public InputStream getIncomingAttachmentsAsSingleStream() throws IllegalStateException
{
+        if (partsRequested) {
+            throw new IllegalStateException(
+                    "The attachments stream can only be accessed once; either by using the
IncomingAttachmentStreams class or by getting a " +
+                            "collection of AttachmentPart objects. They cannot both be called
within the life time of the same service request.");
+        }
+        if (noStreams) {
+            throw new IllegalStateException(
+                    "The attachments map was created programatically. No streams are available.");
+        }
+
+        streamsRequested = true;
+
+    	return this.pushbackInStream;
+    }
+
+    /**
+     * @return the Next valid MIME part + store the Part in the Parts List
+     * @throws OMException throw if content id is null or if two MIME parts contain the same
+     *                     content-ID & the exceptions throws by getPart()
+     */
+    private DataHandler getNextPartDataHandler() throws OMException {
+        if (endOfStreamReached) {
+            return null;
+        }
+        Part nextPart;
+        nextPart = getPart();
+        if (nextPart == null) {
+            return null;
+        } else
+            try {
+                long size = nextPart.getSize();
+                String partContentID;
+                DataHandler dataHandler;
+                try {
+                    partContentID = nextPart.getContentID();
+
+                    if (partContentID == null & partIndex == 1) {
+                        String id = "firstPart_" + UIDGenerator.generateContentId();
+                        firstPartId = id;
+                        if (size > 0) {
+                            dataHandler = nextPart.getDataHandler();
+                        } else {
+                            // Either the mime part is empty or the stream ended without
having 
+                            // a MIME message terminator
+                            dataHandler = new DataHandler(new ByteArrayDataSource(new byte[]{}));
+                        }
+                        addDataHandler(id, dataHandler);
+                        return dataHandler;
+                    }
+                    if (partContentID == null) {
+                        throw new OMException(
+                                "Part content ID cannot be blank for non root MIME parts");
+                    }
+                    if ((partContentID.indexOf("<") > -1)
+                            & (partContentID.indexOf(">") > -1)) {
+                        partContentID = partContentID.substring(1, (partContentID
+                                .length() - 1));
+
+                    }
+                    if (partIndex == 1) {
+                        firstPartId = partContentID;
+                    }
+                    if (attachmentsMap.containsKey(partContentID)) {
+                        throw new OMException(
+                                "Two MIME parts with the same Content-ID not allowed.");
+                    }
+                    if (size > 0) {
+                        dataHandler = nextPart.getDataHandler();
+                    } else {
+                        // Either the mime part is empty or the stream ended without having

+                        // a MIME message terminator
+                        dataHandler = new DataHandler(new ByteArrayDataSource(new byte[]{}));
+                    }
+                    addDataHandler(partContentID, dataHandler);
+                    return dataHandler;
+                } catch (MessagingException e) {
+                    throw new OMException("Error reading Content-ID from the Part."
+                            + e);
+                }
+            } catch (MessagingException e) {
+                throw new OMException(e);
+            }
+    }
+
+    /**
+     * @return This will return the next available MIME part in the stream.
+     * @throws OMException if Stream ends while reading the next part...
+     */
+    private Part getPart() throws OMException {
+
+        if (streamsRequested) {
+            throw new IllegalStateException("The attachments stream can only be accessed
once; either by using the IncomingAttachmentStreams class or by getting a collection of AttachmentPart
objects. They cannot both be called within the life time of the same service request.");
+        }
+
+        partsRequested = true;
+
+        boolean isSOAPPart = (partIndex == 0);
+        int threshhold = (fileCacheEnable) ? fileStorageThreshold : 0;
+
+        // Create a MIMEBodyPartInputStream that simulates a single stream for this MIME
body part
+        MIMEBodyPartInputStream partStream =
+            new MIMEBodyPartInputStream(pushbackInStream,
+                                        boundary,
+                                        this,
+                                        PUSHBACK_SIZE);
+
+        // The PartFactory will determine which Part implementation is most appropriate.
+        Part part = PartFactory.createPart(getLifecycleManager(), partStream, 
+                                      isSOAPPart, 
+                                      threshhold, 
+                                      attachmentRepoDir, 
+                                      contentLength);  // content-length for the whole message
+        partIndex++;
+        return part;
+    }
+    
+    /**
+     * Read bytes into the buffer until full or until the EOS
+     * @param is
+     * @param buffer
+     * @return number of bytes read
+     * @throws IOException
+     */
+    private static int readToBuffer(InputStream is, byte[] buffer) throws IOException {
+        int index = 0;
+        int remainder = buffer.length;
+        do {
+            int bytesRead;
+            while ((bytesRead = is.read(buffer, index, remainder)) > 0) {
+                index += bytesRead;
+                remainder -= bytesRead;
+            }
+        } while (remainder > 0 && is.available() > 0);  // repeat if more bytes
are now available
+        return index;
+    }
+}
\ No newline at end of file

Propchange: geronimo/bundles/trunk/axiom-all/src/main/java/org/apache/axiom/attachments/Attachments.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/bundles/trunk/axiom-all/src/main/java/org/apache/axiom/attachments/Attachments.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/bundles/trunk/axiom-all/src/main/java/org/apache/axiom/attachments/Attachments.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message