/*
* MultipartMap.java
*
* Created on October 26, 2003, 12:03 PM
*/
package gov.nist.registry.common2.soap;
import gov.nist.registry.common2.ContentDisposition;
import gov.nist.registry.common2.exception.ExceptionUtil;
import java.io.InputStream;
import java.io.StringBufferInputStream;
import java.util.Enumeration;
import java.util.HashMap;
import javax.mail.internet.MimeBodyPart;
import javax.servlet.http.HttpServletRequest;
import org.apache.soap.util.mime.ByteArrayDataSource;
/**
* Class used for easier manipulation of Multipart MIME data.
* @author Bill Majurski
*/
public class MultipartMap {
javax.mail.internet.MimeMultipart mp;
HashMap map, typemap;
HashMap<Integer, Object> positionmap = null;
HashMap<Integer, String> positiontypemap = null;
String stripQuotes(String s) {
if (s == null) return s;
if (s.startsWith("\""))
s = s.substring(1);
if (s.endsWith("\""))
s = s.substring(0,s.length()-1);
return s;
}
/**
* Used for testing and demonstration purposes.
*/
static public void main(String args[]) throws Exception, java.io.IOException {
try {
//String xx = "------=_Part_2_9110923.1073664290010\r\nContent-Type: text/plain\r\nContent-ID: urn:uuid:d4bfb124-7922-45bc-a03d-823351eed716\r\n\r\nhttp://ratbert.ncsl.nist.gov:8081/hl7services/transform.html\r\n------=_Part_2_9110923.1073664290010\r\nContent-Type: text/plain\r\nContent-ID: urn:uuid:45b90888-49c1-4b64-a8eb-e94f541368f0\r\n\r\nhttp://ratbert.ncsl.nist.gov:8081/hl7services/rawSQL.html\r\n------=_Part_2_9110923.1073664290010--\r\n";
String xx = "------_Part_\r\nContent-Type: text/plain\r\nContent-ID: urn:uuid:d4bfb124-7922-45bc-a03d-823351eed716\r\n\r\nhttp://ratbert.ncsl.nist.gov:8081/hl7services/transform.html\r\n------_Part_\r\nContent-Type: text/plain\r\nContent-ID: urn:uuid:45b90888-49c1-4b64-a8eb-e94f541368f0\r\n\r\nhttp://ratbert.ncsl.nist.gov:8081/hl7services/rawSQL.html\r\n------_Part_--\r\n";
StringBufferInputStream is = new StringBufferInputStream(xx);
String contentType = "multipart/related; boundary=----_Part_";
ByteArrayDataSource ds = new ByteArrayDataSource(is, contentType);
//ByteArrayDataSource ds = new ByteArrayDataSource();
javax.mail.internet.MimeMultipart mp = new javax.mail.internet.MimeMultipart(ds);
int i = mp.getCount();
} catch (javax.mail.MessagingException me) {
throw new Exception("messaging exception in parsing for MultipartMap");
}
System.out.println("Done");
}
/**
* Constructor.
* @param is The content as an InputStream.
* @param contentType The type of content this multipart piece is.
* @throws java.lang.Exception Thrown if there is a problem parsing this input.
* @throws java.io.IOException Thrown if there is an IO problem accessing this input. (Check that
* InputStream is valid.)
*/
public MultipartMap(InputStream is, String contentType)
throws Exception, java.io.IOException {
try {
//contentType = contentType.replaceFirst("boundary=--", "boundary=");
map = new HashMap();
typemap = new HashMap();
positionmap = new HashMap<Integer, Object>();
positiontypemap = new HashMap<Integer, String>();
boolean isMultipart = contentType.startsWith("multipart");
if (isMultipart) {
ByteArrayDataSource ds = new ByteArrayDataSource(is, contentType);
//ByteArrayDataSource ds;
// this should be rewritten, ByteArrayDataSource will take directly from an input stream
//String input = getStringFromInputStream(request.getInputStream());
//ds = new ByteArrayDataSource(input,request.getHeader("Content-Type"));
//String ext =ds.getText();
//String xx = "------=_Part_2_9110923.1073664290010\r\nContent-Type: text/plain\r\nContent-ID: urn:uuid:d4bfb124-7922-45bc-a03d-823351eed716\r\n\r\nhttp://ratbert.ncsl.nist.gov:8081/hl7services/transform.html\r\n------=_Part_2_9110923.1073664290010\r\nContent-Type: text/plain\r\nContent-ID: urn:uuid:45b90888-49c1-4b64-a8eb-e94f541368f0\r\n\r\nhttp://ratbert.ncsl.nist.gov:8081/hl7services/rawSQL.html\r\n------=_Part_2_9110923.1073664290010--\r\n";
mp = new javax.mail.internet.MimeMultipart(ds);
for (int i=0; i<mp.getCount(); i++) {
MimeBodyPart bp = (MimeBodyPart) mp.getBodyPart(i);
String name = null;
String contentID[] = bp.getHeader("Content-ID");
if (contentID.length > 0)
name = contentID[0];
if (name == null) name = "Part " + Integer.toString(i);
typemap.put(name, bp.getContentType());
positiontypemap.put(new Integer(i), bp.getContentType());
InputStream part_is = bp.getInputStream();
Object part_object = null;
String type[] = bp.getContentType().split("/");
if (type[0].equals("text") && type[1].equals("plain")) {
part_object = bp.getContent();
map.put(name, part_object);
} else {
map.put(name, part_is);
part_object = part_is;
}
positionmap.put(new Integer(i), part_object);
}
} else {
map.put("Content", is);
typemap.put("Content", contentType);
}
} catch (javax.mail.MessagingException me) {
throw new Exception("messaging exception in parsing for MultipartMap: " + ExceptionUtil.exception_details(me));
}
}
public HashMap<Integer, Object> getPositionMap() {
return positionmap;
}
public HashMap<Integer, String> getPositionTypeMap() {
return positiontypemap;
}
/**
* Constructor builds a MultipartMap object based upon the contents of an entire
* HttpServletRequest object.
* @param request An HttpServletRequest object that contains Multipart content.
* @throws javax.mail.MessagingException Thrown if there is a problem parsing this input.
* @throws java.io.IOException Thrown if there is an IO problem accessing this input. (Check that
* HttpServletRequest is valid.)
*/
public MultipartMap(HttpServletRequest request) throws javax.mail.MessagingException, java.io.IOException {
if (isMultipartForm(request)) {
map = new HashMap();
typemap = new HashMap();
ByteArrayDataSource ds = new ByteArrayDataSource(request.getInputStream(), request.getContentType());
//ByteArrayDataSource ds;
// this should be rewritten, ByteArrayDataSource will take directly from an input stream
//String input = getStringFromInputStream(request.getInputStream());
//ds = new ByteArrayDataSource(input,request.getHeader("Content-Type"));
mp = new javax.mail.internet.MimeMultipart(ds);
for (int i=0; i<mp.getCount(); i++) {
MimeBodyPart bp = (MimeBodyPart) mp.getBodyPart(i);
ContentDisposition cd = new ContentDisposition(bp.getHeader("Content-Disposition")[0]);
String name = stripQuotes(cd.get("name"));
String filename = stripQuotes(cd.get("filename"));
if (filename != null)
map.put("filename", filename);
//String name = getName(bp);
typemap.put(name, bp.getContentType());
String type[] = bp.getContentType().split("/");
if (type[0].equals("text") && type[1].equals("plain")) {
map.put(name, bp.getContent());
} else {
map.put(name, bp.getInputStream()); //getDataHandler());
}
}
} else {
throw new javax.mail.MessagingException("MultipartMap requires Multipart/Form format as input");
}
}
/**
* Returns the HashMap representing the content in this object.
* @return The HashMap representing the content in this object.
*/
public HashMap getMap() {
return map;
}
/**
* Returns the HashMap representing the content types in this object.
* @return The HashMap representing the content types in this object.
*/
public HashMap getTypeMap() {
return typemap;
}
/**
* Returns the attachment that has this name. Returns null if nothing with that
* name is found.
* @param name The name to search for.
* @return The attachment or null if none found.
*/
public Object get(String name) {
return getMap().get(name);
}
/**
* Returns the content type of the attachment that has this name. Returns null
* if nothing with that name is found.
* @param name The name to search for.
* @return The content type or null if none found.
*/
public Object getType(String name) {
return getTypeMap().get(name);
}
/**
* A check to see whether the HttpServletRequest really contains Multipart
* information. Returns true, if it does. Returns false, if not.
* @param request The HttpServletRequest to check.
* @return True, if the HttpServletRequest contains Multipart information.
* False, if it does not.
*/
public static boolean isMultipartForm(HttpServletRequest request) {
String contentType = request.getHeader("Content-Type");
if (contentType == null) return false;
String ct = contentType.substring(0,19);
return ct.compareToIgnoreCase("multipart/form-data") == 0;
}
String getName(MimeBodyPart bp) throws java.io.IOException {
Enumeration e;
try {
e = bp.getAllHeaderLines();
} catch (javax.mail.MessagingException ex) {
throw new java.io.IOException("cannot retrieve header lines inside getName()");
}
while(e.hasMoreElements()) {
String s = (String) e.nextElement();
int strt = s.indexOf("name=");
if (strt != -1) {
strt = strt+6;
int end = s.indexOf('"',strt);
if (end != -1) {
return s.substring(strt,end);
}
}
}
return null;
}
}