PageRenderTime 53ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/xpath/xslt-rt/src/org/intellij/plugins/xslt/run/rt/XSLTRunner.java

https://github.com/JetBrains/intellij-community
Java | 323 lines | 261 code | 40 blank | 22 comment | 66 complexity | c12257e0a956dd3274436866b74e27fe MD5 | raw file
  1. /*
  2. * Copyright 2005 Sascha Weinreuter
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.intellij.plugins.xslt.run.rt;
  17. import org.xml.sax.SAXParseException;
  18. import javax.xml.transform.*;
  19. import javax.xml.transform.stream.StreamResult;
  20. import javax.xml.transform.stream.StreamSource;
  21. import java.io.*;
  22. import java.net.InetAddress;
  23. import java.net.ServerSocket;
  24. import java.net.Socket;
  25. import java.net.SocketTimeoutException;
  26. import java.util.Enumeration;
  27. import java.util.HashSet;
  28. import java.util.Set;
  29. /** @noinspection CallToPrintStackTrace, UseOfSystemOutOrSystemErr, IOResourceOpenedButNotSafelyClosed, SocketOpenedButNotSafelyClosed */
  30. public final class XSLTRunner implements XSLTMain {
  31. private XSLTRunner() {
  32. }
  33. public static void main(String[] args) throws Throwable {
  34. final XSLTMain main = loadMain();
  35. TransformerFactory transformerFactory;
  36. try {
  37. transformerFactory = main.createTransformerFactory();
  38. } catch (AbstractMethodError e) {
  39. // old debugger
  40. transformerFactory = createTransformerFactoryStatic();
  41. } catch (ClassNotFoundException e) {
  42. transformerFactory = createTransformerFactoryStatic();
  43. }
  44. final String uriResolverClass = System.getProperty("xslt.uri-resolver");
  45. if (uriResolverClass != null) {
  46. transformerFactory.setURIResolver((URIResolver)Class.forName(uriResolverClass).newInstance());
  47. }
  48. final boolean[] trouble = new boolean[]{ false };
  49. final MyErrorListener listener = new MyErrorListener(trouble);
  50. final boolean isSmartErrorHandling = System.getProperty("xslt.smart-error-handling", "false").equals("true");
  51. if (isSmartErrorHandling) {
  52. transformerFactory.setErrorListener(listener);
  53. }
  54. final File xslt = new File(System.getProperty("xslt.file"));
  55. try {
  56. final Transformer transformer = transformerFactory.newTransformer(new StreamSource(xslt));
  57. if (transformer != null && !trouble[0]) {
  58. final Enumeration props = System.getProperties().keys();
  59. while (props.hasMoreElements()) {
  60. String s = (String)props.nextElement();
  61. if (s.startsWith("xslt.param.")) {
  62. final String name = s.substring("xslt.param.".length());
  63. final String value = System.getProperty(s);
  64. transformer.setParameter(name, value);
  65. }
  66. }
  67. final File input = new File(System.getProperty("xslt.input"));
  68. final String out = System.getProperty("xslt.output");
  69. OutputStream fileStream;
  70. if (out != null) {
  71. final File output = new File(out);
  72. fileStream = new BufferedOutputStream(new FileOutputStream(output));
  73. } else {
  74. fileStream = null;
  75. }
  76. final StreamResult result;
  77. final Integer _port = Integer.getInteger("xslt.listen-port", -1);
  78. final int port = _port.intValue();
  79. if (port != -1) {
  80. // block until IDEA connects
  81. try {
  82. final ServerSocket serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
  83. serverSocket.setSoTimeout(Integer.getInteger("xslt.listen-timeout", 5000).intValue());
  84. final Socket socket = serverSocket.accept();
  85. final BufferedOutputStream socketStream = new BufferedOutputStream(socket.getOutputStream(), 16);
  86. if (out != null) {
  87. result = new StreamResult(new ForkedOutputStream(new OutputStream[]{ socketStream, fileStream }));
  88. } else {
  89. result = new StreamResult(new OutputStreamWriter(socketStream, "UTF-8"));
  90. }
  91. } catch (SocketTimeoutException ignored) {
  92. System.err.println("Plugin did not connect to runner within timeout. Run aborted.");
  93. return;
  94. }
  95. } else {
  96. final String encoding = System.getProperty("file.encoding");
  97. if (encoding != null) {
  98. // ensure proper encoding in xml declaration
  99. transformer.setOutputProperty("encoding", encoding);
  100. if (out != null) {
  101. result = new StreamResult(new OutputStreamWriter(new ForkedOutputStream(new OutputStream[]{System.out, fileStream}), encoding));
  102. } else {
  103. result = new StreamResult(new OutputStreamWriter(System.out, encoding));
  104. }
  105. } else {
  106. if (out != null) {
  107. result = new StreamResult(new ForkedOutputStream(new OutputStream[]{ System.out, fileStream }));
  108. } else {
  109. result = new StreamResult(System.out);
  110. }
  111. }
  112. }
  113. Runtime.getRuntime().addShutdownHook(new Thread("XSLT runner") {
  114. public void run() {
  115. try {
  116. final Writer out = result.getWriter();
  117. if (out != null) {
  118. out.flush();
  119. out.close();
  120. } else if (result.getOutputStream() != null) {
  121. result.getOutputStream().flush();
  122. result.getOutputStream().close();
  123. }
  124. } catch (IOException e) {
  125. // no chance to fix...
  126. }
  127. }
  128. });
  129. main.start(transformer, new StreamSource(input), result);
  130. }
  131. } catch (TransformerException e) {
  132. if (isSmartErrorHandling) {
  133. listener.error(e);
  134. } else {
  135. throw e;
  136. }
  137. } catch (Throwable t) {
  138. t.printStackTrace();
  139. System.exit(1);
  140. }
  141. }
  142. public TransformerFactory createTransformerFactory() throws Exception {
  143. return createTransformerFactoryStatic();
  144. }
  145. public static TransformerFactory createTransformerFactoryStatic() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
  146. final String factoryClass = System.getProperty("xslt.transformer-factory");
  147. if (factoryClass != null) {
  148. return (TransformerFactory)Class.forName(factoryClass).newInstance();
  149. } else {
  150. return TransformerFactory.newInstance();
  151. }
  152. }
  153. public void start(Transformer transformer, Source source, Result result) throws TransformerException {
  154. transformer.transform(source, result);
  155. }
  156. private static XSLTMain loadMain() {
  157. final String mainClass = System.getProperty("xslt.main");
  158. if (mainClass == null) {
  159. return new XSLTRunner();
  160. }
  161. try {
  162. return (XSLTMain)Class.forName(mainClass).newInstance();
  163. } catch (ClassNotFoundException e) {
  164. throw new AssertionError(e);
  165. } catch (IllegalAccessException e) {
  166. throw new AssertionError(e);
  167. } catch (InstantiationException e) {
  168. throw new AssertionError(e);
  169. }
  170. }
  171. /** @noinspection UseOfSystemOutOrSystemErr*/
  172. private static class MyErrorListener implements ErrorListener {
  173. private final Set myMessages = new HashSet();
  174. private final boolean[] myTrouble;
  175. MyErrorListener(boolean[] trouble) {
  176. myTrouble = trouble;
  177. }
  178. public void warning(TransformerException exception) {
  179. handleException(exception, "WARNING");
  180. }
  181. public void error(TransformerException exception) {
  182. handleException(exception, "ERROR");
  183. myTrouble[0] = true;
  184. }
  185. public void fatalError(TransformerException exception) {
  186. handleException(exception, "FATAL");
  187. myTrouble[0] = true;
  188. }
  189. private void handleException(TransformerException exception, String type) {
  190. final String message = getMessage(exception);
  191. if (!myMessages.contains(message)) {
  192. System.err.println("[" + type + "]: " + message);
  193. myMessages.add(message);
  194. }
  195. }
  196. private static String getMessage(TransformerException exception) {
  197. final SourceLocator[] locators = new SourceLocator[]{ exception.getLocator() };
  198. final String[] messages = new String[1];
  199. findLocator(exception, locators, messages);
  200. final SourceLocator locator = locators[0];
  201. if (locator != null) {
  202. final String systemId = locator.getSystemId();
  203. if (systemId != null) {
  204. String s = systemId.replaceAll(" ", "%20") + ": ";
  205. final int lineNumber = locator.getLineNumber();
  206. if (lineNumber != -1) {
  207. s += "line " + lineNumber + ": ";
  208. final int columnNumber = locator.getColumnNumber();
  209. if (columnNumber != -1) {
  210. s += "column " + columnNumber + ": ";
  211. }
  212. }
  213. return s + (messages[0] != null ? messages[0] : exception.getMessage());
  214. }
  215. }
  216. return messages[0] != null ? messages[0] : exception.getMessage();
  217. }
  218. private static void findLocator(Throwable exception, SourceLocator[] locators, String[] messages) {
  219. if (exception instanceof TransformerException) {
  220. final TransformerException t = (TransformerException)exception;
  221. if (t.getLocator() != null) {
  222. messages[0] = t.getMessage();
  223. locators[0] = t.getLocator();
  224. } else if (exception.getCause() != null) {
  225. findLocator(exception.getCause(), locators, messages);
  226. }
  227. } else if (exception instanceof SAXParseException) {
  228. final SAXParseException sae = (SAXParseException)exception;
  229. messages[0] = sae.getMessage();
  230. locators[0] = new SourceLocator() {
  231. public int getColumnNumber() {
  232. return sae.getColumnNumber();
  233. }
  234. public int getLineNumber() {
  235. return sae.getLineNumber();
  236. }
  237. public String getPublicId() {
  238. return null;
  239. }
  240. public String getSystemId() {
  241. return sae.getSystemId();
  242. }
  243. };
  244. } else if (exception.getCause() != null) {
  245. findLocator(exception.getCause(), locators, messages);
  246. }
  247. try {
  248. final Throwable t = (Throwable)exception.getClass().getMethod("getException", new Class[0]).invoke(exception, new Object[0]);
  249. if (t != exception) {
  250. findLocator(t, locators, messages);
  251. }
  252. } catch (Exception e) {
  253. //
  254. }
  255. }
  256. }
  257. static class ForkedOutputStream extends OutputStream {
  258. OutputStream[] outs;
  259. ForkedOutputStream(OutputStream[] out) {
  260. outs = out;
  261. }
  262. public void write(byte[] b, int off, int len) throws IOException {
  263. for (int i = 0, outsLength = outs.length; i < outsLength; i++) {
  264. outs[i].write(b, off, len);
  265. }
  266. }
  267. public void write(int b) throws IOException {
  268. for (int i = 0, outsLength = outs.length; i < outsLength; i++) {
  269. outs[i].write(b);
  270. }
  271. }
  272. public void flush() throws IOException {
  273. for (int i = 0, outsLength = outs.length; i < outsLength; i++) {
  274. outs[i].flush();
  275. }
  276. }
  277. public void close() throws IOException {
  278. for (int i = 0, outsLength = outs.length; i < outsLength; i++) {
  279. outs[i].close();
  280. }
  281. }
  282. }
  283. }