• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
MultipartMimeContentImpl(ContentTypeHeader contentTypeHeader)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      */
add(Content content)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      */
getContentTypeHeader()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
toString()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      */
createContentList(String body)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      */
getContentByType(String contentType, String contentSubtype)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      */
addContent(Content content)177     public void addContent(Content content) {
178         this.add(content);
179     }
180 
getContents()181     public Iterator<Content> getContents() {
182         return this.contentList.iterator();
183     }
184 
185 
getContentCount()186     public int getContentCount() {
187         return this.contentList.size();
188     }
189 
190 }
191