001: package pygmy.nntp;
002:
003: import java.util.*;
004: import java.io.*;
005:
006: import org.apache.lucene.store.Directory;
007: import org.apache.lucene.store.FSDirectory;
008: import org.apache.lucene.search.IndexSearcher;
009: import org.apache.lucene.search.Query;
010: import org.apache.lucene.search.Hits;
011: import org.apache.lucene.queryParser.QueryParser;
012: import org.apache.lucene.queryParser.ParseException;
013: import org.apache.lucene.analysis.standard.StandardAnalyzer;
014:
015: public class Forum {
016:
017: private ArticleSpool spool;
018: private File root;
019: private File groupsRoot;
020: private File spoolDirectory;
021:
022: private Directory articleOverviewDirectory;
023:
024: private WeakHashMap newsgroupMap;
025:
026: public Forum(File aRoot, ArticleSpool aSpool) throws IOException {
027: this .root = aRoot;
028: this .groupsRoot = new File(root, "news");
029: this .spoolDirectory = new File(root, "spool");
030: this .spool = aSpool;
031: this .newsgroupMap = new WeakHashMap();
032: this .articleOverviewDirectory = createArticleOverviewDirectory();
033: }
034:
035: private Directory createArticleOverviewDirectory()
036: throws IOException {
037: groupsRoot.mkdir();
038: spoolDirectory.mkdir();
039: File segments = new File(groupsRoot, "segments");
040: return FSDirectory.getDirectory(groupsRoot, segments.exists());
041: }
042:
043: public NewsGroup createNewsgroup(String newsgroupName) {
044: File newsgroupFile = new File(groupsRoot, newsgroupName);
045: NewsGroup newsgroup = new NewsGroup(newsgroupFile,
046: newsgroupName);
047: newsgroupMap.put(newsgroupName, newsgroup);
048: return newsgroup;
049: }
050:
051: public Iterator newsgroupIterator() {
052: ArrayList list = new ArrayList();
053: File[] groups = groupsRoot.listFiles();
054: for (int i = 0; i < groups.length; i++) {
055: if (groups[i].isDirectory()) {
056: list.add(getNewsgroup(groups[i].getName()));
057: }
058: }
059:
060: return list.iterator();
061: }
062:
063: public NewsGroup getNewsgroup(final String groupName) {
064: if (newsgroupMap.containsKey(groupName)) {
065: return (NewsGroup) newsgroupMap.get(groupName);
066: }
067: String[] names = groupsRoot.list(new FilenameFilter() {
068: public boolean accept(File dir, String name) {
069: if (name.equalsIgnoreCase(groupName)) {
070: return true;
071: } else {
072: return false;
073: }
074: }
075: });
076: if (names.length > 0) {
077: NewsGroup newGroup = new NewsGroup(new File(groupsRoot,
078: names[0]), names[0]);
079: newsgroupMap.put(groupName, newGroup);
080: return newGroup;
081: } else {
082: return null;
083: }
084: }
085:
086: public List getNewsgroups(final Date since,
087: final String[] distributions) {
088: final ArrayList list = new ArrayList();
089: groupsRoot.listFiles(new FileFilter() {
090: public boolean accept(File pathname) {
091: if (pathname.isDirectory()
092: && pathname.lastModified() >= since.getTime()
093: && matchesDistribution(distributions, pathname)) {
094: list.add(getNewsgroup(pathname.getName()));
095: return true;
096: }
097: return false;
098: }
099: });
100: return list;
101: }
102:
103: public List getArticle(final Date since) {
104: final ArrayList list = new ArrayList();
105: spoolDirectory.listFiles(new FileFilter() {
106: public boolean accept(File pathname) {
107: if (pathname.isFile()
108: && pathname.lastModified() >= since.getTime()) {
109: list.add(pathname.getName());
110: return true;
111: }
112: return false;
113: }
114: });
115: return list;
116: }
117:
118: private boolean matchesDistribution(String[] distributions,
119: File newsgroup) {
120: if (distributions == null)
121: return true;
122:
123: for (int i = 0; i < distributions.length; i++) {
124: if (newsgroup.getName().startsWith(distributions[i])) {
125: return true;
126: }
127: }
128: return false;
129: }
130:
131: public File getNewsRepository() {
132: return groupsRoot;
133: }
134:
135: public File getArticleRepository() {
136: return spoolDirectory;
137: }
138:
139: public File getRootRepository() {
140: return root;
141: }
142:
143: public Article getArticle(String messageId) throws IOException {
144: NntpInputStream stream = null;
145: try {
146: stream = new NntpInputStream(new FileInputStream(
147: getArticleFile(messageId)));
148: return new Article(stream);
149: } finally {
150: if (stream != null)
151: stream.close();
152: }
153: }
154:
155: private File getArticleFile(String messageId) {
156: return new File(spoolDirectory, NntpUtil
157: .base64Encode(messageId));
158: }
159:
160: public void addArticle(Article article, String host)
161: throws IOException {
162: spool.addArticle(article, host);
163: }
164:
165: public Directory getArticleOverview() {
166: return articleOverviewDirectory;
167: }
168:
169: // private void saveUniqueArticle(Article article) throws IOException {
170: // File articleFile = getArticleFile(article.getMessageId());
171: // InternetOutputStream stream = null;
172: // try {
173: // stream = new InternetOutputStream( new FileOutputStream( articleFile ) );
174: // article.save( stream );
175: // } finally {
176: // if( stream != null ) {
177: // stream.flush();
178: // stream.close();
179: // }
180: // }
181: // }
182:
183: public static void main(String[] args) {
184: File dir = new File(args[0]);
185: File[] files = dir.listFiles();
186: for (int i = 0; i < files.length; i++) {
187: String base64 = NntpUtil.base64Encode("<"
188: + files[i].getName() + ">");
189: System.out.println(files[i].getName() + ": " + base64);
190: }
191: }
192:
193: public Hits getOverview(NewsGroup group) throws IOException,
194: ParseException {
195: IndexSearcher searcher = new IndexSearcher(
196: articleOverviewDirectory);
197: Query query = QueryParser.parse(group.getName(), "newsgroup",
198: new StandardAnalyzer());
199: Hits hits = searcher.search(query);
200: return hits;
201: }
202: }
|