All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aeontronix.commons.StringUtils Maven / Gradle / Ivy

Go to download

Various utility classes. Except for very rare exceptions (annotation-based validation) this will not require any dependencies beyond the JRE

The newest version!
/*
 * Copyright (c) 2015 Kloudtek Ltd
 */

package com.aeontronix.commons;

import com.aeontronix.commons.exception.UnexpectedException;
import org.jetbrains.annotations.Nullable;

import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.lang.Character.isWhitespace;
import static java.lang.Character.toTitleCase;

/**
 * 

Various string manipulation utility functions

*/ public class StringUtils { public static Pattern varSubFuncPattern; public static final String UNSAFE_URLPATH = " %$&+,/:;=?@<|>#%"; public static boolean isEmpty(String txt) { return txt == null || txt.isEmpty(); } public static boolean isNotEmpty(String txt) { return !isEmpty(txt); } public static boolean isBlank(String txt) { int strLen; if (txt == null || (strLen = txt.length()) == 0) { return true; } for (int i = 0; i < strLen; i++) { if ((!isWhitespace(txt.charAt(i)))) { return false; } } return true; } public static boolean isNotBlank(String txt) { return !isBlank(txt); } /** * URL encode a string using UTF-8 * * @param txt String to encode. * @return URL encoded string. */ public static String urlEncode(String txt) { try { return URLEncoder.encode(txt, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } /** * URL decode a string using UTF-8 * * @param txt String to decode. * @return Decoded string. */ public static String urlDecode(String txt) { try { return URLDecoder.decode(txt, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } public static String capitalize(String txt) { int len; if (txt == null || (len = txt.length()) == 0) { return txt; } return toTitleCase(txt.charAt(0)) + txt.substring(1); } public static byte[] base64Encode(byte[] data) { return base64Encode(data, false); } public static String base64EncodeToString(String data) { return base64EncodeToString(data, false); } public static String base64EncodeToString(byte[] data) { return base64EncodeToString(data, false); } /** * Base64 encode a string by converting it to bytes (using UTF8) * * @param data String to encode * @param urlSafe If true, base64url will be used instead of base64 * @return encoded string */ public static byte[] base64Encode(String data, boolean urlSafe) { return base64Encode(utf8(data), urlSafe); } public static String base64EncodeToString(String data, boolean urlSafe) { return base64EncodeToString(utf8(data), urlSafe); } public static byte[] base64Encode(byte[] data, boolean urlSafe) { return getBase64Encoder(urlSafe).encode(data); } public static String base64EncodeToString(byte[] data, boolean urlSafe) { return getBase64Encoder(urlSafe).encodeToString(data); } public static byte[] base64Decode(String data) { return base64Decode(data, false); } public static String base64DecodeToString(String data) { return base64DecodeToString(data, false); } public static byte[] base64Decode(String data, boolean urlSafe) { return getBase64Decoder(urlSafe).decode(data); } public static String base64DecodeToString(String data, boolean urlSafe) { return utf8(getBase64Decoder(urlSafe).decode(data)); } public static byte[] base32Encode(byte[] data) { return new Base32(0, Base32.CHUNK_SEPARATOR).encode(data); } public static String base32EncodeToString(byte[] data) { return new Base32(0, Base32.CHUNK_SEPARATOR).encodeToString(data); } public static byte[] base32Decode(String data) { return base32Decode(data, false); } public static String base32DecodeToString(String data) { return utf8(base32Decode(data, false)); } public static byte[] base32Decode(String data, boolean useHex) { return new Base32(0, Base32.CHUNK_SEPARATOR, useHex).decode(data); } public static String base32DecodeToString(byte[] data, boolean useHex) { return utf8(new Base32(0, Base32.CHUNK_SEPARATOR, useHex).decode(data)); } public static String urlPathEncode(String path) { StringBuilder buffer = new StringBuilder(); for (char c : path.toCharArray()) { if (UNSAFE_URLPATH.indexOf(c) >= 0) { buffer.append('%'); buffer.append(toHex(c / 16)); buffer.append(toHex(c % 16)); } else if (c < 32 && c > 128) { buffer.append(urlEncode(Character.toString(c))); } else { buffer.append(c); } } return buffer.toString(); } private static char toHex(int ch) { return (char) (ch < 10 ? '0' + ch : 'A' + ch - 10); } /** * Convert string to an UTF-8 encoded byte array * * @param str String to convert. * @return UTF-8 characters byte array */ public static byte[] utf8(String str) { return str.getBytes(StandardCharsets.UTF_8); } /** * Convert UTF-8 encoded byte arrays to a string * * @param utf8Chars UTF-8 characters byte array * @return Converted string. */ public static String utf8(byte[] utf8Chars) { try { return new String(utf8Chars, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new UnexpectedException(e); } } public static boolean containsVariableSubstitution(String str) { char[] chars = str.toCharArray(); for (int i = 0; i < chars.length; i++) { char c = chars[i]; if (c == '\\') { i++; } else if (c == '$') { if (nextChar(chars, i) == '{') { return true; } } } return false; } /** * Same as calling {@link #substituteVariables(String, Map)} with neverFail set to true */ public static String substituteVariables(String str, Map variables) throws IllegalArgumentException { return substituteVariables(str, variables, true); } /** * Substitute variables in a string. * * @param str String to substitute variables from * @param variables Variables * @param neverFail If set to true, this will suppress any errors and instead return empty string in the invalid part of the variable substituation. * @return String with variables substituted * @throws IllegalArgumentException If an invalid variable substituation is found and neverFail is set to false */ public static String substituteVariables(String str, Map variables, boolean neverFail) throws IllegalArgumentException { if (str == null) { return null; } char[] chars = str.toCharArray(); int nested = 0; StringWriter newStr = new StringWriter(); StringWriter varStr = new StringWriter(); StringWriter cStr = newStr; boolean varParse = false; for (int i = 0; i < chars.length; i++) { char c = chars[i]; if (c == '$') { char nc = nextChar(chars, i); if (nc == '$' && nextChar(chars, i + 1) == '{') { i += 2; cStr.append("${"); } else if (nc == '{') { i++; if (!varParse) { varParse = true; cStr = varStr; } else { nested++; varStr.append("${"); } } else { cStr.append(c); } } else if (varParse && c == '}') { if (nested > 0) { nested--; varStr.append('}'); } else { varParse = false; cStr = newStr; newStr.append(resolveVarSub(varStr.toString(), variables, neverFail)); varStr = new StringWriter(); } } else { cStr.append(c); } } return newStr.toString(); } private static char nextChar(char[] chars, int idx) { int newIdx = idx + 1; if (newIdx < chars.length) { return chars[newIdx]; } else { return 0; } } private static String resolveVarSub(String exp, Map provisioningParams, boolean neverFail) throws IllegalArgumentException { if (containsVariableSubstitution(exp)) { exp = substituteVariables(exp, provisioningParams, neverFail); } Pattern pattern = getVarSubFuncPattern(); Matcher m = pattern.matcher(exp); if (m.find()) { String functionName = m.group(1).toLowerCase(); String functionParams = m.group(2); boolean prefixFunc = functionName.equals("p"); boolean suffixFunc = functionName.equals("s"); if (prefixFunc || suffixFunc) { String[] args = splitTwoArgFunction(functionParams, neverFail); if (args != null) { String xfix = args[0]; String val = resolveVarSub(args[1], provisioningParams, neverFail); if (StringUtils.isNotBlank(val)) { return suffixFunc ? xfix + val : val + xfix; } else { return val; } } else { resolveVarSubFail(exp, neverFail); } } else if (functionName.equals("u")) { return resolveVarSub(functionParams, provisioningParams, neverFail).toUpperCase(); } else if (functionName.equals("l")) { return resolveVarSub(functionParams, provisioningParams, neverFail).toLowerCase(); } else if (functionName.equals("c")) { return capitalize(resolveVarSub(functionParams, provisioningParams, neverFail)); } else if (functionName.equals("eb64")) { return base64EncodeToString(utf8(resolveVarSub(functionParams, provisioningParams, neverFail))); } else if (functionName.equals("db64")) { return base64DecodeToString(resolveVarSub(functionParams, provisioningParams, neverFail)); } else if (functionName.equals("t")) { return functionParams; } else { resolveVarSubFail(exp, neverFail); } } else { String val = provisioningParams.get(exp); if (val == null) { if (!neverFail) { throw new IllegalArgumentException("Variable not found: " + exp); } } else { return val; } } return ""; } private static String resolveVarSubFail(String exp, boolean neverFail) { if (!neverFail) { throw new IllegalArgumentException("Invalid variable substitution expression: " + exp); } else { return ""; } } private static synchronized Pattern getVarSubFuncPattern() { if (varSubFuncPattern == null) { varSubFuncPattern = Pattern.compile("([a-zA-Z]*?):(.*)"); } return varSubFuncPattern; } @Nullable private static String[] splitTwoArgFunction(String str, boolean neverFail) { StringWriter arg1 = new StringWriter(); StringWriter arg2 = new StringWriter(); boolean potentialMatch = false; boolean match = false; for (char c : str.toCharArray()) { if (match) { arg2.append(c); } else if (c == ':') { if (potentialMatch) { arg1.append(':'); } potentialMatch = !potentialMatch; } else if (potentialMatch) { match = true; arg2.append(c); } else { arg1.append(c); } } if (match) { return new String[]{arg1.toString(), arg2.toString()}; } else { resolveVarSubFail(str, neverFail); return null; } } private static Base64.Encoder getBase64Encoder(boolean urlSafe) { final Base64.Encoder encoder; if (urlSafe) { encoder = Base64.getUrlEncoder(); } else { encoder = Base64.getEncoder(); } return encoder.withoutPadding(); } private static Base64.Decoder getBase64Decoder(boolean urlSafe) { final Base64.Decoder decoder; if (urlSafe) { decoder = Base64.getUrlDecoder(); } else { decoder = Base64.getDecoder(); } return decoder; } public static String generateId() { return generateId(null, true); } public static String generateId(String prefix) { return generateId(prefix, true); } public static String generateId(String prefix, boolean b32) { final byte[] uuidData = DataUtils.uuidToByteArray(UUID.randomUUID()); String id; if (b32) { id = new Base32(0, null, true).encodeToString(uuidData).replace("=", "").toLowerCase(); } else { id = Base64.getUrlEncoder().withoutPadding().encodeToString(uuidData); } if (prefix != null) { return prefix + "-" + id; } else { return id; } } public static String uuid() { return UUIDUtils.generate().toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy