PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

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

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