package org.nutz.mock.servlet.multipart;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import org.nutz.lang.Files;
import org.nutz.lang.Lang;
import org.nutz.mock.servlet.MockInputStream;
import org.nutz.mock.servlet.multipart.inputing.InputingHelper;
import org.nutz.mock.servlet.multipart.item.EndlMultipartItem;
import org.nutz.mock.servlet.multipart.item.FileMultipartItem;
import org.nutz.mock.servlet.multipart.item.ParamMultipartItem;
public class MultipartInputStream extends MockInputStream {
private Map<String, String> mimes;
private LinkedList<MultipartItem> items;
private Iterator<MultipartItem> it;
private MultipartItem current;
private String boundary;
private InputingHelper helper;
public MultipartInputStream(String charset, String boundary) {
this.boundary = boundary;
this.helper = new InputingHelper(charset);
mimes = new HashMap<String, String>();
addMime("png", "image/png");
addMime("jpg", "image/jpg");
addMime("gif", "image/gif");
addMime("txt", "text/plain");
items = new LinkedList<MultipartItem>();
items.add(new EndlMultipartItem(helper, boundary));
}
public String getCharset() {
return helper.getCharset();
}
private String getContentType(String suffixName) {
String ct = mimes.get(suffixName);
if (null == ct)
return "application/octet-stream";
return ct;
}
public String getContentType() {
return "multipart/form-data; boundary=" + boundary;
}
@Override
public int available() throws IOException {
int re = 0;
Iterator<MultipartItem> it = items.iterator();
while (it.hasNext())
re += it.next().size();
return re;
}
public MultipartInputStream addMime(String suffix, String contentType) {
mimes.put(suffix, contentType);
return this;
}
public void append(String name, File f) {
String contentType = getContentType(Files.getSuffixName(f));
FileMultipartItem fmi = new FileMultipartItem(helper, boundary, name, f, contentType);
append(fmi);
}
public void append(String name, String value) {
append(new ParamMultipartItem(helper, boundary, name, value));
}
private void append(MultipartItem item) {
items.add(items.size() - 1, item);
}
public int read() throws IOException {
int d = current.read();
while (-1 == d) {
if (!it.hasNext())
return -1;
current = it.next();
d = current.read();
}
return d;
}
public void init() {
try {
for (MultipartItem item : items)
item.init();
}
catch (IOException e) {
throw Lang.wrapThrow(e);
}
it = items.iterator();
current = it.next();
}
@Override
public void close() throws IOException {
try {
for (MultipartItem item : items)
item.close();
}
catch (IOException e) {
throw Lang.wrapThrow(e);
}
}
}