PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/src/main/java/expect4j/ExpectEmulation.java

http://expect4j.googlecode.com/
Java | 701 lines | 470 code | 93 blank | 138 comment | 97 complexity | 1f47db46eec7e86cc821170f2958cb68 MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. * Copyright 2007 Justin Ryan
  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 expect4j;
  17. import java.text.StringCharacterIterator;
  18. import java.util.logging.Level;
  19. import tcl.lang.*;
  20. import expect4j.matches.*;
  21. import org.apache.oro.text.regex.MalformedPatternException;
  22. import java.util.*;
  23. import java.util.logging.Level;
  24. import java.util.logging.Logger;
  25. /**
  26. * Register commands to support the Expect API
  27. *
  28. * Commands:
  29. * exp_continue
  30. * exp_internal 0;
  31. * expect
  32. * log_user 0;
  33. * send " ";
  34. * send -- "$command\r";
  35. * sleep
  36. * spawn
  37. * stty -echo;
  38. * stty echo;
  39. * timestamp
  40. *
  41. * Variables:
  42. * expect_out(1,string)
  43. * through
  44. * expect_out(5,string)
  45. * expect_out(buffer)
  46. * spawn_id
  47. */
  48. public class ExpectEmulation extends Extension {
  49. static final public Logger log = Logger.getLogger(ExpectEmulation.class.getName());
  50. //@Overrides
  51. public void init(Interp interp) {
  52. interp.createCommand("exp_continue", new ExpContinueCommand());
  53. interp.createCommand("exp_internal", new ExpInternalCommand());
  54. interp.createCommand("expect", new ExpectCommand());
  55. interp.createCommand("log_user", new LogUserCommand());
  56. interp.createCommand("send", new SendCommand());
  57. interp.createCommand("sleep", new SleepCommand());
  58. interp.createCommand("spawn", new SpawnCommand());
  59. interp.createCommand("stty", new SttyCommand());
  60. interp.createCommand("timestamp", new TimestampCommand());
  61. //interp.eval("rename subst ::tcl::subst");
  62. //interp.createCommand("subst", new tcl.lang.SubstCrCommand() );
  63. interp.createCommand("substcr", new tcl.lang.SubstCrCommand() );
  64. try {
  65. interp.pkgProvide("expect", "2.0"); // closest equivalent
  66. }catch(TclException te) {
  67. log.log( Level.WARNING, te.getMessage(), te);
  68. }
  69. }
  70. /**
  71. * expect [[-opts] pat1 body1] ... [-opts] patn [bodyn]
  72. *
  73. * TODO Fully integrate with Expect4j
  74. * TODO upvar the whole closure when running
  75. * TODO set expect_out array
  76. */
  77. public class ExpectCommand implements Command {
  78. void releaseClosures(Interp interp, Collection preserved) {
  79. Iterator iter = preserved.iterator();
  80. while( iter.hasNext() ) {
  81. TclObject tclCode = (TclObject) iter.next();
  82. tclCode.release();
  83. }
  84. }
  85. public void cmdProc(Interp interp, TclObject args[]) throws TclException {
  86. // Do not allow empty expect statement
  87. if (args.length != 2)
  88. throw new TclNumArgsException(interp, 0, args, "expect {[-opts] pat1 body1] ... [-opts] patn [bodyn]}");
  89. TclObject argArr = args[1];
  90. TclObject argv[] = TclList.getElements(interp, argArr);
  91. List /* <Pair> */ pairs = new ArrayList();
  92. int i=0;
  93. String arg;
  94. log.info("Looking at expect args");
  95. Match pair;
  96. Collection preserved = new ArrayList(argv.length - i);
  97. while( i < argv.length ) {
  98. arg = argv[i].toString();
  99. //log.info(i + " Looking at " + arg);
  100. if( arg.equals("timeout") ) {
  101. if( i + 1 >= argv.length )
  102. throw new TclNumArgsException(interp, i, argv, "expect [[-opts] pat1 body1] ... [-opts] patn [bodyn]");
  103. TclObject tclCode = argv[++i];
  104. TclClosure closure = new TclClosure(interp, tclCode);
  105. pair = new TimeoutMatch( closure );
  106. log.finer("Adding Timeout Match");
  107. pairs.add( pair );
  108. } else if( arg.equals("eof") ) {
  109. if( i + 1 >= argv.length )
  110. throw new TclNumArgsException(interp, i, argv, "expect [[-opts] pat1 body1] ... [-opts] patn [bodyn]");
  111. TclObject tclCode = argv[++i];
  112. TclClosure closure = new TclClosure(interp, tclCode);
  113. pair = new EofMatch( closure );
  114. log.finer("Adding Eof Match");
  115. pairs.add( pair );
  116. } else {
  117. TclObject patternObj;
  118. if( arg.startsWith("-") ) {
  119. // TODO do NumArgs check
  120. patternObj = argv[++i];
  121. } else {
  122. patternObj = argv[i];
  123. arg = "-gl"; // default to glob
  124. }
  125. String javaStr = patternObj.toString();
  126. /*
  127. StringBuffer hexString = new StringBuffer();
  128. for(int j=0; j < javaStr.length(); j++ ) {
  129. hexString.append( ((int) javaStr.charAt(j)) + ",");
  130. }
  131. log.info(i + " Characters " + hexString);
  132. */
  133. javaStr = javaStr.replaceAll("\\r", "\\\\r");
  134. javaStr = javaStr.replaceAll("\\n", "\\\\n");
  135. //interp.eval("subst -nobackslashes -nocommands {" + patternObj.toString() + "}", 0);
  136. Command substCmd = interp.getCommand("substcr");
  137. TclObject substArgv[] = new TclObject[] {
  138. TclString.newInstance("substcr"),
  139. TclString.newInstance("-nocommands"),
  140. TclString.newInstance("-nobackslashes"),
  141. patternObj
  142. };
  143. substCmd.cmdProc(interp, substArgv);
  144. TclObject substPatternObj = interp.getResult();
  145. String pattern = substPatternObj.toString();
  146. TclClosure closure = null;
  147. TclObject tclCode = null;
  148. if( i + 1 < argv.length ) {
  149. TclObject tclCodeDirect = argv[++i];
  150. tclCodeDirect.preserve();
  151. preserved.add(tclCodeDirect);
  152. tclCode = tclCodeDirect;
  153. }
  154. closure = new TclClosure(interp, tclCode);
  155. log.info(i + " Pattern Obj is >>" + javaStr + "<< and pattern is >>>" + pattern + "<<<");
  156. try {
  157. if( arg.startsWith("-re") ) {
  158. // In TCL \[ is used to tell TCL that this is not a nested command
  159. /* Need to support:
  160. * -re "User=(.+) Date=(.+) Time=(\[^\r]+)\r"
  161. * -re "\[Pp]assword: "
  162. * -re "/(\[a-z]+)/(\[0-9]+)/(\[a-z]+)\[\\$|>]"
  163. * -re "/(\[a-z]+)/(\[0-9]+)/(\[a-z]+)>"
  164. * -re "\\$ |....> "
  165. * -re "(\[^\n]*)\r\n"
  166. * -re "(\[^\r]*)\r\n"
  167. */
  168. pair = new RegExpMatch(pattern, closure);
  169. } else if ( arg.startsWith("-ex") )
  170. throw new TclException(interp, "Exact matches not supported yet");
  171. else if( arg.startsWith("-gl") ) {
  172. pair = new GlobMatch(pattern, closure);
  173. log.info(i + " Glob at regexp " + ((GlobMatch) pair).getPattern().getPattern() );
  174. } else {
  175. throw new TclException(interp, "Unknown type of pattern");
  176. }
  177. } catch(TclException te) {
  178. releaseClosures(interp, preserved);
  179. throw te;
  180. } catch(MalformedPatternException mpe) {
  181. releaseClosures(interp, preserved);
  182. throw new TclException(interp, "Invalid pattern: " + pattern);
  183. }
  184. pairs.add( pair );
  185. }
  186. i++;
  187. } // end while
  188. // Lookup Expect
  189. Expect4j expect4j = expStateCurrent(interp);
  190. // Timeout
  191. try {
  192. TclObject timeoutObj = interp.getVar("timeout", null, 0);
  193. int timeout = TclInteger.get(interp, timeoutObj);
  194. expect4j.setDefaultTimeout(timeout * 1000);
  195. }catch(Exception e) {
  196. expect4j.setDefaultTimeout( Expect4j.TIMEOUT_DEFAULT );
  197. }
  198. boolean isDebug = isExpDebug(interp);
  199. boolean isEcho = isEcho(interp);
  200. boolean isLogUser = isLogUser(interp);
  201. // TODO
  202. //expect4j.setDebugLevels(isDebug, isEcho, isLogUser);
  203. // Run Expect
  204. int ret;
  205. try {
  206. ret = expect4j.expect(pairs);
  207. } catch(TclException te) {
  208. throw te;
  209. } catch(Exception e) {
  210. throw new TclException(interp, e.getMessage() );
  211. } finally {
  212. releaseClosures(interp, preserved);
  213. }
  214. interp.setResult(ret);
  215. }
  216. }
  217. /* Commands in alphabetical order*/
  218. /**
  219. * exp_continue
  220. *
  221. * TODO Make calling Closure check for continue var
  222. */
  223. public class ExpContinueCommand implements Command {
  224. public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
  225. if (argv.length != 1)
  226. throw new TclNumArgsException(interp, 0, argv, "");
  227. setExpContinue(interp, true);
  228. // TODO immeadiately set debug level on Expect4j object
  229. }
  230. }
  231. /**
  232. * exp_internal [-f file] [-info] [0|1]
  233. *
  234. * TODO find out how isExpDebug would be called
  235. */
  236. public class ExpInternalCommand implements Command {
  237. public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
  238. if (argv.length != 2)
  239. throw new TclNumArgsException(interp, 0, argv, "[0|1]");
  240. String arg = argv[1].toString();
  241. if( arg.equals("1") )
  242. setExpDebug(interp, true);
  243. else if( arg.equals("0") )
  244. setExpDebug(interp, false);
  245. else
  246. throw new TclNumArgsException(interp, 0, argv, "[0|1]");
  247. }
  248. }
  249. /**
  250. * log_user [0|1]
  251. *
  252. * TODO find out how isLogUser would be called
  253. */
  254. public class LogUserCommand implements Command {
  255. public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
  256. if (argv.length != 2)
  257. throw new TclNumArgsException(interp, 0, argv, "[0|1]");
  258. String arg = argv[1].toString();
  259. if( arg.equals("1") )
  260. setLogUser(interp, true);
  261. else if( arg.equals("0") )
  262. setLogUser(interp, false);
  263. else
  264. throw new TclNumArgsException(interp, 0, argv, "[0|1]");
  265. // TODO immeadiately set debug level on Expect4j object
  266. }
  267. }
  268. /**
  269. * Send
  270. */
  271. public class SendCommand implements Command {
  272. public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
  273. log.finest("Send Command arg # " + argv.length);
  274. if (argv.length == 1)
  275. throw new TclNumArgsException(interp, 1, argv, "[-flags] [--] string");
  276. boolean checkingFlags = true;
  277. int i=1;
  278. String arg = null;
  279. for(; i < argv.length; i++) {
  280. arg = argv[i].toString();
  281. if( checkingFlags && arg.equals("--") ) {
  282. checkingFlags = false;
  283. continue;
  284. }
  285. // skip flags
  286. if( checkingFlags && arg.startsWith("-") )
  287. continue;
  288. }
  289. // Compensate for the added i++
  290. if (i - 1 == argv.length)
  291. throw new TclNumArgsException(interp, 1, argv, "[-flags] [--] string");
  292. //arg = interp.convertStringCRLF(arg); // TODO confirm is CRLF removal is necessary
  293. String pattern1 = "\r(?=[^\n])";
  294. String pattern2 = "\r$";
  295. arg = arg.replaceAll(pattern1, org.apache.commons.net.SocketClient.NETASCII_EOL);
  296. arg = arg.replaceAll(pattern2, org.apache.commons.net.SocketClient.NETASCII_EOL);
  297. Expect4j expect4j = expStateCurrent(interp);
  298. try {
  299. expect4j.send(arg);
  300. }catch(Exception ioe) {
  301. throw new TclException(interp, "Unable to send " + arg);
  302. }
  303. if( isEcho(interp) )
  304. System.out.println(arg);
  305. }
  306. }
  307. /**
  308. * sleep seconds
  309. */
  310. public class SleepCommand implements Command {
  311. public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
  312. if (argv.length > 2)
  313. throw new TclNumArgsException(interp, 0, argv, "seconds");
  314. int seconds = TclInteger.get(interp, argv[1]);
  315. try {
  316. Thread.sleep( seconds * 1000 );
  317. } catch(InterruptedException e) {
  318. }
  319. }
  320. }
  321. /**
  322. * spawn [args] program [args]
  323. * Called with possible local paths, like C:\Windows\ssh.exe.
  324. */
  325. public class SpawnCommand implements Command, VarTrace {
  326. public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
  327. if (argv.length == 1)
  328. throw new TclNumArgsException(interp, 0, argv, "[args] program [args]");
  329. // Skip the -args, e.g. -console, -ignore, -leaveopen, etc
  330. int i = 1;
  331. while( i < argv.length && argv[i].toString().indexOf('-') == 0 ) {
  332. i++;
  333. }
  334. if( i == argv.length ) // missing program arg
  335. throw new TclNumArgsException(interp, i, argv, "[args] program [args]");
  336. String program = argv[i++].toString().trim();
  337. // Determine if we're running ssh or telnet and create Pair
  338. Expect4j expect4j;
  339. if( program.indexOf("ssh") != -1 ) {
  340. // SSH
  341. // Command will look like:
  342. // spawn $path(ssh) -l fieldsvc $chassis(scpAddr)
  343. String username = null;
  344. String password = null;
  345. while( argv[i].toString().indexOf('-') == 0) {
  346. // process arg
  347. log.fine("ssh arg: " + argv[i].toString() );
  348. if( argv[i].toString().equals("-l") && i + 1 < argv.length - 1) {
  349. username = argv[++i].toString();
  350. }
  351. if( argv[i].toString().equals("-P") && i + 1 < argv.length - 1) {
  352. password = argv[++i].toString();
  353. }
  354. i++;
  355. }
  356. if( username == null)
  357. throw new TclException(interp, "Username needs to be provided");
  358. else
  359. log.finer("Username: " + username);
  360. if( i >= argv.length )
  361. throw new TclNumArgsException(interp, i - 1, argv, "[-l username] [-P password] hostname");
  362. String hostname = argv[i].toString().trim();
  363. try {
  364. expect4j = ExpectUtils.SSH( hostname, username, password );
  365. }catch(Exception e) {
  366. e.printStackTrace();
  367. throw new TclException(interp, "Unable to connect using SSH");
  368. }
  369. } else if( program.indexOf("telnet") == 0 ) {
  370. // Telnet
  371. // spawn telnet $chassis(scpAddr) 7653
  372. String hostname = null;
  373. String portStr = null;
  374. if( i >= argv.length )
  375. throw new TclNumArgsException(interp, i, argv, "hostname port" );
  376. hostname = argv[i++].toString().trim();
  377. if( i < argv.length )
  378. portStr = argv[i++].toString().trim();
  379. int port = 23;
  380. if( portStr != null ) {
  381. try {
  382. port = Integer.parseInt(portStr);
  383. }catch(NumberFormatException e) {
  384. throw new TclException(interp, "Unable to parse the port number");
  385. }
  386. }
  387. try {
  388. expect4j = ExpectUtils.telnet( hostname, port);
  389. }catch(Exception e) {
  390. throw new TclException(interp, "Unable to connect using Telnet");
  391. }
  392. } else {
  393. // Unsupported
  394. String[] cmdarray;
  395. int cmdidx = 0;
  396. int addlargs = argv.length - i + 1;
  397. // Guess OS
  398. String OS = System.getProperty("os.name").toLowerCase();
  399. if (OS.indexOf("windows 9") > -1) {
  400. // Windows 98
  401. cmdarray = new String[ addlargs + 2];
  402. cmdarray[cmdidx++] = "command.com";
  403. cmdarray[cmdidx++] = "/c";
  404. } else if ( OS.indexOf("windows") > -1 ) {
  405. // NT
  406. cmdarray = new String[ addlargs + 2];
  407. cmdarray[cmdidx++] = "cmd.exe";
  408. cmdarray[cmdidx++] = "/c";
  409. } else {
  410. // Unix
  411. cmdarray = new String[ addlargs];
  412. }
  413. // Append actual command and its args
  414. cmdarray[cmdidx++] = program;
  415. for(;i < argv.length; i++) {
  416. cmdarray[cmdidx++] = argv[i].toString().trim();
  417. }
  418. try {
  419. Process process = Runtime.getRuntime().exec(cmdarray);
  420. expect4j = new Expect4j(process);
  421. }catch(Exception e) {
  422. throw new TclException(interp, "Unable to start arbitary process");
  423. }
  424. }
  425. // Load and store lastSpawnId
  426. int nextId = 1;
  427. IntegerAssocData lastSpawnId = (IntegerAssocData) interp.getAssocData("lastSpawnId");
  428. if( lastSpawnId != null )
  429. nextId = lastSpawnId._i.intValue() + 1;
  430. lastSpawnId = new IntegerAssocData(nextId);
  431. interp.setAssocData("lastSpawnId", lastSpawnId);
  432. // register spawn_id with list
  433. MapAssocData spawnIds = (MapAssocData) interp.getAssocData("spawnIds");
  434. if( spawnIds == null ) {
  435. spawnIds = new MapAssocData();
  436. }
  437. String spawnId = lastSpawnId._i.toString();
  438. log.finer("Putting id in " + spawnId);
  439. spawnIds.put( spawnId, expect4j );
  440. interp.setAssocData("spawnIds", spawnIds);
  441. // register spawn_id with interp
  442. TclObject spawnIdObj = TclInteger.newInstance( nextId );
  443. interp.setVar("spawn_id", spawnIdObj, 0);
  444. interp.traceVar("spawn_id", this, 0);
  445. interp.setResult(spawnIdObj);
  446. }
  447. public void traceProc(Interp interp, String name1, String name2, int flags) {
  448. log.info("Tracing");
  449. if ( (flags & TCL.TRACE_DESTROYED) != 0 )
  450. log.warning("Trace Destroyed");
  451. if ( (flags & TCL.INTERP_DESTROYED) != 0 )
  452. log.warning("Interp Destroyed");
  453. }
  454. }
  455. /**
  456. * timestamp [-seconds NNN] [-gmt] [-format format]
  457. *
  458. * TODO support formattings
  459. */
  460. public class TimestampCommand implements Command {
  461. public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
  462. if (argv.length > 1)
  463. throw new TclNumArgsException(interp, 0, argv, "");
  464. long epoch = new Date().getTime();
  465. if( epoch >= Double.MAX_VALUE )
  466. throw new TclException(interp, "Epoch is too large to convert to double");
  467. double epochd = new Long(epoch).doubleValue();
  468. TclObject result = TclDouble.newInstance(epochd);
  469. interp.setResult( result );
  470. }
  471. }
  472. /**
  473. * stty [-echo|echo]
  474. *
  475. * Only called in ask, which shouldn't be called in automated script mode
  476. */
  477. public class SttyCommand implements Command {
  478. public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
  479. if (argv.length > 2)
  480. throw new TclNumArgsException(interp, 0, argv, "[echo|-echo]");
  481. String cmd = argv[1].toString();
  482. log.info("stty cmd is " + cmd);
  483. if( cmd.equals("echo") )
  484. setEcho(interp, true);
  485. else if( cmd.equals("-echo") )
  486. setEcho(interp, false);
  487. else
  488. throw new TclException(interp, "Only echo is supported");
  489. // TODO immeadiately set debug level on Expect4j object
  490. }
  491. }
  492. public class IntegerAssocData implements AssocData {
  493. public Integer _i;
  494. public IntegerAssocData(int value) {
  495. _i = new Integer(value);
  496. }
  497. public IntegerAssocData(String s) {
  498. _i = new Integer(s);
  499. }
  500. public void disposeAssocData(Interp interp) {
  501. }
  502. }
  503. public class MapAssocData extends HashMap implements AssocData {
  504. public void disposeAssocData(Interp interp) {
  505. }
  506. }
  507. /* TODO change return type to Expect4j */
  508. public static Expect4j expStateCurrent(Interp interp) throws TclException {
  509. TclObject spawnObj = interp.getVar("spawn_id", 0); // confirm that this works and we don't need TCL.NAMESPACE_ONLY
  510. Map spawnIds = (Map) interp.getAssocData("spawnIds");
  511. if( spawnIds == null )
  512. throw new TclException(interp, "spawn not called yet");
  513. String spawnId = spawnObj.toString();
  514. if( !spawnIds.containsKey(spawnId) )
  515. throw new TclException(interp, "Unable to find spawn_id of " + spawnId);
  516. Expect4j expect4j = (Expect4j) spawnIds.get(spawnId);
  517. if( expect4j == null )
  518. throw new TclException(interp, "Unable to find Expect context from " + spawnId);
  519. return expect4j;
  520. }
  521. public static boolean isVar(Interp interp, String varname) throws TclException {
  522. TclObject obj = null;
  523. try {
  524. obj = interp.getVar(varname, null, TCL.GLOBAL_ONLY);
  525. }catch(Exception e) {
  526. return false;
  527. }
  528. if ( obj == null) {
  529. return false;
  530. }
  531. return TclBoolean.get(interp, obj);
  532. }
  533. public static void setBooleanVar(Interp interp, String varname, boolean value) throws TclException {
  534. if( isVar(interp, varname) == value)
  535. return;
  536. TclObject obj = TclBoolean.newInstance(value);
  537. log.finest("Setting " + varname + " to " + Boolean.toString(value) );
  538. interp.setVar(varname, obj, TCL.GLOBAL_ONLY);
  539. }
  540. public static boolean isEcho(Interp interp) throws TclException {
  541. return isVar(interp, "exp_tty_echo");
  542. }
  543. public static void setEcho(Interp interp, boolean setEcho) throws TclException {
  544. setBooleanVar(interp, "exp_tty_echo", setEcho);
  545. }
  546. public static boolean isLogUser(Interp interp) throws TclException {
  547. return isVar(interp, "exp_log_user");
  548. }
  549. public static void setLogUser(Interp interp, boolean setLogUser) throws TclException {
  550. setBooleanVar(interp, "exp_log_user", setLogUser);
  551. }
  552. public static boolean isExpDebug(Interp interp) throws TclException {
  553. return isVar(interp, "exp_debug");
  554. }
  555. public static void setExpDebug(Interp interp, boolean setExpDebug) throws TclException {
  556. setBooleanVar(interp, "exp_debug", setExpDebug);
  557. }
  558. public static boolean isExpContinue(Interp interp) throws TclException {
  559. return isVar(interp, "exp_continue_set");
  560. }
  561. public static void setExpContinue(Interp interp, boolean setExpContinue) throws TclException {
  562. setBooleanVar(interp, "exp_continue_set", setExpContinue);
  563. }
  564. public static String escape(final String value) {
  565. String raw = value;
  566. boolean isString = false;
  567. if( value.indexOf('"') == 0 && value.lastIndexOf('"') == value.length() - 1) {
  568. isString = true;
  569. raw = value.substring(1, value.length() - 1);
  570. }
  571. final StringBuffer result = new StringBuffer();
  572. StringCharacterIterator iterator = new StringCharacterIterator(raw);
  573. char character = iterator.current();
  574. while (character != StringCharacterIterator.DONE ){
  575. /*
  576. * All literals need to have backslashes doubled.
  577. * &;`'"|*?~<>^()[]{}$\
  578. */
  579. switch( character ) {
  580. case '&':
  581. case ';':
  582. case '\'':
  583. case '"':
  584. case '|':
  585. case '*':
  586. case '?':
  587. case '~':
  588. case '<':
  589. case '>':
  590. case '^':
  591. case '(':
  592. case ')':
  593. case '[':
  594. case ']':
  595. case '{':
  596. case '}':
  597. case '$':
  598. case '\\': result.append("\\");
  599. default: result.append(character);
  600. }
  601. character = iterator.next();
  602. }
  603. String clean = result.toString();
  604. if( isString )
  605. clean = '"' + clean + '"';
  606. return clean;
  607. }
  608. }