package com.bluevia.android.messagery.mo.mms.parser;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import com.bluevia.android.commons.Entity;
import com.bluevia.android.commons.parser.IParser;
import com.bluevia.android.commons.parser.ParseException;
import com.bluevia.android.messagery.mo.mms.data.MimeContent;
import com.bluevia.android.messagery.mo.mms.data.MmsMessage;
import com.bluevia.android.messagery.mo.mms.data.MmsMessageInfo;
/**
* Multipart MMS parser
*
*/
public class MultipartMmsParser {
private IParser mParser;
public MultipartMmsParser(IParser parser){
mParser = parser;
}
public MmsMessage parseMultipart(MimeMultipart multipart) throws ParseException {
MmsMessage result = null;
try {
if (multipart == null)
return null;
if (multipart.getCount() < 2) //At least 2: "root-fields" & "multiparts"
return null;
result = new MmsMessage();
String[] headers = null;
//Parse root-fields
BodyPart rootFieldsPart = multipart.getBodyPart(0);
headers = rootFieldsPart.getHeader("Content-Disposition");
if (headers != null && headers.length > 0 && headers[0] != null && headers[0].contains("root-fields")){
if (rootFieldsPart.getContent() instanceof ByteArrayInputStream){
ByteArrayInputStream is = (ByteArrayInputStream) rootFieldsPart.getContent();
Entity entity = mParser.parse(is);
is.close();
if (entity instanceof MmsMessageInfo){
result.setMessageInfo((MmsMessageInfo) entity);
} else throw new ParseException("Error parsing multipart: no message info");
}
}
BodyPart attachmentsPart = multipart.getBodyPart(1);
headers = attachmentsPart.getHeader("Content-Disposition");
if (headers != null && headers.length > 0 && headers[0] != null && headers[0].contains("attachments")){
ArrayList<MimeContent> attachList = new ArrayList<MimeContent>();
headers = attachmentsPart.getHeader("Content-Type");
if (headers != null && headers.length > 0 && headers[0] != null){
if (headers[0].contains("multipart")){
//Multipart/mixed or related
MimeMultipart attachments = null;
if (attachmentsPart.getContent() instanceof MimeMultipart){
attachments = (MimeMultipart) attachmentsPart.getContent();
} else if (attachmentsPart.getContent() instanceof InputStream){
ByteArrayDataSource ds = new ByteArrayDataSource((InputStream) attachmentsPart.getContent(),
headers[0]);
attachments = new MimeMultipart(ds);
}
if (attachments != null){
for (int i=0; i<attachments.getCount(); i++){
BodyPart part = attachments.getBodyPart(i);
String contentType = part.getContentType();
String contentDisp = null;
String[] cte = part.getHeader("Content-Transfer-Encoding");
if (cte != null && cte.length > 0)
contentDisp = cte[0];
Object content = part.getContent();
MimeContent mime = buildMimeContent(contentType, contentDisp, content, false);
attachList.add(mime);
}
}
}
}
result.setAttachments(attachList);
}
} catch (MessagingException e){
throw new ParseException("Error parsing multipart: " + e.getLocalizedMessage(), e);
} catch (IOException e) {
throw new ParseException("Error parsing multipart: " + e.getLocalizedMessage(), e);
}
return result;
}
public MimeContent buildMimeContent(String contentType, String contentDisp, Object content, boolean useAttachments)
throws IOException{
MimeContent mimeContent = new MimeContent();
//Content-Type
Pattern p = null;
if (useAttachments)
p = Pattern.compile("(.*);(.*);(.*)");
else p = Pattern.compile("(.*);(.*)");
Matcher m = p.matcher(contentType);
if (m.matches()){
mimeContent.setContentType(m.group(1));
} else mimeContent.setContentType(contentType);
//Content-Transfer-Encoding
mimeContent.setEncoding(contentDisp);
//Filename
Pattern pattern;
if (useAttachments)
pattern = Pattern.compile("(.*)ame=(.*);(.*)");
else pattern = Pattern.compile("(.*)ame=(.*)");
Matcher matcher = pattern.matcher(contentType);
if (matcher.matches()){
mimeContent.setName(matcher.group(2));
}
//Content
if (content instanceof String){
mimeContent.setContent(content);
} else if (content instanceof InputStream){
InputStream is = (InputStream) content;
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int read = 0;
while ((read = is.read(buf)) != -1) {
os.write(buf, 0, read);
}
mimeContent.setContent(os.toByteArray());
is.close();
}
return mimeContent;
}
}