Home | History | Annotate | Download | only in message
      1 package gov.nist.javax.sip.message;
      2 
      3 import gov.nist.javax.sip.header.HeaderFactoryExt;
      4 import gov.nist.javax.sip.header.HeaderFactoryImpl;
      5 import gov.nist.javax.sip.parser.StringMsgParser;
      6 
      7 import java.text.ParseException;
      8 import java.util.Iterator;
      9 import java.util.LinkedList;
     10 import java.util.List;
     11 
     12 import javax.sip.header.ContentDispositionHeader;
     13 import javax.sip.header.ContentTypeHeader;
     14 import javax.sip.header.Header;
     15 import javax.sip.header.HeaderFactory;
     16 import javax.sip.message.Message;
     17 
     18 
     19 
     20 /**
     21  * Content list for multipart mime content type.
     22  *
     23  * @author M. Ranganathan
     24  *
     25  */
     26 public class MultipartMimeContentImpl implements MultipartMimeContent {
     27     private List<Content> contentList = new LinkedList<Content>();
     28 
     29     private ContentTypeHeader multipartMimeContentTypeHeader;
     30 
     31     private String boundary;
     32 
     33     public static String BOUNDARY = "boundary";
     34 
     35     /**
     36      * Creates a default content list.
     37      */
     38     public MultipartMimeContentImpl(ContentTypeHeader contentTypeHeader) {
     39         this.multipartMimeContentTypeHeader = contentTypeHeader;
     40         this.boundary = contentTypeHeader.getParameter(BOUNDARY);
     41 
     42     }
     43 
     44     /*
     45      * (non-Javadoc)
     46      *
     47      * @see gov.nist.javax.sip.message.MultipartMimeContentExt#add(gov.nist.javax.sip.message.Content)
     48      */
     49     public boolean add(Content content) {
     50         return contentList.add((ContentImpl) content);
     51     }
     52 
     53     /*
     54      * (non-Javadoc)
     55      *
     56      * @see gov.nist.javax.sip.message.MultipartMimeContentExt#getContentTypeHeader()
     57      */
     58     public ContentTypeHeader getContentTypeHeader() {
     59         return multipartMimeContentTypeHeader;
     60     }
     61 
     62     /*
     63      * (non-Javadoc)
     64      *
     65      * @see gov.nist.javax.sip.message.MultipartMimeContentExt#toString()
     66      */
     67     @Override
     68     public String toString() {
     69         StringBuffer stringBuffer = new StringBuffer();
     70 
     71         for (Content content : this.contentList) {
     72             stringBuffer.append(content.toString());
     73         }
     74         return stringBuffer.toString();
     75 
     76     }
     77 
     78     /**
     79      * unpack a multipart mime packet and return a list of content packets.
     80      *
     81      * @return -- an iterator of Content blocks.
     82      *
     83      */
     84     public void createContentList(String body) throws ParseException {
     85         try {
     86             HeaderFactoryExt headerFactory = new HeaderFactoryImpl();
     87             String delimiter = this.getContentTypeHeader().getParameter(BOUNDARY);
     88 
     89             if (delimiter == null) {
     90                 this.contentList = new LinkedList<Content>();
     91                 ContentImpl content = new ContentImpl(body, delimiter);
     92                 content.setContentTypeHeader(this.getContentTypeHeader());
     93                 this.contentList.add(content);
     94                 return;
     95             }
     96 
     97             String[] fragments = body.split("--" + delimiter + "\r\n");
     98 
     99 
    100             for (String nextPart : fragments) {
    101                 // NOTE - we are not hanlding line folding for the sip header here.
    102 
    103                 if (nextPart == null) {
    104                     return;
    105                 }
    106                 StringBuffer strbuf = new StringBuffer(nextPart);
    107                 while (strbuf.length() > 0
    108                         && (strbuf.charAt(0) == '\r' || strbuf.charAt(0) == '\n'))
    109                     strbuf.deleteCharAt(0);
    110 
    111                 if (strbuf.length() == 0)
    112                     continue;
    113                 nextPart = strbuf.toString();
    114                 int position = nextPart.indexOf("\r\n\r\n");
    115                 int off = 4;
    116                 if (position == -1) {
    117                     position = nextPart.indexOf("\n");
    118                     off = 2;
    119                 }
    120                 if (position == -1)
    121                     throw new ParseException("no content type header found in " + nextPart, 0);
    122                 String rest = nextPart.substring(position + off);
    123 
    124                 if (rest == null)
    125                     throw new ParseException("No content [" + nextPart + "]", 0);
    126                 // logger.debug("rest = [[" + rest + "]]");
    127                 String headers = nextPart.substring(0, position);
    128                 ContentImpl content = new ContentImpl(rest, boundary);
    129 
    130                 String[] headerArray = headers.split("\r\n");
    131                 for (String hdr : headerArray) {
    132                     Header header = headerFactory.createHeader(hdr);
    133                     if (header instanceof ContentTypeHeader) {
    134                         content.setContentTypeHeader((ContentTypeHeader) header);
    135                     } else if (header instanceof ContentDispositionHeader) {
    136                         content.setContentDispositionHeader((ContentDispositionHeader) header);
    137                     } else {
    138                         throw new ParseException("Unexpected header type " + header.getName(), 0);
    139                     }
    140                     contentList.add(content);
    141                 }
    142 
    143             }
    144         } catch (StringIndexOutOfBoundsException ex) {
    145             throw new ParseException("Invalid Multipart mime format", 0);
    146         }
    147     }
    148 
    149     /*
    150      * (non-Javadoc)
    151      *
    152      * @see gov.nist.javax.sip.message.MultipartMimeContentExt#getContentByType(java.lang.String,
    153      *      java.lang.String)
    154      */
    155     public Content getContentByType(String contentType, String contentSubtype) {
    156         Content retval = null;
    157         if (contentList == null)
    158             return null;
    159         for (Content content : contentList) {
    160             if (content.getContentTypeHeader().getContentType().equalsIgnoreCase(contentType)
    161                     && content.getContentTypeHeader().getContentSubType().equalsIgnoreCase(
    162                             contentSubtype)) {
    163                 retval = content;
    164                 break;
    165             }
    166 
    167         }
    168         return retval;
    169     }
    170 
    171     /*
    172      * (non-Javadoc)
    173      *
    174      * @see gov.nist.javax.sip.message.MultipartMimeContentExt#setContent(java.lang.String,
    175      *      java.lang.String, gov.nist.javax.sip.message.Content)
    176      */
    177     public void addContent(Content content) {
    178         this.add(content);
    179     }
    180 
    181     public Iterator<Content> getContents() {
    182         return this.contentList.iterator();
    183     }
    184 
    185 
    186     public int getContentCount() {
    187         return this.contentList.size();
    188     }
    189 
    190 }
    191