PageRenderTime 46ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

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

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