1 package org.paneris.bibliomania.population;
2
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.FileReader;
6 import java.util.Enumeration;
7 import java.util.Vector;
8
9 import org.melati.poem.AccessToken;
10 import org.melati.poem.PoemTask;
11 import org.melati.util.MelatiRuntimeException;
12 import org.paneris.bibliomania.BibliomaniaDatabase;
13 import org.paneris.bibliomania.Book;
14 import org.paneris.bibliomania.Chapter;
15 import org.paneris.bibliomania.util.OROUtils;
16
17 import org.apache.oro.text.regex.MatchResult;
18 import org.apache.oro.text.regex.Pattern;
19 import org.apache.oro.text.regex.Perl5Compiler;
20 import org.apache.oro.text.regex.Perl5Matcher;
21
22 public class KeyDotTxtFilter {
23
24 public static class PopulationException extends MelatiRuntimeException {
25
26 private static final long serialVersionUID = 1L;
27
28 public File keyDotTxtFile;
29
30 public PopulationException(File keyDotTxtFile, Exception problem) {
31 super(problem);
32 this.keyDotTxtFile = keyDotTxtFile;
33 }
34
35 public String getMessage() {
36 return "A problem was encountered importing " + keyDotTxtFile + ":\n" +
37 subException.getMessage();
38 }
39 }
40
41 public static class SyntaxException extends MelatiRuntimeException {
42 private static final long serialVersionUID = 1L;
43
44 public int linenum;
45 public String line;
46
47 public SyntaxException(int linenum, String line) {
48 this.linenum = linenum;
49 this.line = line;
50 }
51
52 public String getMessage() {
53 return "Line " + linenum + " was not in the " +
54 "<filename>.html <chapter title> format:\n" +
55 "[[" + line + "]]";
56 }
57 }
58
59 private static final Pattern
60 data = OROUtils.perl5Pattern(
61 "^\\s*(.*?\\.html)\\s+(.*?)(( |\t)\\s*(.*?))?\\s*$",
62 Perl5Compiler.CASE_INSENSITIVE_MASK),
63 white = OROUtils.perl5Pattern("^(#.*|\\s*)$", Perl5Compiler.DEFAULT_MASK);
64
65 private static void populateFromDataRE(Book book, Vector oldChapters,
66 int seq, MatchResult match) {
67 Chapter chapter;
68 if (oldChapters.size() <= seq)
69 chapter = null;
70 else {
71 chapter = (Chapter)oldChapters.elementAt(seq);
72 oldChapters.setElementAt(null, seq);
73 }
74
75 if (chapter == null)
76 chapter = (Chapter)book.getBibliomaniaDatabase().getChapterTable().
77 newPersistent();
78
79 chapter.setBook(book);
80 chapter.setSequence(seq);
81 chapter.setTitle(match.group(2));
82 chapter.setLongtitle(match.group(5));
83 chapter.setFilepath(book.getPath(), match.group(1));
84
85 if (!chapter.statusExistent())
86 chapter.makePersistent();
87 }
88
89 public static void populate(Book book) {
90 File keyDotTxtFile = new File(book.getSourceDir(), "key.txt");
91 try {
92 BufferedReader keyDotTxt =
93 new BufferedReader(new FileReader(keyDotTxtFile));
94
95 Perl5Matcher matcher = new Perl5Matcher();
96
97 Vector oldChapters = new Vector();
98
99 for (Enumeration existingChapters = book.getChapters();
100 existingChapters.hasMoreElements();) {
101 Chapter chapter = (Chapter)existingChapters.nextElement();
102 int seq = chapter.getSequence().intValue();
103 if (oldChapters.size() <= seq)
104 oldChapters.setSize(seq + 1);
105 oldChapters.setElementAt(chapter, seq);
106 }
107
108 int chapterCount = 0;
109 for (int lineno = 0;; ++lineno) {
110 String line = keyDotTxt.readLine();
111 if (line == null)
112 break;
113
114 if (matcher.matches(line, white)) {}
115 else if (matcher.matches(line, data))
116 populateFromDataRE(book, oldChapters,
117 chapterCount++, matcher.getMatch());
118 else
119 throw new SyntaxException(lineno, line);
120 }
121
122 for (int c = 0; c < oldChapters.size(); ++c) {
123 Chapter chapter = (Chapter)oldChapters.elementAt(c);
124 if (chapter != null)
125 chapter.delete_unsafe_butCleanFTI();
126 }
127 }
128 catch (Exception e) {
129 throw new PopulationException(keyDotTxtFile, e);
130 }
131 }
132
133 public static void main(final String[] args) throws Exception {
134 final BibliomaniaDatabase bib = new BibliomaniaDatabase();
135 bib.connect("bibliomania", "org.melati.poem.dbms.Postgresql",
136 "jdbc:postgresql:bibliomania", "postgres", "*",8);
137 bib.inSession(
138 AccessToken.root,
139 new PoemTask() {
140 public void run() {
141 populate((Book)bib.getBookTable().getTitleColumn().firstWhereEq(args[0]));
142 }
143 });
144 }
145 }