PageRenderTime 52ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/bundles/plugins-trunk/XML/sidekick/ecmascript/parser/Util.java

#
Java | 699 lines | 388 code | 96 blank | 215 comment | 140 complexity | 6db5ff0d3d272584dcae12618fd43bd7 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. Copyright (c) 2004-2005, The Dojo Foundation
  3. All Rights Reserved.
  4. Licensed under the Academic Free License version 2.1 or above OR the
  5. modified BSD license. For more information on Dojo licensing, see:
  6. http://dojotoolkit.org/community/licensing.shtml <http://dojotoolkit.org/community/licensing.shtml>
  7. Code donated to the Dojo Foundation by AOL LLC under the terms of
  8. the Dojo CCLA (http://dojotoolkit.org/ccla.txt).
  9. */
  10. package sidekick.ecmascript.parser;
  11. import java.util.*;
  12. import java.util.logging.Level;
  13. import java.io.*;
  14. import java.text.*;
  15. import java.nio.*;
  16. import java.nio.channels.*;
  17. import java.nio.charset.*;
  18. /**
  19. * Collection of useful static utility methods.
  20. *
  21. *
  22. * @since JDK 1.4
  23. */
  24. public class Util extends Object {
  25. /**
  26. * Converts milliseconds to some more human readable representation.
  27. *
  28. * @param millis
  29. * An amount of elapsed milliseconds
  30. * @return A human readable time string
  31. */
  32. static public final String millisToNice(long millis) {
  33. long seconds = millis / 1000;
  34. long sec = (seconds % 3600) % 60;
  35. long min = (seconds % 3600) / 60;
  36. long hour = seconds / 3600;
  37. StringBuffer strbuf = new StringBuffer(60);
  38. strbuf.append(" [ ");
  39. if (hour > 0L) {
  40. strbuf.append(hour + " h ");
  41. }
  42. if (min > 0L) {
  43. strbuf.append(min + " min ");
  44. }
  45. if (sec > 0L) {
  46. strbuf.append(sec + " sec ");
  47. }
  48. strbuf.append((millis % 1000) + " millis");
  49. strbuf.append(" ]");
  50. return strbuf.toString();
  51. }
  52. /**
  53. * Creates an array of strings from a string of comma-separated string
  54. * tokens.
  55. *
  56. * @param aString
  57. * string containing tokens separated by ","
  58. * @return array containing string tokens, can be null if string empty
  59. */
  60. static public final String[] tokenizeCommaSepString(String aString) {
  61. if (aString == null) {
  62. return null;
  63. }
  64. StringTokenizer tokenizer = new StringTokenizer(aString, ",");
  65. String[] result = null;
  66. int n = tokenizer.countTokens();
  67. if (n > 0) {
  68. result = new String[n];
  69. int i = 0;
  70. while (tokenizer.hasMoreTokens()) {
  71. result[i] = tokenizer.nextToken().trim();
  72. i++;
  73. }
  74. }
  75. return result;
  76. }
  77. /**
  78. * Finds the common prefix of two specified strings.
  79. *
  80. * @param str1
  81. * first string
  82. * @param str2
  83. * second string
  84. * @return string which is a common prefix of the two strings, can be empty
  85. * string, is never null
  86. */
  87. static public final String commonPrefix(String str1, String str2) {
  88. boolean done = false;
  89. StringBuffer buffer = new StringBuffer();
  90. int i = 0;
  91. int n1 = str1.length();
  92. int n2 = str2.length();
  93. while (!done) {
  94. char c = str1.charAt(i);
  95. if (c == str2.charAt(i)) {
  96. buffer.append(c);
  97. i++;
  98. if ((i == n1) || (i == n2)) {
  99. done = true;
  100. }
  101. } else {
  102. done = true;
  103. }
  104. }
  105. return buffer.toString();
  106. }
  107. /**
  108. * Finds the common path prefix of two specified paths. Paths have to be
  109. * canonical
  110. *
  111. * @param path1
  112. * first path
  113. * @param path2
  114. * second path
  115. * @return string which is a non-empty common path prefix of the two paths,
  116. * or null if they don't have a non-empty common prefix
  117. */
  118. static public final String commonPathPrefix(String path1, String path2) {
  119. boolean done = false;
  120. StringBuffer buffer = new StringBuffer();
  121. StringTokenizer st1 = new StringTokenizer(path1, File.separator, true);
  122. StringTokenizer st2 = new StringTokenizer(path2, File.separator, true);
  123. done = (!(st1.hasMoreTokens() && st2.hasMoreTokens()));
  124. while (!done) {
  125. String p1 = st1.nextToken();
  126. String p2 = st2.nextToken();
  127. if (p1.equals(p2)) {
  128. buffer.append(p1);
  129. done = (!(st1.hasMoreTokens() && st2.hasMoreTokens()));
  130. } else {
  131. done = true;
  132. }
  133. }
  134. return buffer.length() > 0 ? buffer.toString() : null;
  135. }
  136. static private final ByteBuffer copyBuffer = ByteBuffer
  137. .allocateDirect(16 * 1024);
  138. /**
  139. * Does a fast file copy from specified source to specified destination.
  140. * Uses nio API introduced in jdk 1.4.
  141. *
  142. * @param srcFilename
  143. * file name of source file
  144. * @param dstFilename
  145. * file name of copy
  146. * @exception IOException
  147. * if an I/O error occurs
  148. */
  149. static public final void copyFile(String srcFilename, String dstFilename)
  150. throws IOException {
  151. FileInputStream fis = null;
  152. FileOutputStream fos = null;
  153. FileChannel ifc = null;
  154. FileChannel ofc = null;
  155. Util.copyBuffer.clear();
  156. try {
  157. // Open the file and then get a channel from the stream
  158. fis = new FileInputStream(srcFilename);
  159. ifc = fis.getChannel();
  160. fos = new FileOutputStream(dstFilename);
  161. ofc = fos.getChannel();
  162. int sz = (int) ifc.size();
  163. int n = 0;
  164. while (n < sz) {
  165. if (ifc.read(Util.copyBuffer) < 0) {
  166. break;
  167. }
  168. Util.copyBuffer.flip();
  169. n += ofc.write(Util.copyBuffer);
  170. Util.copyBuffer.compact();
  171. }
  172. } finally {
  173. try {
  174. if (ifc != null) {
  175. ifc.close();
  176. } else if (fis != null) {
  177. fis.close();
  178. }
  179. } catch (IOException exc) {
  180. }
  181. try {
  182. if (ofc != null) {
  183. ofc.close();
  184. } else if (fos != null) {
  185. fos.close();
  186. }
  187. } catch (IOException exc) {
  188. }
  189. }
  190. // FileInputStream fis = null;
  191. // FileOutputStream fos = null;
  192. // FileChannel ifc = null;
  193. // FileChannel ofc = null;
  194. // try {
  195. // fis = new FileInputStream(srcFilename);
  196. // ifc = fis.getChannel();
  197. // fos = new FileOutputStream(dstFilename);
  198. // ofc = fos.getChannel();
  199. // int sz = (int)ifc.size();
  200. // ifc.transferTo(0, sz, ofc);
  201. // } finally {
  202. // try {
  203. // if(ifc != null){
  204. // ifc.close();
  205. // } else if(fis != null){
  206. // fis.close();
  207. // }
  208. // } catch(IOException exc){
  209. // }
  210. // try {
  211. // if(ofc != null){
  212. // ofc.close();
  213. // } else if(fos != null){
  214. // fos.close();
  215. // }
  216. // } catch(IOException exc){
  217. // }
  218. // }
  219. }
  220. static private final DateFormat dateFormat = DateFormat
  221. .getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
  222. /**
  223. * Creates a string representing a date stamp of the current system date and
  224. * system time. Returned string is suitable to be used in a filename.
  225. *
  226. * @return string with date/time stamp
  227. */
  228. static public final String getDateStamp() {
  229. String dateStamp = dateFormat.format(new Date());
  230. dateStamp = dateStamp.replace(' ', '_');
  231. dateStamp = dateStamp.replace(',', '_');
  232. dateStamp = dateStamp.replace('/', '-');
  233. dateStamp = dateStamp.replace(':', '-');
  234. return dateStamp;
  235. }
  236. /**
  237. * Returns <code>true</code> if specified string is a valid identifier for
  238. * java or javascript.
  239. *
  240. * @param candidate
  241. * potential identifier
  242. * @return <code>true</code> if it is in fact an identifier
  243. */
  244. static public final boolean isJavaIdentifier(String candidate) {
  245. if ((candidate == null) || (candidate.length() == 0)) {
  246. return false;
  247. }
  248. char c = candidate.charAt(0);
  249. if (!Character.isJavaIdentifierStart(c)) {
  250. return false;
  251. }
  252. int n = candidate.length();
  253. for (int i = 1; i < n; i++) {
  254. c = candidate.charAt(i);
  255. if (!Character.isJavaIdentifierPart(c)) {
  256. return false;
  257. }
  258. }
  259. return true;
  260. }
  261. /**
  262. * Returns <code>true</code> if specified string is a valid composite
  263. * reference where each part is a valid identifier for java or javascript.
  264. *
  265. * @param candidate
  266. * potential identifier
  267. * @return <code>true</code> if it is in fact a valid composite reference
  268. */
  269. static public final boolean isValidCompositeReference(String candidate) {
  270. if ((candidate == null) || (candidate.length() == 0)) {
  271. return false;
  272. }
  273. char c = candidate.charAt(0);
  274. if (!Character.isJavaIdentifierStart(c)) {
  275. return false;
  276. }
  277. int n = candidate.length();
  278. for (int i = 1; i < n; i++) {
  279. c = candidate.charAt(i);
  280. if (!(Character.isJavaIdentifierPart(c) || (c == '.'))) {
  281. return false;
  282. }
  283. }
  284. if (c == '.') {
  285. return false;
  286. }
  287. return true;
  288. }
  289. /**
  290. * Returns <code>true</code> if specified string is whitespace
  291. *
  292. * @param candidate
  293. * potential whitespace
  294. * @return <code>true</code> if it is in fact whitespace
  295. */
  296. static public final boolean isWhitespace(String candidate) {
  297. int n = candidate.length();
  298. for (int i = 0; i < n; i++) {
  299. char c = candidate.charAt(i);
  300. if (!Character.isWhitespace(c)) {
  301. return false;
  302. }
  303. }
  304. return true;
  305. }
  306. /**
  307. * Returns <code>true</code> if specified string is a mixed case string
  308. * with case mixing happening in the middle of the string (starting with
  309. * uppercase char and continuing with all lowercase chars does count).
  310. *
  311. * @param candidate
  312. * potential mixed case
  313. * @return <code>true</code> if it is in fact mixed case
  314. */
  315. static public final boolean isLikelyIdentifier(String candidate) {
  316. int n = candidate.length();
  317. if (n < 3) {
  318. return false;
  319. }
  320. boolean hasLower = false;
  321. boolean hasUpper = false;
  322. boolean hasUnderscore = false;
  323. int nUpper = Character.isUpperCase(candidate.charAt(0)) ? 1 : 0;
  324. for (int i = 1; i < n; i++) {
  325. char c = candidate.charAt(i);
  326. if (Character.isLowerCase(c)) {
  327. hasLower = true;
  328. } else if (Character.isUpperCase(c)) {
  329. hasUpper = true;
  330. nUpper++;
  331. } else if (c == '_') {
  332. hasUnderscore = true;
  333. }
  334. }
  335. return (hasLower && hasUpper) || hasUnderscore
  336. || (nUpper == candidate.length());
  337. }
  338. /**
  339. * Replaces occurences of substring <code>sub</code> with string
  340. * <code>with</code> in specified string.
  341. *
  342. * @param s
  343. * string for replacement
  344. * @param sub
  345. * substring to replace
  346. * @param with
  347. * substring to take its place
  348. * @return new string with replacements done
  349. */
  350. static public String replaceString(String s, String sub, String with) {
  351. int c = 0;
  352. int i = s.indexOf(sub, c);
  353. if (i == -1) {
  354. return s;
  355. }
  356. StringBuffer buf = new StringBuffer(s.length() + with.length());
  357. do {
  358. buf.append(s.substring(c, i));
  359. buf.append(with);
  360. c = i + sub.length();
  361. } while ((i = s.indexOf(sub, c)) != -1);
  362. if (c < s.length()) {
  363. buf.append(s.substring(c, s.length()));
  364. }
  365. return buf.toString();
  366. }
  367. /**
  368. * Replaces occurences of substring <code>sub</code> with string
  369. * <code>with</code> in specified string but only if substring is
  370. * delimited by non-alphanumeric characters.
  371. *
  372. * @param s
  373. * string for replacement
  374. * @param sub
  375. * substring to replace
  376. * @param with
  377. * substring to take its place
  378. * @return new string with replacements done
  379. */
  380. static public String replaceSeparatedString(String s, String sub,
  381. String with) {
  382. int c = 0;
  383. int i = s.indexOf(sub, c);
  384. if (i == -1) {
  385. return s;
  386. }
  387. StringBuffer buf = new StringBuffer(s.length() + with.length());
  388. int n = s.length();
  389. do {
  390. buf.append(s.substring(c, i));
  391. int beginChar = i > 0 ? s.charAt(i - 1) : -1;
  392. int m = i + sub.length();
  393. int endChar = m < n ? s.charAt(m) : -1;
  394. if (((beginChar == -1) || (!Character
  395. .isJavaIdentifierStart((char) beginChar)))
  396. && ((endChar == -1) || (!Character
  397. .isJavaIdentifierPart((char) endChar)))) {
  398. buf.append(with);
  399. } else {
  400. buf.append(sub);
  401. }
  402. c = i + sub.length();
  403. } while ((i = s.indexOf(sub, c)) != -1);
  404. if (c < s.length()) {
  405. buf.append(s.substring(c, s.length()));
  406. }
  407. return buf.toString();
  408. }
  409. /**
  410. * Tests if specified string ends with the specified suffix.
  411. *
  412. * @param aString
  413. * string to test
  414. * @param aSuffix
  415. * suffix.
  416. * @return <code>true</code> if the ends in suffix
  417. */
  418. static public boolean endsWith(String aString, String aSuffix) {
  419. if (aString == null) {
  420. return aSuffix == null;
  421. }
  422. if (aString.equals("")) {
  423. return (aSuffix != null) && aSuffix.equals("");
  424. }
  425. int index = aString.lastIndexOf(aSuffix);
  426. return index == aString.length() - aSuffix.length();
  427. }
  428. /**
  429. * Returns <code>true</code> if the specified filename has wildcard
  430. * characters in it, i.e. the name contains either "*" or "?" characters.
  431. *
  432. * @param filename
  433. * filename
  434. * @return <code>true</code> if has wildcard characters
  435. */
  436. static public boolean hasWildcards(String filename) {
  437. return (filename.indexOf('*') != -1) || (filename.indexOf('?') != -1);
  438. }
  439. /**
  440. * Transforms a user wildcard into a java.util.regex.Pattern pattern string.
  441. *
  442. * @param wildcard
  443. * wildcard string
  444. * @return pattern string
  445. */
  446. static public String wildCard2Pattern(String wildcard) {
  447. int n = wildcard.length();
  448. StringBuffer regexPatternBuffer = new StringBuffer(n);
  449. for (int i = 0; i < n; i++) {
  450. char c = wildcard.charAt(i);
  451. if (c == '*') {
  452. regexPatternBuffer.append(".*");
  453. } else if (c == '?') {
  454. regexPatternBuffer.append('.');
  455. } else if (c == '.') {
  456. regexPatternBuffer.append("\\.");
  457. } else if (c == '$') {
  458. regexPatternBuffer.append("\\$");
  459. } else {
  460. regexPatternBuffer.append(c);
  461. }
  462. }
  463. return regexPatternBuffer.toString();
  464. }
  465. /**
  466. * Resolves the specified url path to a file on the local file system. Uses
  467. * the specified web root and web map aliases to complete the resolution.
  468. *
  469. * @param urlPath
  470. * a url path
  471. * @param webroot
  472. * directory path on local file system of the web root
  473. * @param webmaps
  474. * web map aliases
  475. * @return a local File instance
  476. */
  477. static public File resolveWebURL(String urlPath, String webroot, Map webmaps) {
  478. File result = null;
  479. Iterator iter = webmaps.keySet().iterator();
  480. while (iter.hasNext()) {
  481. String key = (String) iter.next();
  482. if (urlPath.startsWith(key)) {
  483. result = new File(((String) webmaps.get(key))
  484. + urlPath.substring(key.length()));
  485. break;
  486. }
  487. }
  488. if (result == null) {
  489. result = new File(webroot + urlPath);
  490. }
  491. return result;
  492. }
  493. /**
  494. * Reads an input stream completely into memory and returns a CharBuffer
  495. * instance with the contents.
  496. *
  497. * @param inputStream
  498. * an input stream
  499. * @param decoder
  500. * charset decoder
  501. * @return CharBuffer instance with the contents
  502. * @exception IOException
  503. * if reading from inputStream throws IOException
  504. */
  505. static public CharBuffer readBytes(InputStream inputStream,
  506. CharsetDecoder decoder) throws IOException {
  507. byte[] buffer = new byte[1024];
  508. int b = inputStream.read();
  509. int i = 0;
  510. while (b != -1) {
  511. if (i == buffer.length) {
  512. byte[] grow = new byte[buffer.length * 2];
  513. System.arraycopy(buffer, 0, grow, 0, buffer.length);
  514. buffer = grow;
  515. }
  516. buffer[i++] = (byte) b;
  517. b = inputStream.read();
  518. }
  519. return decoder.decode(ByteBuffer.wrap(buffer, 0, i));
  520. }
  521. /**
  522. * Escapes a plain text string for html. Doesn't look into those funny
  523. * characters like euro symbol, copyright symbol etc.
  524. *
  525. * @param plainString
  526. * plain text string
  527. * @return html-escaped string
  528. */
  529. static public String escape2Html(String plainString) {
  530. if (plainString == null) {
  531. return null;
  532. }
  533. StringBuffer sb = new StringBuffer();
  534. int n = plainString.length();
  535. int spaceState = 0;
  536. int nlState = 0;
  537. for (int i = 0; i < n; i++) {
  538. char c = plainString.charAt(i);
  539. if (c == ' ') {
  540. if (nlState > 0) {
  541. if (nlState == 1) {
  542. sb.append('\n');
  543. } else {
  544. sb.append("<p>");
  545. }
  546. }
  547. nlState = 0;
  548. if (spaceState == 0) {
  549. spaceState = 1;
  550. sb.append(c);
  551. } else if (spaceState == 1) {
  552. spaceState = 0;
  553. sb.append("&nbsp;");
  554. }
  555. } else if (c == '\n') {
  556. if (nlState == 0) {
  557. nlState = 1;
  558. } else if (nlState == 1) {
  559. nlState = 2;
  560. }
  561. } else {
  562. if (nlState > 0) {
  563. if (nlState == 1) {
  564. sb.append('\n');
  565. } else {
  566. sb.append("<p>");
  567. }
  568. }
  569. nlState = 0;
  570. spaceState = 0;
  571. switch (c) {
  572. case '<':
  573. sb.append("&lt;");
  574. break;
  575. case '>':
  576. sb.append("&gt;");
  577. break;
  578. case '&':
  579. sb.append("&amp;");
  580. break;
  581. case '"':
  582. sb.append("&quot;");
  583. break;
  584. case '\'':
  585. sb.append("&#039;");
  586. break;
  587. case '\n':
  588. sb.append("<br>");
  589. break;
  590. default:
  591. sb.append(c);
  592. break;
  593. }
  594. }
  595. }
  596. return sb.toString();
  597. }
  598. }