Skip to content

Instantly share code, notes, and snippets.

@hoat4
Created March 21, 2015 19:56
Show Gist options
  • Save hoat4/96a50598b227a8e86d26 to your computer and use it in GitHub Desktop.
Save hoat4/96a50598b227a8e86d26 to your computer and use it in GitHub Desktop.
package sandbox.maildata;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class HeaderSection {
private final Map<String, List<String>> map = new HashMap<>();
public void put(String key, String value) {
map.put(key, new ArrayList<>(Arrays.asList(value)));
}
public void add(String key, String value) {
List<String> list = map.get(key);
if (list == null) {
list = new ArrayList<>();
map.put(key, list);
}
list.add(value);
}
public String get(String key) {
if (!map.containsKey(key))
return null;
List<String> list = map.get(key);
if (list.size() != 1)
throw new InvalidHeaderException("HeaderSection has " + list.size() + " values for '"
+ key + "', not 1");
return list.get(1);
}
public List<String> getList(String key) {
return map.get(key);
}
void parse(String headerField) {
String key = headerField.substring(0, headerField.indexOf(": "));
String value = headerField.substring(headerField.indexOf(": ") + 2);
add(key, value);
}
@Override
public String toString() {
return map.toString();
}
public void writeTo(OutputStream out) throws IOException {
OutputStreamWriter writer = new OutputStreamWriter(out);
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
for (Object value : entry.getValue()) {
writer.write(entry.getKey() + ": " + value + "\r\n");
}
writer.flush();
}
}
}
package sandbox.maildata;
public class InvalidHeaderException extends RuntimeException {
public InvalidHeaderException(String msg) {
super(msg);
}
}
package sandbox.maildata;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.util.Scanner;
public class MailData {
private File file;
public MailData(File file) {
this.file = file;
}
public HeaderSection parseHeaders() throws FileNotFoundException {
Scanner in = new Scanner(new FileReader(file));
HeaderSection headers = new HeaderSection();
StringBuilder buf = new StringBuilder();
boolean prevCont = false;
while (in.hasNextLine()) {
String ln = in.nextLine();
boolean cont = !ln.trim().equals(ln);
if (!cont && buf.length() > 0) {
headers.parse(buf.toString());
buf.setLength(0);
}
if (ln.isEmpty())
break;
buf.append(ln.trim());
prevCont = cont;
}
return headers;
}
public InputStream decodeBody(HeaderSection headers) throws IOException {
InputStream in = new FileInputStream(file);
boolean prev = false;
for (int ch; (ch = in.read()) != -1;) {
if (ch == '\r' && prev) {
in.read();
break;
}
prev = ch == '\n';
}
return in;
}
public OutputStream output() throws FileNotFoundException {
File tmpfile = new File(file.getAbsolutePath() + "_TMP");
final FileOutputStream out = new FileOutputStream(tmpfile);
return new FilterOutputStream(out) {
@Override
public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
}
@Override
public void close() throws IOException {
out.close();
file.delete();
tmpfile.renameTo(file);
file = tmpfile;
}
};
}
}
package sandbox.maildata;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class MailDataTest {
public static void main(String[] args) throws FileNotFoundException, IOException {
MailData mail = new MailData(new File("/home/attila/mzn.eml"));
HeaderSection headers = mail.parseHeaders();
InputStream in = mail.decodeBody(headers);
headers.add("X-MailData-Test", "a");
headers.put("X-MailData-Test", "b");
headers.add("X-MailData-Test", "c");
try (OutputStream out = mail.output()) {
headers.writeTo(out);
for(int ch; (ch = in.read()) != -1;)
out.write(ch);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment