| package gov.nist.javax.sip.message; |
| |
| import gov.nist.javax.sip.header.HeaderFactoryExt; |
| import gov.nist.javax.sip.header.HeaderFactoryImpl; |
| import gov.nist.javax.sip.parser.StringMsgParser; |
| |
| import java.text.ParseException; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| import javax.sip.header.ContentDispositionHeader; |
| import javax.sip.header.ContentTypeHeader; |
| import javax.sip.header.Header; |
| import javax.sip.header.HeaderFactory; |
| import javax.sip.message.Message; |
| |
| |
| |
| /** |
| * Content list for multipart mime content type. |
| * |
| * @author M. Ranganathan |
| * |
| */ |
| public class MultipartMimeContentImpl implements MultipartMimeContent { |
| private List<Content> contentList = new LinkedList<Content>(); |
| |
| private ContentTypeHeader multipartMimeContentTypeHeader; |
| |
| private String boundary; |
| |
| public static String BOUNDARY = "boundary"; |
| |
| /** |
| * Creates a default content list. |
| */ |
| public MultipartMimeContentImpl(ContentTypeHeader contentTypeHeader) { |
| this.multipartMimeContentTypeHeader = contentTypeHeader; |
| this.boundary = contentTypeHeader.getParameter(BOUNDARY); |
| |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see gov.nist.javax.sip.message.MultipartMimeContentExt#add(gov.nist.javax.sip.message.Content) |
| */ |
| public boolean add(Content content) { |
| return contentList.add((ContentImpl) content); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see gov.nist.javax.sip.message.MultipartMimeContentExt#getContentTypeHeader() |
| */ |
| public ContentTypeHeader getContentTypeHeader() { |
| return multipartMimeContentTypeHeader; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see gov.nist.javax.sip.message.MultipartMimeContentExt#toString() |
| */ |
| @Override |
| public String toString() { |
| StringBuffer stringBuffer = new StringBuffer(); |
| |
| for (Content content : this.contentList) { |
| stringBuffer.append(content.toString()); |
| } |
| return stringBuffer.toString(); |
| |
| } |
| |
| /** |
| * unpack a multipart mime packet and return a list of content packets. |
| * |
| * @return -- an iterator of Content blocks. |
| * |
| */ |
| public void createContentList(String body) throws ParseException { |
| try { |
| HeaderFactoryExt headerFactory = new HeaderFactoryImpl(); |
| String delimiter = this.getContentTypeHeader().getParameter(BOUNDARY); |
| |
| if (delimiter == null) { |
| this.contentList = new LinkedList<Content>(); |
| ContentImpl content = new ContentImpl(body, delimiter); |
| content.setContentTypeHeader(this.getContentTypeHeader()); |
| this.contentList.add(content); |
| return; |
| } |
| |
| String[] fragments = body.split("--" + delimiter + "\r\n"); |
| |
| |
| for (String nextPart : fragments) { |
| // NOTE - we are not hanlding line folding for the sip header here. |
| |
| if (nextPart == null) { |
| return; |
| } |
| StringBuffer strbuf = new StringBuffer(nextPart); |
| while (strbuf.length() > 0 |
| && (strbuf.charAt(0) == '\r' || strbuf.charAt(0) == '\n')) |
| strbuf.deleteCharAt(0); |
| |
| if (strbuf.length() == 0) |
| continue; |
| nextPart = strbuf.toString(); |
| int position = nextPart.indexOf("\r\n\r\n"); |
| int off = 4; |
| if (position == -1) { |
| position = nextPart.indexOf("\n"); |
| off = 2; |
| } |
| if (position == -1) |
| throw new ParseException("no content type header found in " + nextPart, 0); |
| String rest = nextPart.substring(position + off); |
| |
| if (rest == null) |
| throw new ParseException("No content [" + nextPart + "]", 0); |
| // logger.debug("rest = [[" + rest + "]]"); |
| String headers = nextPart.substring(0, position); |
| ContentImpl content = new ContentImpl(rest, boundary); |
| |
| String[] headerArray = headers.split("\r\n"); |
| for (String hdr : headerArray) { |
| Header header = headerFactory.createHeader(hdr); |
| if (header instanceof ContentTypeHeader) { |
| content.setContentTypeHeader((ContentTypeHeader) header); |
| } else if (header instanceof ContentDispositionHeader) { |
| content.setContentDispositionHeader((ContentDispositionHeader) header); |
| } else { |
| throw new ParseException("Unexpected header type " + header.getName(), 0); |
| } |
| contentList.add(content); |
| } |
| |
| } |
| } catch (StringIndexOutOfBoundsException ex) { |
| throw new ParseException("Invalid Multipart mime format", 0); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see gov.nist.javax.sip.message.MultipartMimeContentExt#getContentByType(java.lang.String, |
| * java.lang.String) |
| */ |
| public Content getContentByType(String contentType, String contentSubtype) { |
| Content retval = null; |
| if (contentList == null) |
| return null; |
| for (Content content : contentList) { |
| if (content.getContentTypeHeader().getContentType().equalsIgnoreCase(contentType) |
| && content.getContentTypeHeader().getContentSubType().equalsIgnoreCase( |
| contentSubtype)) { |
| retval = content; |
| break; |
| } |
| |
| } |
| return retval; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see gov.nist.javax.sip.message.MultipartMimeContentExt#setContent(java.lang.String, |
| * java.lang.String, gov.nist.javax.sip.message.Content) |
| */ |
| public void addContent(Content content) { |
| this.add(content); |
| } |
| |
| public Iterator<Content> getContents() { |
| return this.contentList.iterator(); |
| } |
| |
| |
| public int getContentCount() { |
| return this.contentList.size(); |
| } |
| |
| } |