PageRenderTime 41ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

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

#
Java | 485 lines | 407 code | 43 blank | 35 comment | 85 complexity | ea0d33666f277ce5330244316420d85b MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  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 java.util.Hashtable;
  23. import org.gjt.sp.jedit.*;
  24. import org.gjt.sp.util.Log;
  25. class DefaultShell extends Shell
  26. {
  27. public DefaultShell()
  28. {
  29. super("Console");
  30. java13 = (System.getProperty("java.version").compareTo("1.3") >= 0);
  31. Log.log(Log.DEBUG,this,"cd command " + (java13 ? "enabled" : "disabled"));
  32. dir = System.getProperty("user.dir");
  33. initTableWinBuiltIns();
  34. }
  35. public void printInfoMessage(Console console)
  36. {
  37. console.printInfo(jEdit.getProperty("console.shell.info"));
  38. }
  39. public void execute(View view, String command, Console console)
  40. {
  41. stop();
  42. ConsolePlugin.clearErrors();
  43. // Expand variables
  44. StringBuffer buf = new StringBuffer();
  45. for(int i = 0; i < command.length(); i++)
  46. {
  47. char c = command.charAt(i);
  48. switch(c)
  49. {
  50. case '$':
  51. if(i == command.length() - 1)
  52. buf.append(c);
  53. else
  54. {
  55. Buffer buffer = view.getBuffer();
  56. switch(command.charAt(++i))
  57. {
  58. case 'd':
  59. String path = MiscUtilities.getParentOfPath(
  60. buffer.getPath());
  61. if(path.endsWith("/")
  62. || path.endsWith(File.separator))
  63. path = path.substring(0,
  64. path.length() - 1);
  65. buf.append(path);
  66. break;
  67. case 'u':
  68. path = buffer.getPath();
  69. if(!MiscUtilities.isURL(path))
  70. path = "file:" + path;
  71. buf.append(path);
  72. break;
  73. case 'f':
  74. buf.append(buffer.getPath());
  75. break;
  76. case 'j':
  77. buf.append(jEdit.getJEditHome());
  78. break;
  79. case 'n':
  80. String name = buffer.getName();
  81. int index = name.lastIndexOf('.');
  82. if(index == -1)
  83. buf.append(name);
  84. else
  85. buf.append(name.substring(0,index));
  86. break;
  87. case '$':
  88. buf.append('$');
  89. break;
  90. }
  91. }
  92. break;
  93. case '~':
  94. // insert the home directory if the tilde
  95. // is the last character on the line, or if
  96. // the character after it is whitespace or
  97. // a path separator.
  98. if(i == command.length() - 1)
  99. {
  100. buf.append(System.getProperty("user.home"));
  101. break;
  102. }
  103. c = command.charAt(i + 1);
  104. if(c == '/' || c == ' ' || c == File.separatorChar)
  105. {
  106. buf.append(System.getProperty("user.home"));
  107. break;
  108. }
  109. buf.append('~');
  110. break;
  111. default:
  112. buf.append(c);
  113. }
  114. }
  115. if(command.equals("pwd"))
  116. {
  117. console.printPlain(dir);
  118. return;
  119. }
  120. else if(command.startsWith("cd "))
  121. {
  122. if(!java13)
  123. console.printError(jEdit.getProperty("console.shell.cd-unsup"));
  124. else
  125. {
  126. String newDir = command.substring(3).trim();
  127. if(newDir.equals(".."))
  128. newDir = MiscUtilities.getParentOfPath(dir);
  129. else
  130. newDir = MiscUtilities.constructPath(dir,newDir);
  131. String[] args = { newDir };
  132. if(new File(newDir).exists())
  133. {
  134. dir = newDir;
  135. console.printPlain(jEdit.getProperty("console.shell.cd",args));
  136. }
  137. else
  138. console.printError(jEdit.getProperty("console.shell.cd-error",args));
  139. }
  140. return;
  141. }
  142. String osName = System.getProperty("os.name");
  143. boolean appendEXE = (osName.indexOf("Windows") != -1 ||
  144. osName.indexOf("OS/2") != -1);
  145. command = buf.toString();
  146. // this will be set to true if adding a Windows extension
  147. // to the executable file name works
  148. boolean alreadyDone = false;
  149. // On Windows and OS/2, try running <command>.bat,
  150. // then <command>.exe
  151. if(appendEXE)
  152. {
  153. // first, let's deal with some built-in Windows commands
  154. // and pass them to an instance of the Windows command
  155. // interpreter
  156. if(IsWinBuiltIn(command))
  157. {
  158. // which command interpreter?
  159. String cmdInterp;
  160. if(osName.indexOf("Windows 9") != -1)
  161. cmdInterp = new String("command.com /C ");
  162. else cmdInterp = new String("cmd.exe /C ");
  163. command = cmdInterp + command;
  164. }
  165. int spaceIndex = command.indexOf(' ');
  166. if(spaceIndex == -1)
  167. spaceIndex = command.length();
  168. int dotIndex = command.indexOf('.');
  169. if(dotIndex == -1 || dotIndex > spaceIndex)
  170. {
  171. String[] extensionsToTry = { ".cmd", ".bat", ".com", ".exe" };
  172. for(int i = 0; i < extensionsToTry.length; i++)
  173. {
  174. try
  175. {
  176. String newCommand = command.substring(
  177. 0,spaceIndex) + extensionsToTry[i]
  178. + command.substring(spaceIndex);
  179. process = _exec(newCommand);
  180. process.getOutputStream().close();
  181. alreadyDone = true;
  182. break;
  183. }
  184. catch(IOException io)
  185. {
  186. }
  187. catch(Throwable t)
  188. {
  189. Log.log(Log.ERROR,this,t);
  190. return;
  191. }
  192. }
  193. }
  194. }
  195. if(!alreadyDone)
  196. {
  197. try
  198. {
  199. process = _exec(command);
  200. process.getOutputStream().close();
  201. }
  202. catch(IOException io)
  203. {
  204. String[] args = { io.getMessage() };
  205. console.printInfo(jEdit.getProperty("console.shell.ioerror",args));
  206. return;
  207. }
  208. catch(Throwable t)
  209. {
  210. Log.log(Log.ERROR,this,t);
  211. }
  212. }
  213. this.command = command;
  214. this.console = console;
  215. stdout = new StdoutThread();
  216. stderr = new StderrThread();
  217. }
  218. public synchronized void stop()
  219. {
  220. if(command != null)
  221. {
  222. stdout.stop();
  223. stderr.stop();
  224. process.destroy();
  225. String[] args = { command };
  226. console.printError(jEdit.getProperty("console.shell.killed",args));
  227. exitStatus = false;
  228. commandDone();
  229. }
  230. }
  231. public synchronized boolean waitFor()
  232. {
  233. if(command != null)
  234. {
  235. try
  236. {
  237. wait();
  238. }
  239. catch(InterruptedException ie)
  240. {
  241. return false;
  242. }
  243. }
  244. return exitStatus;
  245. }
  246. // private members
  247. private String command;
  248. private Console console;
  249. private Process process;
  250. private Thread stdout;
  251. private Thread stderr;
  252. private String dir;
  253. private boolean java13;
  254. private int threadDoneCount;
  255. private boolean exitStatus;
  256. // used to store built-in commands
  257. private Hashtable tableWinBuiltIns;
  258. private void initTableWinBuiltIns()
  259. {
  260. String [] elems = { "md", "rd", "del", "dir", "copy",
  261. "move", "erase", "mkdir", "rmdir" };
  262. this.tableWinBuiltIns = new Hashtable();
  263. for( int i = 0; i < elems.length; ++i)
  264. {
  265. this.tableWinBuiltIns.put(elems[i], elems[i]);
  266. }
  267. }
  268. private boolean IsWinBuiltIn(String command)
  269. {
  270. String com = command.trim();
  271. final int i1 = com.indexOf(' ');
  272. final int i2 = com.indexOf('.');
  273. final int i3 = com.indexOf('\\');
  274. final int i4 = com.indexOf('\"');
  275. final int cLen = com.length();
  276. int pos = cLen;
  277. if( i1 != -1 && i1 < pos) pos = i1;
  278. if( i2 != -1 && i2 < pos) pos = i2;
  279. if( i3 != -1 && i3 < pos) pos = i3;
  280. if( i4 != -1 && i4 < pos) pos = i4;
  281. String builtIn = com.substring( 0, pos);
  282. if( tableWinBuiltIns.get( builtIn) != null)
  283. {
  284. int bLen = builtIn.length();
  285. if( cLen == bLen)
  286. return true;
  287. final char c = com.charAt(++bLen);
  288. if( c == ' ' || c == '\\' || c == '\"')
  289. return true;
  290. if( c == '.')
  291. {
  292. if( cLen == bLen)
  293. return true;
  294. final char cc = com.charAt(++bLen);
  295. if( cc == '.' || cc == '\\')
  296. return true;
  297. }
  298. }
  299. return false;
  300. }
  301. private void parseLine(String line)
  302. {
  303. if(console == null)
  304. return;
  305. int type = ConsolePlugin.parseLine(line,dir);
  306. switch(type)
  307. {
  308. case ErrorSource.ERROR:
  309. console.printError(line);
  310. break;
  311. case ErrorSource.WARNING:
  312. console.printWarning(line);
  313. break;
  314. default:
  315. console.printPlain(line);
  316. break;
  317. }
  318. }
  319. private synchronized void threadDone()
  320. {
  321. threadDoneCount++;
  322. if(threadDoneCount == 2)
  323. commandDone();
  324. }
  325. private synchronized void commandDone()
  326. {
  327. if(process != null)
  328. {
  329. int exitCode;
  330. try
  331. {
  332. exitCode = process.waitFor();
  333. }
  334. catch(InterruptedException e)
  335. {
  336. Log.log(Log.ERROR,this,"Yo Flav, what is this?");
  337. return;
  338. }
  339. Object[] args = { command, new Integer(exitCode) };
  340. String msg = jEdit.getProperty("console.shell.exited",args);
  341. if(exitCode == 0)
  342. console.printInfo(msg);
  343. else
  344. console.printError(msg);
  345. exitStatus = (exitCode == 0);
  346. }
  347. threadDoneCount = 0;
  348. command = null;
  349. stdout = null;
  350. stderr = null;
  351. process = null;
  352. console = null;
  353. notify();
  354. }
  355. private Process _exec(String command) throws Throwable
  356. {
  357. if(java13)
  358. {
  359. try
  360. {
  361. Class[] classes = { String.class, String[].class, File.class };
  362. Method method = Runtime.class.getMethod("exec",classes);
  363. Object[] args = { command, null, new File(dir) };
  364. return (Process)method.invoke(Runtime.getRuntime(),args);
  365. }
  366. catch(InvocationTargetException e)
  367. {
  368. throw e.getTargetException();
  369. }
  370. }
  371. else
  372. return Runtime.getRuntime().exec(command);
  373. }
  374. class StdoutThread extends Thread
  375. {
  376. StdoutThread()
  377. {
  378. setName(StdoutThread.class + "[" + command + "]");
  379. start();
  380. }
  381. public void run()
  382. {
  383. try
  384. {
  385. BufferedReader in = new BufferedReader(
  386. new InputStreamReader(process
  387. .getInputStream()));
  388. String line;
  389. while((line = in.readLine()) != null)
  390. {
  391. parseLine(line);
  392. }
  393. in.close();
  394. }
  395. catch(IOException io)
  396. {
  397. String[] args = { io.getMessage() };
  398. console.printError(jEdit.getProperty("console.shell.ioerror",args));
  399. }
  400. finally
  401. {
  402. threadDone();
  403. }
  404. }
  405. }
  406. class StderrThread extends Thread
  407. {
  408. StderrThread()
  409. {
  410. setName(StderrThread.class + "[" + command + "]");
  411. start();
  412. }
  413. public void run()
  414. {
  415. try
  416. {
  417. // If process exits really fast, it could
  418. // be null by now. So check first...
  419. if(process == null)
  420. return;
  421. BufferedReader in = new BufferedReader(
  422. new InputStreamReader(process
  423. .getErrorStream()));
  424. String line;
  425. while((line = in.readLine()) != null)
  426. {
  427. parseLine(line);
  428. }
  429. in.close();
  430. }
  431. catch(IOException io)
  432. {
  433. String[] args = { io.getMessage() };
  434. console.printError(jEdit.getProperty("console.shell.ioerror",args));
  435. }
  436. finally
  437. {
  438. threadDone();
  439. }
  440. }
  441. }
  442. }