Index: [Article Count Order] [Thread]

Date:  Tue, 24 Oct 2000 16:43:25 +0900
From:  tetsuya@....jp
Subject:  [XP-jp:01079] VXP メッセージ関連(その1)
To:  extremeprogramming-jp@....jp (extremeprogramming-jp ML)
Message-Id:  <97BA340C0480D411BDA800062939A1890607D7@....jp>
Posted:  Tue, 24 Oct 2000 16:43:31 +0900
X-Mail-Count: 01079

栗原です。

あまりに停滞させておくと忘れ去られそうなので、昨日の夜
スクラッチで作ってみました。

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