1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.net.nntp;
19
20 import java.io.PrintStream;
21 import java.util.ArrayList;
22 import java.util.Collections;
23
24 import org.apache.commons.net.util.NetConstants;
25
26
27
28
29 public class Article implements Threadable {
30
31
32
33
34
35
36 public static void printThread(final Article article) {
37 printThread(article, 0, System.out);
38 }
39
40
41
42
43
44
45
46 public static void printThread(final Article article, final int depth) {
47 printThread(article, depth, System.out);
48 }
49
50
51
52
53
54
55
56
57
58 public static void printThread(final Article article, final int depth, final PrintStream ps) {
59 for (int i = 0; i < depth; ++i) {
60 ps.print("==>");
61 }
62 ps.println(article.getSubject() + "\t" + article.getFrom() + "\t" + article.getArticleId());
63 if (article.kid != null) {
64 printThread(article.kid, depth + 1);
65 }
66 if (article.next != null) {
67 printThread(article.next, depth);
68 }
69 }
70
71
72
73
74
75
76
77
78 public static void printThread(final Article article, final PrintStream ps) {
79 printThread(article, 0, ps);
80 }
81
82 private long articleNumber;
83 private String subject;
84 private String date;
85 private String articleId;
86
87 private String simplifiedSubject;
88
89 private String from;
90 private ArrayList<String> references;
91
92 private boolean isReply;
93
94 public Article kid, next;
95
96 public Article() {
97 articleNumber = -1;
98 }
99
100 @Deprecated
101
102 public void addHeaderField(final String name, final String val) {
103 }
104
105
106
107
108
109
110 public void addReference(final String msgId) {
111 if (msgId == null || msgId.isEmpty()) {
112 return;
113 }
114 if (references == null) {
115 references = new ArrayList<>();
116 }
117 isReply = true;
118 Collections.addAll(references, msgId.split(" "));
119 }
120
121 private void flushSubjectCache() {
122 simplifiedSubject = null;
123 }
124
125 public String getArticleId() {
126 return articleId;
127 }
128
129 @Deprecated
130 public int getArticleNumber() {
131 return (int) articleNumber;
132 }
133
134 public long getArticleNumberLong() {
135 return articleNumber;
136 }
137
138 public String getDate() {
139 return date;
140 }
141
142 public String getFrom() {
143 return from;
144 }
145
146
147
148
149
150
151 public String[] getReferences() {
152 if (references == null) {
153 return NetConstants.EMPTY_STRING_ARRAY;
154 }
155 return references.toArray(NetConstants.EMPTY_STRING_ARRAY);
156 }
157
158 public String getSubject() {
159 return subject;
160 }
161
162 @Override
163 public boolean isDummy() {
164 return articleNumber == -1;
165 }
166
167 @Override
168 public Threadable makeDummy() {
169 return new Article();
170 }
171
172 @Override
173 public String messageThreadId() {
174 return articleId;
175 }
176
177 @Override
178 public String[] messageThreadReferences() {
179 return getReferences();
180 }
181
182 public void setArticleId(final String string) {
183 articleId = string;
184 }
185
186 @Deprecated
187 public void setArticleNumber(final int a) {
188 articleNumber = a;
189 }
190
191 public void setArticleNumber(final long l) {
192 articleNumber = l;
193 }
194
195 @Override
196 public void setChild(final Threadable child) {
197 this.kid = (Article) child;
198 flushSubjectCache();
199 }
200
201 public void setDate(final String string) {
202 date = string;
203 }
204
205 public void setFrom(final String string) {
206 from = string;
207 }
208
209 @Override
210 public void setNext(final Threadable next) {
211 this.next = (Article) next;
212 flushSubjectCache();
213 }
214
215 public void setSubject(final String string) {
216 subject = string;
217 }
218
219 @Override
220 public String simplifiedSubject() {
221 if (simplifiedSubject == null) {
222 simplifySubject();
223 }
224 return simplifiedSubject;
225 }
226
227
228
229
230
231
232 private void simplifySubject() {
233 int start = 0;
234 final String subject = getSubject();
235 final int len = subject.length();
236
237 boolean done = false;
238
239 while (!done) {
240 done = true;
241
242
243
244 while (start < len && subject.charAt(start) == ' ') {
245 start++;
246 }
247
248 if (start < len - 2 && (subject.charAt(start) == 'r' || subject.charAt(start) == 'R')
249 && (subject.charAt(start + 1) == 'e' || subject.charAt(start + 1) == 'E')) {
250
251 if (subject.charAt(start + 2) == ':') {
252 start += 3;
253 done = false;
254 } else if (start < len - 2 && (subject.charAt(start + 2) == '[' || subject.charAt(start + 2) == '(')) {
255
256 int i = start + 3;
257
258 while (i < len && subject.charAt(i) >= '0' && subject.charAt(i) <= '9') {
259 i++;
260 }
261
262 if (i < len - 1 && (subject.charAt(i) == ']' || subject.charAt(i) == ')') && subject.charAt(i + 1) == ':') {
263 start = i + 2;
264 done = false;
265 }
266 }
267 }
268
269 if ("(no subject)".equals(simplifiedSubject)) {
270 simplifiedSubject = "";
271 }
272
273 int end = len;
274
275 while (end > start && subject.charAt(end - 1) < ' ') {
276 end--;
277 }
278
279 if (start == 0 && end == len) {
280 simplifiedSubject = subject;
281 } else {
282 simplifiedSubject = subject.substring(start, end);
283 }
284 }
285 }
286
287 @Override
288 public boolean subjectIsReply() {
289 return isReply;
290 }
291
292 @Override
293 public String toString() {
294 return articleNumber + " " + articleId + " " + subject;
295 }
296
297 }