001: /**********************************************************************************
002: *
003: * Copyright (c) 2003, 2004 The Regents of the University of Michigan, Trustees of Indiana University,
004: * Board of Trustees of the Leland Stanford, Jr., University, and The MIT Corporation
005: *
006: * Licensed under the Educational Community License Version 1.0 (the "License");
007: * By obtaining, using and/or copying this Original Work, you agree that you have read,
008: * understand, and will comply with the terms and conditions of the Educational Community License.
009: * You may obtain a copy of the License at:
010: *
011: * http://cvs.sakaiproject.org/licenses/license_1_0.html
012: *
013: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
014: * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
015: * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
016: * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
017: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
018: *
019: **********************************************************************************/package edu.indiana.lib.twinpeaks.util;
020:
021: import java.io.*;
022: import java.util.*;
023: import java.util.regex.*;
024:
025: public class StringUtils {
026:
027: private static org.apache.commons.logging.Log _log = LogUtils
028: .getLog(StringUtils.class);
029: /**
030: * Minimum length supported by <code>truncateAtWhitespace()</code>
031: */
032: private static final int MINIMUM_SUPPORTED_LENGTH = 4;
033:
034: private StringUtils() {
035: }
036:
037: /**
038: * Replace all occurances of the target text with the provided replacement
039: * text. Both target and replacement may be regular expressions - see
040: * <code>java.util.regex.Matcher</code>.
041: * @param text Text to modify
042: * @param targetText Text to find and replace
043: * @param newText New text
044: * @return Updated text
045: */
046: public static String replace(String text, String targetText,
047: String newText) {
048:
049: Pattern pattern = Pattern.compile(targetText,
050: Pattern.CASE_INSENSITIVE);
051: Matcher matcher = pattern.matcher(text);
052:
053: return matcher.replaceAll(newText);
054: }
055:
056: /**
057: * Null (or zero-length) String?
058: */
059: public static boolean isNull(String string) {
060: return (string == null) || (string.length() == 0);
061: }
062:
063: /**
064: * Truncate text on a whitespace boundary (near a specified length).
065: * The length of the resultant string will be in the range:<br>
066: * <code> (requested-length * .25) ~ (requested-length * 1.5) </code>
067: * @param text Text to truncate
068: * @param length Target length
069: * @return Truncated text
070: */
071: public static String truncateAtWhitespace(String text, int length) {
072: int desired, lowerBound, upperBound;
073: /*
074: * Make sure we have a reasonable length to work with
075: */
076: if (length < MINIMUM_SUPPORTED_LENGTH) {
077: throw new IllegalArgumentException(
078: "Requested length too short (must be "
079: + MINIMUM_SUPPORTED_LENGTH + " or greated)");
080: }
081: /*
082: * No need to truncate - the original string "fits"
083: */
084: if (text.length() <= length) {
085: return text;
086: }
087: /*
088: * Try to find whitespace befor the requested maximum
089: */
090: lowerBound = length / 4;
091: upperBound = length + (length / 2);
092:
093: for (int i = length - 1; i > lowerBound; i--) {
094: if (Character.isWhitespace(text.charAt(i))) {
095: return text.substring(0, i);
096: }
097: }
098: /*
099: * No whitespace - look beyond the desired maximum
100: */
101: for (int i = (length); i < upperBound; i++) {
102: if (Character.isWhitespace(text.charAt(i))) {
103: return text.substring(0, i);
104: }
105: }
106: /*
107: * No whitespace, just truncate the text at the requested length
108: */
109: return text.substring(0, length);
110: }
111:
112: /**
113: * Trim specified charcater from front of string
114: * @param text Text
115: * @param character Character to remove
116: * @return Trimmed text
117: */
118: public static String trimFront(String text, char character) {
119: String normalizedText;
120: int index;
121:
122: if (StringUtils.isNull(text)) {
123: return text;
124: }
125:
126: normalizedText = text.trim();
127: index = 0;
128:
129: while (normalizedText.charAt(index) == character) {
130: index++;
131: }
132: return normalizedText.substring(index).trim();
133: }
134:
135: /**
136: * Trim specified charcater from end of string
137: * @param text Text
138: * @param character Character to remove
139: * @return Trimmed text
140: */
141: public static String trimEnd(String text, char character) {
142: String normalizedText;
143: int index;
144:
145: if (StringUtils.isNull(text)) {
146: return text;
147: }
148:
149: normalizedText = text.trim();
150: index = normalizedText.length() - 1;
151:
152: while (normalizedText.charAt(index) == character) {
153: if (--index < 0) {
154: return "";
155: }
156: }
157: return normalizedText.substring(0, index + 1).trim();
158: }
159:
160: /**
161: * Trim specified charcater from both ends of a String
162: * @param text Text
163: * @param character Character to remove
164: * @return Trimmed text
165: */
166: public static String trimAll(String text, char character) {
167: String normalizedText = trimFront(text, character);
168:
169: return trimEnd(normalizedText, character);
170: }
171:
172: /**
173: * Capitlize each word in a string (journal titles, etc)
174: * @param text Text to inspect
175: * @return Capitalized text
176: */
177: public static String capitalize(String text) {
178: StringBuffer resultText;
179: char previousC;
180:
181: resultText = new StringBuffer();
182: previousC = '.';
183:
184: for (int i = 0; i < text.length(); i++) {
185: char c = text.charAt(i);
186:
187: if (Character.isLetter(c) && !Character.isLetter(previousC)) {
188: resultText.append(Character.toUpperCase(c));
189: } else {
190: resultText.append(c);
191: }
192: previousC = c;
193: }
194: return resultText.toString();
195: }
196:
197: /**
198: * Remove a character (or range of characters) from a string. If the
199: * character is in a word, remove the entire word.
200: * @param source String to edit
201: * @param pattern Character (or range) to remove. Range is a regular
202: * expression: <code>[\u002c-\u002f]</code> or <code>[,-/]</code>
203: * @return Modified text
204: */
205: public static String removeCharacterOrRangeAsWord(String source,
206: String pattern) {
207: return removeCharacterOrRange(source, pattern, true);
208: }
209:
210: /**
211: * Remove a character (or range of characters) from a string. If the
212: * character is at the start or end of a word, remove the character only
213: * (leave the word in place).
214: * @param source String to edit
215: * @param pattern Character (or range) to remove. Range is a regular
216: * expression: <code>[\u002c-\u002f]</code> or <code>[,-/]</code>
217: * @return Modified text
218: */
219: public static String removeCharacterOrRangeAsCharacter(
220: String source, String pattern) {
221: return removeCharacterOrRange(source, pattern, false);
222: }
223:
224: /*
225: * Helpers
226: */
227:
228: /**
229: * Remove a character (or range of characters) from a string.
230: * [optional] If a character is embedded in a word, remove the entire word.
231: * @param source String to edit
232: * @param pattern Character (or range) to remove. Range is a regular
233: * expression: <code>[\u002c-\u002f]</code> or <code>[,-/]</code>
234: * @param removeAsWord Always remove entire word?
235: * @return Modified text
236: */
237: private static String removeCharacterOrRange(String source,
238: String pattern, boolean removeAsWord) {
239: StringBuffer patternBuffer = new StringBuffer();
240: String rangePattern, result;
241:
242: patternBuffer.append('[');
243: patternBuffer.append(pattern);
244: patternBuffer.append(']');
245:
246: rangePattern = patternBuffer.toString();
247:
248: result = StringUtils.replace(source, "\\S+" + rangePattern
249: + "\\S+", "");
250:
251: if (removeAsWord) {
252: result = StringUtils.replace(result, rangePattern + "\\S+",
253: "");
254: result = StringUtils.replace(result, "\\S+" + rangePattern,
255: "");
256: }
257: return StringUtils.replace(result, rangePattern, " ");
258: }
259:
260: /*
261: * Test
262: */
263: public static void main(String[] args) throws Exception {
264: System.out.println(StringUtils.replace(args[0], args[1],
265: args[2]));
266: }
267: }
|