/******************************************************************************
*
* Copyright 2014 Paphus Solutions Inc.
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
*
* 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.botlibre.sdk.util;
import java.io.StringWriter;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Utility class.
*/
public class Utils {
public static Random random = new Random();
public static Pattern httpRegex = Pattern.compile("\\b(?:https?|ftp|file):\\/\\/[a-z0-9-+&@#\\/%?=~_|!:,.;]*[a-z0-9-+&@#\\/%=~_|]", Pattern.CASE_INSENSITIVE);
public static Pattern wwwRegex = Pattern.compile("((www\\.)[^\\s]+)", Pattern.CASE_INSENSITIVE);
public static Pattern emailRegex = Pattern.compile("(([a-zA-Z0-9_\\-\\.]+)@[a-zA-Z_]+?(?:\\.[a-zA-Z]{2,6}))+", Pattern.CASE_INSENSITIVE);
/**
* Replace links with HTML links.
* Includes http, www, images, video, audio, email address.
*/
public static String linkHTML(String text) {
if (text == null || text.length() == 0) {
return "";
}
boolean http = text.indexOf("http") != -1;
boolean www = text.indexOf("www.") != -1;
boolean email = text.indexOf("@") != -1;
if (!http && !www && !email) {
return text;
}
if (text.indexOf("<") != -1 && text.indexOf(">") != -1) {
return text;
}
if (http) {
Matcher matcher = httpRegex.matcher(text);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String url = matcher.group();
if (url.indexOf(".png") != -1 || url.indexOf(".jpg") != -1 || url.indexOf(".jpeg") != -1 || url.indexOf(".gif") != -1) {
url = "<a href='" + url + "' target='_blank'><img src='" + url + "' height='50'></a>";
} else if (url.indexOf(".mp4") != -1 || url.indexOf(".webm") != -1 || url.indexOf(".ogg") != -1) {
url = "<a href='" + url + "' target='_blank'><video src='" + url + "' height='50'></a>";
} else if (url.indexOf(".wav") != -1 || url.indexOf(".mp3") != -1) {
url = "<a href='" + url + "' target='_blank'><audio src='" + url + "' controls>audio</a>";
} else {
url = "<a href='" + url + "' target='_blank'>" + url + "</a>";
}
matcher.appendReplacement(sb, url);
}
matcher.appendTail(sb);
text = sb.toString();
} else if (www) {
Matcher matcher = wwwRegex.matcher(text);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String url = matcher.group();
matcher.appendReplacement(sb, "<a href='http://" + url + "' target='_blank'>" + url + "</a>");
}
matcher.appendTail(sb);
text = sb.toString();
}
if (email) {
Matcher matcher = emailRegex.matcher(text);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String address = matcher.group();
matcher.appendReplacement(sb, "<a href='mailto://" + address + "' target='_blank'>" + address + "</a>");
}
matcher.appendTail(sb);
text = sb.toString();
}
return text;
}
/**
* Replace reserved HTML character with their HTML escape codes.
*/
public static String escapeHTML(String html) {
return html.replace("&", "&")
.replace("<", "<")
.replace(">", ">")
.replace("\"", """)
.replace("`", "`")
.replace("'", "'");
}
/**
* Strip the HTML tags from the text.
*/
public static String stripTags(String html) {
if (html == null) {
return "";
}
String result = html;
if ((html.indexOf('<') != -1) && (html.indexOf('>') != -1)) {
StringWriter writer = new StringWriter();
TextStream stream = new TextStream(html);
while (!stream.atEnd()) {
String text = stream.upTo('<');
writer.write(text);
int position = stream.getPosition();
stream.skip();
String word = stream.nextWord();
if (word != null) {
if (word.equals("p")) {
writer.write("\n\n");
} else if (word.equals("br")) {
writer.write("\n");
} else if (word.equals("div")) {
writer.write("\n");
}
stream.skipTo('>');
if (stream.atEnd()) {
stream.setPosition(position);
writer.write(stream.upToEnd());
} else {
stream.skip();
}
}
}
result = writer.toString();
}
if (result.contains("&")) {
result = result.replace(""", "\"");
result = result.replace("`", "`");
result = result.replace("'", "'");
result = result.replace("@", "@");
result = result.replace("=", "=");
result = result.replace("<", "<");
result = result.replace(">", ">");
}
return result;
}
/**
* Format the text that may be HTML, or may be text, or markup, or a mix.
*/
public static String formatHTMLOutput(String text) {
if (text == null) {
return "";
}
int index = text.indexOf('<');
int index2 = text.indexOf('>');
boolean isHTML = (index != -1) && (index2 > index);
boolean isMixed = isHTML && text.contains("[code]");
if (isHTML && !isMixed) {
return text;
}
if (!isMixed && ((index != -1) || (index2 != -1))) {
text = text.replace("<", "<");
text = text.replace(">", ">");
}
TextStream stream = new TextStream(text);
StringWriter writer = new StringWriter();
boolean bullet = false;
boolean nbullet = false;
while (!stream.atEnd()) {
String line = stream.nextLine();
if (!isMixed && (line.contains("http://") || line.contains("https://"))) {
line = Utils.linkHTML(line);
}
TextStream lineStream = new TextStream(line);
boolean firstWord = true;
boolean span = false;
boolean cr = true;
while (!lineStream.atEnd()) {
while (!isMixed && firstWord && lineStream.peek() == ' ') {
lineStream.next();
writer.write(" ");
}
String whitespace = lineStream.nextWhitespace();
writer.write(whitespace);
if (lineStream.atEnd()) {
break;
}
String word = lineStream.nextWord();
if (!isMixed && nbullet && firstWord && !word.equals("#")) {
writer.write("</ol>\n");
nbullet = false;
} else if (!isMixed && bullet && firstWord && !word.equals("*")) {
writer.write("</ul>\n");
bullet = false;
}
if (firstWord && word.equals("[")) {
String peek = lineStream.peekWord();
if ("code".equals(peek)) {
lineStream.nextWord();
String next = lineStream.nextWord();
String lang = "javascript";
int lines = 20;
if ("lang".equals(next)) {
lineStream.skip();
lang = lineStream.nextWord();
if ("\"".equals(lang)) {
lang = lineStream.nextWord();
lineStream.skip();
}
next = lineStream.nextWord();
}
if ("lines".equals(next)) {
lineStream.skip();
String value = lineStream.nextWord();
if ("\"".equals(value)) {
value = lineStream.nextWord();
lineStream.skip();
}
lineStream.skip();
try {
lines = Integer.valueOf(value);
} catch (NumberFormatException ignore) {}
}
String id = "code" + stream.getPosition();
writer.write("<div style=\"width:100%;height:" + lines * 14 + "px;max-width:none\" id=\"" + id + "\">");
String code = lineStream.upToAll("[code]");
if (code.indexOf('<') != -1) {
code = code.replace("<", "<");
}
if (code.indexOf('>') != -1) {
code = code.replace(">", ">");
}
writer.write(code);
while (lineStream.atEnd() && !stream.atEnd()) {
line = stream.nextLine();
lineStream = new TextStream(line);
while (lineStream.peek() == ':') {
lineStream.next();
writer.write(" ");
}
code = lineStream.upToAll("[code]");
if (code.indexOf('<') != -1) {
code = code.replace("<", "<");
}
if (code.indexOf('>') != -1) {
code = code.replace(">", ">");
}
writer.write(code);
}
lineStream.skip("[code]".length());
writer.write("</div>\n");
writer.write("<script>\n");
writer.write("var " + id + " = ace.edit('" + id + "');\n");
writer.write(id + ".getSession().setMode('ace/mode/" + lang + "');\n");
writer.write(id + ".setReadOnly(true);\n");
writer.write("</script>\n");
} else {
writer.write(word);
}
} else if (!isMixed && firstWord && word.equals("=")) {
int count = 2;
String token = word;
while (!lineStream.atEnd() && lineStream.peek() == '=') {
lineStream.skip();
count++;
token = token + "=";
}
String header = lineStream.upToAll(token);
if (lineStream.atEnd()) {
writer.write(token);
writer.write(header);
} else {
lineStream.skip(token.length());
writer.write("<h");
writer.write(String.valueOf(count));
writer.write(">");
writer.write(header);
writer.write("</h");
writer.write(String.valueOf(count));
writer.write(">");
cr = false;
}
} else if (!isMixed && firstWord && word.equals(":")) {
span = true;
int indent = 1;
while (!lineStream.atEnd() && lineStream.peek() == ':') {
lineStream.skip();
indent++;
}
writer.write("<span style=\"display:inline-block;text-indent:");
writer.write(String.valueOf(indent * 20));
writer.write("px;\">");
} else if (!isMixed && firstWord && word.equals("*")) {
if (!bullet) {
writer.write("<ul>");
bullet = true;
}
writer.write("<li>");
cr = false;
} else if (!isMixed && firstWord && word.equals("#")) {
if (!nbullet) {
writer.write("<ol>");
nbullet = true;
}
writer.write("<li>");
cr = false;
} else {
writer.write(word);
}
firstWord = false;
}
if (!isMixed && span) {
writer.write("</span>");
}
if (!isMixed && cr) {
writer.write("<br/>\n");
}
}
if (!isMixed && bullet) {
writer.write("</ul>");
}
if (!isMixed && nbullet) {
writer.write("</ol>");
}
return writer.toString();
}
public static String displayTimestamp(Date date) {
if (date == null) {
return "";
}
StringWriter writer = new StringWriter();
Calendar today = Calendar.getInstance();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
if (calendar.get(Calendar.YEAR) == today.get(Calendar.YEAR)
&& calendar.get(Calendar.DAY_OF_YEAR) == today.get(Calendar.DAY_OF_YEAR)) {
writer.write("Today");
} else if (calendar.get(Calendar.YEAR) == today.get(Calendar.YEAR)
&& calendar.get(Calendar.DAY_OF_YEAR) == (today.get(Calendar.DAY_OF_YEAR) - 1)) {
writer.write("Yesterday");
} else {
writer.write(calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.US));
writer.write(" ");
writer.write(String.valueOf(calendar.get(Calendar.DAY_OF_MONTH)));
if (calendar.get(Calendar.YEAR) != today.get(Calendar.YEAR)) {
writer.write(" ");
writer.write(String.valueOf(calendar.get(Calendar.YEAR)));
}
}
writer.write(", ");
writer.write(String.valueOf(calendar.get(Calendar.HOUR_OF_DAY)));
writer.write(":");
if (calendar.get(Calendar.MINUTE) < 10) {
writer.write("0");
}
writer.write(String.valueOf(calendar.get(Calendar.MINUTE)));
return writer.toString();
}
public static String displayTime(Date date) {
if (date == null) {
return "";
}
StringWriter writer = new StringWriter();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
writer.write(String.valueOf(calendar.get(Calendar.HOUR_OF_DAY)));
writer.write(":");
if (calendar.get(Calendar.MINUTE) < 10) {
writer.write("0");
}
writer.write(String.valueOf(calendar.get(Calendar.MINUTE)));
writer.write(":");
if (calendar.get(Calendar.SECOND) < 10) {
writer.write("0");
}
writer.write(String.valueOf(calendar.get(Calendar.SECOND)));
return writer.toString();
}
public static String displayDate(Date date) {
if (date == null) {
return "";
}
StringWriter writer = new StringWriter();
Calendar today = Calendar.getInstance();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
if (calendar.get(Calendar.YEAR) == today.get(Calendar.YEAR)
&& calendar.get(Calendar.DAY_OF_YEAR) == today.get(Calendar.DAY_OF_YEAR)) {
writer.write("Today");
} else if (calendar.get(Calendar.YEAR) == today.get(Calendar.YEAR)
&& calendar.get(Calendar.DAY_OF_YEAR) == (today.get(Calendar.DAY_OF_YEAR) - 1)) {
writer.write("Yesterday");
} else {
writer.write(calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.US));
writer.write(" ");
writer.write(String.valueOf(calendar.get(Calendar.DAY_OF_MONTH)));
if (calendar.get(Calendar.YEAR) != today.get(Calendar.YEAR)) {
writer.write(" ");
writer.write(String.valueOf(calendar.get(Calendar.YEAR)));
}
}
return writer.toString();
}
/**
* Capitalize the first character of the string.
*/
public static String capitalize(String text) {
if (text.length() == 0) {
return text;
}
return Character.toUpperCase(text.charAt(0)) + text.substring(1, text.length());
}
public static Random random() {
return random;
}
public static int random(int max) {
return random().nextInt(max);
}
public static <T> T random(List<T> list) {
if ((list == null) || list.isEmpty()) {
return null;
}
return list.get(random().nextInt(list.size()));
}
public static <T> T random(Collection<T> collection) {
if ((collection == null) || collection.isEmpty()) {
return null;
}
int value = random().nextInt(collection.size());
int index = 0;
for (T element : collection) {
if (index == value) {
return element;
}
index++;
}
return null;
}
}