栗原です。
あまりに停滞させておくと忘れ去られそうなので、昨日の夜
スクラッチで作ってみました。
jp.co.esm.wiki.extremedomo.message.MessageParser
ヘッダー部とボディ部の分割を行う
jp.co.esm.wiki.extremedomo.message.HeaderParts
ヘッダー部を解析して、コレクション化する
jp.co.esm.wiki.extremedomo.message.HeaderField
個々のヘッダー情報をあらわす
jp.co.esm.wiki.extremedomo.message.MessageException
ラップ例外
以下、ソースコード(長いです。)
幅も長かったりしますm(_ _)m
/*
* $Id$
*/
package jp.co.esm.wiki.extremedomo.message;
import java.io.*;
public class MessageParser {
public MessageParser(byte[] msg) {
message = msg;
}
public void parse()
throws MessageException {
setHeaderParts();
setBodyPart();
}
public HeaderParts getHeaderParts() {
return headerParts;
}
public String getBodyPart() {
return bodyPart;
}
private void setHeaderParts()
throws MessageException {
headerParts = new HeaderParts(message);
}
private void setBodyPart()
throws MessageException {
BufferedReader bufIn = null;
try {
bufIn = new BufferedReader(
new InputStreamReader(
new ByteArrayInputStream(message)));
while (true) {
String line = bufIn.readLine();
if (line == null)
return;
if (line.length() == 0)
break;
}
// It is not well reflected at the time
// only of a new-line of the message last.
StringBuffer buf = new StringBuffer(512);
int count = 0;
while (true) {
String line = bufIn.readLine();
if (line == null)
break;
if (count != 0)
buf.append("\r\n");
buf.append(line);
count++;
}
bodyPart = buf.toString();
} catch (IOException e) {
throw new MessageException(e.toString());
} finally {
try {
if (bufIn != null)
bufIn.close();
} catch (IOException e) {
}
}
}
private byte[] message;
private HeaderParts headerParts;
private String bodyPart;
}
/*
* $Id$
*/
package jp.co.esm.wiki.extremedomo.message;
import java.io.*;
import java.util.*;
public class HeaderParts {
public HeaderParts(byte[] msg)
throws MessageException {
headers = new Vector();
parse(msg);
}
public String[] getHeader(String name) {
Iterator itr = headers.iterator();
List tempList = new ArrayList();
while (itr.hasNext()) {
HeaderField headerField = (HeaderField)itr.next();
if (name.equals(headerField.getName()))
tempList.add(headerField.getValue());
}
if (tempList.size() == 0)
return null;
String[] result = new String[tempList.size()];
System.arraycopy(tempList.toArray(), 0, result, 0, tempList.size());
return result;
}
private void parse(byte[] msg)
throws MessageException {
BufferedReader bufIn = null;
String line;
try {
bufIn = new BufferedReader(
new InputStreamReader(
new ByteArrayInputStream(msg)));
while (true) {
line = bufIn.readLine();
if (line == null)
break;
if (line.length() == 0)
break;
addHeader(line);
}
} catch (IOException e) {
throw new MessageException(e.toString());
} finally {
try {
if (bufIn != null)
bufIn.close();
} catch (IOException e) {
}
}
}
private void addHeader(String line)
throws MessageException {
char c = line.charAt(0);
if (c == ' ' || c == '\t') {
HeaderField lastHeader = (HeaderField)headers.lastElement();
lastHeader.setValue(lastHeader.getValue() + "\r\n" + line);
} else {
headers.addElement(new HeaderField(line));
}
}
private Vector headers;
}
/*
* $Id$
*/
package jp.co.esm.wiki.extremedomo.message;
public class HeaderField {
public HeaderField(String aField)
throws MessageException {
int index = aField.indexOf(':');
if (index < 0)
throw new MessageException("HeaderField is an illegal format.");
name = aField.substring(0, index).trim();
value = aField;
}
public String getName() {
return name;
}
public void setValue(String aValue) {
value = aValue;
}
public String getValue() {
return value;
}
private String name;
private String value;
}
/*
* $Id$
*/
package jp.co.esm.wiki.extremedomo.message;
public class MessageException extends Exception {
public MessageException() {
super();
}
public MessageException(String s) {
super(s);
}
}
それと、これまたスクラッチのテストケースのソースです。
/*
* $Id$
*/
package jp.co.esm.wiki.extremedomo.message;
import junit.framework.*;
public class MessageParserTest extends TestCase {
public MessageParserTest(String name) {
super(name);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(MessageParserTest.class);
}
public void testParse() throws MessageException {
MessageParser parser = new MessageParser(message1);
parser.parse();
StringBuffer buf1 = new StringBuffer(64);
buf1.append("This is a sample mail.").append("\r\n");
buf1.append("Dummy: aaaaaa").append("\r\n");
// careful here.
buf1.append(".");
assertEquals(buf1.toString(), parser.getBodyPart());
}
protected void setUp() {
StringBuffer buf = new StringBuffer(512);
buf.append("Received: foo").append("\r\n");
buf.append(" Receive: foo 2nd.").append("\r\n");
buf.append(" Receive: foo 3rd.").append("\r\n");
buf.append("Received: bar").append("\r\n");
buf.append("\tReceive: bar 2nd.").append("\r\n");
buf.append("\tReceive: bar 3rd.").append("\r\n");
buf.append("Date: Thu, 19 Oct 2000 20:00:40 +0900").append("\r\n");
buf.append("Posted: Thu, 19 Oct 2000 19:54:52 +0900
(JST)").append("\r\n");
buf.append("From: Yamada Taro <taro@....zz>").append("\r\n");
buf.append("Reply-To:
extremeprogramming-jp@....jp").append("\r\n");
buf.append("Subject: [XP-jp:01074] test mail").append("\r\n");
buf.append("To: extremeprogramming-jp@....jp
(extremeprogramming-jp ML)").append("\r\n");
buf.append("X-ML-Name: extremeprogramming-jp").append("\r\n");
buf.append("X-Mail-Count: 01074").append("\r\n");
buf.append("X-MLServer: fml [fml 2.1_GAMMA#185](distribute only
mode)").append("\r\n");
buf.append("X-ML-Info: x-ml-info message.").append("\r\n");
buf.append("Mime-Version: 1.0").append("\r\n");
buf.append("Content-Type: Text/Plain;
charset=iso-2022-jp").append("\r\n");
buf.append("Content-Transfer-Encoding: 7bit").append("\r\n");
buf.append("\r\n");
buf.append("This is a sample mail.").append("\r\n");
buf.append("Dummy: aaaaaa").append("\r\n");
buf.append(".").append("\r\n");
message1 = buf.toString().getBytes();
}
private byte[] message1;
}
/*
* $Id$
*/
package jp.co.esm.wiki.extremedomo.message;
import junit.framework.*;
public class HeaderPartsTest extends TestCase {
public HeaderPartsTest(String name) {
super(name);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(HeaderPartsTest.class);
}
public void testGetHeader() throws MessageException {
HeaderParts headerParts = new HeaderParts(message1);
String[] dateHeader = headerParts.getHeader("Date");
assertEquals("Date: Thu, 19 Oct 2000 20:00:40 +0900",
dateHeader[0]);
}
public void testNotExistHeader() throws MessageException {
HeaderParts headerParts = new HeaderParts(message1);
String[] notExistHeader = headerParts.getHeader("OpaOpa");
assertNull(notExistHeader);
}
public void testDummyHeader() throws MessageException {
HeaderParts headerParts = new HeaderParts(message1);
String[] dummyHeader = headerParts.getHeader("Dummy");
assertNull(dummyHeader);
}
public void testHeaderExistingTwoOrMore() throws MessageException {
HeaderParts headerParts = new HeaderParts(message1);
String[] headers = headerParts.getHeader("Received");
assertEquals(2, headers.length);
StringBuffer buf1 = new StringBuffer(64);
buf1.append("Received: foo").append("\r\n");
buf1.append(" Receive: foo 2nd.").append("\r\n");
buf1.append(" Receive: foo 3rd.");
assertEquals(buf1.toString(), headers[0]);
StringBuffer buf2 = new StringBuffer(64);
buf2.append("Received: bar").append("\r\n");
buf2.append("\tReceive: bar 2nd.").append("\r\n");
buf2.append("\tReceive: bar 3rd.");
assertEquals(buf2.toString(), headers[1]);
}
protected void setUp() throws MessageException {
StringBuffer buf = new StringBuffer(512);
buf.append("Received: foo").append("\r\n");
buf.append(" Receive: foo 2nd.").append("\r\n");
buf.append(" Receive: foo 3rd.").append("\r\n");
buf.append("Received: bar").append("\r\n");
buf.append("\tReceive: bar 2nd.").append("\r\n");
buf.append("\tReceive: bar 3rd.").append("\r\n");
buf.append("Date: Thu, 19 Oct 2000 20:00:40 +0900").append("\r\n");
buf.append("Posted: Thu, 19 Oct 2000 19:54:52 +0900
(JST)").append("\r\n");
buf.append("From: Yamada Taro <taro@....zz>").append("\r\n");
buf.append("Reply-To:
extremeprogramming-jp@....jp").append("\r\n");
buf.append("Subject: [XP-jp:01074] test mail").append("\r\n");
buf.append("To: extremeprogramming-jp@....jp
(extremeprogramming-jp ML)").append("\r\n");
buf.append("X-ML-Name: extremeprogramming-jp").append("\r\n");
buf.append("X-Mail-Count: 01074").append("\r\n");
buf.append("X-MLServer: fml [fml 2.1_GAMMA#185](distribute only
mode)").append("\r\n");
buf.append("X-ML-Info: x-ml-info message.").append("\r\n");
buf.append("Mime-Version: 1.0").append("\r\n");
buf.append("Content-Type: Text/Plain;
charset=iso-2022-jp").append("\r\n");
buf.append("Content-Transfer-Encoding: 7bit").append("\r\n");
buf.append("\r\n");
buf.append("This is a sample mail.").append("\r\n");
buf.append("Dummy: aaaaaa").append("\r\n");
buf.append(".").append("\r\n");
message1 = buf.toString().getBytes();
}
private byte[] message1;
}
/*
* $Id$
*/
package jp.co.esm.wiki.extremedomo.message;
import junit.framework.*;
public class HeaderFieldTest extends TestCase {
public HeaderFieldTest(String name) {
super(name);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(HeaderFieldTest.class);
}
public void testConstructor1()
throws MessageException {
HeaderField hf = new HeaderField("From: aaa@....ccc");
assertEquals("From", hf.getName());
assertEquals("From: aaa@....ccc", hf.getValue());
}
public void testConstructor2()
throws MessageException {
HeaderField hf = new HeaderField("From:");
assertEquals("From", hf.getName());
assertEquals("From:", hf.getValue());
}
public void testIllegalHeader() {
try {
HeaderField hf = new HeaderField("To aaa@....ccc");
fail("Should raise a MessageException");
} catch (MessageException e) {
assert(true);
}
}
}
---
Tetsuya Kurihara
tetsuya@....jp