1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.nuiton.jrst;
23
24 import java.awt.GraphicsDevice;
25 import java.awt.GraphicsEnvironment;
26 import java.io.ByteArrayInputStream;
27 import java.io.ByteArrayOutputStream;
28 import java.io.File;
29 import java.io.FileNotFoundException;
30 import java.io.FileOutputStream;
31 import java.io.IOException;
32 import java.io.InputStreamReader;
33 import java.io.OutputStream;
34 import java.io.OutputStreamWriter;
35 import java.io.Reader;
36 import java.net.URL;
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.Locale;
40 import java.util.Map;
41
42 import javax.xml.parsers.DocumentBuilder;
43 import javax.xml.parsers.DocumentBuilderFactory;
44 import javax.xml.transform.TransformerException;
45
46 import org.apache.commons.io.FileUtils;
47 import org.apache.commons.logging.Log;
48 import org.apache.commons.logging.LogFactory;
49 import org.dom4j.Document;
50 import org.dom4j.DocumentException;
51 import org.dom4j.DocumentHelper;
52 import org.nuiton.config.ApplicationConfig;
53 import org.nuiton.i18n.I18n;
54 import org.nuiton.i18n.init.ClassPathI18nInitializer;
55 import org.nuiton.jrst.convertisor.DocUtils2RST;
56 import org.nuiton.jrst.convertisor.DocUtilsVisitor;
57 import org.nuiton.jrst.legacy.JRSTReader;
58 import org.nuiton.jrst.ui.JRSTView;
59 import org.nuiton.util.Resource;
60 import org.nuiton.util.StringUtil;
61 import org.python.util.PythonInterpreter;
62 import org.xhtmlrenderer.pdf.ITextRenderer;
63
64
65
66
67
68
69
70
71
72
73
74
75
76 public class JRST {
77
78 public static final String UTF_8 = "UTF-8";
79
80 public static final String DOCUTILS_LAUNCHER = "__run__.py";
81
82 public static final String IMPORT_SCRIPT = "import __run__";
83
84 public static final String WINDOWS_NAME = "win";
85
86 public static final String OS_NAME = "os.name";
87
88 public static final String BANG = "!";
89
90 public static final String FILE_URI_PREFIX = "file:";
91
92 public enum Overwrite {
93 NEVER, IFNEWER, ALLTIME
94 }
95
96
97 protected static Log log = LogFactory.getLog(JRST.class);
98
99
100 protected static final String RST_2_XHTML = "/xsl/rst2xhtml.xsl";
101
102
103 protected static final String XSL_RST_2_XHTML_INNER_BODY_XSL = "/xsl/rst2xhtmlInnerBody.xsl";
104
105
106 protected static final String RST_2_XDOC = "/xsl/rst2xdoc.xsl";
107
108
109 protected static final String RST_2_DOCBOOK = "/xsl/dn2dbk.xsl";
110
111
112 protected static final String DOCBOOK_2_XHTML = "/docbook/xhtml/docbook.xsl";
113
114
115 protected static final String DOCBOOK_2_JAVAHELP = "/docbook/javahelp/javahelp.xsl";
116
117
118 protected static final String DOCBOOK_2_HTMLHELP = "/docbook/htmlhelp/htmlhelp.xsl";
119
120
121 protected static final String DOCBOOK_2_FO = "/docbook/fo/docbook.xsl";
122
123 public static final String PATTERN_TYPE = "xml|xhtml|docbook|html|htmlInnerBody|xdoc|fo|pdf";
124
125
126 public static final String TYPE_HTML = "html";
127
128
129 public static final String TYPE_HTML_INNER_BODY = "htmlInnerBody";
130
131
132 public static final String TYPE_XDOC = "xdoc";
133
134
135 public static final String TYPE_DOCBOOK = "docbook";
136
137
138 public static final String TYPE_XHTML = "xhtml";
139
140
141 public static final String TYPE_JAVAHELP = "javahelp";
142
143
144 public static final String TYPE_HTMLHELP = "htmlhelp";
145
146
147 public static final String TYPE_ODT = "odt";
148
149
150 public static final String TYPE_FO = "fo";
151
152
153 public static final String TYPE_PDF = "pdf";
154
155
156 public static final String TYPE_XML = "xml";
157
158
159 protected static Map<String, String> stylesheets;
160
161
162 protected static Map<String, String> mimeType;
163
164 static {
165 stylesheets = new HashMap<String, String>();
166 stylesheets.put(TYPE_HTML, RST_2_XHTML);
167 stylesheets.put(TYPE_HTML_INNER_BODY, XSL_RST_2_XHTML_INNER_BODY_XSL);
168 stylesheets.put(TYPE_XDOC, RST_2_XDOC);
169 stylesheets.put(TYPE_DOCBOOK, RST_2_DOCBOOK);
170 stylesheets.put(TYPE_XHTML, RST_2_DOCBOOK + "," + DOCBOOK_2_XHTML);
171 stylesheets.put(TYPE_JAVAHELP, RST_2_DOCBOOK + "," + DOCBOOK_2_JAVAHELP);
172 stylesheets.put(TYPE_HTMLHELP, RST_2_DOCBOOK + "," + DOCBOOK_2_HTMLHELP);
173 stylesheets.put(TYPE_FO, RST_2_DOCBOOK + "," + DOCBOOK_2_FO);
174 stylesheets.put(TYPE_PDF, RST_2_XHTML);
175
176 mimeType = new HashMap<String, String>();
177 mimeType.put(TYPE_HTML, "text/html");
178 mimeType.put(TYPE_HTML_INNER_BODY, "text/html");
179 mimeType.put(TYPE_XDOC, "text/xml");
180 mimeType.put(TYPE_DOCBOOK, "text/xml");
181 mimeType.put(TYPE_XHTML, "text/html");
182 mimeType.put(TYPE_JAVAHELP, "text/plain");
183 mimeType.put(TYPE_HTMLHELP, "text/html");
184 mimeType.put(TYPE_ODT, "application/vnd.oasis.opendocument.text");
185 mimeType.put(TYPE_FO, "text/xml");
186 mimeType.put(TYPE_PDF, "application/pdf");
187
188 }
189
190
191
192
193
194
195
196 public static void main(String... args) throws Exception {
197
198 I18n.init(new ClassPathI18nInitializer(), Locale.UK);
199
200 if (args.length == 0) {
201 askOption();
202 } else {
203
204 ApplicationConfig config = JRSTConfig.getConfig(args);
205 config.doAction(0);
206
207
208 String xslList = JRSTConfigOption.XSL_FILE.getOption(config);
209 if (xslList == null) {
210 xslList = JRSTConfigOption.OUT_TYPE.getOption(config);
211 }
212 List<String> unparsed = config.getUnparsed();
213 if (unparsed.isEmpty()) {
214 JRSTConfig.help();
215 }
216 File inputFile = new File(config.getUnparsed().get(0));
217 File ouputFile = JRSTConfigOption.OUT_FILE.getOptionAsFile(config);
218 Overwrite overwrite = Overwrite.NEVER;
219 if (JRSTConfigOption.FORCE.getOptionAsBoolean(config)) {
220 overwrite = Overwrite.ALLTIME;
221 }
222 boolean simpleGeneration = false;
223 if (JRSTConfigOption.SIMPLE.getOptionAsBoolean(config)) {
224 simpleGeneration = true;
225 }
226
227 generate(xslList, inputFile, ouputFile, overwrite, simpleGeneration);
228 }
229 }
230
231 private static void askOption() throws SecurityException,
232 NoSuchMethodException, IOException {
233 try {
234 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
235 GraphicsDevice[] gs = ge.getScreenDevices();
236 if (!(gs == null)) {
237 if (gs.length > 0) {
238 askOptionGraph();
239 }
240 }
241 } catch (java.awt.HeadlessException e) {
242 log.error("Can't generate document", e);
243 }
244 }
245
246
247
248
249
250
251
252 protected static void askOptionGraph() throws SecurityException,
253 NoSuchMethodException {
254 JRSTView jrstView = new JRSTView();
255 jrstView.pack();
256 jrstView.setVisible(true);
257 }
258
259
260
261
262
263
264
265
266
267
268 public static void generate(String outputType, File fileIn,
269 File fileOut, Overwrite overwrite,
270 boolean simpleGeneration) throws Exception {
271 if (fileOut != null
272 && fileOut.exists()
273 && (overwrite == Overwrite.NEVER || (overwrite == Overwrite.IFNEWER && FileUtils
274 .isFileNewer(fileIn, fileOut)))) {
275
276 log.info("Don't generate file " + fileOut
277 + ", because already exists");
278 } else {
279 Document doc;
280
281 JRSTToXmlStrategy strategy;
282 if (simpleGeneration) {
283 strategy = new JRSTToXmlStrategyJRSTReader();
284 } else {
285 strategy = new JRSTToXmlStrategyDocutils();
286 }
287
288 doc = strategy.generateRstToXml(fileIn, UTF_8);
289
290
291 doc = generateXml(doc, outputType);
292
293
294 if (outputType.equals("pdf")) {
295 generatePdf(doc, fileIn, fileOut);
296 } else {
297 generateFile(doc, fileOut);
298 }
299 }
300 }
301
302
303
304
305
306
307
308
309
310
311 public static void generatePdf(File fileIn, File fileOut, Overwrite overwrite,
312 Document doc) throws Exception {
313 if (fileOut != null
314 && fileOut.exists()
315 && (overwrite == Overwrite.NEVER || (overwrite == Overwrite.IFNEWER && FileUtils
316 .isFileNewer(fileIn, fileOut)))) {
317
318 log.info("Don't generate file " + fileOut
319 + ", because already exists");
320 } else {
321
322
323 doc = generateXml(doc, "pdf");
324
325
326 generatePdf(doc, fileIn, fileOut);
327
328 }
329 }
330
331
332
333
334
335
336
337
338
339 public static Document generateSimpleDoc(File fileIn, String encoding) throws Exception {
340 URL url = fileIn.toURI().toURL();
341 Reader in = new InputStreamReader(url.openStream(), encoding);
342
343
344 JRSTReader jrst = new JRSTReader();
345 return jrst.read(in);
346 }
347
348
349
350
351
352
353
354
355
356 public static Document generateDocutils(File in, String encoding) throws Exception {
357
358 ByteArrayOutputStream out = null;
359
360 try {
361
362 out = new ByteArrayOutputStream();
363
364
365
366
367
368
369 URL resource = JRST.class.getResource("/" + DOCUTILS_LAUNCHER);
370 String docutilsPath = resource.getPath()
371 .replaceAll(DOCUTILS_LAUNCHER, "");
372
373 docutilsPath = docutilsPath.replaceAll(BANG, "");
374 docutilsPath = docutilsPath.replaceAll(FILE_URI_PREFIX, "");
375
376
377 PythonInterpreter interp = new PythonInterpreter();
378 String commandImport = IMPORT_SCRIPT;
379 interp.exec(commandImport);
380
381
382 String filePath = in.getAbsolutePath();
383 String property = System.getProperty(OS_NAME).toLowerCase();
384 if (property.contains(WINDOWS_NAME)) {
385 filePath = filePath.replaceAll("\\\\", "\\\\\\\\");
386 }
387
388
389 interp.setOut(out);
390
391
392 String commandExec = String.format("__run__.exec_docutils('%s', '%s', '%s')",
393 docutilsPath, TYPE_XML, filePath);
394 interp.exec(commandExec);
395
396
397 interp.cleanup();
398
399
400 String xmlString = new String(out.toByteArray(), encoding);
401
402 Document doc = null;
403 try {
404 doc = DocumentHelper.parseText(xmlString);
405 } catch (DocumentException e) {
406 log.error("Error during the creation of the document", e);
407 }
408
409 return doc;
410 } finally {
411 if (out != null) {
412 out.close();
413 }
414 }
415 }
416
417
418
419
420
421
422
423
424
425
426 public static Document generateXml(Document doc, String xslListOrOutType) throws IOException, TransformerException {
427
428
429 String xslList = stylesheets.get(xslListOrOutType);
430 if (xslListOrOutType == null) {
431 xslList = xslListOrOutType;
432 }
433
434
435 JRSTGenerator gen = new JRSTGenerator();
436 String[] xsls = StringUtil.split(xslList, ",");
437 for (String xsl : xsls) {
438 URL stylesheet;
439 File file = new File(xsl);
440 if (file.exists()) {
441 stylesheet = file.toURI().toURL();
442 } else {
443 stylesheet = Resource.getURL(xsl);
444 }
445 if (stylesheet == null) {
446 throw new FileNotFoundException("Can't find stylesheet: "
447 + xsl);
448 }
449
450
451 gen.setUriResolver(new JRSTResourceResolver(xsl));
452
453
454 doc = gen.transform(doc, stylesheet);
455 }
456 return doc;
457 }
458
459
460
461
462
463
464
465
466 public static void generateFile(Document doc, File fileOut) throws IOException {
467
468
469 OutputStreamWriter writer = null;
470
471 try {
472 OutputStream outputStream = new FileOutputStream(fileOut);
473
474
475 writer = new OutputStreamWriter(outputStream, UTF_8);
476
477
478 writer.write(doc.asXML());
479 } catch (Exception eee) {
480 log.error("Failed to write file", eee);
481 } finally {
482 if (writer != null) {
483 writer.close();
484 }
485 }
486 }
487
488
489
490
491
492
493
494
495
496 public static void generatePdf(Document result, File fileIn, File fileOut) throws Exception {
497
498
499 OutputStream outputStream = null;
500
501 try {
502 outputStream = new FileOutputStream(fileOut);
503
504
505 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
506 builder.setEntityResolver(result.getEntityResolver());
507
508
509 ByteArrayInputStream inputStream = new ByteArrayInputStream(result.asXML().getBytes());
510 org.w3c.dom.Document doc = builder.parse(inputStream);
511
512 ITextRenderer renderer = new ITextRenderer();
513
514
515 String absolutePath = fileIn.getParentFile().getAbsolutePath();
516 JRSTUserAgent jrstUserAgent = new JRSTUserAgent(absolutePath);
517 jrstUserAgent.setBaseURL(absolutePath);
518 renderer.getSharedContext().setUserAgentCallback(jrstUserAgent);
519 jrstUserAgent.setSharedContext(renderer.getSharedContext());
520
521
522 renderer.setDocument(doc, null);
523 renderer.layout();
524 renderer.createPDF(outputStream);
525 } catch (Exception eee) {
526 log.error("Failed to write PDF", eee);
527 } finally {
528 if (outputStream != null) {
529 outputStream.close();
530 }
531 }
532 }
533
534
535
536
537
538
539
540
541
542
543 public static String generateRST(Document doc) throws IOException {
544
545 DocUtilsVisitor visitor = new DocUtils2RST();
546
547
548
549 doc.accept(visitor);
550
551
552 String result = visitor.getResult();
553
554 visitor.clear();
555
556 return result;
557 }
558 }