📄 text.java
字号:
/** * Does a URL encoding of the <code>path</code>. The characters that * don't need encoding are those defined 'unreserved' in section 2.3 of * the 'URI generic syntax' RFC 2396. In contrast to the * {@link #escape(String)} method, not the entire path string is escaped, * but every individual part (i.e. the slashes are not escaped). * * @param path the path to encode * @return the escaped path * @throws NullPointerException if <code>path</code> is <code>null</code>. */ public static String escapePath(String path) { return escape(path, '%', true); } /** * Does a URL decoding of the <code>string</code> using the * <code>escape</code> character. Please note that in opposite to the * {@link java.net.URLDecoder} it does not transform the + into spaces. * * @param string the string to decode * @param escape the escape character * @return the decoded string * @throws NullPointerException if <code>string</code> is <code>null</code>. * @throws ArrayIndexOutOfBoundsException if not enough character follow an * escape character * @throws IllegalArgumentException if the 2 characters following the escape * character do not represent a hex-number. */ public static String unescape(String string, char escape) { ByteArrayOutputStream out = new ByteArrayOutputStream(string.length()); for (int i = 0; i < string.length(); i++) { char c = string.charAt(i); if (c == escape) { try { out.write(Integer.parseInt(string.substring(i + 1, i + 3), 16)); } catch (NumberFormatException e) { throw new IllegalArgumentException(); } i += 2; } else { out.write(c); } } try { return new String(out.toByteArray(), "utf-8"); } catch (UnsupportedEncodingException e) { throw new InternalError(e.toString()); } } /** * Does a URL decoding of the <code>string</code>. Please note that in * opposite to the {@link java.net.URLDecoder} it does not transform the + * into spaces. * * @param string the string to decode * @return the decoded string * @throws NullPointerException if <code>string</code> is <code>null</code>. * @throws ArrayIndexOutOfBoundsException if not enough character follow an * escape character * @throws IllegalArgumentException if the 2 characters following the escape * character do not represent a hex-number. */ public static String unescape(String string) { return unescape(string, '%'); } /** * Escapes all illegal JCR name characters of a string. * The encoding is loosely modeled after URI encoding, but only encodes * the characters it absolutely needs to in order to make the resulting * string a valid JCR name. * Use {@link #unescapeIllegalJcrChars(String)} for decoding. * <p/> * QName EBNF:<br> * <xmp> * simplename ::= onecharsimplename | twocharsimplename | threeormorecharname * onecharsimplename ::= (* Any Unicode character except: '.', '/', ':', '[', ']', '*', ''', '"', '|' or any whitespace character *) * twocharsimplename ::= '.' onecharsimplename | onecharsimplename '.' | onecharsimplename onecharsimplename * threeormorecharname ::= nonspace string nonspace * string ::= char | string char * char ::= nonspace | ' ' * nonspace ::= (* Any Unicode character except: '/', ':', '[', ']', '*', ''', '"', '|' or any whitespace character *) * </xmp> * * @param name the name to escape * @return the escaped name */ public static String escapeIllegalJcrChars(String name) { StringBuffer buffer = new StringBuffer(name.length() * 2); for (int i = 0; i < name.length(); i++) { char ch = name.charAt(i); if (ch == '%' || ch == '/' || ch == ':' || ch == '[' || ch == ']' || ch == '*' || ch == '\'' || ch == '"' || ch == '|' || (ch == '.' && name.length() < 3) || (ch == ' ' && (i == 0 || i == name.length() - 1)) || ch == '\t' || ch == '\r' || ch == '\n') { buffer.append('%'); buffer.append(Character.toUpperCase(Character.forDigit(ch / 16, 16))); buffer.append(Character.toUpperCase(Character.forDigit(ch % 16, 16))); } else { buffer.append(ch); } } return buffer.toString(); } /** * Unescapes previously escaped jcr chars. * <p/> * Please note, that this does not exactly the same as the url related * {@link #unescape(String)}, since it handles the byte-encoding * differently. * * @param name the name to unescape * @return the unescaped name */ public static String unescapeIllegalJcrChars(String name) { StringBuffer buffer = new StringBuffer(name.length()); int i = name.indexOf('%'); while (i > -1 && i + 2 < name.length()) { buffer.append(name.toCharArray(), 0, i); int a = Character.digit(name.charAt(i + 1), 16); int b = Character.digit(name.charAt(i + 2), 16); if (a > -1 && b > -1) { buffer.append((char) (a * 16 + b)); name = name.substring(i + 3); } else { buffer.append('%'); name = name.substring(i + 1); } i = name.indexOf('%'); } buffer.append(name); return buffer.toString(); } /** * Returns the name part of the path * * @param path the path * @return the name part */ public static String getName(String path) { int pos = path.lastIndexOf('/'); return pos >= 0 ? path.substring(pos + 1) : ""; } /** * Returns the name part of the path, delimited by the given <code>delim</code> * * @param path the path * @param delim the delimiter * @return the name part */ public static String getName(String path, char delim) { int pos = path.lastIndexOf(delim); return pos >= 0 ? path.substring(pos + 1) : ""; } /** * Same as {@link #getName(String)} but adding the possibility * to pass paths that end with a trailing '/' * * @see #getName(String) */ public static String getName(String path, boolean ignoreTrailingSlash) { if (ignoreTrailingSlash && path.endsWith("/") && path.length() > 1) { path = path.substring(0, path.length()-1); } return getName(path); } /** * Returns the namespace prefix of the given <code>qname</code>. If the * prefix is missing, an empty string is returned. Please note, that this * method does not validate the name or prefix. * </p> * the qname has the format: qname := [prefix ':'] local; * * @param qname a qualified name * @return the prefix of the name or "". * * @see #getLocalName(String) * * @throws NullPointerException if <code>qname</code> is <code>null</code> */ public static String getNamespacePrefix(String qname) { int pos = qname.indexOf(':'); return pos >=0 ? qname.substring(0, pos) : ""; } /** * Returns the local name of the given <code>qname</code>. Please note, that * this method does not validate the name. * </p> * the qname has the format: qname := [prefix ':'] local; * * @param qname a qualified name * @return the localname * * @see #getNamespacePrefix(String) * * @throws NullPointerException if <code>qname</code> is <code>null</code> */ public static String getLocalName(String qname) { int pos = qname.indexOf(':'); return pos >=0 ? qname.substring(pos+1) : qname; } /** * Determines, if two paths denote hierarchical siblins. * * @param p1 first path * @param p2 second path * @return true if on same level, false otherwise */ public static boolean isSibling(String p1, String p2) { int pos1 = p1.lastIndexOf('/'); int pos2 = p2.lastIndexOf('/'); return (pos1 == pos2 && pos1 >= 0 && p1.regionMatches(0, p2, 0, pos1)); } /** * Determines if the <code>descendant</code> path is hierarchical a * descendant of <code>path</code>. * * @param path the current path * @param descendant the potential descendant * @return <code>true</code> if the <code>descendant</code> is a descendant; * <code>false</code> otherwise. */ public static boolean isDescendant(String path, String descendant) { return !path.equals(descendant) && descendant.startsWith(path) && descendant.charAt(path.length()) == '/'; } /** * Determines if the <code>descendant</code> path is hierarchical a * descendant of <code>path</code> or equal to it. * * @param path the path to check * @param descendant the potential descendant * @return <code>true</code> if the <code>descendant</code> is a descendant * or equal; <code>false</code> otherwise. */ public static boolean isDescendantOrEqual(String path, String descendant) { if (path.equals(descendant)) { return true; } else { String pattern = path.endsWith("/") ? path : path + "/"; return descendant.startsWith(pattern); } } /** * Returns the n<sup>th</sup> relative parent of the path, where n=level. * <p>Example:<br> * <code> * Text.getRelativeParent("/foo/bar/test", 1) == "/foo/bar" * </code> * * @param path the path of the page * @param level the level of the parent */ public static String getRelativeParent(String path, int level) { int idx = path.length(); while (level > 0) { idx = path.lastIndexOf('/', idx - 1); if (idx < 0) { return ""; } level--; } return (idx == 0) ? "/" : path.substring(0, idx); } /** * Same as {@link #getRelativeParent(String, int)} but adding the possibility * to pass paths that end with a trailing '/' * * @see #getRelativeParent(String, int) */ public static String getRelativeParent(String path, int level, boolean ignoreTrailingSlash) { if (ignoreTrailingSlash && path.endsWith("/") && path.length() > 1) { path = path.substring(0, path.length()-1); } return getRelativeParent(path, level); } /** * Returns the n<sup>th</sup> absolute parent of the path, where n=level. * <p>Example:<br> * <code> * Text.getAbsoluteParent("/foo/bar/test", 1) == "/foo/bar" * </code> * * @param path the path of the page * @param level the level of the parent */ public static String getAbsoluteParent(String path, int level) { int idx = 0; int len = path.length(); while (level >= 0 && idx < len) { idx = path.indexOf('/', idx + 1); if (idx < 0) { idx = len; } level--; } return level >= 0 ? "" : path.substring(0, idx); } /** * Performs variable replacement on the given string value. * Each <code>${...}</code> sequence within the given value is replaced * with the value of the named parser variable. If a variable is not found * in the properties an IllegalArgumentException is thrown unless * <code>ignoreMissing</code> is <code>true</code>. In the later case, the * missing variable is replaced by the empty string. * * @param value the original value * @param ignoreMissing if <code>true</code>, missing variables are replaced * by the empty string. * @return value after variable replacements * @throws IllegalArgumentException if the replacement of a referenced * variable is not found */ public static String replaceVariables(Properties variables, String value, boolean ignoreMissing) throws IllegalArgumentException { StringBuffer result = new StringBuffer(); // Value: // +--+-+--------+-+-----------------+ // | |p|--> |q|--> | // +--+-+--------+-+-----------------+ int p = 0, q = value.indexOf("${"); // Find first ${ while (q != -1) { result.append(value.substring(p, q)); // Text before ${ p = q; q = value.indexOf("}", q + 2); // Find } if (q != -1) { String variable = value.substring(p + 2, q); String replacement = variables.getProperty(variable); if (replacement == null) { if (ignoreMissing) { replacement = ""; } else { throw new IllegalArgumentException( "Replacement not found for ${" + variable + "}."); } } result.append(replacement); p = q + 1; q = value.indexOf("${", p); // Find next ${ } } result.append(value.substring(p, value.length())); // Trailing text return result.toString(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -