%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.commons.net.nntp.Article |
|
|
1 | /* ==================================================================== |
|
2 | * The Apache Software License, Version 1.1 |
|
3 | * |
|
4 | * Copyright (c) 2001-2005 The Apache Software Foundation. All rights |
|
5 | * reserved. |
|
6 | * |
|
7 | * Redistribution and use in source and binary forms, with or without |
|
8 | * modification, are permitted provided that the following conditions |
|
9 | * are met: |
|
10 | * |
|
11 | * 1. Redistributions of source code must retain the above copyright |
|
12 | * notice, this list of conditions and the following disclaimer. |
|
13 | * |
|
14 | * 2. Redistributions in binary form must reproduce the above copyright |
|
15 | * notice, this list of conditions and the following disclaimer in |
|
16 | * the documentation and/or other materials provided with the |
|
17 | * distribution. |
|
18 | * |
|
19 | * 3. The end-user documentation included with the redistribution, |
|
20 | * if any, must include the following acknowledgment: |
|
21 | * "This product includes software developed by the |
|
22 | * Apache Software Foundation (http://www.apache.org/)." |
|
23 | * Alternately, this acknowledgment may appear in the software itself, |
|
24 | * if and wherever such third-party acknowledgments normally appear. |
|
25 | * |
|
26 | * 4. The names "Apache" and "Apache Software Foundation" and |
|
27 | * "Apache Commons" must not be used to endorse or promote products |
|
28 | * derived from this software without prior written permission. For |
|
29 | * written permission, please contact apache@apache.org. |
|
30 | * |
|
31 | * 5. Products derived from this software may not be called "Apache", |
|
32 | * nor may "Apache" appear in their name, without |
|
33 | * prior written permission of the Apache Software Foundation. |
|
34 | * |
|
35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
|
36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
38 | * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR |
|
39 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
40 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
41 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
42 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
|
43 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
|
44 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
|
45 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
46 | * SUCH DAMAGE. |
|
47 | * ==================================================================== |
|
48 | * |
|
49 | * This software consists of voluntary contributions made by many |
|
50 | * individuals on behalf of the Apache Software Foundation. For more |
|
51 | * information on the Apache Software Foundation, please see |
|
52 | * <http://www.apache.org/>. |
|
53 | */ |
|
54 | ||
55 | package org.apache.commons.net.nntp; |
|
56 | ||
57 | import java.util.ArrayList; |
|
58 | import java.util.StringTokenizer; |
|
59 | ||
60 | /** |
|
61 | * This is a class that contains the basic state needed for message retrieval and threading. |
|
62 | * With thanks to Jamie Zawinski <jwz@jwz.org> |
|
63 | * @author rwinston <rwinston@checkfree.com> |
|
64 | * |
|
65 | */ |
|
66 | public class Article implements Threadable { |
|
67 | private int articleNumber; |
|
68 | private String subject; |
|
69 | private String date; |
|
70 | private String articleId; |
|
71 | private String simplifiedSubject; |
|
72 | private String from; |
|
73 | private StringBuffer header; |
|
74 | private StringBuffer references; |
|
75 | 0 | private boolean isReply = false; |
76 | ||
77 | public Article kid, next; |
|
78 | ||
79 | 0 | public Article() { |
80 | 0 | header = new StringBuffer(); |
81 | 0 | } |
82 | ||
83 | /** |
|
84 | * Adds an arbitrary header key and value to this message's header. |
|
85 | * @param name the header name |
|
86 | * @param val the header value |
|
87 | */ |
|
88 | public void addHeaderField(String name, String val) { |
|
89 | 0 | header.append(name); |
90 | 0 | header.append(": "); |
91 | 0 | header.append(val); |
92 | 0 | header.append('\n'); |
93 | 0 | } |
94 | ||
95 | /** |
|
96 | * Adds a message-id to the list of messages that this message references (i.e. replies to) |
|
97 | * @param msgId |
|
98 | */ |
|
99 | public void addReference(String msgId) { |
|
100 | 0 | if (references == null) { |
101 | 0 | references = new StringBuffer(); |
102 | 0 | references.append("References: "); |
103 | } |
|
104 | 0 | references.append(msgId); |
105 | 0 | references.append("\t"); |
106 | 0 | } |
107 | ||
108 | /** |
|
109 | * Returns the MessageId references as an array of Strings |
|
110 | * @return an array of message-ids |
|
111 | */ |
|
112 | public String[] getReferences() { |
|
113 | 0 | if (references == null) |
114 | 0 | return new String[0]; |
115 | 0 | ArrayList list = new ArrayList(); |
116 | 0 | int terminator = references.toString().indexOf(':'); |
117 | 0 | StringTokenizer st = |
118 | new StringTokenizer(references.substring(terminator), "\t"); |
|
119 | 0 | while (st.hasMoreTokens()) { |
120 | 0 | list.add(st.nextToken()); |
121 | } |
|
122 | 0 | return (String[]) list.toArray(); |
123 | } |
|
124 | ||
125 | /** |
|
126 | * Attempts to parse the subject line for some typical reply signatures, and strip them out |
|
127 | * |
|
128 | */ |
|
129 | private void simplifySubject() { |
|
130 | 0 | int start = 0; |
131 | 0 | String subject = getSubject(); |
132 | 0 | int len = subject.length(); |
133 | ||
134 | 0 | boolean done = false; |
135 | ||
136 | 0 | while (!done) { |
137 | 0 | done = true; |
138 | ||
139 | // skip whitespace |
|
140 | // "Re: " breaks this |
|
141 | 0 | while (start < len && subject.charAt(start) == ' ') { |
142 | 0 | start++; |
143 | } |
|
144 | ||
145 | 0 | if (start < (len - 2) |
146 | && (subject.charAt(start) == 'r' || subject.charAt(start) == 'R') |
|
147 | && (subject.charAt(start + 1) == 'e' || subject.charAt(start + 1) == 'E')) { |
|
148 | ||
149 | 0 | if (subject.charAt(start + 2) == ':') { |
150 | 0 | start += 3; // Skip "Re:" |
151 | 0 | isReply = true; |
152 | 0 | done = false; |
153 | 0 | } else if ( |
154 | start < (len - 2) |
|
155 | && |
|
156 | (subject.charAt(start + 2) == '[' || subject.charAt(start + 2) == '(')) { |
|
157 | ||
158 | 0 | int i = start + 3; |
159 | ||
160 | 0 | while (i < len && subject.charAt(i) >= '0' && subject.charAt(i) <= '9') |
161 | 0 | i++; |
162 | ||
163 | 0 | if (i < (len - 1) |
164 | && (subject.charAt(i) == ']' || subject.charAt(i) == ')') |
|
165 | && subject.charAt(i + 1) == ':') { |
|
166 | 0 | start = i + 2; |
167 | 0 | isReply = true; |
168 | 0 | done = false; |
169 | } |
|
170 | } |
|
171 | } |
|
172 | ||
173 | 0 | if (simplclass="keyword">ifiedSubject == "(no subject)") |
174 | 0 | simplifiedSubject = ""; |
175 | ||
176 | 0 | int end = len; |
177 | ||
178 | 0 | while (end > start && subject.charAt(end - 1) < ' ') |
179 | 0 | end--; |
180 | ||
181 | 0 | if (start == 0 && end == len) |
182 | 0 | simplifiedSubject = subject; |
183 | else |
|
184 | 0 | simplifiedSubject = subject.substring(start, end); |
185 | } |
|
186 | 0 | } |
187 | ||
188 | /** |
|
189 | * Recursive method that traverses a pre-threaded graph (or tree) |
|
190 | * of connected Article objects and prints them out. |
|
191 | * @param article the root of the article 'tree' |
|
192 | * @param depth the current tree depth |
|
193 | */ |
|
194 | public static void printThread(Article article, int depth) { |
|
195 | 0 | for (int i = 0; i < depth; ++i) |
196 | 0 | System.out.print("==>"); |
197 | 0 | System.out.println(article.getSubject() + "\t" + article.getFrom()); |
198 | 0 | if (article.kid != null) |
199 | 0 | printThread(article.kid, depth + 1); |
200 | 0 | if (article.next != null) |
201 | 0 | printThread(article.next, depth); |
202 | 0 | } |
203 | ||
204 | public String getArticleId() { |
|
205 | 0 | return articleId; |
206 | } |
|
207 | ||
208 | public int getArticleNumber() { |
|
209 | 0 | return articleNumber; |
210 | } |
|
211 | ||
212 | public String getDate() { |
|
213 | 0 | return date; |
214 | } |
|
215 | ||
216 | public String getFrom() { |
|
217 | 0 | return from; |
218 | } |
|
219 | ||
220 | public String getSubject() { |
|
221 | 0 | return subject; |
222 | } |
|
223 | ||
224 | public void setArticleId(String string) { |
|
225 | 0 | articleId = string; |
226 | 0 | } |
227 | ||
228 | public void setArticleNumber(int i) { |
|
229 | 0 | articleNumber = i; |
230 | 0 | } |
231 | ||
232 | public void setDate(String string) { |
|
233 | 0 | date = string; |
234 | 0 | } |
235 | ||
236 | public void setFrom(String string) { |
|
237 | 0 | from = string; |
238 | 0 | } |
239 | ||
240 | public void setSubject(String string) { |
|
241 | 0 | subject = string; |
242 | 0 | } |
243 | ||
244 | ||
245 | public boolean isDummy() { |
|
246 | 0 | return (getSubject() == null); |
247 | } |
|
248 | ||
249 | public String messageThreadId() { |
|
250 | 0 | return articleId; |
251 | } |
|
252 | ||
253 | public String[] messageThreadReferences() { |
|
254 | 0 | return getReferences(); |
255 | } |
|
256 | ||
257 | public String simplifiedSubject() { |
|
258 | 0 | if(simplclass="keyword">ifiedSubject == null) |
259 | 0 | simplifySubject(); |
260 | 0 | return simplifiedSubject; |
261 | } |
|
262 | ||
263 | ||
264 | public boolean subjectIsReply() { |
|
265 | 0 | if(simplclass="keyword">ifiedSubject == null) |
266 | 0 | simplifySubject(); |
267 | 0 | return isReply; |
268 | } |
|
269 | ||
270 | ||
271 | public void setChild(Threadable child) { |
|
272 | 0 | this.kid = (Article) child; |
273 | 0 | flushSubjectCache(); |
274 | 0 | } |
275 | ||
276 | private void flushSubjectCache() { |
|
277 | 0 | simplifiedSubject = null; |
278 | 0 | } |
279 | ||
280 | ||
281 | public void setNext(Threadable next) { |
|
282 | 0 | this.next = (Article)next; |
283 | 0 | flushSubjectCache(); |
284 | 0 | } |
285 | ||
286 | ||
287 | public Threadable makeDummy() { |
|
288 | 0 | return (Threadable)new Article(); |
289 | } |
|
290 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |