1 package org.paneris.bibliomania;
2
3 import java.io.OutputStreamWriter;
4 import java.io.Writer;
5 import java.util.Enumeration;
6
7 import org.melati.LogicalDatabase;
8 import org.melati.Melati;
9 import org.melati.poem.AccessToken;
10 import org.melati.poem.PoemTask;
11 import org.melati.poem.PoemThread;
12 import org.melati.poem.Table;
13 import org.melati.poem.UnexpectedExceptionPoemException;
14 import org.melati.poem.util.ArrayUtils;
15 import org.melati.poem.util.ConsEnumeration;
16 import org.melati.poem.util.FlattenedEnumeration;
17 import org.melati.poem.util.MappedEnumeration;
18 import org.melati.util.MelatiRuntimeException;
19 import org.webmacro.servlet.WebContext;
20
21 public class BatchImporter extends BibliomaniaServlet {
22 private static final long serialVersionUID = 6162775496346853625L;
23
24 public static final int KEYDOTTXT = 8, PAGINATE = 4, INDEX = 2, ENCACHE = 1;
25
26 public static class Result {
27 public Exception trouble;
28 public Unit unit;
29 }
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public static Enumeration<Result> importResults(
49 final Unit unit,
50 final boolean recurse,
51 final int actions,
52 final boolean doChapters,
53 final boolean flushDuring) {
54
55 Result result = new Result();
56 result.unit = unit;
57
58 try {
59 if ((actions & KEYDOTTXT) != 0)
60 unit.readKeyDotTxt();
61
62 if ((actions & PAGINATE) != 0) {
63 unit.paginate();
64 unit.getBibliomaniaDatabase().pagination().flush();
65 }
66
67 if ((actions & ENCACHE) != 0)
68 unit.encache();
69
70 if ((actions & INDEX) != 0) {
71 try {
72 unit.index();
73 } finally {
74
75
76
77 if (flushDuring) {
78 unit.getBibliomaniaDatabase().fti().flush();
79 unit.getBibliomaniaDatabase().infoFTI().flush();
80 }
81 }
82 }
83
84 PoemThread.commit();
85 } catch (Exception e) {
86 e.printStackTrace();
87 result.trouble = e;
88 PoemThread.rollback();
89 }
90
91 return new ConsEnumeration<Result>(
92 result,
93 recurse
94 && !(unit instanceof Book && !doChapters)
95 ? new FlattenedEnumeration<Result>(
96 new MappedEnumeration<Enumeration<Result>,Unit>(
97 unit.getMembersSlowly()) {
98 public Enumeration<Result> mapped(Unit member) {
99 return importResults(
100 member,
101 recurse,
102 actions,
103 doChapters,
104 flushDuring);
105 }
106 }) : null);
107 }
108
109 protected String bibliomaniaHandle(Melati melati, WebContext context)
110 throws Exception {
111 melati.setBufferingOff();
112 melati.setFlushingOn();
113 melati.setPassbackExceptionHandling();
114
115 context.put(
116 "results",
117 importResults(
118 (Unit)melati.getObject(),
119 "true".equals(context.getForm("recurse")),
120 Integer.parseInt(context.getForm("actions")),
121 !"true".equals(context.getForm("skipChaps")),
122 true));
123
124 return bibliomaniaTemplate("admin/BatchImport");
125 }
126
127 private static void doImport(
128 BibliomaniaDatabase db,
129 String[] args,
130 final Writer commentary)
131 throws Exception {
132 final boolean recurse, skipChaps;
133
134 if (args[1].equals("recurse")) {
135 recurse = true;
136 skipChaps = false;
137 } else if (args[1].equals("skipChaps")) {
138 recurse = true;
139 skipChaps = true;
140 } else if (args[1].equals("norecurse")) {
141 recurse = false;
142 skipChaps = false;
143 } else
144 throw new IllegalArgumentException("second arg must be norecurse, recurse or skipChaps");
145
146 final boolean flushDuring;
147
148 if (args.length > 4) {
149 if (args[4].equals("flushDuring"))
150 flushDuring = true;
151 else if (args[4].equals("flushAfter"))
152 flushDuring = false;
153 else
154 throw new IllegalArgumentException("fifth arg must be flushDuring or flushAfter");
155 } else
156 flushDuring = true;
157
158 final int actions = Integer.parseInt(args[0]);
159
160 @SuppressWarnings("unchecked")
161 Table<Unit> table = (Table<Unit>)db.getTable(args[2]);
162
163 Enumeration<Result> results;
164
165 if (args[3].equals("_"))
166 results =
167 new FlattenedEnumeration<Result>(
168 new MappedEnumeration<Enumeration<Result>, Unit>(table.selection()) {
169 public Enumeration<Result> mapped(Unit member) {
170 return importResults(
171 member,
172 recurse,
173 actions,
174 !skipChaps,
175 flushDuring);
176 }
177 });
178 else
179 results =
180 importResults(
181 (Unit)table.getObject(Integer.parseInt(args[3])),
182 recurse,
183 actions,
184 !skipChaps,
185 flushDuring);
186
187 while (results.hasMoreElements()) {
188 Result result = (Result)results.nextElement();
189 commentary.write(
190 "=== ... finished "
191 + result.unit.getTable().getName()
192 + "/"
193 + result.unit.getTroid()
194 + " `"
195 + result.unit.getPath());
196 if (result.unit instanceof Chapter)
197 commentary.write(((Chapter)result.unit).getFilename());
198 commentary.write("'\n\n");
199
200 if (result.trouble != null)
201 commentary.write("!!! " + result.trouble + "\n");
202 commentary.flush();
203 }
204
205 if (!flushDuring) {
206 long now = System.currentTimeMillis();
207
208
209 db.fti().flush();
210 db.infoFTI().flush();
211
212 commentary.write(
213 "... final flush millis " + (System.currentTimeMillis() - now) + "\n");
214 commentary.flush();
215
216 }
217 }
218
219 public static void main(final String[] args) {
220 final BibliomaniaDatabase db = new BibliomaniaDatabase(false);
221 db.connect("bibliomania",
222 "org.paneris.bibliomania.poem.dbms.Postgresql",
223 "jdbc:postgresql:bibliomania",
224 "postgres",
225 "*",
226 8);
227
228 db.inSession(AccessToken.root,
229 new PoemTask() {
230 public void run() {
231 try {
232 doImport(db, args, new OutputStreamWriter(System.err));
233 } catch (Exception e) {
234 throw new UnexpectedExceptionPoemException(e);
235 }
236 }
237 });
238 }
239
240 public static class Interpreter implements CommandServer.Interpreter {
241
242 public static class AuthenticationException
243 extends MelatiRuntimeException {
244 public String getMessage() {
245 return "Authentication failed";
246 }
247 }
248
249
250
251
252
253
254 public void interpret(
255 final String[] args,
256 final Writer output,
257 final Writer errors)
258 throws Exception {
259
260 final BibliomaniaDatabase db =
261 (BibliomaniaDatabase)LogicalDatabase.getDatabase(args[0]);
262
263 db.inSession(AccessToken.root, new PoemTask() {
264 public void run() {
265 try {
266 User user =
267 (User)PoemThread
268 .database()
269 .getUserTable()
270 .getLoginColumn()
271 .firstWhereEq(
272 args[1]);
273 if (user == null || !user.getPassword_unsafe().equals(args[2]))
274 throw new AuthenticationException();
275
276 PoemThread.setAccessToken(user);
277
278 doImport(
279 db,
280 (String[])ArrayUtils.section(args, 3, args.length),
281 errors);
282 } catch (Exception e) {
283 try {
284 errors.write(e + "\n");
285 } catch (Exception ee) {
286 }
287 }
288 }
289 });
290 }
291 }
292 }