/*
* Copyright 2013
*
* @author Devin S. Olson (dolson@czarnowski.com)
*
* Licensed 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.openntf.domino.utils;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.Vector;
import java.util.regex.Pattern;
import org.openntf.arpa.ISO;
import org.openntf.domino.Document;
import org.openntf.domino.Name;
import org.openntf.domino.Session;
import org.openntf.domino.WrapperFactory;
import org.openntf.domino.utils.Factory.SessionType;
/**
* String Utilities
*
* @author Devin S. Olson (dolson@czarnowski.com)
*
*/
public enum Strings {
;
/*
* **************************************************************************
* **************************************************************************
*
* PUBLIC STATIC properties
*
* **************************************************************************
* **************************************************************************
*/
public static final String CHARSET_NAME = "UTF-8";
// <ALT> + 0216 on numeric keypad
public static final String DEFAULT_DELIMITER = "~";
public static final String MESSAGE_DIGEST_ALGORYTHM = "MD5";
public static final String MESSAGE_FORMULA_INVALID = "The Formula syntax is invalid. ";
public static final String REGEX_PIPE = "\\|";
public static final Pattern PATTERN_PIPE = Pattern.compile(REGEX_PIPE);
public static final String REGEX_NEWLINE = "\\r?\\n";
public static final Pattern PATTERN_NEWLINE = Pattern.compile(REGEX_NEWLINE);
public static final String REGEX_BEGIN_NOCASE = "(?i)^";
public static final Pattern PATTERN_BEGIN_NOCASE = Pattern.compile(REGEX_BEGIN_NOCASE);
public static final String REGEX_MONTH = "(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May?|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)";
public static final String REGEX_DAYOFWEEK = "(?:Sun(?:day)?|Mon(?:day)?|Tue(?:sday)?|Wed(?:nesday)?|Thu(?:rsday)?|Fri(?:day)?|Sat(?:urday)?)";
public static final String REGEX_9_1 = "\\d{1}";
public static final String REGEX_9_2 = "\\d{2}";
public static final String REGEX_9_3 = "\\d{3}";
public static final String REGEX_9_4 = "\\d{4}";
public static final String REGEX_9_5 = "\\d{5}";
public static final String REGEX_9_6 = "\\d{6}";
public static final String REGEX_9_7 = "\\d{7}";
public static final String REGEX_9_8 = "\\d{8}";
public static final String REGEX_9_9 = "\\d{9}";
public static final String REGEX_ampm = "[ap]m";
public static final String REGEX_TIMEZONE = "[a-z]{3}";
public static final String REGEX_HHmm = Strings.join(":", Strings.REGEX_9_2, Strings.REGEX_9_2);
public static final String REGEX_HHmmss = Strings.join(":", Strings.REGEX_9_2, Strings.REGEX_9_2, Strings.REGEX_9_2);
public static final String REGEX_END = "$";
public static final String REGEX_DATEONLY = Strings.join(" ", Strings.REGEX_9_2, Strings.REGEX_MONTH, Strings.REGEX_9_4);
public static final String REGEX_TIMEONLY = Strings.join(" ", Strings.REGEX_HHmm, Strings.REGEX_ampm);
public static final String REGEX_DEFAULT = Strings.join(" ", Strings.REGEX_DATEONLY, Strings.REGEX_TIMEONLY, Strings.REGEX_TIMEZONE);
public static final String REGEX_DAYMONTH_NAMES = Strings.join(" ", Strings.REGEX_DAYOFWEEK, Strings.REGEX_DATEONLY,
Strings.REGEX_HHmmss, Strings.REGEX_ampm, Strings.REGEX_TIMEZONE);
public static final String REGEX_MILITARY = Strings.join(" ", Strings.REGEX_9_8, Strings.REGEX_HHmmss + ",", Strings.REGEX_TIMEZONE);
public static final String REGEX_MEDDATE = "\\d+/\\d+/\\d{4}";
public static final String REGEX_SHORTDATE = "\\d+/\\d+/\\d+";
public static final String REGEX_SIMPLETIME = Strings.REGEX_9_4 + Strings.REGEX_ampm;
public static final String TIMESTAMP_DATEONLY = "dd MMM yyyy";
public static final String TIMESTAMP_TIMEONLY = "HH:mm aa";
public static final String TIMESTAMP_DEFAULT = "dd MMM yyyy hh:mm aa zzz";
public static final String TIMESTAMP_DAYMONTH_NAMES = "EEE, dd MMM yyyy HH:mm:ss aa zzz";
public static final String TIMESTAMP_MEDDATE = "MM/dd/yyyy";
public static final String TIMESTAMP_MILITARY = "yyyyMMdd HHmm:ss, zzz";
public static final String TIMESTAMP_SHORTDATE = "MM/dd/yy";
public static final String TIMESTAMP_SIMPLETIME = "HHmmaa";
public static enum IDTYPE {
BLANK, REPLICA, NOTE, UNIVERSAL;
@Override
public String toString() {
return this.name();
}
public String getInfo() {
return this.getDeclaringClass() + "." + this.getClass() + ":" + this.name();
}
};
/*
* ************************************************************************
* ************************************************************************
*
* PUBLIC Methods
*
* ************************************************************************
* ************************************************************************
*/
/**
* Gets or generates a Vector of Strings from an Object
*
* @param object
* Object from which to get or generate the result. Attempts to retrieve the string values from the object.
*
* @return Vector of Strings retrieved or generated from the input. Returns null on error.
*
*/
public static Vector<String> getVectorizedStrings(final Object object) {
final List<String> al = CollectionUtils.getListStrings(object);
return ((null == al) || (al.size() < 1)) ? null : new Vector<String>(al);
}
/**
* Generates a properly formatted String which can be used as an Environment Variable name.
*
* Returns trimmed identifier converted to all uppercase with spaces converted to underscores.
*
* @param identifier
* String from which to generate an Environment Variable name.
*
* @return Environment Variable name generated from identifier. Empty string "" if blank.
*/
public static String getEnvarName(final String identifier) {
return (Strings.isBlankString(identifier)) ? "" : identifier.trim().toUpperCase().replaceAll(" ", "_");
}
/**
* Determines if a specified id is a potential id based upon the specified idType.
*
* @param id
* String to check if potential ID for type.
* @param idType
* Type of id for which to check id.
* @return Flag indicating if the specified id is an allowed potential id for the specified type.
*/
public static boolean isPotentialID(final String id, final IDTYPE idType) {
try {
if (null == id) {
return IDTYPE.BLANK.equals(idType);
}
if (IDTYPE.UNIVERSAL.equals(idType)) {
return ((32 == id.length()) && Strings.isHexadecimalString(id));
}
if (IDTYPE.NOTE.equals(idType)) {
boolean result = ((id.length() > 0) && (id.length() <= 8));
if (result) {
return Strings.isHexadecimalString(id);
}
if ((id.length() > 2) && ("NT".equalsIgnoreCase(id.substring(0, 1)))) {
result = Strings.isPotentialID(id.substring(2), idType);
}
return result;
}
if (IDTYPE.REPLICA.equals(idType)) {
return ((16 == id.length()) && Strings.isHexadecimalString(id));
}
if (IDTYPE.BLANK.equals(idType)) {
return (Strings.isBlankString(id));
}
throw new IllegalArgumentException("Unsupported IDTYPE");
} catch (final Exception e) {
DominoUtils.handleException(e);
}
return false;
}
/**
* Generates a UniversalID from a String
*
* wrapper method for {@link #getHash(String)}
*
* @param string
* Source from which to generate the UniversalID.
*
* @return UniversalID (MD5 Message Digest Hash)
*
* @see #getHash(String)
*/
public static String generateUniversalID(final String string) {
return Strings.getHash(string);
}
/**
* Generates a RecordID from a Name
*
* Format: Name.idPrefix (4 Alpha characters) + "-" + Dates.TimeCode (6 character base36 value representing the time).
*
* wrapper method for {@link #getSpawnedRecordID(Name)}
*
* @param name
* Name for which to generate a RecordID
*
* @return new RecordID
*
* @see #generateRecordID(Name)
*/
public static String generateRecordID(final Name name) {
return Strings.getSpawnedRecordID(name);
}
/**
* Generates a RecordID from a Name
*
* Format: Name.idPrefix (4 Alpha characters) + "-" + Dates.TimeCode (6 character base36 value representing the time).
*
* wrapper method for {@link #getSpawnedRecordID(Session)}
*
* @return new RecordID
*
* @see #generateRecordID()
*/
public static String generateRecordID() {
return Strings.getSpawnedRecordID(Factory.getSession(SessionType.CURRENT));
}
/**
* Generates a Hash from a string.
*
* Uses the MD5 Message Digest Algorythm.
*
* @param string
* Source from which to generate the hash.
* @return MD5 Message Digest Hash
*
* @see #md5Hex(String)
*/
public static String getHash(final String string) {
return (Strings.isBlankString(string)) ? "" : Strings.md5Hex(string);
}
/**
* Generates a String filled with a specific character.
*
* @param length
* The length of the String to return. Negative values will be treated as positive.
*
* @param c
* Character with which to populate the result.
*
* @return String consisting c characters repeated length times.
*/
public static String getFilledString(final int length, final char c) {
if (0 == length) {
return "";
}
final int abslen = Math.abs(length);
final StringBuilder sb = new StringBuilder(abslen);
for (int i = 0; i < abslen; i++) {
sb.append(c);
}
return sb.toString();
}
/**
* Generates a Proper Case (first character capitalized, all other characters unchanged) string from an input string.
*
* @param string
* Source string for which to generate a Proper Case string.
*
* @return Proper Case string from the specified source string.
*/
public static String toProperCase(final String string) {
return isBlankString(string) ? "" : string.substring(0, 1).toUpperCase() + string.substring(1).toLowerCase();
}
/**
* NTF: DO NOT REMOVE. WHILE THIS SEEMS REDUNDANT, SSJS/EL WILL NOT FIND A CHARSEQUENCE Determines whether a String consists only of
* "White Spaces" (or is null or empty)
*
* @param cs
* The String to test
*
* @return true if it does
*/
public static boolean isBlankString(final String str) {
return isBlankString((CharSequence) str);
}
/**
* Determines whether a CharSequence consists only of "White Spaces" (or is null or empty)
*
* @param cs
* The CharSequence to test
*
* @return true if it does
*/
public static boolean isBlankString(final CharSequence cs) {
if (cs == null) {
return true;
}
return ISO.isBlankString(cs.toString());
}
/**
* Determines if a string is null or blank
*
* @param o
* Source string to check for null or blank value.
*
* @return Flag indicating if the source string is null or blank.
*/
public static boolean isBlankString(final Object o) {
return ISO.isBlankString(getString(o));
}
/**
* Determines if a specified object is a Hexadecimal string (comprised of characters 0-9 or A-F, case insensitive)
*
* @param o
* Object to check.
* @return true if it is
*/
public static boolean isHexadecimalString(final Object o) {
if (o == null) {
return false;
}
if (o instanceof CharSequence) {
return isHexadecimalString((CharSequence) o);
}
throw new RuntimeException("Cannot check for hexidecimal on a non-null object of type " + o.getClass().getName());
}
private static final Pattern PatternHexadecimal = Pattern.compile("^[A-Fa-f0-9]+$");
/**
* Determines if a specified string is a Hexadecimal string (comprised of characters 0-9 or A-F, case insensitive)
*
* @param cs
* Source string to check.
* @return Flag indicating if string is comprised only of Hexadecimal characters.
*/
public static boolean isHexadecimalString(final CharSequence cs) {
return Strings.isBlankString(cs) ? false : PatternHexadecimal.matcher(cs).matches();
}
/**
* Joins elements into a String using a specified delimiter.
*
* Concatenates the string values of elements from collection using a specified delimiter
*
* @param source
* Collection to join
*
* @param delimiter
* String used to delimit elements in source
*
* @return String values of all elements in source concatenated by delimiter
*/
@SuppressWarnings({ "rawtypes", "cast" })
public static String join(final Collection source, final String delimiter) {
if ((null != source) && (source.size() > 0)) {
final StringBuilder stringbuilder = new StringBuilder();
if (source.iterator().next() instanceof Object) {
// treat as an object
for (final Object o : source) {
stringbuilder.append(o.toString() + delimiter);
}
} else {
// treat as a primitive
final Iterator it = source.iterator();
while (it.hasNext()) {
stringbuilder.append(String.valueOf(it.next()) + delimiter);
}
}
return stringbuilder.substring(0, stringbuilder.lastIndexOf(delimiter));
}
return "";
}
public static String join(final String[] source, final String delimiter) {
if ((null != source) && (source.length > 0)) {
final StringBuilder stringbuilder = new StringBuilder();
for (int i = 0; i < source.length; i++) {
stringbuilder.append(source[i]);
if (i < source.length) {
stringbuilder.append(delimiter);
}
}
return stringbuilder.toString();
}
return "";
}
/**
* Joins elements into a String using a specified delimiter.
*
* Concatenates the string values of elements from collection using a specified delimiter
*
* @param delimiter
* String used to delimit elements in source
*
* @param objects
* Objects to join
*
* @return String values of all elements in source concatenated by delimiter
*/
public static String join(final String delimiter, final Object... objects) {
final StringBuilder stringbuilder = new StringBuilder();
if (Strings.isBlankString(delimiter)) {
for (final Object o : objects) {
stringbuilder.append(o.toString());
}
return stringbuilder.toString();
} else {
for (final Object o : objects) {
stringbuilder.append(o.toString() + delimiter);
}
return stringbuilder.substring(0, stringbuilder.lastIndexOf(delimiter));
}
}
/**
* Joins elements into a String using a specified delimiter.
*
* Concatenates the string values of elements from an array or collection using a specified delimiter
*
* @param source
* Array or Collection to join
*
* @param delimiter
* String used to delimit elements
*
* @return String values of all elements in source concatenated by delimiter
*/
@SuppressWarnings("rawtypes")
public static String join(final Object source, final String delimiter) {
if (null != source) {
if (source instanceof Collection) {
return Strings.join((Collection) source, delimiter);
}
final String classname = source.getClass().getName();
if (classname.equalsIgnoreCase("java.lang.String[]") || classname.equalsIgnoreCase("[Ljava.lang.String;")) {
final StringBuilder stringbuilder = new StringBuilder();
if (Strings.isBlankString(delimiter)) {
for (final String s : (String[]) source) {
stringbuilder.append(s + delimiter);
}
return stringbuilder.toString();
} else {
for (final String s : (String[]) source) {
stringbuilder.append(s + delimiter);
}
return stringbuilder.substring(0, stringbuilder.lastIndexOf(delimiter));
} // if (Strings.isBlankString(delimiter))
} else {
return Strings.join(CollectionUtils.getStringArray(source), delimiter);
}
}
return "";
}
/**
* Removes all blank spaces from a specified StringBuilder object.
*
* @param sb
* StringBuilder object from which to remove all blank spaces.
* @return StringBuilder object with all blank spaces removed.
*/
public static StringBuilder removeBlankSpace(final StringBuilder sb) {
if (null != sb) {
int currentEnd = -1;
for (int i = sb.length() - 1; i >= 0; i--) {
if (Character.isWhitespace(sb.charAt(i))) {
if (currentEnd == -1) {
currentEnd = i + 1;
}
} else {
// Moved from whitespace to non-whitespace
if (currentEnd != -1) {
sb.delete(i + 1, currentEnd);
currentEnd = -1;
}
}
}
// All leading whitespace
if (currentEnd != -1) {
sb.delete(0, currentEnd);
}
}
return sb;
}
/**
* Returns the substring to the left of the specified substring in the specified String, starting from the left.
*
* @param source
* String within which to search for searchFor
*
* @param searchFor
* String to search for within source
*
* @return Substring to the left of the specified substring in the specified String, starting from the left.
*/
public static String left(final String source, final String searchFor) {
final int idx = (Strings.isBlankString(source) || Strings.isBlankString(searchFor)) ? -1 : source.indexOf(searchFor);
return (idx > -1) ? source.substring(0, idx) : "";
}
/**
* Returns the substring to the left of the specified substring in the specified String, starting from the right.
*
* @param source
* String within which to search for searchFor
*
* @param searchFor
* String to search for within source
*
* @return Substring to the left of the specified substring in the specified String, starting from the right.
*/
public static String leftBack(final String source, final String searchFor) {
final int idx = (Strings.isBlankString(source) || Strings.isBlankString(searchFor)) ? -1 : source.lastIndexOf(searchFor);
return (idx > -1) ? source.substring(0, idx) : "";
}
/**
* Returns the substring to the right of the specified substring in the specified String, starting from the left.
*
* @param source
* String within which to search for searchFor
*
* @param searchFor
* String to search for within source
*
* @return Substring to the right of the specified substring in the specified String, starting from the left.
*/
public static String right(final String source, final String searchFor) {
final int idx = (Strings.isBlankString(source) || Strings.isBlankString(searchFor)) ? -1 : source.indexOf(searchFor);
return (idx > -1) ? source.substring(idx + 1) : "";
}
/**
* Returns the substring to the right of the specified substring in the specified String, starting from the right.
*
* @param source
* String within which to search for searchFor
*
* @param searchFor
* String to search for within source
*
* @return Substring to the right of the specified substring in the specified String, starting from the right.
*/
public static String rightBack(final String source, final String searchFor) {
final int idx = (Strings.isBlankString(source) || Strings.isBlankString(searchFor)) ? -1 : source.lastIndexOf(searchFor);
return (idx > -1) ? source.substring(idx + 1) : "";
}
/**
* Returns the substring to the left of the specified substring in the specified String, starting from the left.
*
* @param source
* String within which to search for searchFor
*
* @param searchFor
* String to search for within source
*
* @return Substring to the left of the specified substring in the specified String, starting from the left.
*/
public static String left(final String source, final char searchFor) {
final int idx = (Strings.isBlankString(source)) ? -1 : source.indexOf(searchFor);
return (idx > -1) ? source.substring(0, idx) : "";
}
/**
* Returns the substring to the left of the specified substring in the specified String, starting from the right.
*
* @param source
* String within which to search for searchFor
*
* @param searchFor
* String to search for within source
*
* @return Substring to the left of the specified substring in the specified String, starting from the right.
*/
public static String leftBack(final String source, final char searchFor) {
final int idx = (Strings.isBlankString(source)) ? -1 : source.lastIndexOf(searchFor);
return (idx > -1) ? source.substring(0, idx) : "";
}
/**
* Returns the substring to the right of the specified substring in the specified String, starting from the left.
*
* @param source
* String within which to search for searchFor
*
* @param searchFor
* String to search for within source
*
* @return Substring to the right of the specified substring in the specified String, starting from the left.
*/
public static String right(final String source, final char searchFor) {
final int idx = (Strings.isBlankString(source)) ? -1 : source.indexOf(searchFor);
return (idx > -1) ? source.substring(idx + 1) : "";
}
/**
* Returns the substring to the right of the specified substring in the specified String, starting from the right.
*
* @param source
* String within which to search for searchFor
*
* @param searchFor
* String to search for within source
*
* @return Substring to the right of the specified substring in the specified String, starting from the right.
*/
public static String rightBack(final String source, final char searchFor) {
final int idx = (Strings.isBlankString(source)) ? -1 : source.lastIndexOf(searchFor);
return (idx > -1) ? source.substring(idx + 1) : "";
}
/**
* Strips all non-alphanumeric characters from a source string.
*
* Alphanumeric is defined as all characters from A-Z, a-z, and 0-9
*
* @param source
* String from which to strip the non-alphanumeric characters.
* @return source with all non-alphanumeric characters removed.
*/
public static String getAlphanumericOnly(final String source) {
return (null == source) ? "" : source.trim().replaceAll("[^A-Za-z0-9]", "");
}
/**
* Checks a String to determine if it begins with a prefix.
*
* Performs a Case-INSENSITIVE check.
*
* <strong>Special Behavior</strong>: Returns false if source or prefix are null.
*
* @param source
* CharSequence to check if begins with prefix.
*
* @param prefix
* CharSequence to match against the beginning of source.
*
* @return Flag indicating if source begins with prefix.
*/
public static boolean startsWithIgnoreCase(final CharSequence source, final CharSequence prefix) {
// return source.toLowerCase().startsWith(prefix.toLowerCase());
// Of source, this works for Strings, but the variant below is cheaper
if (null == source || null == prefix) {
return false;
}
int sz = prefix.length();
if (sz > source.length()) {
return false;
}
for (int i = 0; i < sz; i++) {
if (Character.toLowerCase(source.charAt(i)) != Character.toLowerCase(prefix.charAt(i))) {
return false;
}
}
return true;
}
/**
* Generates a RecordID from a Name
*
* Format: Name.idPrefix (4 Alpha characters) + "-" + Dates.TimeCode (6 character base36 value representing the time).
*
* @param name
* Name for which to generate a RecordID
*
* @return new RecordID
*
* @see Name#getIDprefix()
* @see Dates#getTimeCode()
*
*/
public static String getSpawnedRecordID(final Name name) {
try {
if (null == name) {
throw new IllegalArgumentException("NameHandle is null");
}
String result = name.getIDprefix() + "-" + Dates.getTimeCode();
// RPr: Dates.getTimeCode() does not produce duplicates any more
// try {
// // avoid potential duplicate consecutive results by sleeping for 1/4 second
// Thread.sleep(5); // 5 millis
// } catch (InterruptedException ex) {
// Thread.currentThread().interrupt();
// DominoUtils.handleException(ex);
// }
return result;
} catch (final Exception e) {
DominoUtils.handleException(e);
}
return "";
}
/**
* Generates a RecordID from a Name
*
* Format: Name.idPrefix (4 Alpha characters) + "-" + Dates.TimeCode (6 character base36 value representing the time).
*
* @param name
* Name for which to generate a RecordID
*
* @return new RecordID
*
* @see Name#getIDprefix()
* @see Dates#getTimeCode()
*
*/
public static String getSpawnedRecordID(final lotus.domino.Name name) {
WrapperFactory wf = Factory.getWrapperFactory();
return Strings.getSpawnedRecordID(wf.fromLotus(name, Name.SCHEMA, null));
}
/**
* Generates a RecordID from a Name
*
* Format: Name.idPrefix (4 Alpha characters) + "-" + Dates.TimeCode (6 character base36 value representing the time).
*
* @param session
* Session from which to get the current effective user name.
*
* @return new RecordID
*
* @see Name#getIDprefix()
* @see Dates#getTimeCode()
*
*/
public static String getSpawnedRecordID(final Session session) {
try {
if (null == session) {
throw new IllegalArgumentException("Session is null");
}
return Strings.getSpawnedRecordID(session.createName(session.getEffectiveUserName()));
} catch (final Exception e) {
DominoUtils.handleException(e);
}
return "";
}
/**
* Generates a List of Strings from a source String.
*
* Breaks the source string at all br and at the ends of div and p elements.
*
* @param source
* String from which to generate the list.
*
* @return List constructed of source segments.
*/
public static List<String> getTextLinesRemoveHTMLtags(final String source) {
final List<String> result = new ArrayList<String>();
try {
if (!Strings.isBlankString(source)) {
final String stripped = source.replaceAll("<br></div><div>", "<br>").replaceAll("</p></div><div>", "</p>");
final String searchfor = "</div><div>|<br>|</p>";
final String[] chunks = stripped.split(searchfor);
if ((null == chunks) || (chunks.length < 1)) {
return CollectionUtils.getListStrings(Strings.stripHTMLtags(source));
} else {
for (final String s : chunks) {
result.add(Strings.stripHTMLtags(s));
}
}
}
} catch (final Exception e) {
DominoUtils.handleException(e);
}
return result;
}
/**
* Wraps String elements of a collection with a prefix and suffix string
*
* @param collection
* AbstractCollection from which to get or generate the result.
* @param prefix
* String to prepend each returned element.
* @param suffix
* String to append each returned element.
*
* @return List of Strings retrieved or generated from the input. Returns null on error.
*/
@SuppressWarnings({ "rawtypes", "cast" })
public static List<String> wrapStringElements(final AbstractCollection collection, final String prefix, final String suffix) {
try {
final String prepend = Strings.isBlankString(prefix) ? "" : prefix;
final String append = Strings.isBlankString(suffix) ? "" : suffix;
if ((null != collection) && (collection.size() > 0)) {
final List<String> result = new ArrayList<String>();
if (collection.iterator().next() instanceof Object) {
// treat as an object
for (final Object o : collection) {
result.add(prepend + o.toString() + append);
}
} else {
// treat as a primitive
final Iterator it = collection.iterator();
while (it.hasNext()) {
result.add(prepend + String.valueOf(it.next()) + append);
}
}
return result;
}
} catch (final Exception e) {
DominoUtils.handleException(e);
}
return null;
}
/**
* Strips all HTML tags from a source string.
*
* @param source
* String from which to strip HTML tags.
*
* @return source with all HTML tags removed.
*/
public static String stripHTMLtags(final String source) {
return (Strings.isBlankString(source)) ? "" : source.replaceAll("\\<.*?>", "");
}
/**
* Gets an HTML Unordered List
*
* Converts TreeSet elements to HTML list item elements.
*
* @param source
* TreeSet containing elements to be wrapped as HTML List Items
*
* @return Concatenated HTML Unordered List
*/
public static String getHTMLunorderedList(final TreeSet<String> source) {
try {
if (null == source) {
throw new IllegalArgumentException("Source is null");
}
if (source.size() > 0) {
final StringBuilder sb = new StringBuilder("<ul>");
for (final String element : Strings.wrapStringElements(source, "<li>", "</li>")) {
sb.append(element);
}
sb.append("</ul>");
return sb.toString();
}
} catch (final Exception e) {
DominoUtils.handleException(e);
}
return "";
}
/**
* Generates an XML Node
*
* @param node
* Node name
* @param content
* Node content
*
* @return XML Node constructed from name and content
*/
public static String getXMLnode(String node, final String content) {
String result = "";
node = (null == node) ? "" : node.trim().toLowerCase();
if (0 == node.length()) {
return result;
}
// TODO: Fail if "xml" is in node
if (Strings.isBlankString(content)) {
result = "<" + node + " />";
} else {
result = "<" + node + ">" + content + "</" + node + ">";
}
return result;
}
/**
* Generates an XML Node
*
* @param node
* Node name
* @param content
* Node content
* @param attributes
* Attributes for the node.
*
* @return XML Node constructed from name, attributes and content
*/
public static String getXMLnode(String node, final String content, final Map<String, String> attribs) {
node = (null == node) ? "" : node.trim().toLowerCase();
if (0 == node.length()) {
return "";
}
// TODO: Fail if "xml" is in node
if (null == attribs) {
return Strings.getXMLnode(node, content);
}
String result = "<" + node;
for (String key : attribs.keySet()) {
if (key.trim().length() > 0) {
result += " " + key + "=\"" + attribs.get(key) + "\"";
}
} // for (String key : attribs.keySet())
if (Strings.isBlankString(content)) {
result += " />";
} else {
result += ">" + content + "</" + node + ">";
}
return result;
}
/**
* Gets the String of an object WITHOUT THROWING AN EXCEPTION.
*
* Handles null and enum instances.
*
* Null is returned as an empty string "", Enum instances return the name of the enum. If the object is an instance of String, it will
* be cast as a String and returned. Otherwise, the result of the object's toString() method will be returned.
*
* @param obj
* object for which to return the String.
*
* @return String representation the object. Empty string "" on exception.
*/
public static String getString(final Object obj) {
try {
return (null == obj) ? "" : (obj instanceof Enum<?>) ? ((Enum<?>) obj).name() : obj.toString();
} catch (final Exception e) {
DominoUtils.handleException(e, "obj: " + obj);
}
return "";
}
/*
* ************************************************************************
* ************************************************************************
*
* PROTECTED Methods
*
* ************************************************************************
* ************************************************************************
*/
/**
* Generates a Hexidecimal string from an array of bytes
*
* @param array
* bytes from which to generate the string
*
* @return Hexidecimal String generated from the input array.
*/
protected static String hex(final byte[] array) {
final StringBuffer sb = new StringBuffer();
for (byte element : array) {
sb.append(Integer.toHexString((element & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toUpperCase();
}
/**
* Generates an MD5 MessageDigest String from a source string
*
* @param string
* Source from which to generate the MessageDigest
*
* @return Generated Message Digest
*
* @see java.security.MessageDigest#digest(byte[])
*/
protected static String md5Hex(final String arg0) {
if (Strings.isBlankString(arg0)) {
return "";
}
try {
final MessageDigest md = MessageDigest.getInstance(Strings.MESSAGE_DIGEST_ALGORYTHM);
return Strings.hex(md.digest(arg0.getBytes(Strings.CHARSET_NAME)));
} catch (final NoSuchAlgorithmException e) {
DominoUtils.handleException(e);
} catch (final UnsupportedEncodingException e) {
DominoUtils.handleException(e);
}
return "";
}
@SuppressWarnings("rawtypes")
public static Vector safeEvaluate(final Session session, final String formula) {
try {
if (null == session) {
throw new IllegalArgumentException("Session is null");
}
return Strings.safeEvaluate(session, formula, null);
} catch (final Exception e) {
DominoUtils.handleException(e);
// Logger.slogException(Core.CLASSNAME, e, "formula:" + formula);
}
return null;
}
@SuppressWarnings("rawtypes")
public static Vector safeEvaluate(final Session session, final String formula, final Document context) {
String evalformula = "";
try {
if (null == session) {
throw new IllegalArgumentException("Session is null");
}
if (Strings.isBlankString(formula)) {
throw new IllegalArgumentException("Parameter is blank or null");
}
final String unicodeReplacement = "�";
evalformula = formula.replaceAll(unicodeReplacement, "\"").replaceAll(unicodeReplacement, "\"");
if (Strings.checkFormulaSyntax(session, evalformula)) {
return (null == context) ? session.evaluate(evalformula) : session.evaluate(evalformula, context);
}
} catch (final Exception e) {
DominoUtils.handleException(e);
// Logger.slogException(Core.CLASSNAME, e, "formula:" + formula);
}
return null;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static boolean checkFormulaSyntax(final Session session, final String formula) {
String syntaxformula = "";
try {
if (null == session) {
throw new IllegalArgumentException("Session is null");
}
if (Strings.isBlankString(formula)) {
throw new IllegalArgumentException("Formula is blank or null");
}
syntaxformula = "@CheckFormulaSyntax({" + formula + "})";
final Vector syntax = session.evaluate(syntaxformula);
if (syntax.get(0).toString().trim().equalsIgnoreCase("1")) {
return true;
}
String msg = Strings.MESSAGE_FORMULA_INVALID;
msg += "\n syntax.elementAt(0): \"" + syntax.get(0).toString() + "\"";
final String[] info = (String[]) syntax.toArray(new String[syntax.size()]);
for (int i = 0; i < info.length; i++) {
msg += "\n syntax.elementAt(" + i + "):" + info[i];
}
throw new IllegalArgumentException(msg);
} catch (final Exception e) {
DominoUtils.handleException(e);
// Logger.slogException(Core.CLASSNAME, e, "formula:" + formula, "syntaxformula:" + syntaxformula);
}
return false;
}
public static String asString(final Object object, final String ifNull) {
return object == null ? ifNull : TypeUtils.toString(object);
}
public static String[] asStringArray(final boolean allowBlanks, final String... args) {
String[] result = new String[args.length];
int nbCount = 0;
for (int i = 0; i < args.length; i++) {
if (args[i] != null) {
if (allowBlanks) {
result[nbCount++] = args[i];
} else {
if (args[i].length() > 0)
result[nbCount++] = args[i];
}
}
}
String[] returning = new String[nbCount];
System.arraycopy(result, 0, returning, 0, nbCount);
return returning;
}
}