/plugins/Console/tags/release-2-4/console/DefaultShell.java

# · Java · 428 lines · 361 code · 39 blank · 28 comment · 48 complexity · 68f0fddab510972891d8862ae1fd18d1 MD5 · raw file

  1. /*
  2. * DefaultShell.java - Executes OS commands
  3. * Copyright (C) 1999, 2000 Slava Pestov
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version 2
  8. * of the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. package console;
  20. import java.lang.reflect.*;
  21. import java.io.*;
  22. import org.gjt.sp.jedit.*;
  23. import org.gjt.sp.util.Log;
  24. class DefaultShell extends Shell
  25. {
  26. public DefaultShell()
  27. {
  28. super("Console");
  29. java13 = (System.getProperty("java.version").compareTo("1.3") >= 0);
  30. Log.log(Log.DEBUG,this,"cd command " + (java13 ? "enabled" : "disabled"));
  31. dir = System.getProperty("user.dir");
  32. }
  33. public void printInfoMessage(Console console)
  34. {
  35. console.printInfo(jEdit.getProperty("console.shell.info"));
  36. }
  37. public void execute(View view, String command, Console console)
  38. {
  39. stop();
  40. ConsolePlugin.clearErrors();
  41. if(command.equals("pwd"))
  42. {
  43. console.printPlain(dir);
  44. return;
  45. }
  46. else if(command.startsWith("cd "))
  47. {
  48. if(!java13)
  49. console.printError(jEdit.getProperty("console.shell.cd-unsup"));
  50. else
  51. {
  52. String newDir = command.substring(3).trim();
  53. if(newDir.equals(".."))
  54. newDir = MiscUtilities.getParentOfPath(dir);
  55. else
  56. newDir = MiscUtilities.constructPath(dir,newDir);
  57. String[] args = { newDir };
  58. if(new File(newDir).exists())
  59. {
  60. dir = newDir;
  61. console.printPlain(jEdit.getProperty("console.shell.cd",args));
  62. }
  63. else
  64. console.printError(jEdit.getProperty("console.shell.cd-error",args));
  65. }
  66. return;
  67. }
  68. String osName = System.getProperty("os.name");
  69. boolean appendEXE = (osName.indexOf("Windows") != -1 ||
  70. osName.indexOf("OS/2") != -1);
  71. // Expand variables
  72. StringBuffer buf = new StringBuffer();
  73. for(int i = 0; i < command.length(); i++)
  74. {
  75. char c = command.charAt(i);
  76. switch(c)
  77. {
  78. case '$':
  79. if(i == command.length() - 1)
  80. buf.append(c);
  81. else
  82. {
  83. Buffer buffer = view.getBuffer();
  84. switch(command.charAt(++i))
  85. {
  86. case 'd':
  87. String path = MiscUtilities.getParentOfPath(
  88. buffer.getPath());
  89. if(path.endsWith("/")
  90. || path.endsWith(File.separator))
  91. path = path.substring(0,
  92. path.length() - 1);
  93. buf.append(path);
  94. break;
  95. case 'u':
  96. path = buffer.getPath();
  97. if(!MiscUtilities.isURL(path))
  98. path = "file:" + path;
  99. buf.append(path);
  100. break;
  101. case 'f':
  102. buf.append(buffer.getPath());
  103. break;
  104. case 'j':
  105. buf.append(jEdit.getJEditHome());
  106. break;
  107. case 'n':
  108. String name = buffer.getName();
  109. int index = name.lastIndexOf('.');
  110. if(index == -1)
  111. buf.append(name);
  112. else
  113. buf.append(name.substring(0,index));
  114. break;
  115. case '$':
  116. buf.append('$');
  117. break;
  118. }
  119. }
  120. break;
  121. case '~':
  122. // insert the home directory if the tilde
  123. // is the last character on the line, or if
  124. // the character after it is whitespace or
  125. // a path separator.
  126. if(i == command.length() - 1)
  127. {
  128. buf.append(System.getProperty("user.home"));
  129. break;
  130. }
  131. c = command.charAt(i + 1);
  132. if(c == '/' || c == ' ' || c == File.separatorChar)
  133. {
  134. buf.append(System.getProperty("user.home"));
  135. break;
  136. }
  137. buf.append('~');
  138. break;
  139. default:
  140. buf.append(c);
  141. }
  142. }
  143. command = buf.toString();
  144. // On Windows and OS/2, try running <command>.bat,
  145. // then <command>.exe
  146. if(appendEXE)
  147. {
  148. int spaceIndex = command.indexOf(' ');
  149. if(spaceIndex == -1)
  150. spaceIndex = command.length();
  151. int dotIndex = command.indexOf('.');
  152. if(dotIndex == -1 || dotIndex > spaceIndex)
  153. {
  154. try
  155. {
  156. String newCommand = command.substring(
  157. 0,spaceIndex) + ".bat" + command
  158. .substring(spaceIndex);
  159. process = _exec(newCommand);
  160. process.getOutputStream().close();
  161. return;
  162. }
  163. catch(IOException io)
  164. {
  165. try
  166. {
  167. String newCommand = command.substring(
  168. 0,spaceIndex) + ".exe" + command
  169. .substring(spaceIndex);
  170. process = _exec(newCommand);
  171. process.getOutputStream().close();
  172. }
  173. catch(IOException _io)
  174. {
  175. String[] args = { _io.getMessage() };
  176. console.printInfo(jEdit.getProperty("console.shell.ioerror",args));
  177. }
  178. catch(Throwable t)
  179. {
  180. Log.log(Log.ERROR,this,t);
  181. }
  182. return;
  183. }
  184. catch(Throwable t)
  185. {
  186. Log.log(Log.ERROR,this,t);
  187. }
  188. }
  189. }
  190. try
  191. {
  192. process = _exec(command);
  193. process.getOutputStream().close();
  194. }
  195. catch(IOException io)
  196. {
  197. String[] args = { io.getMessage() };
  198. console.printInfo(jEdit.getProperty("console.shell.ioerror",args));
  199. return;
  200. }
  201. catch(Throwable t)
  202. {
  203. Log.log(Log.ERROR,this,t);
  204. }
  205. this.command = command;
  206. this.console = console;
  207. stdout = new StdoutThread();
  208. stderr = new StderrThread();
  209. }
  210. public synchronized void stop()
  211. {
  212. if(command != null)
  213. {
  214. stdout.stop();
  215. stderr.stop();
  216. process.destroy();
  217. String[] args = { command };
  218. console.printError(jEdit.getProperty("console.shell.killed",args));
  219. exitStatus = false;
  220. commandDone();
  221. }
  222. }
  223. public synchronized boolean waitFor()
  224. {
  225. if(command != null)
  226. {
  227. try
  228. {
  229. wait();
  230. }
  231. catch(InterruptedException ie)
  232. {
  233. return false;
  234. }
  235. }
  236. return exitStatus;
  237. }
  238. // private members
  239. private String command;
  240. private Console console;
  241. private Process process;
  242. private Thread stdout;
  243. private Thread stderr;
  244. private String dir;
  245. private boolean java13;
  246. private int threadDoneCount;
  247. private boolean exitStatus;
  248. private void parseLine(String line)
  249. {
  250. if(console == null)
  251. return;
  252. int type = ConsolePlugin.parseLine(line,dir);
  253. switch(type)
  254. {
  255. case ErrorSource.ERROR:
  256. console.printError(line);
  257. break;
  258. case ErrorSource.WARNING:
  259. console.printWarning(line);
  260. break;
  261. default:
  262. console.printPlain(line);
  263. break;
  264. }
  265. }
  266. private synchronized void threadDone()
  267. {
  268. threadDoneCount++;
  269. if(threadDoneCount == 2)
  270. commandDone();
  271. }
  272. private synchronized void commandDone()
  273. {
  274. if(process != null)
  275. {
  276. int exitCode;
  277. try
  278. {
  279. exitCode = process.waitFor();
  280. }
  281. catch(InterruptedException e)
  282. {
  283. Log.log(Log.ERROR,this,"Yo Flav, what is this?");
  284. return;
  285. }
  286. Object[] args = { command, new Integer(exitCode) };
  287. String msg = jEdit.getProperty("console.shell.exited",args);
  288. if(exitCode == 0)
  289. console.printInfo(msg);
  290. else
  291. console.printError(msg);
  292. exitStatus = (exitCode == 0);
  293. }
  294. threadDoneCount = 0;
  295. command = null;
  296. stdout = null;
  297. stderr = null;
  298. process = null;
  299. console = null;
  300. notify();
  301. }
  302. private Process _exec(String command) throws Throwable
  303. {
  304. if(java13)
  305. {
  306. try
  307. {
  308. Class[] classes = { String.class, String[].class, File.class };
  309. Method method = Runtime.class.getMethod("exec",classes);
  310. Object[] args = { command, null, new File(dir) };
  311. return (Process)method.invoke(Runtime.getRuntime(),args);
  312. }
  313. catch(InvocationTargetException e)
  314. {
  315. throw e.getTargetException();
  316. }
  317. }
  318. else
  319. return Runtime.getRuntime().exec(command);
  320. }
  321. class StdoutThread extends Thread
  322. {
  323. StdoutThread()
  324. {
  325. setName(StdoutThread.class + "[" + command + "]");
  326. start();
  327. }
  328. public void run()
  329. {
  330. try
  331. {
  332. BufferedReader in = new BufferedReader(
  333. new InputStreamReader(process
  334. .getInputStream()));
  335. String line;
  336. while((line = in.readLine()) != null)
  337. {
  338. parseLine(line);
  339. }
  340. in.close();
  341. }
  342. catch(IOException io)
  343. {
  344. String[] args = { io.getMessage() };
  345. console.printError(jEdit.getProperty("console.shell.ioerror",args));
  346. }
  347. finally
  348. {
  349. threadDone();
  350. }
  351. }
  352. }
  353. class StderrThread extends Thread
  354. {
  355. StderrThread()
  356. {
  357. setName(StderrThread.class + "[" + command + "]");
  358. start();
  359. }
  360. public void run()
  361. {
  362. try
  363. {
  364. // If process exits really fast, it could
  365. // be null by now. So check first...
  366. if(process == null)
  367. return;
  368. BufferedReader in = new BufferedReader(
  369. new InputStreamReader(process
  370. .getErrorStream()));
  371. String line;
  372. while((line = in.readLine()) != null)
  373. {
  374. parseLine(line);
  375. }
  376. in.close();
  377. }
  378. catch(IOException io)
  379. {
  380. String[] args = { io.getMessage() };
  381. console.printError(jEdit.getProperty("console.shell.ioerror",args));
  382. }
  383. finally
  384. {
  385. threadDone();
  386. }
  387. }
  388. }
  389. }