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