View Javadoc
1   /*
2    * #%L
3    * JRst :: Api
4    * %%
5    * Copyright (C) 2004 - 2012 CodeLutin
6    * %%
7    * This program is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU Lesser General Public License as 
9    * published by the Free Software Foundation, either version 3 of the 
10   * License, or (at your option) any later version.
11   * 
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Lesser Public License for more details.
16   * 
17   * You should have received a copy of the GNU General Lesser Public 
18   * License along with this program.  If not, see
19   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
20   * #L%
21   */
22  package org.nuiton.jrst;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.codehaus.plexus.component.annotations.Component;
27  import org.dom4j.Document;
28  import org.dom4j.DocumentException;
29  import org.dom4j.DocumentHelper;
30  import org.nuiton.jrst.legacy.JRSTReader;
31  import org.python.util.PythonInterpreter;
32  
33  import java.io.ByteArrayOutputStream;
34  import java.io.File;
35  import java.net.URL;
36  
37  /**
38   * Old mecanism to transform rst file to xml format using {@link JRSTReader}.
39   *
40   * @author tchemit <chemit@codelutin.com>
41   * @since 2.0.1
42   */
43  @Component(role = JRSTToXmlStrategy.class, hint = "docutils",
44             description = "Transform a RST model (using jython + docutils), " +
45                           "to a xml format.")
46  
47  public class JRSTToXmlStrategyDocutils implements JRSTToXmlStrategy {
48  
49      private static final String DOCUTILS_LAUNCHER = "__run__.py";
50  
51      private static final String IMPORT_SCRIPT = "import __run__";
52  
53      private static final String WINDOWS_NAME = "win";
54  
55      private static final String OS_NAME = "os.name";
56  
57      private static final String BANG = "!";
58  
59      private static final String FILE_URI_PREFIX = "file:";
60  
61      /** Logger. */
62      private static final Log log =
63              LogFactory.getLog(JRSTToXmlStrategyDocutils.class);
64  
65      @Override
66      public Document generateRstToXml(File in, String encoding) throws Exception {
67          ByteArrayOutputStream out = null;
68  
69          try {
70              // Transformation to XML
71              out = new ByteArrayOutputStream();
72  
73              // Transformation of the __run__ URL into a path that python will use
74              // For example the URL is :
75              // jar:file:/home/user/.m2/repository/org/nuiton/jrst/docutils/1.6-SNAPSHOT/docutils-1.6-SNAPSHOT.jar!/__run__.py
76              // and it becomes :
77              // /home/user/.m2/repository/org/nuiton/jrst/docutils/1.6-SNAPSHOT/docutils-1.6-SNAPSHOT.jar/
78              URL resource = JRST.class.getResource("/" + DOCUTILS_LAUNCHER);
79              String docutilsPath = resource.getPath()
80                      .replaceAll(DOCUTILS_LAUNCHER, "");
81  
82              docutilsPath = docutilsPath.replaceAll(BANG, "");
83              docutilsPath = docutilsPath.replaceAll(FILE_URI_PREFIX, "");
84  
85              // Import of the main script to use docutils ( __run__ )
86              PythonInterpreter interp = new PythonInterpreter();
87              String commandImport = IMPORT_SCRIPT;
88              interp.exec(commandImport);
89  
90              // If the OS is windows, escapes the backslashs in the filepath
91              String filePath = in.getAbsolutePath();
92              String property = System.getProperty(OS_NAME).toLowerCase();
93              if (property.contains(WINDOWS_NAME)) {
94                  filePath = filePath.replaceAll("\\\\", "\\\\\\\\");
95              }
96  
97              // Sets an output stream in the python interpreter and executes the code
98              interp.setOut(out);
99  
100             // Execution of the docutils script to transform rst to xml
101             String commandExec = String.format("__run__.exec_docutils('%s', '%s', '%s')",
102                                                docutilsPath, JRST.TYPE_XML, filePath);
103             interp.exec(commandExec);
104 
105             // Cleans the python interpreter to avoid problems if they are multiple execution of this method
106             interp.cleanup();
107 
108             // Transforms the output stream to a document
109             String xmlString = new String(out.toByteArray(), encoding);
110 
111             Document doc = null;
112             try {
113                 doc = DocumentHelper.parseText(xmlString);
114             } catch (DocumentException e) {
115                 log.error("Error during the creation of the document", e);
116             }
117             out.close();
118 
119             return doc;
120         } finally {
121             if (out != null) {
122                 out.close();
123             }
124         }
125     }
126 }