Java tutorial
/* * Copyright (C) 2011-2014 Bekwam, Inc. * * 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 routines; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.CodingErrorAction; import java.util.Date; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.apache.commons.lang3.StringUtils; import org.joda.time.LocalDate; import org.joda.time.Years; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; import com.google.i18n.phonenumbers.NumberParseException; import com.google.i18n.phonenumbers.PhoneNumberUtil; import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; /** * BRules is a collection of Java methods used for validation, formatting, and * transformation. * * @author Carl2 * @since 1.0.0 */ public class BRules { private final static String ERROR_MESSAGE_LISTTYPE_ARG = "listType must be 'ul' or 'ol'"; private final static String UTF8_CHARSET = "UTF-8"; private final static int DEFAULT_PAD_SIZE = 10; private final static String DEFAULT_LIST_TO_STRING_DELIMITER = ","; /** * isPhoneNum: true if valid in accordance with country specifier; uses * strict check * * {talendTypes} String * * {Category} BRules * * {param} string("regionCode") input: The country or region code to use * {param} string("phoneNumber") input: The phone number to check * * {example} isPhoneNum("US", "(301) 555-5555") # true */ public static boolean isPhoneNum(String _countryCode, String _toValidate) { return isPhoneNum(_countryCode, _toValidate, false); } /** * isPhoneNum: true if valid in accordance with country specifier and * loose flag (false for strict) * * {talendTypes} String * * {Category} BRules * * {param} string("regionCode") input: The country or region code to use * {param} string("phoneNumber") input: The phone number to check * {param} boolean: use loose validation (true) or strict (false) * * {example} isPhoneNum("US", "(301) 555-5555") # true */ public static boolean isPhoneNum(String _countryCode, String _toValidate, boolean _loose) { boolean valid = false; PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); try { PhoneNumber pn = phoneUtil.parse(_toValidate, _countryCode); if (_loose) { valid = phoneUtil.isPossibleNumber(pn); } else { valid = phoneUtil.isValidNumber(pn); } } catch (NumberParseException ignore) { } return valid; } /** * all: true if all arguments are not empty (not null for Objects, * not null, empty string, or whitespace for java.lang.String) * * {talendTypes} String * * {Category} BRules * * {param} object() input: a variable number of params to check * * {example} all("one", "two", "") # false * {example} all("one") # true */ public static boolean all(Object... _objects) { boolean allSet = true; if (_objects == null) return false; for (Object obj : _objects) { if (obj instanceof String) { if (StringUtils.isEmpty((String) obj)) { allSet = false; break; } } else { if (obj == null) { allSet = false; break; } } } return allSet; } /** * xor: true if one and only one argument is not empty (not null for Objects, * not null, empty string, or whitespace for java.lang.String) * * {talendTypes} String * * {Category} BRules * * {param} object() input: a variable number of params to check * * {example} xor("one", "") # true * {example} xor("", "") # false */ public static boolean xor(Object... _objects) { boolean onlyOneSet = false; if (_objects == null) return false; for (Object obj : _objects) { if (obj instanceof String) { if (StringUtils.isNotEmpty((String) obj)) { if (!onlyOneSet) { onlyOneSet = true; } else { onlyOneSet = false; break; } } } else { if (obj != null) { if (!onlyOneSet) { onlyOneSet = true; } else { onlyOneSet = false; break; } } } } return onlyOneSet; } /** * isBlank: true if the string is null, the empty string, or whitespace * * {talendTypes} String * * {Category} BRules * * {param} string("hello") input : string to be tested * * {example} isBlank("hello") # false * {example} isBlank(null) # true * {example} isBlank("") # true * {example} isBlank(" ") # true * */ public static boolean isBlank(String _s) { return StringUtils.isBlank(_s); } /** * isXML: true if the passed-in string adheres to XML well-formedness * and the specified charset * * {talendTypes} String * * {Category} BRules * * {param} string("<message>hello</message>") input: xml to be tested * {param} string("ISO8859_1") input: the charset of the xml * * {example} isXML("<message>hello</message>", "ISO8859_1") # true * {example} isXML("<message>hello", "ISO8859_1") # false */ public static boolean isXML(String _xml, String _charset) throws Exception { boolean result = false; if (StringUtils.isEmpty(_xml)) return false; try { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(true); SAXParser parser = factory.newSAXParser(); InputStream is = new ByteArrayInputStream(_xml.getBytes(_charset)); parser.parse(is, new DefaultHandler()); result = true; } catch (SAXParseException ignore) { } return result; } /** * isXML: true if the passed-in string adheres to XML well-formedness * using a UTF-8 string * * {talendTypes} String * * {Category} BRules * * {param} string("<message>hello</message>") input: xml to be tested * * {example} isXML("<message>hello</message>") # true * {example} isXML("<message>hello") # false */ public static boolean isXML(String _xml) throws Exception { return isXML(_xml, UTF8_CHARSET); } /** * okChars: true if the passed-in string is valid for the specified * character set * * The supported character set values are those supported by Java. The * particular constants include "ASCII", "Cp1252", "ISO8859_1", "UTF-8". * * If the string parameter is empty or null, 'true' is returned. * * {talendTypes} String * * {Category} BRules * * {param} string("hello") input: string to be tested * {param} string("charset") input: charset of string * * {example} okChar("hello", "ISO8859_1") # true */ public static boolean okChars(String _s, String _charset) { if (StringUtils.isEmpty(_s)) { return true; } CharsetEncoder encoder = Charset.forName(_charset).newEncoder(); return encoder.canEncode(_s); } /** * toCharset: convert a string to the character set used by Windows Latin-1. * Will convert unmappable characters to a space (" ") rather than throwing * an error * * For example, this will conveniently map a \u2122 (TM) symbol to a * Windows-recognized hex 99 * * {talendTypes} String * * {Category} BRules * * {param} string(_s) input string to convert * {example} toCharset("My Product\u2122") # returns "My Product " */ public static String toCharset(String _s) { return toCharset(_s, "Cp1252"); } /** * toCharset: convert a string to the specified character set * Will convert unmappable characters to a space (" ") rather than throwing * an error * * For example, this will conveniently map a \u2122 (TM) symbol to a * Windows-recognized hex 99 * * Uses Java names for charsets: Cp1252, US-ASCII * {talendTypes} String * * {Category} BRules * * {param} string(_s) input string to convert * {param} string(_charset) character set to use for conversion * {example} toCharset("My Product\u2122", "Cp1252") # returns "My Product " */ public static String toCharset(String _s, String _charset) { String cs = (StringUtils.isEmpty(_charset)) ? "Cp1252" : _charset; return toCharset(_s, cs, " "); } /** * toCharset: convert a string to the specified character set * * Will convert unmappable characters to a specified character * * For example, this will conveniently map a \u2122 (TM) symbol to a * Windows-recognized hex 99 * * Uses Java names for charsets: Cp1252, US-ASCII, ISO-8859-1, UTF-8, UTF-16 * * {talendTypes} String * * {Category} BRules * * {param} string(_s) input string to convert * {param} string(_charset) character set to use for conversion * {param} string(_replaceCh) character to use for unmappables * {example} toCharset("My Product\u2122", "Cp1252", "?") # returns "My Product?" */ public static String toCharset(String _s, String _charset, String _replaceCh) { String s = ""; String cs = (StringUtils.isEmpty(_charset)) ? "Cp1252" : _charset; String rc = (StringUtils.isEmpty(_replaceCh)) ? " " : _replaceCh; try { CharsetEncoder enc = Charset.forName(cs).newEncoder(); enc.onUnmappableCharacter(CodingErrorAction.REPLACE); enc.replaceWith(rc.getBytes()); ByteBuffer buf = enc.encode(CharBuffer.wrap(_s)); s = new String(buf.array(), cs); } catch (Exception ignore) { } return s; } /** * isJSON: true if the passed-in string adheres to JSON format * * Not supported for JDKs < 6; will throw exception * * Empty expressions - {} and [] - will return true * * {talendTypes} String * * {Category} BRules * * {param} string("{name: 'Carl', program: 'BRules'}") input: json to be tested * * {example} isJSON("<message>hello</message>") # false * {example} isJSON("{name: 'Carl', program: 'BRules'}") # true * {example} isJSON("{}") #true * {example} isJSON(null) #false */ public static boolean isJSON(String _json) { return BRulesJSON.isJSON(_json); } /** * hasJSONPath: true if the passed-in json has elements referenced in path * * Not supported for JDKs < 6; will throw exception * * {talendTypes} String * * {Category} BRules * * {param} string("{name: 'Carl', program: 'BRules'}") input: json to be tested * * {example} hasJSONPath("<message>hello</message>") # false * {example} hasJSONPath("{name: 'Carl', program: 'BRules'}", "$.name") # true * {example} isJSON("{}") #true * {example} hasJSONPath(null) #false */ public static boolean hasJSONPath(String _json, String _path) throws Exception { return BRulesJSON.hasJSONPath(_json, _path); } /** * comma: join the string representation of objects together with a * comma * * Appends an empty string where an element is null * * {talendTypes} String * * {Category} BRules * * {param} object() input: a variable number of strings to join * * {example} comma("one", "two", "three") # "one,two,three" */ public static String comma(Object... _objects) { return join(",", _objects); } /** * join: join the string representation of objects together with a * character * * Appends an empty string where an element is null * * {talendTypes} String * * {Category} BRules * * {param} object() input: a variable number of strings to join * * {example} join("one", "two", "three") # "one,two,three" */ public static String join(String _delim, Object... _objects) { StringBuffer sb = new StringBuffer(); boolean firstPass = true; if (_objects != null) { for (Object obj : _objects) { if (!firstPass) { sb.append(_delim); } else { firstPass = false; } if (obj == null) { sb.append(""); } else { sb.append(obj.toString()); } } } return sb.toString(); } /** * ul: form an html list of the specified css style from * the list of objects * * null objects returns an empty list (ex, "<ul></ul>") * * {talendTypes} String * * {Category} BRules * * {param} styleClass : a style to apply for the toplevel list element * {param} object() input: a variable number of strings to join * * {example} ul("infolist", "a", "b") # "<ul><li>a</li><li>b</li></ul>" */ public static String ul(String _styleClass, Object... _objects) { return htmlList(_styleClass, "ul", _objects); } /** * ol: form an html list of the specified css style from * the list of objects * * null objects returns an empty list (ex, "<ol></ol>") * * {talendTypes} String * * {Category} BRules * * {param} styleClass : a style to apply for the toplevel list element * {param} object() input: a variable number of strings to join * * {example} ol("infolist", "a", "b") # "<ol><li>a</li><li>b</li></ol>" */ public static String ol(String _styleClass, Object... _objects) { return htmlList(_styleClass, "ol", _objects); } protected static String htmlList(String _styleClass, String _listType, Object... _objects) { if (_listType == null || !(_listType.equals("ul") || _listType.equals("ol"))) { throw new IllegalArgumentException(ERROR_MESSAGE_LISTTYPE_ARG); } StringBuffer sb = new StringBuffer(); if (_styleClass != null && _styleClass.length() > 0) { sb.append("<" + _listType + " class=\"" + _styleClass + "\">"); } else { sb.append("<" + _listType + ">"); } if (_objects != null) { for (Object obj : _objects) { sb.append("<li>" + ((obj == null) ? "" : obj.toString()) + "</li>"); } } sb.append("</" + _listType + ">"); return sb.toString(); } /** * p: form an html paragraph of the specified css style from * the list of objects * * null objects returns an empty list (ex, "<p></p>") * * {talendTypes} String * * {Category} BRules * * {param} styleClass : a style to apply for the toplevel list element * {param} object() input: a variable number of strings to join * * {example} p("note", "a") # "<p class=\"note\">a</p>" */ public static String p(String _styleClass, String _text) { StringBuffer sb = new StringBuffer(); if (_styleClass != null && _styleClass.length() > 0) { sb.append("<p class=\"" + _styleClass + "\">"); } else { sb.append("<p>"); } sb.append((_text == null) ? "" : _text); sb.append("</p>"); return sb.toString(); } /** * Pad a 10 character string with spaces * * If the string exceeds 10 chars, the input string will be returned * * The method is deprecated because of the limited utility in a predefined * size. * * {talendTypes} String * * {Category} BRules * * {param} pad(stringToPad) input: The string to be divided * * {example} pad("100") # " 100" */ @Deprecated public static String pad(String s) { return pad(s, DEFAULT_PAD_SIZE); } /** * Left pads the input string with spaces * * {talendTypes} String * * {Category} BRules * * {param} string(stringToPad) stringToPad: string to pad * {param} int(numPadChars) numPadChars: number of padded chars * * {example} pad("100",6) # "000100" * * @param s - input string to pad * @param size - number of chars to pad * @return padded string or input string * @since 1.0.0 */ public static String pad(String s, int size) { if (size < 0) throw new IllegalArgumentException("size must be > 0"); if (StringUtils.isEmpty(s)) return s; return StringUtils.leftPad(s, size); } /** * Left pads the input string with the specified character * * {talendTypes} String * * {Category} BRules * * {param} string(stringToPad) stringToPad: string to pad * {param} int(numPadChars) numPadChars: number of padded chars * {param} char(charToUse) charToUse: char to use as padding * * {example} pad("100", 6, '0') # "000100" * * @param s - input string to pad * @param size - number of chars to pad * @param ch - character to pad with * @return padded string or input string * @since 1.4.0 */ public static String pad(String s, int size, char ch) { if (size < 0) throw new IllegalArgumentException("size must be > 0"); if (StringUtils.isEmpty(s)) return s; return StringUtils.leftPad(s, size, ch); } /** * Left pads the input integer with the specified character * * {talendTypes} String * * {Category} BRules * * {param} int(integerToPad) integerToPad: int to pad * {param} int(numPadChars) numPadChars: number of padded chars * {param} char(charToUse) charToUse: char to use as padding * * {example} pad(100, 6, '0') # "000100" * * @param s - input string to pad * @param size - number of chars to pad * @param ch - character to pad with * @return padded string or input string * @since 1.4.0 */ public static String pad(Integer i, int size, char ch) { if (i == null) return null; return StringUtils.leftPad(String.valueOf(i), size, ch); } /** * Left pads the input long with the specified character * * {talendTypes} String * * {Category} BRules * * {param} long(integerToPad) integerToPad: int to pad * {param} long(numPadChars) numPadChars: number of padded chars * {param} char(charToUse) charToUse: char to use as padding * * {example} pad(100L, 6, '0') # "000100" * * @param s - input string to pad * @param size - number of chars to pad * @param ch - character to pad with * @return padded string or input string * @since 1.4.0 */ public static String pad(Long lng, int size, char ch) { if (lng == null) return null; return StringUtils.leftPad(String.valueOf(lng), size, ch); } /** * Right pads the input string with spaces * * {talendTypes} String * * {Category} BRules * * {param} string(stringToPad) stringToPad: string to pad * {param} int(numPadChars) numPadChars: number of padded chars * * {example} pad("100", 6) # "100 " * * @param s - input string to pad * @param size - number of chars to pad * @return padded string or input string * @since 1.4.0 */ public static String padRight(String s, int size) { if (size < 0) throw new IllegalArgumentException("size must be > 0"); if (StringUtils.isEmpty(s)) return s; return StringUtils.rightPad(s, size); } /** * Right pads the input string with the specified character * * {talendTypes} String * * {Category} BRules * * {param} string(stringToPad) stringToPad: string to pad * {param} int(numPadChars) numPadChars: number of padded chars * {param} char(charToUse) charToUse: char to use as padding * * {example} pad("100", 6, '0') # "100000" * * @param s - input string to pad * @param size - number of chars to pad * @param ch - character to pad with * @return padded string or input string * @since 1.4.0 */ public static String padRight(String s, int size, char ch) { if (size < 0) throw new IllegalArgumentException("size must be > 0"); if (StringUtils.isEmpty(s)) return s; return StringUtils.rightPad(s, size, ch); } /** * Take off leading zeros; assumes a number * * {talendTypes} String * * {Category} BRules * * {param} trimLeadingZeros(string) input: The string to be divided * */ public static String trimLeadingZeros(String num_s) { if (num_s == null || num_s.length() == 0) return ""; try { int i = Integer.parseInt(num_s); return String.valueOf(i); } catch (NumberFormatException exc) { return num_s; } } /** * Calculates age in whole years based on today's date * * {talendTypes} Integer * * {Category} BRules * * {param} date(birthDate) input: the date of birth * * @param birthDate date of birth * @return whole years of age * */ public static Integer ageInYears(Date birthDate) { return ageInYears(birthDate, new Date()); } /** * Calculates age in whole years using the specified * as of date * * Returns null if birthDate or asOfDate is null * * {talendTypes} Integer * * {Category} BRules * * {param} date(birthDate) input: the date of birth * {param} date(asOfDate) input: date used for comparison; alternative to * today * * @param birthDate date of birth * @param asOfDate date of comparison (instead of today) * @return whole years of age */ public static Integer ageInYears(Date birthDate, Date asOfDate) { if (birthDate == null || asOfDate == null) { return null; } return ageInYears(new LocalDate(birthDate), new LocalDate(asOfDate)); } /** * For internal use only * * Joda Time classes aren't exposed to the calling Talend jobs because of * library dependency management * * @param birthDate date of birth * @param asOfDate date of comparison (instead of today) * @return whole years of age */ static Integer ageInYears(LocalDate birthDate, LocalDate asOfDate) { if (birthDate == null || asOfDate == null) { return null; } Years age = Years.yearsBetween(birthDate, asOfDate); return age.getYears(); } /** * Forms a comma-separated list given the input java.util.List * * Handles different types * * Nulls are skipped, for example [A, null, B] -> A,,B * * {talendTypes} String * * {Category} BRules * * {param} list(inputList) input: the list to convert * * @param inputList list of objects of any time * @return empty string or list of values separated by comma */ public static String listToString(List<?> inputList) { return listToString(inputList, DEFAULT_LIST_TO_STRING_DELIMITER); } /** * Forms a comma-separated list given the input java.util.List using the * specified delimeter * * Handles different types * * Nulls are skipped, for example [A, null, B] -> A,,B * * {talendTypes} String * * {Category} BRules * * {param} list(inputList) input: the list to convert * {param} string(delimiter) input: delimiter to used in string separating * items * * @param inputList list of objects of any time * @return empty string or list of values separated by delimiter * */ public static String listToString(List<?> inputList, String delimiter) { return listToString(inputList, delimiter, null); } /** * Forms a comma-separated list given the input java.util.List * * Handles different types * * Nulls are skipped, for example [A, null, B] -> A,,B * * {talendTypes} String * * {Category} BRules * * {param} list(inputList) input: the list to convert * {param} string(delimiter) input: delimiter to used in string separating * items * {param} string(escapeString) input: string to wrap each item * * @param inputList list of objects of any time * @param escapeString String added to start and end of each element * @return empty string or list of values separated by comma */ public static String listToString(List<?> inputList, String delimiter, String escapeString) { StringBuffer sb = new StringBuffer(""); if (inputList == null) { return sb.toString(); } boolean initialized = false; for (Object obj : inputList) { if (initialized) { sb.append(delimiter); } else { initialized = true; } if (obj != null) { if (escapeString == null) { sb.append(String.valueOf(obj)); } else { sb.append(escapeString + String.valueOf(obj) + escapeString); } } } return sb.toString(); } }