1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.james.nntpserver.repository;
23
24 import org.apache.avalon.framework.logger.AbstractLogEnabled;
25 import org.apache.james.nntpserver.DateSinceFileFilter;
26 import org.apache.james.util.io.AndFileFilter;
27 import org.apache.james.util.io.ExtensionFileFilter;
28 import org.apache.james.util.io.IOUtil;
29 import org.apache.james.util.io.InvertedFileFilter;
30
31 import java.io.File;
32 import java.io.FileOutputStream;
33 import java.io.InputStream;
34 import java.io.IOException;
35 import java.util.ArrayList;
36 import java.util.Date;
37 import java.util.Iterator;
38 import java.util.List;
39
40
41
42
43
44
45 class NNTPGroupImpl extends AbstractLogEnabled implements NNTPGroup {
46
47
48
49
50 private final File root;
51
52
53
54
55 private int lastArticle;
56
57
58
59
60 private int firstArticle;
61
62
63
64
65 private int numOfArticles;
66
67
68
69
70
71
72 private boolean articleRangeInfoCollected = false;
73
74
75
76
77
78
79 NNTPGroupImpl(File root) {
80 this.root = root;
81 }
82
83
84
85
86 public String getName() {
87 return root.getName();
88 }
89
90
91
92
93 public String getDescription() {
94 return getName();
95 }
96
97
98
99
100 public boolean isPostAllowed() {
101 return true;
102 }
103
104
105
106
107
108 private void collectArticleRangeInfo() {
109 if ( articleRangeInfoCollected ) {
110 return;
111 }
112 String[] list = root.list();
113 int first = -1;
114 int last = -1;
115 for ( int i = 0 ; i < list.length ; i++ ) {
116 int num = Integer.parseInt(list[i]);
117 if ( first == -1 || num < first ) {
118 first = num;
119 }
120 if ( num > last ) {
121 last = num;
122 }
123 }
124 numOfArticles = list.length;
125 firstArticle = Math.max(first,0);
126 lastArticle = Math.max(last,0);
127 articleRangeInfoCollected = true;
128 }
129
130
131
132
133 public int getNumberOfArticles() {
134 collectArticleRangeInfo();
135 return numOfArticles;
136 }
137
138
139
140
141 public int getFirstArticleNumber() {
142 collectArticleRangeInfo();
143 return firstArticle;
144 }
145
146
147
148
149 public int getLastArticleNumber() {
150 collectArticleRangeInfo();
151 return lastArticle;
152 }
153
154
155
156
157 public NNTPArticle getArticle(int number) {
158 File f = new File(root,number + "");
159 return f.exists() ? new NNTPArticleImpl(this, f) : null;
160 }
161
162
163
164
165 public Iterator getArticlesSince(Date dt) {
166 File[] f = root.listFiles(new AndFileFilter
167 (new DateSinceFileFilter(dt.getTime()),
168 new InvertedFileFilter(new ExtensionFileFilter(".id"))));
169 List list = new ArrayList();
170 for ( int i = 0 ; i < f.length ; i++ ) {
171 list.add(new NNTPArticleImpl(this, f[i]));
172 }
173 return list.iterator();
174 }
175
176
177
178
179 public Iterator getArticles() {
180 File[] f = root.listFiles();
181 List list = new ArrayList();
182 for ( int i = 0 ; i < f.length ; i++ )
183 list.add(new NNTPArticleImpl(this, f[i]));
184 return list.iterator();
185 }
186
187
188
189
190 public String getListFormat() {
191 StringBuffer showBuffer =
192 new StringBuffer(128)
193 .append(getName())
194 .append(" ")
195 .append(getLastArticleNumber())
196 .append(" ")
197 .append(getFirstArticleNumber())
198 .append(" ")
199 .append((isPostAllowed() ? "y":"n"));
200 return showBuffer.toString();
201 }
202
203
204
205
206 public String getListNewsgroupsFormat() {
207 StringBuffer showBuffer =
208 new StringBuffer(128)
209 .append(getName())
210 .append(" ")
211 .append(getDescription());
212 return showBuffer.toString();
213 }
214
215
216
217
218 public NNTPArticle addArticle(InputStream newsStream)
219 throws IOException {
220 File articleFile = null;
221 synchronized (this) {
222 int artNum;
223 if (numOfArticles < 0)
224 throw new IllegalStateException("NNTP Group is corrupt (articles < 0).");
225 else if (numOfArticles == 0) {
226 firstArticle = 1;
227 artNum = 1;
228 } else {
229 artNum = getLastArticleNumber() + 1;
230 }
231
232 articleFile = new File(root, artNum + "");
233 articleFile.createNewFile();
234 lastArticle = artNum;
235 numOfArticles++;
236 }
237 if (getLogger().isDebugEnabled()) {
238 getLogger().debug("Copying message to: "+articleFile.getAbsolutePath());
239 }
240 FileOutputStream fout = null;
241 try {
242 fout = new FileOutputStream(articleFile);
243 IOUtil.copy(newsStream,fout);
244 fout.flush();
245 } finally {
246 try {
247 if (fout != null) {
248 fout.close();
249 }
250 } catch (IOException ioe) {
251
252
253 }
254 }
255 return new NNTPArticleImpl(this, articleFile);
256 }
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281 }