All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.wicket.util.string.Strings Maven / Gradle / Ivy

Go to download

Pax Wicket Service is an OSGi extension of the Wicket framework, allowing for dynamic loading and unloading of Wicket components and pageSources.

There is a newer version: 5.0.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.wicket.util.string;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.wicket.Component;
import org.apache.wicket.WicketRuntimeException;


/**
 * A variety of static String utility methods.
 * 

* The escapeMarkup() and toMultilineMarkup() methods are useful for turning normal Java Strings * into HTML strings. *

* The lastPathComponent(), firstPathComponent(), afterFirstPathComponent() and * beforeLastPathComponent() methods can chop up a String into path components using a separator * character. If the separator cannot be found the original String is returned. *

* Similarly, the beforeLast(), beforeFirst(), afterFirst() and afterLast() methods return sections * before and after a separator character. But if the separator cannot be found, an empty string is * returned. *

* Some other miscellaneous methods will strip a given ending off a String if it can be found * (stripEnding()), replace all occurrences of one String with another (replaceAll), do type * conversions (toBoolean(), toChar(), toString()), check a String for emptiness (isEmpty()), * convert a Throwable to a String (toString(Throwable)) or capitalize a String (capitalize()). * * @author Jonathan Locke */ public final class Strings { /** * The line separator for the current platform. */ public static final String LINE_SEPARATOR; /** A table of hex digits */ private static final char[] hexDigit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; private static final Pattern htmlNumber = Pattern.compile("\\&\\#\\d+\\;"); static { LINE_SEPARATOR = AccessController.doPrivileged(new PrivilegedAction() { public String run() { return System.getProperty("line.separator"); } }); } /** * Returns everything after the first occurrence of the given character in s. * * @param s * The string * @param c * The character * @return Everything after the first occurrence of the given character in s. If the character * cannot be found, an empty string is returned. */ public static String afterFirst(final String s, final char c) { if (s == null) { return null; } final int index = s.indexOf(c); if (index == -1) { return ""; } return s.substring(index + 1); } /** * Gets everything after the first path component of a path using a given separator. If the * separator cannot be found, an empty String is returned. *

* For example, afterFirstPathComponent("foo.bar.baz", '.') would return "bar.baz" and * afterFirstPathComponent("foo", '.') would return "". * * @param path * The path to parse * @param separator * The path separator character * @return Everything after the first component in the path */ public static String afterFirstPathComponent(final String path, final char separator) { return afterFirst(path, separator); } /** * Returns everything after the last occurrence of the given character in s. * * @param s * The string * @param c * The character * @return Everything after the last occurrence of the given character in s. If the character * cannot be found, an empty string is returned. */ public static String afterLast(final String s, final char c) { if (s == null) { return null; } final int index = s.lastIndexOf(c); if (index == -1) { return ""; } return s.substring(index + 1); } /** * Returns everything before the first occurrence of the given character in s. * * @param s * The string * @param c * The character * @return Everything before the first occurrence of the given character in s. If the character * cannot be found, an empty string is returned. */ public static String beforeFirst(final String s, final char c) { if (s == null) { return null; } final int index = s.indexOf(c); if (index == -1) { return ""; } return s.substring(0, index); } /** * Returns everything before the last occurrence of the given character in s. * * @param s * The string * @param c * The character * @return Everything before the last occurrence of the given character in s. If the character * cannot be found, an empty string is returned. */ public static String beforeLast(final String s, final char c) { if (s == null) { return null; } final int index = s.lastIndexOf(c); if (index == -1) { return ""; } return s.substring(0, index); } /** * Gets everything before the last path component of a path using a given separator. If the * separator cannot be found, the path itself is returned. *

* For example, beforeLastPathComponent("foo.bar.baz", '.') would return "foo.bar" and * beforeLastPathComponent("foo", '.') would return "". * * @param path * The path to parse * @param separator * The path separator character * @return Everything before the last component in the path */ public static String beforeLastPathComponent(final String path, final char separator) { return beforeLast(path, separator); } /** * Capitalizes a string. * * @param s * The string * @return The capitalized string */ public static String capitalize(final String s) { if (s == null) { return null; } final char[] chars = s.toCharArray(); if (chars.length > 0) { chars[0] = Character.toUpperCase(chars[0]); } return new String(chars); } /** * Converts a Java String to an HTML markup string, but does not convert normal spaces to * non-breaking space entities (<nbsp>). * * @param s * The string to escape * @see Strings#escapeMarkup(String, boolean) * @return The escaped string */ public static CharSequence escapeMarkup(final String s) { return escapeMarkup(s, false); } /** * Converts a Java String to an HTML markup String by replacing illegal characters with HTML * entities where appropriate. Spaces are converted to non-breaking spaces (<nbsp>) if * escapeSpaces is true, tabs are converted to four non-breaking spaces, less than signs are * converted to &lt; entities and greater than signs to &gt; entities. * * @param s * The string to escape * @param escapeSpaces * True to replace ' ' with nonbreaking space * @return The escaped string */ public static CharSequence escapeMarkup(final String s, final boolean escapeSpaces) { return escapeMarkup(s, escapeSpaces, false); } /** * Converts a Java String to an HTML markup String by replacing illegal characters with HTML * entities where appropriate. Spaces are converted to non-breaking spaces (<nbsp>) if * escapeSpaces is true, tabs are converted to four non-breaking spaces, less than signs are * converted to &lt; entities and greater than signs to &gt; entities. * * @param s * The string to escape * @param escapeSpaces * True to replace ' ' with nonbreaking space * @param convertToHtmlUnicodeEscapes * True to convert non-7 bit characters to unicode HTML (&#...) * @return The escaped string */ public static CharSequence escapeMarkup(final String s, final boolean escapeSpaces, final boolean convertToHtmlUnicodeEscapes) { if (s == null) { return null; } else { int len = s.length(); final AppendingStringBuffer buffer = new AppendingStringBuffer((int)(len * 1.1)); for (int i = 0; i < len; i++) { final char c = s.charAt(i); switch (c) { case '\t' : if (escapeSpaces) { // Assumption is four space tabs (sorry, but that's // just how it is!) buffer.append("    "); } else { buffer.append(c); } break; case ' ' : if (escapeSpaces) { buffer.append(" "); } else { buffer.append(c); } break; case '<' : buffer.append("<"); break; case '>' : buffer.append(">"); break; case '&' : buffer.append("&"); break; case '"' : buffer.append("""); break; case '\'' : buffer.append("'"); break; default : int ci = 0xffff & c; if (ci < 0x20) { // http://en.wikipedia.org/wiki/Valid_characters_in_XML if (ci != 0x09 && ci != 0x0A && ci != 0x0D) { buffer.append("&#"); buffer.append(new Integer(ci).toString()); buffer.append(';'); break; } } if (convertToHtmlUnicodeEscapes) { if (ci < 160) { // nothing special only 7 Bit buffer.append(c); } else { // Not 7 Bit use the unicode system buffer.append("&#"); buffer.append(new Integer(ci).toString()); buffer.append(';'); } } else { buffer.append(c); } break; } } return buffer; } } /** * Gets the first path component of a path using a given separator. If the separator cannot be * found, the path itself is returned. *

* For example, firstPathComponent("foo.bar", '.') would return "foo" and * firstPathComponent("foo", '.') would return "foo". * * @param path * The path to parse * @param separator * The path separator character * @return The first component in the path or path itself if no separator characters exist. */ public static String firstPathComponent(final String path, final char separator) { if (path == null) { return null; } final int index = path.indexOf(separator); if (index == -1) { return path; } return path.substring(0, index); } /** * Converts encoded \uxxxx to unicode chars and changes special saved chars to their * original forms. * * @param escapedUnicodeString * escaped unicode string, like '\u4F60\u597D'. * * @return The actual unicode. Can be used for instance with message bundles */ public static String fromEscapedUnicode(String escapedUnicodeString) { int off = 0; char[] in = escapedUnicodeString.toCharArray(); int len = in.length; char[] convtBuf = new char[len]; char aChar; char[] out = convtBuf; int outLen = 0; int end = off + len; while (off < end) { aChar = in[off++]; if (aChar == '\\') { aChar = in[off++]; if (aChar == 'u') { // Read the xxxx int value = 0; for (int i = 0; i < 4; i++) { aChar = in[off++]; switch (aChar) { case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : value = (value << 4) + aChar - '0'; break; case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' : value = (value << 4) + 10 + aChar - 'a'; break; case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' : value = (value << 4) + 10 + aChar - 'A'; break; default : throw new IllegalArgumentException("Malformed \\uxxxx encoding."); } } out[outLen++] = (char)value; } else { if (aChar == 't') { aChar = '\t'; } else if (aChar == 'r') { aChar = '\r'; } else if (aChar == 'n') { aChar = '\n'; } else if (aChar == 'f') { aChar = '\f'; } out[outLen++] = aChar; } } else { out[outLen++] = aChar; } } return new String(out, 0, outLen); } /** * Checks whether the string is considered empty. Empty means that the string may * contain whitespace, but no visible characters. * * "\n\t " is considered empty, while " a" is not. * * @param string * The string * @return True if the string is null or "" */ public static boolean isEmpty(final CharSequence string) { return string == null || string.length() == 0 || string.toString().trim().length() == 0; } /** * Checks whether two strings are equals taken care of 'null' values and treating 'null' same as * trim(string).equals("") * * @param string1 * @param string2 * @return true, if both strings are equal */ public static boolean isEqual(final String string1, final String string2) { if ((string1 == null) && (string2 == null)) { return true; } if (isEmpty(string1) && isEmpty(string2)) { return true; } if (string1 == null || string2 == null) { return false; } return string1.equals(string2); } /** * Converts the text in s to a corresponding boolean. On, yes, y, true and 1 are * converted to true. Off, no, n, false and 0 (zero) are converted to * false. An empty string is converted to false. Conversion is * case-insensitive, and does not take internationalization into account. * * 'Ja', 'Oui', 'Igen', 'Nein', 'Nee', 'Non', 'Nem' are all illegal values. * * @param s * the value to convert into a boolean * @return Boolean the converted value of s * @throws StringValueConversionException * when the value of s is not recognized. */ public static boolean isTrue(final String s) throws StringValueConversionException { if (s != null) { if (s.equalsIgnoreCase("true")) { return true; } if (s.equalsIgnoreCase("false")) { return false; } if (s.equalsIgnoreCase("on") || s.equalsIgnoreCase("yes") || s.equalsIgnoreCase("y") || s.equalsIgnoreCase("1")) { return true; } if (s.equalsIgnoreCase("off") || s.equalsIgnoreCase("no") || s.equalsIgnoreCase("n") || s.equalsIgnoreCase("0")) { return false; } if (isEmpty(s)) { return false; } throw new StringValueConversionException("Boolean value \"" + s + "\" not recognized"); } return false; } /** * Joins string fragments using the specified separator * * @param separator * @param fragments * @return combined fragments */ public static String join(String separator, String... fragments) { if (fragments.length < 1) { // no elements return ""; } else if (fragments.length < 2) { // single element return fragments[0]; } else { // two or more elements StringBuffer buff = new StringBuffer(128); if (fragments[0] != null) { buff.append(fragments[0]); } for (int i = 1; i < fragments.length; i++) { if ((fragments[i - 1] != null) || (fragments[i] != null)) { boolean lhsClosed = fragments[i - 1].endsWith(separator); boolean rhsClosed = fragments[i].startsWith(separator); if (lhsClosed && rhsClosed) { buff.append(fragments[i].substring(1)); } else if (!lhsClosed && !rhsClosed) { buff.append(separator).append(fragments[i]); } else { buff.append(fragments[i]); } } } return buff.toString(); } } /** * Gets the last path component of a path using a given separator. If the separator cannot be * found, the path itself is returned. *

* For example, lastPathComponent("foo.bar", '.') would return "bar" and * lastPathComponent("foo", '.') would return "foo". * * @param path * The path to parse * @param separator * The path separator character * @return The last component in the path or path itself if no separator characters exist. */ public static String lastPathComponent(final String path, final char separator) { if (path == null) { return null; } final int index = path.lastIndexOf(separator); if (index == -1) { return path; } return path.substring(index + 1); } /** * Replace all occurrences of one string replaceWith another string. * * @param s * The string to process * @param searchFor * The value to search for * @param replaceWith * The value to searchFor replaceWith * @return The resulting string with searchFor replaced with replaceWith */ public static CharSequence replaceAll(final CharSequence s, final CharSequence searchFor, CharSequence replaceWith) { if (s == null) { return null; } // If searchFor is null or the empty string, then there is nothing to // replace, so returning s is the only option here. if (searchFor == null || "".equals(searchFor)) { return s; } // If replaceWith is null, then the searchFor should be replaced with // nothing, which can be seen as the empty string. if (replaceWith == null) { replaceWith = ""; } String searchString = searchFor.toString(); // Look for first occurrence of searchFor int matchIndex = search(s, searchString, 0); if (matchIndex == -1) { // No replace operation needs to happen return s; } else { // Allocate a AppendingStringBuffer that will hold one replacement // with a // little extra room. int size = s.length(); final int replaceWithLength = replaceWith.length(); final int searchForLength = searchFor.length(); if (replaceWithLength > searchForLength) { size += (replaceWithLength - searchForLength); } final AppendingStringBuffer buffer = new AppendingStringBuffer(size + 16); int pos = 0; do { // Append text up to the match` append(buffer, s, pos, matchIndex); // Add replaceWith text buffer.append(replaceWith); // Find next occurrence, if any pos = matchIndex + searchForLength; matchIndex = search(s, searchString, pos); } while (matchIndex != -1); // Add tail of s buffer.append(s.subSequence(pos, s.length())); // Return processed buffer return buffer; } } /** * Replace HTML numbers like 值 by the appropriate character. * * @param str * The text to be evaluated * @return The text with "numbers" replaced */ public static String replaceHtmlEscapeNumber(String str) { if (str == null) { return null; } Matcher matcher = htmlNumber.matcher(str); while (matcher.find()) { int pos = matcher.start(); int end = matcher.end(); int number = Integer.parseInt(str.substring(pos + 2, end - 1)); char ch = (char)number; str = str.substring(0, pos) + ch + str.substring(end); matcher = htmlNumber.matcher(str); } return str; } /** * Simpler, faster version of String.split() for splitting on a simple character. * * @param s * The string to split * @param c * The character to split on * @return The array of strings */ public static String[] split(final String s, final char c) { if (s == null) { return new String[0]; } final List strings = new ArrayList(); int pos = 0; while (true) { int next = s.indexOf(c, pos); if (next == -1) { strings.add(s.substring(pos)); break; } else { strings.add(s.substring(pos, next)); } pos = next + 1; } final String[] result = new String[strings.size()]; strings.toArray(result); return result; } /** * Strips the ending from the string s. * * @param s * The string to strip * @param ending * The ending to strip off * @return The stripped string or the original string if the ending did not exist */ public static String stripEnding(final String s, final String ending) { if (s == null) { return null; } // Stripping a null or empty string from the end returns the // original string. if (ending == null || "".equals(ending)) { return s; } final int endingLength = ending.length(); final int sLength = s.length(); // When the length of the ending string is larger // than the original string, the original string is returned. if (endingLength > sLength) { return s; } final int index = s.lastIndexOf(ending); final int endpos = sLength - endingLength; if (index == endpos) { return s.substring(0, endpos); } return s; } /** * Strip any jsessionid and possibly other redundant info that might be in our way. * * @param url * The url to strip * @return The stripped url */ public static String stripJSessionId(CharSequence url) { if (url == null) { return null; } StringBuffer path = new StringBuffer(url.toString()); int ixSemiColon = path.indexOf(";"); // strip off any jsession id if (ixSemiColon != -1) { int ixEnd = path.indexOf("?"); // there is no ? in the path so set it to the length (no arguments) if (ixEnd == -1) { ixEnd = path.length(); } // there is no ? in the path so set it to the length (no arguments) if (ixEnd == -1) { ixEnd = path.length(); } if (ixEnd <= ixSemiColon) { // ? is before ; - no jsessionid in the url return url.toString(); } if (ixEnd == -1) { ixEnd = path.length(); } path.delete(ixSemiColon, ixEnd); } return path.toString(); } /** * Converts the string s to a Boolean. See isTrue for valid values of s. * * @param s * The string to convert. * @return Boolean TRUE when isTrue(s). * @throws StringValueConversionException * when s is not a valid value * @see #isTrue(String) */ public static Boolean toBoolean(final String s) throws StringValueConversionException { return Boolean.valueOf(isTrue(s)); } /** * Converts the 1 character string s to a character. * * @param s * The 1 character string to convert to a char. * @return Character value to convert * @throws StringValueConversionException * when the string is longer or shorter than 1 character, or null. */ public static char toChar(final String s) throws StringValueConversionException { if (s != null) { if (s.length() == 1) { return s.charAt(0); } else { throw new StringValueConversionException("Expected single character, not \"" + s + "\""); } } throw new StringValueConversionException("Character value was null"); } /** * Converts unicodes to encoded \uxxxx. * * @param unicodeString * The unicode string * @return The escaped unicode string, like '\u4F60\u597D'. */ public static String toEscapedUnicode(String unicodeString) { if ((unicodeString == null) || (unicodeString.length() == 0)) { return unicodeString; } int len = unicodeString.length(); int bufLen = len * 2; StringBuffer outBuffer = new StringBuffer(bufLen); for (int x = 0; x < len; x++) { char aChar = unicodeString.charAt(x); // Handle common case first, selecting largest block that // avoids the specials below if ((aChar > 61) && (aChar < 127)) { if (aChar == '\\') { outBuffer.append('\\'); outBuffer.append('\\'); continue; } outBuffer.append(aChar); continue; } switch (aChar) { case ' ' : if (x == 0) { outBuffer.append('\\'); } outBuffer.append(' '); break; case '\t' : outBuffer.append('\\'); outBuffer.append('t'); break; case '\n' : outBuffer.append('\\'); outBuffer.append('n'); break; case '\r' : outBuffer.append('\\'); outBuffer.append('r'); break; case '\f' : outBuffer.append('\\'); outBuffer.append('f'); break; case '=' : // Fall through case ':' : // Fall through case '#' : // Fall through case '!' : outBuffer.append('\\'); outBuffer.append(aChar); break; default : if ((aChar < 0x0020) || (aChar > 0x007e)) { outBuffer.append('\\'); outBuffer.append('u'); outBuffer.append(toHex((aChar >> 12) & 0xF)); outBuffer.append(toHex((aChar >> 8) & 0xF)); outBuffer.append(toHex((aChar >> 4) & 0xF)); outBuffer.append(toHex(aChar & 0xF)); } else { outBuffer.append(aChar); } } } return outBuffer.toString(); } /** * Converts a String to multiline HTML markup by replacing newlines with line break entities * (<br/>) and multiple occurrences of newline with paragraph break entities (<p>). * * @param s * String to transform * @return String with all single occurrences of newline replaced with <br/> and all * multiple occurrences of newline replaced with <p>. */ public static CharSequence toMultilineMarkup(final CharSequence s) { if (s == null) { return null; } final AppendingStringBuffer buffer = new AppendingStringBuffer(); int newlineCount = 0; buffer.append("

"); for (int i = 0; i < s.length(); i++) { final char c = s.charAt(i); switch (c) { case '\n' : newlineCount++; break; case '\r' : break; default : if (newlineCount == 1) { buffer.append("
"); } else if (newlineCount > 1) { buffer.append("

"); } buffer.append(c); newlineCount = 0; break; } } if (newlineCount == 1) { buffer.append("
"); } else if (newlineCount > 1) { buffer.append("

"); } buffer.append("

"); return buffer; } /** * Converts the given object to a string. Does special conversion for {@link Throwable * throwables} and String arrays of length 1 (in which case it just returns to string in that * array, as this is a common thing to have in the Servlet API). * * @param object * The object * @return The string */ public static String toString(final Object object) { if (object == null) { return null; } if (object instanceof Throwable) { return toString((Throwable)object); } if (object instanceof String) { return (String)object; } if (object instanceof String[] && ((String[])object).length == 1) { return ((String[])object)[0]; } return object.toString(); } /** * Creates a location stacktrace string representation for the component for reference when the * render check fails. This method filters out most of the unnecessary parts of the stack trace. * The message of the location is used as a verb in the rendered string. Use * "added", "constructed" or similar verbs as values. * * @param component * the component that was constructed or added and failed to render * @param location * the location where the component was created or added in the java code. * @return a string giving the line precise location where the component was added or created. */ public static String toString(final Component component, final Throwable location) { Class componentClass = component.getClass(); // try to find the component type, if it is an inner element, then get // the parent component. String componentType = componentClass.getName(); if (componentType.indexOf('$') >= 0) { componentType = componentClass.getSuperclass().getName(); } componentType = componentType.substring(componentType.lastIndexOf('.') + 1); // create a user friendly message, using the location's message as a // differentiator for the message (e.g. "component foo was ***added***" // or "component foo was ***created***") AppendingStringBuffer sb = new AppendingStringBuffer("The " + componentType.toLowerCase() + " with id '" + component.getId() + "' that failed to render was " + location.getMessage() + "\n"); // a list of stacktrace elements that need to be skipped in the location // stack trace String[] skippedElements = new String[] { "org.apache.wicket.MarkupContainer", "org.apache.wicket.Component", "org.apache.wicket.markup" }; // a list of stack trace elements that stop the traversal of the stack // trace String[] breakingElements = new String[] { "org.apache.wicket.protocol.http.WicketServlet", "org.apache.wicket.protocol.http.WicketFilter", "java.lang.reflect" }; StackTraceElement[] trace = location.getStackTrace(); for (int i = 0; i < trace.length; i++) { String traceString = trace[i].toString(); if (shouldSkip(traceString, skippedElements)) { // don't print this line, is wicket internal continue; } if (!(traceString.startsWith("sun.reflect.") && i > 1)) { // filter out reflection API calls from the stack trace if (traceString.indexOf("java.lang.reflect") < 0) { sb.append(" at "); sb.append(traceString); sb.append("\n"); } if (shouldSkip(traceString, breakingElements)) { break; } } } sb.append("\n"); return sb.toString(); } private static boolean shouldSkip(String text, String[] filters) { for (int i = 0; i < filters.length; i++) { if (text.indexOf(filters[i]) >= 0) { return true; } } return false; } /** * Converts a Throwable to a string. * * @param throwable * The throwable * @return The string */ public static String toString(final Throwable throwable) { if (throwable != null) { List al = new ArrayList(); Throwable cause = throwable; al.add(cause); while (cause.getCause() != null && cause != cause.getCause()) { cause = cause.getCause(); al.add(cause); } AppendingStringBuffer sb = new AppendingStringBuffer(256); // first print the last cause int length = al.size() - 1; cause = al.get(length); if (throwable instanceof WicketRuntimeException) { sb.append("WicketMessage: "); sb.append(throwable.getMessage()); sb.append("\n\n"); } sb.append("Root cause:\n\n"); outputThrowable(cause, sb, false); if (length > 0) { sb.append("\n\nComplete stack:\n\n"); for (int i = 0; i < length; i++) { outputThrowable(al.get(i), sb, true); sb.append("\n"); } } return sb.toString(); } else { return ""; } } private static void append(AppendingStringBuffer buffer, CharSequence s, int from, int to) { if (s instanceof AppendingStringBuffer) { AppendingStringBuffer asb = (AppendingStringBuffer)s; buffer.append(asb.getValue(), from, to - from); } else if (s instanceof StringBuffer) { buffer.append((StringBuffer)s, from, to - from); } else { buffer.append(s.subSequence(from, to)); } } /** * Outputs the throwable and its stacktrace to the stringbuffer. If stopAtWicketSerlvet is true * then the output will stop when the org.apache.wicket servlet is reached. sun.reflect. * packages are filtered out. * * @param cause * @param sb * @param stopAtWicketServlet */ private static void outputThrowable(Throwable cause, AppendingStringBuffer sb, boolean stopAtWicketServlet) { sb.append(cause); sb.append("\n"); StackTraceElement[] trace = cause.getStackTrace(); for (int i = 0; i < trace.length; i++) { String traceString = trace[i].toString(); if (!(traceString.startsWith("sun.reflect.") && i > 1)) { sb.append(" at "); sb.append(traceString); sb.append("\n"); if (stopAtWicketServlet && (traceString.startsWith("org.apache.wicket.protocol.http.WicketServlet") || traceString.startsWith("org.apache.wicket.protocol.http.WicketFilter"))) { return; } } } } private static int search(final CharSequence s, String searchString, int pos) { int matchIndex = -1; if (s instanceof String) { matchIndex = ((String)s).indexOf(searchString, pos); } else if (s instanceof StringBuffer) { matchIndex = ((StringBuffer)s).indexOf(searchString, pos); } else if (s instanceof AppendingStringBuffer) { matchIndex = ((AppendingStringBuffer)s).indexOf(searchString, pos); } else { matchIndex = s.toString().indexOf(searchString, pos); } return matchIndex; } /** * Convert a nibble to a hex character * * @param nibble * the nibble to convert. * @return hex character */ private static char toHex(int nibble) { return hexDigit[(nibble & 0xF)]; } /** * Calculates the length of string in bytes, uses specified charset if provided. * * @param string * @param charset * (optional) character set to use when converting string to bytes * @return length of string in bytes */ public static int lengthInBytes(String string, Charset charset) { if (string == null) { throw new NullPointerException("Argument `string` cannot be null"); } if (charset != null) { try { return string.getBytes(charset.name()).length; } catch (UnsupportedEncodingException e) { throw new WicketRuntimeException( "StringResourceStream created with unsupported charset: " + charset.name()); } } else { return string.getBytes().length; } } /** * Extended {@link String#startsWith(String)} with support for case sensitivity * * @param str * @param prefix * @param caseSensitive * @return true if str starts with prefix */ public static boolean startsWith(String str, String prefix, boolean caseSensitive) { if (caseSensitive) { return str.startsWith(prefix); } else { return str.toLowerCase().startsWith(prefix.toLowerCase()); } } /** * Private constructor prevents construction. */ private Strings() { } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy