* Precise to the second. * * @param time * the specified number of milliseconds since the standard base * time known as "the epoch", namely January 1, 1970, 00:00:00 * GMT * * @return the time as a {@link String} */ static public String fromTime(long time) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.format(new Date(time)); } /** * Convert between the time as a {@link String} to milliseconds in a "fixed" * way (to exchange data over the wire, for instance). *
* Precise to the second.
*
* @param displayTime
* the time as a {@link String}
*
* @return the number of milliseconds since the standard base time known as
* "the epoch", namely January 1, 1970, 00:00:00 GMT, or -1 in case
* of error
*
* @throws ParseException
* in case of parse error
*/
static public long toTime(String displayTime) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.parse(displayTime).getTime();
}
/**
* Return a hash of the given {@link String}.
*
* @param input
* the input data
*
* @return the hash
*/
static public String getMd5Hash(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(input.getBytes("UTF-8"));
byte byteData[] = md.digest();
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < byteData.length; i++) {
String hex = Integer.toHexString(0xff & byteData[i]);
if (hex.length() == 1)
hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
return input;
} catch (UnsupportedEncodingException e) {
return input;
}
}
/**
* Remove the HTML content from the given input, and un-html-ize the rest.
*
* @param html
* the HTML-encoded content
*
* @return the HTML-free equivalent content
*/
public static String unhtml(String html) {
StringBuilder builder = new StringBuilder();
int inTag = 0;
for (char car : html.toCharArray()) {
if (car == '<') {
inTag++;
} else if (car == '>') {
inTag--;
} else if (inTag <= 0) {
builder.append(car);
}
}
char nbsp = ' '; // non-breakable space (a special char)
char space = ' ';
return HtmlEscape.unescapeHtml(builder.toString()).replace(nbsp, space);
}
/**
* Escape the given {@link String} so it can be used in XML, as content.
*
* @param input
* the input {@link String}
*
* @return the escaped {@link String}
*/
public static String xmlEscape(String input) {
if (input == null) {
return "";
}
return HtmlEscape.escapeHtml(input,
HtmlEscapeType.HTML4_NAMED_REFERENCES_DEFAULT_TO_HEXA,
HtmlEscapeLevel.LEVEL_1_ONLY_MARKUP_SIGNIFICANT);
}
/**
* Escape the given {@link String} so it can be used in XML, as text content
* inside double-quotes.
*
* @param input
* the input {@link String}
*
* @return the escaped {@link String}
*/
public static String xmlEscapeQuote(String input) {
if (input == null) {
return "";
}
return HtmlEscape.escapeHtml(input,
HtmlEscapeType.HTML4_NAMED_REFERENCES_DEFAULT_TO_HEXA,
HtmlEscapeLevel.LEVEL_1_ONLY_MARKUP_SIGNIFICANT);
}
/**
* Zip the data and then encode it into Base64.
*
* @deprecated use {@link StringUtils#base64(byte[], boolean)} with the
* correct parameter instead
*
* @param data
* the data
*
* @return the Base64 zipped version
*/
@Deprecated
public static String zip64(String data) {
try {
return Base64.encodeBytes(data.getBytes("UTF-8"), Base64.GZIP);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* Unconvert from Base64 then unzip the content.
*
* @deprecated use {@link StringUtils#unbase64s(String, boolean)} with the
* correct parameter instead
*
* @param data
* the data in Base64 format
*
* @return the raw data
*
* @throws IOException
* in case of I/O error
*/
@Deprecated
public static String unzip64(String data) throws IOException {
ByteArrayInputStream in = new ByteArrayInputStream(Base64.decode(data,
Base64.GZIP));
Scanner scan = new Scanner(in);
scan.useDelimiter("\\A");
try {
return scan.next();
} finally {
scan.close();
}
}
/**
* Convert the given data to Base64 format.
*
* @param data
* the data to convert
* @param zip
* TRUE to also compress the data in GZIP format; remember that
* compressed and not-compressed content are different; you need
* to know which is which when decoding
*
* @return the Base64 {@link String} representation of the data
*
* @throws IOException
* in case of I/O errors
*/
public static String base64(String data, boolean zip) throws IOException {
return base64(data.getBytes("UTF-8"), zip);
}
/**
* Convert the given data to Base64 format.
*
* @param data
* the data to convert
* @param zip
* TRUE to also compress the data in GZIP format; remember that
* compressed and not-compressed content are different; you need
* to know which is which when decoding
*
* @return the Base64 {@link String} representation of the data
*
* @throws IOException
* in case of I/O errors
*/
public static String base64(byte[] data, boolean zip) throws IOException {
return Base64.encodeBytes(data, zip ? Base64.GZIP : Base64.NO_OPTIONS);
}
/**
* Convert the given data to Base64 format.
*
* @param data
* the data to convert
* @param zip
* TRUE to also uncompress the data from a GZIP format; take care
* about this flag, as it could easily cause errors in the
* returned content or an {@link IOException}
* @param breakLines
* TRUE to break lines on every 76th character
*
* @return the Base64 {@link String} representation of the data
*
* @throws IOException
* in case of I/O errors
*/
public static OutputStream base64(OutputStream data, boolean zip,
boolean breakLines) throws IOException {
OutputStream out = new Base64.OutputStream(data,
breakLines ? Base64.DO_BREAK_LINES & Base64.ENCODE
: Base64.ENCODE);
if (zip) {
out = new java.util.zip.GZIPOutputStream(out);
}
return out;
}
/**
* Convert the given data to Base64 format.
*
* @param data
* the data to convert
* @param zip
* TRUE to also uncompress the data from a GZIP format; take care
* about this flag, as it could easily cause errors in the
* returned content or an {@link IOException}
* @param breakLines
* TRUE to break lines on every 76th character
*
* @return the Base64 {@link String} representation of the data
*
* @throws IOException
* in case of I/O errors
*/
public static InputStream base64(InputStream data, boolean zip,
boolean breakLines) throws IOException {
if (zip) {
data = new java.util.zip.GZIPInputStream(data);
}
return new Base64.InputStream(data, breakLines ? Base64.DO_BREAK_LINES
& Base64.ENCODE : Base64.ENCODE);
}
/**
* Unconvert the given data from Base64 format back to a raw array of bytes.
*
* @param data
* the data to unconvert
* @param zip
* TRUE to also uncompress the data from a GZIP format; take care
* about this flag, as it could easily cause errors in the
* returned content or an {@link IOException}
*
* @return the raw data represented by the given Base64 {@link String},
* optionally compressed with GZIP
*
* @throws IOException
* in case of I/O errors
*/
public static byte[] unbase64(String data, boolean zip) throws IOException {
return Base64.decode(data, zip ? Base64.GZIP : Base64.NO_OPTIONS);
}
/**
* Unconvert the given data from Base64 format back to a raw array of bytes.
*
* @param data
* the data to unconvert
* @param zip
* TRUE to also uncompress the data from a GZIP format; take care
* about this flag, as it could easily cause errors in the
* returned content or an {@link IOException}
* @param breakLines
* TRUE to break lines on every 76th character
*
* @return the raw data represented by the given Base64 {@link String}
*
* @throws IOException
* in case of I/O errors
*/
public static OutputStream unbase64(OutputStream data, boolean zip,
boolean breakLines) throws IOException {
OutputStream out = new Base64.OutputStream(data,
breakLines ? Base64.DO_BREAK_LINES & Base64.ENCODE
: Base64.ENCODE);
if (zip) {
out = new java.util.zip.GZIPOutputStream(out);
}
return out;
}
/**
* Unconvert the given data from Base64 format back to a raw array of bytes.
*
* @param data
* the data to unconvert
* @param zip
* TRUE to also uncompress the data from a GZIP format; take care
* about this flag, as it could easily cause errors in the
* returned content or an {@link IOException}
* @param breakLines
* TRUE to break lines on every 76th character
*
* @return the raw data represented by the given Base64 {@link String}
*
* @throws IOException
* in case of I/O errors
*/
public static InputStream unbase64(InputStream data, boolean zip,
boolean breakLines) throws IOException {
if (zip) {
data = new java.util.zip.GZIPInputStream(data);
}
return new Base64.InputStream(data, breakLines ? Base64.DO_BREAK_LINES
& Base64.ENCODE : Base64.ENCODE);
}
/**
* Unonvert the given data from Base64 format back to a {@link String}.
*
* @param data
* the data to unconvert
* @param zip
* TRUE to also uncompress the data from a GZIP format; take care
* about this flag, as it could easily cause errors in the
* returned content or an {@link IOException}
*
* @return the {@link String} represented by the given Base64 {@link String}
* , optionally compressed with GZIP
*
* @throws IOException
* in case of I/O errors
*/
public static String unbase64s(String data, boolean zip) throws IOException {
ByteArrayInputStream in = new ByteArrayInputStream(unbase64(data, zip));
Scanner scan = new Scanner(in, "UTF-8");
scan.useDelimiter("\\A");
try {
return scan.next();
} finally {
scan.close();
}
}
/**
* The "remove accents" pattern.
*
* @return the pattern, or NULL if a problem happens
*/
private static Pattern getMarks() {
try {
return Pattern
.compile("[\\p{InCombiningDiacriticalMarks}\\p{IsLm}\\p{IsSk}]+");
} catch (Exception e) {
// Can fail on Android...
return null;
}
}
//
// justify List
* Note that we consider an empty line as full, and a line ending with
* spaces as not complete.
*
* @param line
* the line to check
*
* @return TRUE if it does
*/
static private boolean isFullLine(StringBuilder line) {
if (line.length() == 0) {
return true;
}
char lastCar = line.charAt(line.length() - 1);
switch (lastCar) {
case '.': // points
case '?':
case '!':
case '\'': // quotes
case '‘':
case '’':
case '"': // double quotes
case '”':
case '“':
case '»':
case '«':
return true;
default:
return false;
}
}
/**
* Check if this line represent an item in a list or description (i.e.,
* check that the first non-space char is "-").
*
* @param line
* the line to check
*
* @return TRUE if it is
*/
static private boolean isItemLine(String line) {
String spacing = getItemSpacing(line);
return spacing != null && !spacing.isEmpty()
&& line.charAt(spacing.length()) == '-';
}
/**
* Return all the spaces that start this line (or Empty if none).
*
* @param line
* the line to get the starting spaces from
*
* @return the left spacing
*/
static private String getItemSpacing(String line) {
int i;
for (i = 0; i < line.length(); i++) {
if (line.charAt(i) != ' ') {
return line.substring(0, i);
}
}
return "";
}
/**
* This line is an horizontal spacer line.
*
* @param line
* the line to test
*
* @return TRUE if it is
*/
static private boolean isHrLine(CharSequence line) {
int count = 0;
if (line != null) {
for (int i = 0; i < line.length(); i++) {
char car = line.charAt(i);
if (car == ' ' || car == '\t' || car == '*' || car == '-'
|| car == '_' || car == '~' || car == '=' || car == '/'
|| car == '\\') {
count++;
} else {
return false;
}
}
}
return count > 2;
}
}