All Downloads are FREE. Search and download functionalities are using the official Maven repository.

android.gov.nist.javax.sip.message.MultipartMimeContentImpl Maven / Gradle / Ivy

There is a newer version: 1.3.0-91
Show newest version
/*
 * Conditions Of Use 
 * 
 * This software was developed by employees of the National Institute of
 * Standards and Technology (NIST), an agency of the Federal Government.
 * Pursuant to title 15 Untied States Code Section 105, works of NIST
 * employees are not subject to copyright protection in the United States
 * and are considered to be in the public domain.  As a result, a formal
 * license is not needed to use the software.
 * 
 * This software is provided by NIST as a service and is expressly
 * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
 * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
 * AND DATA ACCURACY.  NIST does not warrant or make any representations
 * regarding the use of the software or the results thereof, including but
 * not limited to the correctness, accuracy, reliability or usefulness of
 * the software.
 * 
 * Permission to use this software is contingent upon your acceptance
 * of the terms of this agreement
 *  
 * .
 * 
 */
/*******************************************************************************
 * Product of NIST/ITL Advanced Networking Technologies Division (ANTD)         *
 *******************************************************************************/
package android.gov.nist.javax.sip.message;

import android.gov.nist.core.Separators;
import android.gov.nist.javax.sip.header.HeaderFactoryExt;
import android.gov.nist.javax.sip.header.HeaderFactoryImpl;

import java.text.ParseException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Scanner;

import android.javax.sip.header.ContentDispositionHeader;
import android.javax.sip.header.ContentTypeHeader;
import android.javax.sip.header.Header;

/**
 * Content list for multipart mime content type.
 * 
 * WARNING -- do not directly cast to this this class.
 * Use the methods of the interface that it implements.
 * 
 * 
 * @author M. Ranganathan
 * 
 */
public class MultipartMimeContentImpl implements MultipartMimeContent {
  public static final String BOUNDARY = "boundary";
  private List contentList = new LinkedList();
  private HeaderFactoryExt headerFactory = new HeaderFactoryImpl();
  private ContentTypeHeader multipartMimeContentTypeHeader;
  private String boundary;

  
  /**
   * Creates a default content list.
   */
  public MultipartMimeContentImpl(ContentTypeHeader contentTypeHeader) {
    this.multipartMimeContentTypeHeader = contentTypeHeader;
    this.boundary = contentTypeHeader.getParameter(BOUNDARY);

  }

  /*
   * (non-Javadoc)
   * 
   * @see android.gov.nist.javax.sip.message.MultipartMimeContentExt#add(android.gov.nist.javax.sip.message.Content)
   */
  public boolean add(Content content) {
    return contentList.add((ContentImpl) content);
  }

  /*
   * (non-Javadoc)
   * 
   * @see android.gov.nist.javax.sip.message.MultipartMimeContentExt#getContentTypeHeader()
   */
  public ContentTypeHeader getContentTypeHeader() {
    return multipartMimeContentTypeHeader;
  }

  /*
   * (non-Javadoc)
   * 
   * @see android.gov.nist.javax.sip.message.MultipartMimeContentExt#toString()
   */
  @Override
  public String toString() {
    StringBuilder result = new StringBuilder();

    for (Content content : this.contentList) {
      result.append("--" + boundary + Separators.NEWLINE);
      result.append(content.toString());
      result.append(Separators.NEWLINE);
    }

    if (!contentList.isEmpty()) {
      result.append("--" + boundary + "--");
    }

    return result.toString();

  }

  /**
   * unpack a multipart mime packet and set a list of content packets.
   * 
   * @return -- an iterator of Content blocks.
   * 
   */
  public void createContentList(String body) throws ParseException {
    if (boundary != null) {
      Scanner scanner = new Scanner(body);
      // scanner.useDelimiter("--" + boundary + "(--)?\r?\n?");
      scanner.useDelimiter("\r?\n?--" + boundary + "(--)?\r?\n?");
      while (scanner.hasNext()) {
    	  try {
    		  String bodyPart = scanner.next();
    		  Content partContent = parseBodyPart(bodyPart);
    		  contentList.add(partContent);
    	  } catch (NoSuchElementException e) {
    		  // ignore
    	    // this is needed for a jain sip bug #16: the scanner which detects an extra
    	    // delimiter when the body is a multiple of the buffer size
    	  }
      }
    } else {
      // No boundary had been set, we will consider the body as a single part
      ContentImpl content = parseBodyPart(body);
      content.setContentTypeHeader(this.getContentTypeHeader());
      this.contentList.add(content);
    }
  }

  private ContentImpl parseBodyPart(String bodyPart) throws ParseException {
    String headers[] = null;
    String bodyContent;
    
    // if a empty line starts the body it means no headers are present
    if (bodyPart.startsWith("\n") || bodyPart.startsWith("\r\n")) {
      bodyContent = bodyPart;
    } else {
      // limit the number of crlf (new lines) we split on, only split the header from
      // the body and don't split on any crlf in the body  
      String[] nextPartSplit = bodyPart.split("\r?\n\r?\n", 2);

      bodyContent = bodyPart;
      
      if (nextPartSplit.length == 2) {
        // since we aren't completely sure the data is a header let's test the first one
        String potentialHeaders[] = nextPartSplit[0].split("\r?\n");
        if (potentialHeaders[0].indexOf(":") > 0) {
          headers = potentialHeaders;
          bodyContent = nextPartSplit[1];
        }
      }
    }
    
    ContentImpl content = new ContentImpl(bodyContent);
    if (headers != null) {
      for (String partHeader : headers) {
        Header header = headerFactory.createHeader(partHeader);
        if (header instanceof ContentTypeHeader) {
          content.setContentTypeHeader((ContentTypeHeader) header);
        } else if (header instanceof ContentDispositionHeader) {
          content.setContentDispositionHeader((ContentDispositionHeader) header);
        } else {
          content.addExtensionHeader(header);
        }
      }
    }
    return content;
  }

  /*
   * (non-Javadoc)
   * 
   * @see android.gov.nist.javax.sip.message.MultipartMimeContentExt#setContent(java.lang.String,
   * java.lang.String, android.gov.nist.javax.sip.message.Content)
   */
  public void addContent(Content content) {
    this.add(content);
  }

  public Iterator getContents() {
    return this.contentList.iterator();
  }

  public int getContentCount() {
    return this.contentList.size();
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy