package com.reliancy.util; /** * Common utility methods. */ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Base64; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; import java.util.zip.DataFormatException; import java.util.zip.Deflater; import java.util.zip.Inflater; public final class Handy { public static String wrap(String verb, String left, String right) { if(verb==null) verb=""; if(verb.startsWith(left) && verb.endsWith(right)) return verb; return left+verb.trim()+right; } public static String unwrap(String verb, String left, String right) { if(verb==null) return verb; String ret=verb.trim(); if(verb.startsWith(left) && verb.endsWith(right)) ret=verb.substring(1,verb.length()-1); return ret; } public static T nz(T val, T def){ return val!=null?val:def; } /** * Will try to convert incoming value to an expected class. * @param clazz * @param val * @return */ public static Object normalize(Class clazz, Object val ) { if(val==null) return null; // we are null if(clazz.isAssignableFrom(val.getClass())) return clazz; // we are assignable if(val instanceof String){ String value=(String) val; if(value.isEmpty() || value.equals("''") || value.equals("\"\"")) return null; if( Boolean.class==( clazz ) || boolean.class==( clazz ) ) return Boolean.parseBoolean( value ); if( Byte.class==( clazz ) || byte.class==( clazz ) ) return Byte.parseByte( value ); if( Short.class==( clazz ) || short.class==( clazz ) ) return Short.parseShort( value ); if( Integer.class==( clazz ) || int.class==( clazz ) ) return Integer.parseInt( value ); if( Long.class==( clazz ) || long.class==( clazz )) return Long.parseLong( value ); if( Float.class==( clazz ) || float.class==( clazz ) ) return Float.parseFloat( value ); if( Double.class==( clazz ) || double.class==( clazz )) return Double.parseDouble( value ); } return val; } /** * This method is a bit more complex because it locks onto two delimiters one for grouping and other * for decimal point and chooses those from a list of [space],'`. which are used all over the world in different places. * Returns true if the string only contains digits and numeric characters. * This should match 1000000 also 1,000,000 and also 1,000,000.00 but it is still not possible to differentiate between 1,000 =1000 in us * from 1000,00 whch is used in europe. So it is difficult to normalize the string so it could process any number. * @param str string to test * @return trie if string looks numeric or is null/empty */ public static final boolean isNumeric(String str){ int strLen; if (str == null || (strLen = str.length()) == 0) { return true; } String delims=" ,.'`"; int delimNumber=0; // 0 we load, 1 we let one more, 2 we exit on second occurance char delimUsed=0; // char used as delim boolean delimLast=false; int digitCount=0; for (int i = 0; i < strLen; i++) { char ch=str.charAt(i); boolean accept=Character.isDigit(ch); if(accept) digitCount++; accept=accept || (ch=='-' && i==0); accept=accept || (ch=='+' && i==0); if(delims.indexOf(ch)>=0){ accept=!delimLast; // prevent delims following each other delimLast=true; if(delimNumber==0){ delimNumber=1; delimUsed=ch; }else if(delimNumber==1){ if(delimUsed!=ch) delimNumber=2; delimUsed=ch; }else{ // we have seen two different delim and whatever is coming here is breaking numeric format like second delim second time or some otehr accept=false; } }else{ delimLast=false; } if(!accept) return false; } return digitCount>0; } /** * returns true if the string is null, empty or contains only white space. */ public static boolean isBlank(CharSequence str) { int strLen; if (str == null || (strLen = str.length()) == 0) { return true; } for (int i = 0; i < strLen; i++) { if ((Character.isWhitespace(str.charAt(i)) == false)) { return false; } } return true; } /** * Provides a unified notion of what constitutes an empty value. * For any object if it is null. * For string also if it is blank * For arrays and lists and collection and maps also if no entries or keys exist. * @param value anything * @return true if any of the above matches */ public static boolean isEmpty(Object value){ if(value==null) return true; if(value instanceof CharSequence){ return isBlank((CharSequence)value); } Class cls=value.getClass(); if(cls.isArray()) { if(value instanceof Object[]){ Object[] arr=(Object[]) value; if(arr.length==0) return true; for(int i=0;i c=(Collection)value; if(c.isEmpty()) return true; for(Object o:c){ if(isEmpty(o)==false) return false; } return true; } return false; } /** Attempts to take a compact string and beautify it. * Will uppercase the first letter. Will also expand CamelCase. * Also will replace _ with empty space. * @param str * @return nicely formatted string ready for display */ public static final String prettyPrint(String str){ if(str==null) return ""; boolean fix=false; char prevCh=0; if(str.startsWith("org.") || str.startsWith("net.") || str.startsWith("com.") || str.startsWith("java.")){ str=str.substring(1+str.lastIndexOf('.')); // we strip class name paths } for(int i=0;i0?bufs.charAt(bufs.length()-1):currCh; if(Character.isWhitespace(currCh)){ if(!Character.isWhitespace(prevCh)){ bufs.append(' '); } continue; // ignore repeated whitespace otherwise emit space } if(bufs.length()==0){ toUC=true; }else if((!Character.isUpperCase(prevCh) && ("-+/%*".indexOf(prevCh)==-1 || Character.isLetter(prevCh))) && Character.isUpperCase(currCh)){ // non uc (a not one of operands) behind, uc ahead bufs.append(" "); }else if(Character.isLetter(prevCh) && Character.isDigit(currCh)){ // letter behind, digit ahead bufs.append(" "); }else if(Character.isUpperCase(prevCh) && Character.isUpperCase(currCh) && i<(str.length()-1) && Character.isLowerCase(str.charAt(i+1))){ // behind me uppercase infrom uppercase then lowercase bufs.append(" "); } bufs.append(toUC?Character.toUpperCase(currCh):currCh); toUC=false; } while(bufs.length()>0 && Character.isWhitespace(bufs.charAt(bufs.length()-1))){ // trims whitespace from end bufs.setLength(bufs.length()-1); } return bufs.toString(); } /** Attempts to take a user string and compact it to camel case. * @param str nicely formatted string * @return nicely compact string */ public static String toCamelCase(String value) { if(value==null || value.trim().isEmpty()) return ""; StringBuilder sb = new StringBuilder(); //final char delimChar = ' '; boolean flip = false; for (int charInd = 0; charInd < value.length(); charInd++) { char ch = value.charAt(charInd); if (Character.isWhitespace(ch)) { flip = true; }else if(flip){ flip = false; if(ch==Character.toLowerCase(ch)) sb.append("_"); sb.append(ch); }else{ sb.append(ch); } } return sb.toString(); } public static byte[] deflate(byte[] content) throws IOException{ Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION,true); deflater.setInput(content); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(content.length); deflater.finish(); byte[] buffer = new byte[1024]; while (!deflater.finished()) { int count = deflater.deflate(buffer); // returns the generated code... index outputStream.write(buffer, 0, count); } outputStream.close(); byte[] output = outputStream.toByteArray(); return output; } public static byte[] inflate(byte[] contentBytes) throws IOException, DataFormatException{ Inflater inflater = new Inflater(true); inflater.setInput(contentBytes); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(contentBytes.length); byte[] buffer = new byte[1024]; while (!inflater.finished()) { int count = inflater.inflate(buffer); outputStream.write(buffer, 0, count); } outputStream.close(); byte[] output = outputStream.toByteArray(); return output; } public static void shuffle(Object[] e){ Random rn = new Random(); for(int i=0;i m){ String ret=null; Object[] es=m.keySet().toArray(); shuffle(es); // we shuffle entries to confuse the string a bit StringBuilder buf=new StringBuilder(); for(int i=0;i0) buf.append("\n"); buf.append(e).append(":").append(m.get(e)); } ret=encryptString(key,buf.toString()); return ret; } /** * This method will encrypt a string and return BASE 64 string that is web safe. * TO make the string web safe we replace + with - and / with _ * Must revert this change on the reverse. * @param key * @param ret * @return */ public static final String encryptString(String key,String ret){ try{ byte[] bkey=key.getBytes("UTF-8"); byte[] bstr=ret.getBytes("UTF-8"); for(int i=0;i decrypt(String key,String m){ m=decryptString(key,m); Map ret=new HashMap<>(); //System.out.println("Output:"+m); Tokenizer tokz=new Tokenizer(m); tokz.setDelimChars("\n"); tokz.setWhiteChars(null); for(String t=tokz.nextToken();t!=null;t=tokz.nextToken()){ if("\n".equals(t)) continue; String[] kv=t.split(":",2); ret.put(kv[0],kv.length>1?kv[1]:null); } return ret; } public static final String decryptString(String key,String m){ try{ //m=URLDecoder.decode(m, "UTF-8"); m=m.replace('-','+'); m=m.replace('_','/'); m=m.replace('.','='); byte[] bkey=key.getBytes("UTF-8"); byte[] bstr=decodeBase64(m); for(int i=0;i> 4]); sb.append(HEX_CHARS[b & 0x0F]); } return sb.toString(); } /** * Finds first occurrence of sub inside body with and without case. * We implement this search via a FSM and ignore the case. * @param body * @param sub * @param offset * @return offset of first occurance */ public static final int indexOf(CharSequence body,CharSequence sub,int offset){ if(body==null) return -1; int state=0; int blen=body.length(); int slen=sub.length(); boolean ignorecase=true; for(int index=offset;index=slen) return index-slen+1; // we found a match } return -1; } /** * Will trim the string from left and right and remove any of the symbols. */ public static String trim(String trim,String sym) { if(trim==null || trim.length()==0) return trim; int start=0; int end=trim.length(); while(start all) { if(all==null) return null; String[] ret=new String[all.size()]; all.toArray(ret); return ret; } public static String toString(Object...args){ StringBuilder buf=new StringBuilder(); if(args.length>1){ buf.append("["); for(int i=0;i it=((Iterable)arg).iterator(); buf.append("["); while(it.hasNext()) buf.append(buf.length()>1?",":"").append(it.next()); buf.append("]"); }else if(arg instanceof java.util.Map){ java.util.Map marg=(Map) arg; buf.append("{"); for(java.util.Map.Entrye:marg.entrySet()){ buf.append(e.getKey().toString()).append(":").append(toString(e.getValue())); } buf.append("}"); }else{ buf.append(String.valueOf(arg)); } } return buf.toString(); } }