EMMA Coverage Report (generated Thu Nov 19 17:07:02 CET 2009)
[all classes][org.apache.james.jdkim.impl]

COVERAGE SUMMARY FOR SOURCE FILE [Message.java]

nameclass, %method, %block, %line, %
Message.java100% (2/2)100% (9/9)93%  (203/219)95%  (53/56)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Message100% (1/1)100% (8/8)92%  (196/212)94%  (50/53)
Message (InputStream): void 100% (1/1)85%  (67/79)95%  (19/20)
getFields (String): List 100% (1/1)86%  (19/22)83%  (5/6)
toString (): String 100% (1/1)98%  (53/54)93%  (13/14)
Message (): void 100% (1/1)100% (16/16)100% (5/5)
addField (String, String): void 100% (1/1)100% (30/30)100% (7/7)
getBodyInputStream (): InputStream 100% (1/1)100% (3/3)100% (1/1)
getFields (): List 100% (1/1)100% (4/4)100% (1/1)
setBodyInputStream (InputStream): void 100% (1/1)100% (4/4)100% (2/2)
     
class Message$ExtendedMimeTokenStream100% (1/1)100% (1/1)100% (7/7)100% (3/3)
Message$ExtendedMimeTokenStream (Message, MimeEntityConfig): void 100% (1/1)100% (7/7)100% (3/3)

1/****************************************************************
2 * Licensed to the Apache Software Foundation (ASF) under one   *
3 * or more contributor license agreements.  See the NOTICE file *
4 * distributed with this work for additional information        *
5 * regarding copyright ownership.  The ASF licenses this file   *
6 * to you under the Apache License, Version 2.0 (the            *
7 * "License"); you may not use this file except in compliance   *
8 * with the License.  You may obtain a copy of the License at   *
9 *                                                              *
10 *   http://www.apache.org/licenses/LICENSE-2.0                 *
11 *                                                              *
12 * Unless required by applicable law or agreed to in writing,   *
13 * software distributed under the License is distributed on an  *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15 * KIND, either express or implied.  See the License for the    *
16 * specific language governing permissions and limitations      *
17 * under the License.                                           *
18 ****************************************************************/
19 
20package org.apache.james.jdkim.impl;
21 
22import java.io.IOException;
23import java.io.InputStream;
24import java.util.Collections;
25import java.util.HashMap;
26import java.util.Iterator;
27import java.util.LinkedList;
28import java.util.List;
29import java.util.Map;
30 
31import org.apache.james.jdkim.api.Headers;
32import org.apache.james.mime4j.MimeException;
33import org.apache.james.mime4j.io.EOLConvertingInputStream;
34import org.apache.james.mime4j.parser.MimeEntityConfig;
35import org.apache.james.mime4j.parser.MimeTokenStream;
36 
37/**
38 * The header of an entity (see RFC 2045).
39 */
40public class Message implements Headers {
41 
42    private List fields = new LinkedList();
43    private Map fieldMap = new HashMap();
44    private InputStream bodyIs = null;
45 
46    /**
47     * Creates a new empty <code>Header</code>.
48     */
49    public Message() {
50    }
51 
52    /**
53     * Creates a new <code>Header</code> from the specified stream.
54     * 
55     * @param is
56     *                the stream to read the header from.
57     * 
58     * @throws IOException
59     *                 on I/O errors.
60     * @throws MimeIOException
61     *                 on MIME protocol violations.
62     */
63    public Message(InputStream is) throws IOException, MimeException {
64        MimeEntityConfig mec = new MimeEntityConfig();
65        mec.setMaxLineLen(10000);
66        MimeTokenStream stream = new ExtendedMimeTokenStream(mec);
67        stream.setRecursionMode(MimeTokenStream.M_FLAT);
68        // DKIM requires no isolated CR or LF, so we alter them at source.
69        stream.parse(new EOLConvertingInputStream(is));
70        for (int state = stream.getState(); state != MimeTokenStream.T_END_OF_STREAM; state = stream
71                .next()) {
72            switch (state) {
73            // a field
74            case MimeTokenStream.T_FIELD:
75                addField(stream.getFieldName(), stream.getField());
76                break;
77 
78            // expected ignored tokens
79            case MimeTokenStream.T_START_MESSAGE:
80            case MimeTokenStream.T_END_MESSAGE:
81            case MimeTokenStream.T_START_HEADER:
82            case MimeTokenStream.T_END_HEADER:
83                break;
84 
85            // the body stream
86            case MimeTokenStream.T_BODY:
87                this.bodyIs = stream.getInputStream();
88                break;
89 
90            default:
91                throw new IllegalStateException("Unexpected stream message: "
92                        + state);
93            }
94            // stop parsing after header
95            if (bodyIs != null)
96                break;
97        }
98 
99    }
100 
101    public InputStream getBodyInputStream() {
102        return bodyIs;
103    }
104 
105    public void setBodyInputStream(InputStream is) {
106        bodyIs = is;
107    }
108 
109    /**
110     * Adds a field to the end of the list of fields.
111     * 
112     * @param field
113     *                the field to add.
114     */
115    public void addField(String fieldName, String field) {
116        List values = (List) fieldMap.get(fieldName.toLowerCase());
117        if (values == null) {
118            values = new LinkedList();
119            fieldMap.put(fieldName.toLowerCase(), values);
120        }
121        values.add(field);
122        fields.add(field);
123    }
124 
125    /**
126     * @see org.apache.james.jdkim.api.Headers#getFields()
127     */
128    public List getFields() {
129        return Collections.unmodifiableList(fields);
130    }
131 
132    /**
133     * @see org.apache.james.jdkim.api.Headers#getFields(java.lang.String)
134     */
135    public List getFields(final String name) {
136        final String lowerCaseName = name.toLowerCase();
137        final List l = (List) fieldMap.get(lowerCaseName);
138        final List results;
139        if (l == null || l.isEmpty()) {
140            results = null;
141        } else {
142            results = Collections.unmodifiableList(l);
143        }
144        return results;
145    }
146 
147    /**
148     * Return Header Object as String representation. Each headerline is
149     * seperated by "\r\n"
150     * 
151     * @return headers
152     */
153    public String toString() {
154        StringBuffer str = new StringBuffer(128);
155        for (Iterator i = fields.iterator(); i.hasNext();) {
156            String field = (String) i.next();
157            str.append(field);
158        }
159        InputStream is = getBodyInputStream();
160        if (is != null) {
161            str.append("\r\n");
162            byte[] buff = new byte[128];
163            int read;
164            try {
165                while ((read = is.read(buff)) > 0) {
166                    str.append(new String(buff, 0, read));
167                }
168            } catch (IOException e) {
169            }
170        }
171        return str.toString();
172    }
173 
174    /**
175     * Extends this to publish the constructor
176     */
177    private final class ExtendedMimeTokenStream extends MimeTokenStream {
178 
179        public ExtendedMimeTokenStream(MimeEntityConfig mec) {
180            super(mec);
181        }
182    }
183 
184}

[all classes][org.apache.james.jdkim.impl]
EMMA 2.0.5312 (C) Vladimir Roubtsov