You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

StringUtils.java 9.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package org.apache.tools.ant.util;
  19. import java.io.PrintWriter;
  20. import java.io.StringWriter;
  21. import java.util.Vector;
  22. /**
  23. * A set of helper methods related to string manipulation.
  24. *
  25. */
  26. public final class StringUtils {
  27. private static final long KILOBYTE = 1024;
  28. private static final long MEGABYTE = KILOBYTE * 1024;
  29. private static final long GIGABYTE = MEGABYTE * 1024;
  30. private static final long TERABYTE = GIGABYTE * 1024;
  31. private static final long PETABYTE = TERABYTE * 1024;
  32. /**
  33. * constructor to stop anyone instantiating the class
  34. */
  35. private StringUtils() {
  36. }
  37. /** the line separator for this OS */
  38. public static final String LINE_SEP = System.getProperty("line.separator");
  39. /**
  40. * Splits up a string into a list of lines. It is equivalent
  41. * to <tt>split(data, '\n')</tt>.
  42. * @param data the string to split up into lines.
  43. * @return the list of lines available in the string.
  44. */
  45. public static Vector lineSplit(String data) {
  46. return split(data, '\n');
  47. }
  48. /**
  49. * Splits up a string where elements are separated by a specific
  50. * character and return all elements.
  51. * @param data the string to split up.
  52. * @param ch the separator character.
  53. * @return the list of elements.
  54. */
  55. public static Vector split(String data, int ch) {
  56. Vector elems = new Vector();
  57. int pos = -1;
  58. int i = 0;
  59. while ((pos = data.indexOf(ch, i)) != -1) {
  60. String elem = data.substring(i, pos);
  61. elems.addElement(elem);
  62. i = pos + 1;
  63. }
  64. elems.addElement(data.substring(i));
  65. return elems;
  66. }
  67. /**
  68. * Replace occurrences into a string.
  69. * @param data the string to replace occurrences into
  70. * @param from the occurrence to replace.
  71. * @param to the occurrence to be used as a replacement.
  72. * @return the new string with replaced occurrences.
  73. */
  74. public static String replace(String data, String from, String to) {
  75. StringBuffer buf = new StringBuffer(data.length());
  76. int pos = -1;
  77. int i = 0;
  78. while ((pos = data.indexOf(from, i)) != -1) {
  79. buf.append(data.substring(i, pos)).append(to);
  80. i = pos + from.length();
  81. }
  82. buf.append(data.substring(i));
  83. return buf.toString();
  84. }
  85. /**
  86. * Convenient method to retrieve the full stacktrace from a given exception.
  87. * @param t the exception to get the stacktrace from.
  88. * @return the stacktrace from the given exception.
  89. */
  90. public static String getStackTrace(Throwable t) {
  91. StringWriter sw = new StringWriter();
  92. PrintWriter pw = new PrintWriter(sw, true);
  93. t.printStackTrace(pw);
  94. pw.flush();
  95. pw.close();
  96. return sw.toString();
  97. }
  98. /**
  99. * Checks that a string buffer ends up with a given string. It may sound
  100. * trivial with the existing
  101. * JDK API but the various implementation among JDKs can make those
  102. * methods extremely resource intensive
  103. * and perform poorly due to massive memory allocation and copying. See
  104. * @param buffer the buffer to perform the check on
  105. * @param suffix the suffix
  106. * @return <code>true</code> if the character sequence represented by the
  107. * argument is a suffix of the character sequence represented by
  108. * the StringBuffer object; <code>false</code> otherwise. Note that the
  109. * result will be <code>true</code> if the argument is the
  110. * empty string.
  111. */
  112. public static boolean endsWith(StringBuffer buffer, String suffix) {
  113. if (suffix.length() > buffer.length()) {
  114. return false;
  115. }
  116. // this loop is done on purpose to avoid memory allocation performance
  117. // problems on various JDKs
  118. // StringBuffer.lastIndexOf() was introduced in jdk 1.4 and
  119. // implementation is ok though does allocation/copying
  120. // StringBuffer.toString().endsWith() does massive memory
  121. // allocation/copying on JDK 1.5
  122. // See http://issues.apache.org/bugzilla/show_bug.cgi?id=37169
  123. int endIndex = suffix.length() - 1;
  124. int bufferIndex = buffer.length() - 1;
  125. while (endIndex >= 0) {
  126. if (buffer.charAt(bufferIndex) != suffix.charAt(endIndex)) {
  127. return false;
  128. }
  129. bufferIndex--;
  130. endIndex--;
  131. }
  132. return true;
  133. }
  134. /**
  135. * xml does not do "c" like interpretation of strings.
  136. * i.e. \n\r\t etc.
  137. * this method processes \n, \r, \t, \f, \\
  138. * also subs \s -> " \n\r\t\f"
  139. * a trailing '\' will be ignored
  140. *
  141. * @param input raw string with possible embedded '\'s
  142. * @return converted string
  143. * @since Ant 1.7
  144. */
  145. public static String resolveBackSlash(String input) {
  146. StringBuffer b = new StringBuffer();
  147. boolean backSlashSeen = false;
  148. for (int i = 0; i < input.length(); ++i) {
  149. char c = input.charAt(i);
  150. if (!backSlashSeen) {
  151. if (c == '\\') {
  152. backSlashSeen = true;
  153. } else {
  154. b.append(c);
  155. }
  156. } else {
  157. switch (c) {
  158. case '\\':
  159. b.append((char) '\\');
  160. break;
  161. case 'n':
  162. b.append((char) '\n');
  163. break;
  164. case 'r':
  165. b.append((char) '\r');
  166. break;
  167. case 't':
  168. b.append((char) '\t');
  169. break;
  170. case 'f':
  171. b.append((char) '\f');
  172. break;
  173. case 's':
  174. b.append(" \t\n\r\f");
  175. break;
  176. default:
  177. b.append(c);
  178. }
  179. backSlashSeen = false;
  180. }
  181. }
  182. return b.toString();
  183. }
  184. /**
  185. * Takes a human readable size representation eg 10K
  186. * a long value. Doesn't support 1.1K or other rational values.
  187. * @param humanSize the amount as a human readable string.
  188. * @return a long value representation
  189. * @throws Exception if there is a problem.
  190. * @since Ant 1.7
  191. */
  192. public static long parseHumanSizes(String humanSize) throws Exception {
  193. long factor = 1L;
  194. char s = humanSize.charAt(0);
  195. switch (s) {
  196. case '+':
  197. humanSize = humanSize.substring(1);
  198. break;
  199. case '-':
  200. factor = -1L;
  201. humanSize = humanSize.substring(1);
  202. break;
  203. default:
  204. break;
  205. }
  206. //last character isn't a digit
  207. char c = humanSize.charAt(humanSize.length() - 1);
  208. if (!Character.isDigit(c)) {
  209. int trim = 1;
  210. switch (c) {
  211. case 'K':
  212. factor *= KILOBYTE;
  213. break;
  214. case 'M':
  215. factor *= MEGABYTE;
  216. break;
  217. case 'G':
  218. factor *= GIGABYTE;
  219. break;
  220. case 'T':
  221. factor *= TERABYTE;
  222. break;
  223. case 'P':
  224. factor *= PETABYTE;
  225. break;
  226. default:
  227. trim = 0;
  228. }
  229. humanSize = humanSize.substring(0, humanSize.length() - trim);
  230. }
  231. return factor * Long.parseLong(humanSize);
  232. }
  233. /**
  234. * Removes the suffix from a given string, if the string contains
  235. * that suffix.
  236. * @param string String for check
  237. * @param suffix Suffix to remove
  238. * @return the <i>string</i> with the <i>suffix</i>
  239. */
  240. public static String removeSuffix(String string, String suffix) {
  241. if (string.endsWith(suffix)) {
  242. return string.substring(0, string.length() - suffix.length());
  243. } else {
  244. return string;
  245. }
  246. }
  247. }