/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* See LICENSE.txt included in this distribution for the specific
* language governing permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at LICENSE.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Portions Copyright 2011, 2012 Jens Elkner.
*/
/**
* Class for useful functions.
*/
public final class Util {
private Util() {
// singleton
}
/**
* Replace all HTML special characters '&', '<', '>' in the given String
* with their corresponding HTML entity references.
* @param s string to htmlize
* @return <var>s</var> if it doesn't contain a special character, a new
* string otherwise.
*/
int start = -1;
for (int i=0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '>' || c == '<' || c == '&') {
start = i;
break;
}
}
if (start == -1) {
return s;
}
// since we can't copy sequences efficiently we copy char by char :(
char c = s.charAt(i);
switch (c) {
case '&':
break;
case '>':
break;
case '<':
break;
default:
}
}
}
/**
* Replace all HTML special characters '&', '<', '>' AND linefeeds ('\n')
* in the given String with their corresponding HTML entity references.
* @param s string to htmlize
* @param eol the replacement to use for linefeeds ('\n')
* @return <var>s</var> if it doesn't contain a special character, a new
* string otherwise.
*/
eol = "\\n";
}
int start = -1;
for (int i=0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '>' || c == '<' || c == '&' || c == '\n') {
start = i;
break;
}
}
if (start == -1) {
return s;
}
// since we can't copy sequences efficiently we copy char by char :(
char c = s.charAt(i);
switch (c) {
case '&':
break;
case '>':
break;
case '<':
break;
case '\n':
break;
default:
}
}
}
/**
* used by BUI - CSS needs this parameter for proper cache refresh (per
* changeset) in client browser jel: but useless, since the page cached
* anyway.
*
* @return html escaped version (hg changeset)
*/
return versionP;
}
/**
* Convinience method for {@code breadcrumbPath(urlPrefix, path, '/')}.
* @param urlPrefix prefix to add to each url
* @param path path to crack
* @return HTML markup fro the breadcrumb or the path itself.
*
* @see #breadcrumbPath(String, String, char)
*/
}
/**
* Convenience method for
* {@code breadcrumbPath(urlPrefix, path, sep, "", false)}.
*
* @param urlPrefix prefix to add to each url
* @param path path to crack
* @param sep separator to use to crack the given path
*
* @return HTML markup fro the breadcrumb or the path itself.
* @see #breadcrumbPath(String, String, char, String, boolean, boolean)
*/
{
}
/**
* Convenience method for
* {@code breadcrumbPath(urlPrefix, path, sep, "", false, path.endsWith(sep)}.
*
* @param urlPrefix prefix to add to each url
* @param path path to crack
* @param sep separator to use to crack the given path
* @param urlPostfix suffix to add to each url
* @param compact if {@code true} the given path gets transformed into
* its canonical form (.i.e. all '.' and '..' and double separators
* removed, but not always resolves to an absolute path) before processing
* starts.
* @return HTML markup fro the breadcrumb or the path itself.
* @see #breadcrumbPath(String, String, char, String, boolean, boolean)
* @see #getCanonicalPath(String, char)
*/
{
return path;
}
}
/**
* Create a breadcrumb path to allow navigation to each element of a path.
* Consecutive separators (<var>sep</var>) in the given <var>path</var> are
* always collapsed into a single separator automatically. If
* <var>compact</var> is {@code true} path gets translated into a canonical
* path similar to {@link File#getCanonicalPath()}, however the current
* working directory is assumed to be "/" and no checks are done (e.g.
* neither whether the path [component] exists nor which type it is).
*
* @param urlPrefix
* what should be prepend to the constructed URL
* @param path
* the full path from which the breadcrumb path is built.
* @param sep
* the character that separates the path components in
* <var>path</var>
* @param urlPostfix
* what should be append to the constructed URL
* @param compact
* if {@code true}, a canonical path gets constructed before
* processing.
* @param isDir
* if {@code true} a "/" gets append to the last path component's
* link and <var>sep</var> to its name
* @return <var>path</var> if it resolves to an empty or "/" or
* {@code null} path, the HTML markup for the breadcrumb path otherwise.
*/
{
return path;
}
return path;
}
}
}
}
}
}
/**
* Normalize the given <var>path</var> to its canonical form. I.e. all
* separators (<var>sep</var>) are replaced with a slash ('/'), all
* double slashes are replaced by a single slash, all single dot path
* components (".") of the formed path are removed and all double dot path
* components (".." ) of the formed path are replaced with its parent or
* '/' if there is no parent.
* <p>
* So the difference to {@link File#getCanonicalPath()} is, that this method
* does not hit the disk (just string manipulation), resolves <var>path</var>
* always against '/' and thus always returns an absolute path, which may
* actually not exist, and which has a single trailing '/' if the given
* <var>path</var> ends with the given <var>sep</var>.
*
* @param path path to mangle. If not absolute or {@code null}, the
* current working directory is assumed to be '/'.
* @param sep file separator to use to crack <var>path</var> into path
* components
* @return always a canonical path which starts with a '/'.
*/
return "/";
}
return "/";
}
}
// since is not a general purpose method. So we waive to handle
// cases like:
// || path.endsWith("/..") || path.endsWith("/.")
}
}
/**
* Get email address of the author.
*
* @param author
* string containing author and possibly email address.
* @return the first email address found in the given parameter, the
* parameter otherwise. Returned values are whitespace trimmed.
*/
if (email_matcher.find()) {
}
}
/**
* Remove all empty and {@code null} string elements from the given
* <var>names</var> and optionally all redundant information like "." and
* "..".
*
* @param names
* names to check
* @param canonical
* if {@code true}, remove redundant elements as well.
* @return a possible empty array of names all with a length > 0.
*/
return new String[0];
}
continue;
}
if (canonical) {
res.removeLast();
}
continue;
} else {
}
} else {
}
}
.size()]);
}
/**
* Generate a regex that matches the specified character. Escape it in case
* it is a character that has a special meaning in a regex.
*
* @param c
* the character that the regex should match
* @return a six-character string on the form <tt>\u</tt><i>hhhh</i>
*/
}
}
/**
* Convert the given size into a human readable string.
* @param num size to convert.
* @return a readable string
*/
float l = num;
if (l < 1024) {
} else if (l < 1048576) {
} else {
}
}
/**
* Generate a string from the given path and date in a way that allows
* stable lexicographic sorting (i.e. gives always the same results) as a
* walk of the file hierarchy. Thus null character (\u0000) is used both
* to separate directory components and to separate the path from the date.
* @param path path to mangle.
* @param date date string to use.
* @return the mangled path.
*/
}
/**
* The reverse operation for {@link #path2uid(String, String)} - re-creates
* the unmangled path from the given uid.
* @param uid uid to unmangle.
* @return the original path.
*/
}
/**
* Append '&name=value" properly URI encoded to the given buffer. If
* the given <var>value</var> is {@code null}, this method does nothing.
*
* @param buf where to append the query string
* @param key the name of the parameter to add. Append as is!
* @param value the decoded value for the given parameter.
* @throws NullPointerException if the given buffer is {@code null}.
* @see #uriEncodeQueryValue(String)
*/
{
}
}
/* ASCII chars 0..63, which need to be escaped in an URI path. The segment
* delimiter '/' (47) is not added to this set, because it is used to
* encode file pathes which use the same delimiter for path components.
* Since we do not use any path parameters we add ';' (59) as well.
* Furthermore to avoid the need of a 2nd run to escape '&' for HTML
* attributes, we encode '&' (38) as well.
* RFC 3986: chars 0..32 34 35 37 60 62 63 */
| 1L<<'%' | 1L<<'<' | 1L<<'>' | 1L<<'?' | 1L<<';' | 1L<<'&';
/* RFC 3986: path-noscheme - ':' (58) in the first segment needs to be encoded */
/* ASCII chars 64..127, which need to be escaped in an URI path.
* NOTE: URIs allow '~' unescaped, URLs not.
* RFC 3986: chars 91 92 93 94 96 123 124 125 127 */
| 1L<<'^'-64 | 1L<<'`'-64 | 1L<<'{'-64 | 1L<<'|'-64 | 1L<<'}'-64 | 1L<<63;
/* ASCII chars 0..63, which need to be escaped in an URI query string as
* well as fragment part.
* RFC 3986: chars 32 34 35 37 60 62 */
private static final long QUERY_ESCAPE_L =
/* ASCII chars 64..127, which need to be escaped in an URI query string as
* well as fragment part.
* RFC 3986: chars 91 92 93 94 96 123 124 125 127 */
/* Query string starts at the left-most '?', ends at the next '#' or if not
* of the form $name['='[$value]] delimited by '&'. So no need to encode '='
* for query values, but for query names. */
/** Loose check, whether we have an entity reference: either #[0-9A-Fa-f]*;
* or [A-Za-z]*; */
return false;
}
if (c == '#') {
start++;
if (c == 'x' || c == 'X') {
start++;
if (start == p) {
return false;
}
for (int i=start; i < p; i++) {
c = s.charAt(i);
if ( ! (('0' <= c && c <= '9') || ('A' <= c && c <= 'F')
|| ('a' <= c && c <= 'f')))
{
return false;
}
}
} else {
for (int i=start; i < p; i++) {
c = s.charAt(i);
if ( ! ('0' <= c && c <= '9')) {
return false;
}
}
}
return true;
}
for (int i=start+1; i < p; i++) {
c = s.charAt(i);
if ( ! (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'))) {
return false;
}
}
return true;
}
/**
* Tries to URI encode a URL. Difference to {@link #uriEncodePath(String)}
* is, that this method tries to find out, whether the URL already contains
* escaped characters and thus avoids double-encoding HTML special chars.
* NOTE: As soon as an entity reference is encountered, encoding stops and
* assumes an already encoded URL - the parameter gets returned as is!
* @param url URL to encode
* @return the URI encoded URL
*/
return url;
}
int i=0;
if (c < 64) {
break;
}
} else if (c < 0x80) {
break;
}
} else {
break;
}
}
return url;
}
if (c < 64) {
if (c == '&') {
return url;
}
} else {
appendEscape(sb, (byte) c);
}
} else {
}
} else if (c < 0x80) {
appendEscape(sb, (byte) c);
} else {
}
} else {
while (bb.hasRemaining()) {
if (b < 0x64) {
if (b == '&') {
return url;
}
} else {
appendEscape(sb, (byte) b);
}
} else {
}
} else if (c < 0x80) {
appendEscape(sb, (byte) b);
} else {
}
} else {
appendEscape(sb, (byte) b);
}
i++;
}
break;
}
}
}
/**
* URI encode the given path using UTF-8 encoding for non-ASCII characters.
* In addition ';', '&' (and ':' for relative paths) get encoded as well,
* but not '/'. This method should not be used to encode query strings - for
* this {@link #uriEncodeQueryName(String)} and
* {@link #uriEncodeQueryValue(String)} should be used.
* NOTE: Since single quote (') gets not encoded, the encoded result should
* be enclosed in double quotes (") when used as attribute values!
*
* @param path path to encode.
* @return the encoded path.
* @throws NullPointerException if a parameter is {@code null}
* @see "http://tools.ietf.org/html/rfc3986"
*/
return path;
}
}
/**
* URI encode the given value for a URI query string pair using UTF-8
* encoding for non-ASCII characters ('&' gets encoded as well). It can also
* be used to encode URI fragments properly.
* NOTE: Since single quote (') gets not encoded, the encoded result should
* be enclosed in double quotes (") when used as attribute values!
* @param value value to encode.
* @return the encoded value.
* @throws NullPointerException if a parameter is {@code null}
* @see "http://tools.ietf.org/html/rfc3986"
* @see #uriEncodeQueryName(String)
*/
}
/**
* URI encode the given name for a URI query string pair using UTF-8
* encoding for non-ASCII characters ('=' and '&' get encoded as well).
* NOTE: Since single quote (') gets not encoded, the encoded result should
* be enclosed in double quotes (") when used as attribute values!
* @param name name to encode.
* @return the encoded name.
* @throws NullPointerException if a parameter is {@code null}
* @see "http://tools.ietf.org/html/rfc3986"
* @see #uriEncodeQueryValue(String)
*/
}
/* int -> hex encoding helper */
}
int i=0;
for (;i < s.length(); i++) {
char c = s.charAt(i);
if (c < 64) {
break;
}
} else if (c < 0x80) {
break;
}
} else {
break;
}
}
if (i == s.length()) {
return s;
}
for(; i < s.length(); i++) {
char c = s.charAt(i);
if (c < 64) {
appendEscape(sb, (byte) c);
} else {
}
} else if (c < 0x80) {
appendEscape(sb, (byte) c);
} else {
}
} else {
while (bb.hasRemaining()) {
if (b < 0x64) {
appendEscape(sb, (byte) b);
} else {
}
} else if (b < 0x80) {
appendEscape(sb, (byte) b);
} else {
}
} else {
appendEscape(sb, (byte) b);
}
}
break;
}
}
}
/**
* Replace all quote and ampersand characters (ASCII 0x22, 0x26) with the
* corresponding html entity (&quot; , &amp;).
* @param q string to escape.
* @return an empty string if a parameter is {@code null}, the mangled
* string otherwise.
*/
return "";
}
char c;
int pos = -1;
for (int i = 0; i < q.length(); i++ ) {
c = q.charAt(i);
if (c == '"' || c == '&') {
pos = i;
break;
}
}
if (pos == -1) {
return q;
}
c = q.charAt(i);
if (c == '"') {
} else if (c == '&') {
} else {
}
}
}
/** span open tag incl. css class used to tag removed source code */
/** span open tag incl. css class used to tag added source code */
/**
* Tag changes in the given <var>line1</var> and <var>line2</var>
* for highlighting. Removed parts are tagged with CSS class {@code d},
* new parts are tagged with CSS class {@code a} using a {@code span}
* element.
*
* @param line1 line of the original file
* @return the tagged lines (field[0] ~= line1, field[1] ~= line2).
* @throws NullPointerException if one of the given parameters is {@code null}.
*/
if (n == 0 || m == 0) {
}
int s = 0;
s++ ;
}
m-- ;
n-- ;
}
// deleted
if (s <= m) {
m++;
} else {
}
// added
if (s <= n) {
n++;
} else {
}
return ret;
}
/**
* Dump the configuration as an HTML table.
*
* @param out
* destination for the HTML output
* @throws IOException
* if an error happens while writing to {@code out}
* @throws HistoryException
* if the history guru cannot be accesses
*/
@SuppressWarnings("boxing")
{
.getCacheInfo());
}
/**
* Just read the given source and dump as is to the given destination.
* Does nothing, if one or more of the parameters is {@code null}.
* @param out write destination
* @param in source to read
* @throws NullPointerException if a parameter is {@code null}.
*/
return;
}
char[] buf = new char[8192];
int len = 0;
}
}
/**
* Silently dump a file to the given destination. All {@link IOException}s
* gets caught and logged, but not re-thrown.
*
* @param out dump destination
* @param dir directory, which should contains the file.
* @param filename the basename of the file to dump.
* @param compressed if {@code true} the denoted file is assumed to be
* gzipped.
* @return {@code true} on success (everything read and written).
* @throws NullPointerException if a parameter is {@code null}.
*/
boolean compressed)
{
}
/**
* Silently dump a file to the given destination. All {@link IOException}s
* gets caught and logged, but not re-thrown.
*
* @param out dump destination
* @param file file to dump.
* @param compressed if {@code true} the denoted file is assumed to be
* gzipped.
* @return {@code true} on success (everything read and written).
* @throws NullPointerException if a parameter is {@code null}.
*/
@SuppressWarnings("resource")
return false;
}
try {
if (compressed) {
} else {
}
return true;
} catch(IOException e) {
+ e.getMessage());
} finally {
}
return false;
}
/**
* Print a row in an HTML table.
*
* @param out
* destination for the HTML output
* @param cells
* the values to print in the cells of the row
* @throws IOException
* if an error happens while writing to {@code out}
*/
throws IOException
{
}
}
/**
* Print an unordered list (HTML).
*
* @param out
* destination for the HTML output
* @param items
* the list items
* @throws IOException
* if an error happens while writing to {@code out}
*/
{
}
}
/**
* Create a string literal for use in JavaScript functions.
*
* @param str the string to be represented by the literal
* @return a JavaScript string literal. {@code null} values are converted to ''.
*/
return "\"\"";
}
switch (c) {
case '"':
break;
case '\\':
break;
case '\n':
break;
case '\r':
break;
default:
}
}
}
/**
* Convert the given array into JSON format and write it to the given stream.
* If <var>name</var> is given, the result is {@code name: [ value, ...]},
* otherwise {@code [ value, ... ]}.
* @param out where to write the json formatted array
* @param name name of the array. Might be {@code null}.
* @param values array to convert. {@code null} are converted to ''.
* @throws IOException
* @see #jsStringLiteral(String)
* @see #writeJsonArray(Writer, String, String[])
*/
{
// could just call writeJsonArray(out, name, values.toArray(new String[]))
// but this can be an issue for big collections - so we rather
// "duplicate" the code
}
if (i.hasNext()) {
while (i.hasNext()) {
}
}
}
/**
* Convert the given array into JSON format and write it to the given stream.
* If <var>name</var> is given, the result is {@code name: [ value, ...]},
* otherwise {@code [ value, ... ]}.
* @param out where to write the json formatted array
* @param name name of the array. Might be {@code null}.
* @param values array to convert. {@code null} are converted to ''.
* @throws IOException
* @see #jsStringLiteral(String)
* @see #writeJsonArray(Writer, String, Collection)
*/
}
}
}
}
}