Package org.apache.axis2.attachments

Source Code of org.apache.axis2.attachments.MIMEHelper

/**
* 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.axis2.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.axis2.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 = "text/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;
 
  String firstPartId=null;

  boolean fileCacheEnable = false;

  String attachmentRepoDir = null;

  public MIMEHelper(InputStream inStream, String contentTypeString,
      boolean fileCacheEnable, String attachmentRepoDir)
      throws OMException {
    this.attachmentRepoDir = attachmentRepoDir;
    this.fileCacheEnable = fileCacheEnable;
    bodyPartsMap = new HashMap();
    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;
          }
        } else if ((byte) 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());
      }
    }
  }
 
  public MIMEHelper(InputStream inStream, String contentTypeString)
      throws OMException {
    this(inStream,contentTypeString,false,null);
  }

  /**
   * @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 We assumes that
   *         the root mime part is always pointed by "start" parameter in
   *         content-type
   */
  public InputStream getSOAPPartInputStream() throws OMException {
    String rootContentID = contentType.getParameter("start");
    // to handle the Start parameter not mentioned situation
    if (rootContentID==null)
    {
      if (partIndex==0)
      {
      getNextPart();
      }
      rootContentID=firstPartId;     
    }
    else
    {
    rootContentID.trim();
    rootContentID = rootContentID
        .substring(1, (rootContentID.length() - 1));
    }
    DataHandler dh;
    try {
      dh = getDataHandler(rootContentID);
      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);
    }
  }

  /**
   * @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.
   */
  public DataHandler getDataHandler(String blobContentID) throws OMException {

    Part bodyPart;
    blobContentID = "<" + blobContentID + ">";
    boolean attachmentFound = false;

    //    // without the following part a Null Pointer Exception is thrown
    //   
    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.getNextPart();
          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;

    MimeBodyPartInputStream partStream;
        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 Part getNextPart() throws OMException {
    MimeBodyPart nextMimeBodyPart;
    nextMimeBodyPart = getMimeBodyPart();
    if (nextMimeBodyPart != null) {
      String partContentID;
      try {
        partContentID = nextMimeBodyPart.getContentID();
        if (partContentID==null & partIndex==1)
        {
          bodyPartsMap.put("firstPart", nextMimeBodyPart);
          firstPartId = "firstPart";
          return nextMimeBodyPart;
        }
        else  if (partIndex==1)
        {
          firstPartId = partContentID;
        }
        if (fileCacheEnable)
        {
          PartOnFile part = new PartOnFile(nextMimeBodyPart,partContentID,attachmentRepoDir);
          return part;
        }
        else{
          bodyPartsMap.put(partContentID, nextMimeBodyPart);
          return nextMimeBodyPart;
       
      } catch (MessagingException e) {
        throw new OMException(
            "Error Reading Content-ID from Mime Part No "
                + partIndex + ". " + e);
      } catch (Exception e) {
        throw new OMException(
            "Error Creating File  Storage Part"
                + partIndex + ". " + e);
      }
    } else
      return null;
  }

}
TOP

Related Classes of org.apache.axis2.attachments.MIMEHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.