001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.jorphan.util;
020:
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.io.OutputStream;
024: import java.io.Reader;
025: import java.io.Writer;
026: import java.net.ServerSocket;
027: import java.net.Socket;
028: import java.util.ArrayList;
029: import java.util.List;
030: import java.util.StringTokenizer;
031: import java.util.Vector;
032:
033: /**
034: * This class contains frequently-used static utility methods.
035: *
036: */
037: public final class JOrphanUtils {
038:
039: /**
040: * Private constructor to prevent instantiation.
041: */
042: private JOrphanUtils() {
043: }
044:
045: /**
046: * This is _almost_ equivalent to the String.split method in JDK 1.4. It is
047: * here to enable us to support earlier JDKs.
048: *
049: * Note that unlike JDK1.4 split(), it optionally ignores leading split Characters,
050: * and the splitChar parameter is not a Regular expression
051: *
052: * <P>
053: * This piece of code used to be part of JMeterUtils, but was moved here
054: * because some JOrphan classes use it too.
055: *
056: * @param splittee
057: * String to be split
058: * @param splitChar
059: * Character(s) to split the string on, these are treated as a single unit
060: * @param truncate
061: * Should adjacent and leading/trailing splitChars be removed?
062: *
063: * @return Array of all the tokens.
064: *
065: * @see #split(String, String, String)
066: *
067: */
068: public static String[] split(String splittee, String splitChar,
069: boolean truncate) {
070: if (splittee == null || splitChar == null) {
071: return new String[0];
072: }
073: final String EMPTY_ELEMENT = "";
074: int spot;
075: final int splitLength = splitChar.length();
076: final String adjacentSplit = splitChar + splitChar;
077: final int adjacentSplitLength = adjacentSplit.length();
078: if (truncate) {
079: while ((spot = splittee.indexOf(adjacentSplit)) != -1) {
080: splittee = splittee.substring(0, spot + splitLength)
081: + splittee.substring(
082: spot + adjacentSplitLength, splittee
083: .length());
084: }
085: if (splittee.startsWith(splitChar))
086: splittee = splittee.substring(splitLength);
087: if (splittee.endsWith(splitChar)) // Remove trailing splitter
088: splittee = splittee.substring(0, splittee.length()
089: - splitLength);
090: }
091: Vector returns = new Vector();
092: final int length = splittee.length(); // This is the new length
093: int start = 0;
094: spot = 0;
095: while (start < length
096: && (spot = splittee.indexOf(splitChar, start)) > -1) {
097: if (spot > 0) {
098: returns.addElement(splittee.substring(start, spot));
099: } else {
100: returns.addElement(EMPTY_ELEMENT);
101: }
102: start = spot + splitLength;
103: }
104: if (start < length) {
105: returns.add(splittee.substring(start));
106: } else if (spot == length - splitLength) {// Found splitChar at end of line
107: returns.addElement(EMPTY_ELEMENT);
108: }
109: String[] values = new String[returns.size()];
110: returns.copyInto(values);
111: return values;
112: }
113:
114: public static String[] split(String splittee, String splitChar) {
115: return split(splittee, splitChar, true);
116: }
117:
118: /**
119: * Takes a String and a tokenizer character string, and returns a new array of
120: * strings of the string split by the tokenizer character(s).
121: *
122: * Trailing delimiters are significant (unless the default = null)
123: *
124: * @param splittee
125: * String to be split.
126: * @param delims
127: * Delimiter character(s) to split the string on
128: * @param def
129: * Default value to place between two split chars that have
130: * nothing between them. If null, then ignore omitted elements.
131: *
132: * @return Array of all the tokens.
133: *
134: * @throws NullPointerException if splittee or delims are null
135: *
136: * @see #split(String, String, boolean)
137: * @see #split(String, String)
138: *
139: * This is a rewritten version of JMeterUtils.split()
140: */
141: public static String[] split(String splittee, String delims,
142: String def) {
143: StringTokenizer tokens = new StringTokenizer(splittee, delims,
144: def != null);
145: boolean lastWasDelim = false;
146: List strList = new ArrayList();
147: while (tokens.hasMoreTokens()) {
148: String tok = tokens.nextToken();
149: if (tok.length() == 1 // we have a single character; could be a token
150: && delims.indexOf(tok) != -1) // it is a token
151: {
152: if (lastWasDelim) {// we saw a delimiter last time
153: strList.add(def);// so add the default
154: }
155: lastWasDelim = true;
156: } else {
157: lastWasDelim = false;
158: strList.add(tok);
159: }
160: }
161: if (lastWasDelim) {
162: strList.add(def);
163: }
164: return (String[]) strList.toArray(new String[0]);
165: }
166:
167: private static final String SPACES = " ";
168:
169: private static final int SPACES_LEN = SPACES.length();
170:
171: /**
172: * Right aligns some text in a StringBuffer N.B. modifies the input buffer
173: *
174: * @param in
175: * StringBuffer containing some text
176: * @param len
177: * output length desired
178: * @return input StringBuffer, with leading spaces
179: */
180: public static StringBuffer rightAlign(StringBuffer in, int len) {
181: int pfx = len - in.length();
182: if (pfx <= 0)
183: return in;
184: if (pfx > SPACES_LEN)
185: pfx = SPACES_LEN;
186: in.insert(0, SPACES.substring(0, pfx));
187: return in;
188: }
189:
190: /**
191: * Left aligns some text in a StringBuffer N.B. modifies the input buffer
192: *
193: * @param in
194: * StringBuffer containing some text
195: * @param len
196: * output length desired
197: * @return input StringBuffer, with trailing spaces
198: */
199: public static StringBuffer leftAlign(StringBuffer in, int len) {
200: int sfx = len - in.length();
201: if (sfx <= 0)
202: return in;
203: if (sfx > SPACES_LEN)
204: sfx = SPACES_LEN;
205: in.append(SPACES.substring(0, sfx));
206: return in;
207: }
208:
209: /**
210: * Convert a boolean to its string representation Equivalent to
211: * Boolean.toString(boolean) but valid also for JDK 1.3, which
212: * does not have toString(boolean)
213: *
214: * @param value
215: * boolean to convert
216: * @return "true" or "false"
217: * @deprecated Use Boolean.toString(boolean) instead.
218: */
219: public static String booleanToString(boolean value) {
220: return value ? "true" : "false";
221: }
222:
223: /**
224: * Convert a boolean to its string representation Equivalent to
225: * Boolean.valueOf(boolean).toString().toUpperCase() but valid also for JDK
226: * 1.3, which does not have valueOf(boolean)
227: *
228: * @param value
229: * boolean to convert
230: * @return "TRUE" or "FALSE"
231: */
232: public static String booleanToSTRING(boolean value) {
233: return value ? "TRUE" : "FALSE";
234: }
235:
236: /**
237: * Version of Boolean.valueOf(boolean) for JDK 1.3
238: *
239: * @param value
240: * boolean to convert
241: * @return Boolean.TRUE or Boolean.FALSE
242: *
243: * @deprecated use Boolean.valueOf(boolean)
244: *
245: */
246: public static Boolean valueOf(boolean value) {
247: return value ? Boolean.TRUE : Boolean.FALSE;
248: }
249:
250: /**
251: * Simple-minded String.replace() for JDK1.3 Should probably be recoded...
252: *
253: * @param source
254: * input string
255: * @param search
256: * string to look for (no regular expressions)
257: * @param replace
258: * string to replace the search string
259: * @return the output string
260: */
261: public static String replaceFirst(String source, String search,
262: String replace) {
263: int start = source.indexOf(search);
264: int len = search.length();
265: if (start == -1)
266: return source;
267: if (start == 0)
268: return replace + source.substring(len);
269: return source.substring(0, start) + replace
270: + source.substring(start + len);
271: }
272:
273: /**
274: * Version of String.replaceAll() for JDK1.3
275: * See below for another version which replaces strings rather than chars
276: *
277: * @param source
278: * input string
279: * @param search
280: * char to look for (no regular expressions)
281: * @param replace
282: * string to replace the search string
283: * @return the output string
284: */
285: public static String replaceAllChars(String source, char search,
286: String replace) {
287: char[] chars = source.toCharArray();
288: StringBuffer sb = new StringBuffer(source.length() + 20);
289: for (int i = 0; i < chars.length; i++) {
290: char c = chars[i];
291: if (c == search) {
292: sb.append(replace);
293: } else {
294: sb.append(c);
295: }
296: }
297: return sb.toString();
298: }
299:
300: /**
301: * Replace all patterns in a String
302: *
303: * @see String#replaceAll(String regex,String replacement) - JDK1.4 only
304: *
305: * @param input - string to be transformed
306: * @param pattern - pattern to replace
307: * @param sub - replacement
308: * @return the updated string
309: */
310: public static String substitute(final String input,
311: final String pattern, final String sub) {
312: StringBuffer ret = new StringBuffer(input.length());
313: int start = 0;
314: int index = -1;
315: final int length = pattern.length();
316: while ((index = input.indexOf(pattern, start)) >= start) {
317: ret.append(input.substring(start, index));
318: ret.append(sub);
319: start = index + length;
320: }
321: ret.append(input.substring(start));
322: return ret.toString();
323: }
324:
325: /**
326: * Trim a string by the tokens provided.
327: *
328: * @param input string to trim
329: * @param delims list of delimiters
330: * @return input trimmed at the first delimiter
331: */
332: public static String trim(final String input, final String delims) {
333: StringTokenizer tokens = new StringTokenizer(input, delims);
334: return tokens.hasMoreTokens() ? tokens.nextToken() : "";
335: }
336:
337: /**
338: * Returns a slice of a byte array.
339: *
340: * TODO - add bounds checking?
341: *
342: * @param array -
343: * input array
344: * @param begin -
345: * start of slice
346: * @param end -
347: * end of slice
348: * @return slice from the input array
349: */
350: public static byte[] getByteArraySlice(byte[] array, int begin,
351: int end) {
352: byte[] slice = new byte[(end - begin + 1)];
353: int count = 0;
354: for (int i = begin; i <= end; i++) {
355: slice[count] = array[i];
356: count++;
357: }
358:
359: return slice;
360: }
361:
362: /**
363: * close a stream with no error thrown
364: * @param is - InputStream (may be null)
365: */
366: public static void closeQuietly(InputStream is) {
367: try {
368: if (is != null)
369: is.close();
370: } catch (IOException e) {
371: }
372: }
373:
374: /**
375: * close a stream with no error thrown
376: * @param os - OutputStream (may be null)
377: */
378: public static void closeQuietly(OutputStream os) {
379: try {
380: if (os != null)
381: os.close();
382: } catch (IOException e) {
383: }
384: }
385:
386: /**
387: * close a Writer with no error thrown
388: * @param wr - Writer (may be null)
389: */
390: public static void closeQuietly(Writer wr) {
391: try {
392: if (wr != null)
393: wr.close();
394: } catch (IOException e) {
395: }
396: }
397:
398: /**
399: * close a Reader with no error thrown
400: * @param rd - Reader (may be null)
401: */
402: public static void closeQuietly(Reader rd) {
403: try {
404: if (rd != null)
405: rd.close();
406: } catch (IOException e) {
407: }
408: }
409:
410: /**
411: * close a Socket with no error thrown
412: * @param sock - Socket (may be null)
413: */
414: public static void closeQuietly(Socket sock) {
415: try {
416: if (sock != null)
417: sock.close();
418: } catch (IOException e) {
419: }
420: }
421:
422: /**
423: * close a Socket with no error thrown
424: * @param sock - ServerSocket (may be null)
425: */
426: public static void closeQuietly(ServerSocket sock) {
427: try {
428: if (sock != null)
429: sock.close();
430: } catch (IOException e) {
431: }
432: }
433: }
|