Created
March 21, 2015 19:56
-
-
Save hoat4/96a50598b227a8e86d26 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package sandbox.maildata; | |
public class InvalidHeaderException extends RuntimeException { | |
public InvalidHeaderException(String msg) { | |
super(msg); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
}; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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