package com.smtscript.utils; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintStream; import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URL; import java.net.URLClassLoader; import java.security.MessageDigest; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.Map.Entry; import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.mozilla.javascript.ConsString; import org.mozilla.javascript.NativeArray; import org.mozilla.javascript.NativeFunction; import org.mozilla.javascript.NativeObject; import org.mozilla.javascript.Undefined; import org.mozilla.javascript.Wrapper; public final class SMTStatic { /** * 数据转换类型 */ public enum SMTConvType { Integer, Long, Float, Double, Date, String, MergeDate, MD5, } /** * 数据转换对于空字符串的处理 */ public enum SMTConvEmpty { SkipEmpty, KeepEmpty, ErrorEmpty, } /** * 计算时间用枚举 */ public enum SMTCalcTime { SET_MILLISECOND, ADD_SECOND, ADD_MINUTE, ADD_HOUR, ADD_DATE, ADD_MONTH, ADD_YEAR, SET_SECOND, SET_MINUTE, SET_HOUR, SET_DATE, SET_MONTH, SET_YEAR, ZERO_TIME, } /** * stringFormat使用的格式化类 */ public static class StringNamedFormat { /** * 参数名 */ public String _name; /** * 参数索引 */ public int _index; /** * 构造函数 * * @param name - 参数名 * @param index - 参数索引 */ public StringNamedFormat(String name, int index) { _name = name; _index = index; } } /** * stringFormat使用的参数通知函数 */ public static interface StringNamedNotify { /** * 通过命名参数获取值 * * @param name - 参数名 * @param args - 输入的参数列表 * @return - 转换后的字符串 */ Object getNamedValue(String name, Object[] args) throws Exception; } /** * 空json对象 */ public static Json emptyObject = Json.object(); /** * stringFormat使用的正则匹配 */ private static final Pattern _patStringFormat = Pattern.compile("^\\{(\\d+|[_A-Za-z\\$][^\\{%\\}]+)(\\%[^\\}]+)?\\}", 0); /** * 分析日期格式用的正则匹配 */ private static final Pattern _patDateFormat = Pattern.compile("^(\\d+)-(\\d+)-(\\d+)(?: (\\d+):(\\d+)(?::(\\d+))?)?$", 0); /** * html转换使用的映射表 */ private static final String[] _convCharToHtml = new String[]{"&", "&", "'", "'","\"", """, "<", "<", ">", ">"}; private static final Pattern _patTimeSpanFormat = Pattern.compile("(\\d+)([smhd])"); /** * newSquence函数用的日期格式化对象 */ private static final ThreadLocal _GuidFmtTime= SMTStatic.newSimpleDateFormat("yyyyMMddHHmmssSSS"); private static final ThreadLocal _dateFmt = SMTStatic.newSimpleDateFormat("yyyy-MM-dd HH:mm:ss"); protected static Pattern _patIsNumber = Pattern.compile("^[1-9]\\d*$"); private static final long _baseTimeTick = SMTStatic.toDate("1970-01-02").getTime(); private static Class _oracleTimeClz; private static Method _oracleTimeMethod; static { try { _oracleTimeClz = Class.forName("oracle.sql.TIMESTAMP"); _oracleTimeMethod = _oracleTimeClz.getDeclaredMethod("timestampValue"); } catch (Exception e) { _oracleTimeClz = null; _oracleTimeMethod = null; } } public static String encodeMD5(byte[] data) throws Exception { StringBuilder sbOut = new StringBuilder(); MessageDigest md5Encoder = MessageDigest.getInstance("MD5"); for(byte b : md5Encoder.digest(data)) { sbOut.append((char)('A' + ((b >> 4) & 0x0F))); sbOut.append((char)('A' + (b & 0x0F))); } return sbOut.toString(); } public static Object convOracleTime(Object value) { if(value == null) return value; if(_oracleTimeClz != null) { if(value.getClass().isAssignableFrom(_oracleTimeClz)) { try { return _oracleTimeMethod.invoke(value); } catch(Exception ex) { return null; } } } return value; } /** * 生成线程安全的SimpleDateFormat对象 * * @param fmt - date格式 * @return - 返回SimpleDateFormat对象 */ public static ThreadLocal newSimpleDateFormat(final String fmt) { return new ThreadLocal (){ @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat(fmt); } }; } /** * 判断字符串是否为空或null * * @param str - 要判断的字符串 * @return - 判断结果 */ public static boolean isNullOrEmpty(String str) { return (str == null || str.length() == 0); } /** * 格式化字符串 * * @param format - 要格式化的内容,可以用'{名称}'或'{索引}'来表示 * @param args - 要格式化的参数,最后的参数可以跟StringNamedFormat或StringNamedNotify * @return - 返回格式化后的字符串 */ public static String stringFormat(String format, Object...args) { try { StringBuilder sbOut = new StringBuilder(); Map mapName2Index = null; StringNamedNotify notify = null; // 如果最后一个参数是StringNamedNotify,则按照这个设置 if(args.length > 0 && args[args.length - 1] instanceof StringNamedNotify) notify = (StringNamedNotify)args[args.length - 1]; for(int i = 0; i < format.length(); i ++) { char ch = format.charAt(i); if(ch == '\\') { i++; ch = format.charAt(i); switch(ch) { case 'r':ch = '\r';break; case 'n':ch = '\n';break; case 'b':ch = '\b';break; case 't':ch = '\t';break; } sbOut.append(ch); } else if(ch == '{') { Matcher mat = _patStringFormat.matcher(format.substring(i)); if(!mat.find()) throw new RuntimeException(String.format("unknow format match for [%s] at [%d]", format.substring(i), i)); String fullFmt = mat.group(); String dataName = mat.group(1); String dataFmt = mat.group(2); Object value = null; // 如果当前是通知类型,则调用通知函数获得值 if(notify != null) { value = notify.getNamedValue(dataName, args); } // 如果参数第一个符号不是数字,则解析名称 else if(dataName.charAt(0) < '0' || dataName.charAt(0) > '9') { if(mapName2Index == null) { mapName2Index = new HashMap(); // 如果最后一个参数是名称数组,则只解析名称数组 if(args[args.length - 1] instanceof StringNamedFormat[]) { for(StringNamedFormat named : (StringNamedFormat[])args[args.length - 1]) { mapName2Index.put(named._name, named._index); } } // 最后一个参数不是名称数组,则解析每一个名称对象 else { for(int j = 0; j < args.length; j ++) { if(args[j] instanceof StringNamedFormat) { StringNamedFormat named = (StringNamedFormat)args[j]; mapName2Index.put(named._name, named._index); } } } } if(!mapName2Index.containsKey(dataName)) throw new RuntimeException(String.format("format name [%s] is not found for string [%s]", dataName, format)); int dataIndex = mapName2Index.get(dataName); if(dataIndex >= args.length) throw new RuntimeException(String.format("format argument name [%s] index [%d] is out of range for string [%s]", dataName, dataIndex, format)); value = args[dataIndex]; } // 如果第一个字符是数字,则解析索引 else { int dataIndex = Integer.parseInt(dataName); if(dataIndex >= args.length) throw new RuntimeException(String.format("format argument index [%d] is out of range for string [%s]", dataIndex, format)); value = args[dataIndex]; } if(dataFmt == null) { sbOut.append(value == null ? "" : value.toString()); } else { sbOut.append(String.format(dataFmt, value)); } i += fullFmt.length() - 1; } else { sbOut.append(ch); } } return sbOut.toString(); } catch(Exception ex) { throw new RuntimeException(String.format("stringFormat [%s] exception", format), ex); } } /** * 转换字符串成html格式 * * @param text - 要转换的字符串 * @return - 返回转换后的html内容 */ public static String convStringToHtmlBody(String text) { for(int i = 0; i < _convCharToHtml.length; i += 2) { text = text.replace(_convCharToHtml[i + 0], _convCharToHtml[i + 1]); } return text; } /** * 读取UTF-8文本流的内容 * * @param inputStream - 要读取的文本流 * @return - 返回读取的内容 */ public static String readTextStream(InputStream inputStream, String encode) { InputStreamReader rd = null; try { StringBuilder sb = new StringBuilder(); int size = 0; char[] data = new char[10240]; rd=new InputStreamReader(inputStream, encode); while((size = rd.read(data)) > 0) { sb.append(data, 0, size); } return sb.toString(); } catch(Exception ex) { throw new RuntimeException(ex); } finally { if(rd != null) try { rd.close(); } catch (IOException e) { } } } /** * 从文本文件中读取UTF-8的文本 * * @param fileName - 文件名 * @return - 返回文件内容 */ public static String readAllText(String fileName, String encode) { return readAllText(new File(fileName), encode); } /** * 从文本文件中读取UTF-8的文本 * * @param fileName - 文件名 * @return - 返回文件内容 */ public static String readAllText(File file, String encode) { FileInputStream fi = null; try { fi = new FileInputStream(file); return readTextStream(fi, encode); } catch(Exception ex) { throw new RuntimeException(String.format("read file [%s] error", file.getAbsolutePath()), ex); } finally { if(fi != null) { try { fi.close(); } catch (IOException e) { } } } } /** * 将文本数据以UTF-8格式写入文件 * * @param file - 要写入的文件名 * @param text - 要写入的内容 */ public static void saveTextFile(File file, String text, String encode) throws Exception { OutputStreamWriter wr = new OutputStreamWriter(new FileOutputStream(file), encode); try { wr.write(text); } finally { wr.close(); } } /** * 将字符串或日期类型转换成日期类型 * * @param value - 要转换的内容 * @return - 返回转换后的日期 */ public static Date toDate(Object value) { if(value instanceof String) { Matcher m = _patDateFormat.matcher(value.toString()); if(!m.find()) throw new RuntimeException("parse time error"); int year = Integer.parseInt(m.group(1)); int month = Integer.parseInt(m.group(2)); int day = Integer.parseInt(m.group(3)); int hour = (m.group(4) != null) ? Integer.parseInt(m.group(4)) : 0; int minute = (m.group(5) != null) ? Integer.parseInt(m.group(5)) : 0; int second = (m.group(6) != null) ? Integer.parseInt(m.group(6)) : 0; //objValue = new Date(year - 1900, month, day, hour, minute, second); Calendar cal = Calendar.getInstance(); cal.set(year, month - 1, day, hour, minute, second); cal.set(Calendar.MILLISECOND, 0); return cal.getTime(); } if(value instanceof Date) return (Date)value; throw new RuntimeException("unknow date type : " + (value == null ? "null" : value.getClass())); } /** * 通过json配置,将字符串转换成值,并保存在map中 * * @param jsonParams - json配置列表 * @param mapName2Value - 返回的映射数据 * @param skipEmpty - 对于空白的缺省处理 * @param throwError - 出错是否抛异常 * @return - true:全部成功,false:有错 */ public static boolean convStrByJson(String value, Json jsonParam, Map mapName2Value, SMTConvEmpty skipEmpty, boolean throwError) throws Exception { if(!jsonParam.isObject()) throw new Exception("current is not map json:" + jsonParam.toString()); // 如果没有field或ctrl属性,则直接忽略 if(!jsonParam.has("field") || !jsonParam.has("ctrl") || !jsonParam.has("type")) return true; try { // 获取字段名 boolean ret = true; String field = jsonParam.at("field").asString(); SMTConvType type = Enum.valueOf(SMTConvType.class, jsonParam.at("type").asString()); String mode = jsonParam.safeGetStr("mode", "only"); if(jsonParam.has("empty")) skipEmpty = Enum.valueOf(SMTConvEmpty.class, jsonParam.at("empty").asString()); // 取值 if(mode.equals("array")) { String split = jsonParam.safeGetStr("split", ","); ret = insertValueToMap(field, convStrToArray(value, type, skipEmpty, split), mapName2Value, ret); } else if(mode.equals("only")) { ret = insertValueToMap(field, convStrToValue(value, type, skipEmpty), mapName2Value, ret); } else throw new Exception(String.format("mode [%s] is not 'between' or 'array' or 'only'", mode)); return ret; } catch(Exception ex) { if(throwError) throw ex; return false; } } /** * 如果value是有效输入则插入map,否则返回false * @param key - 要插入的key * @param value - 要插入的值 * @param mapName2Value - 返回插入的map * @param prevStat - 前一次的状态 * @return - 如果失败则返回false, 如果成功则返回prevStat */ protected static boolean insertValueToMap(String key, Object value, Map mapName2Value, boolean prevStat) { if(value == null) return true; if(value instanceof Exception) return false; mapName2Value.put(key, value); return prevStat; } /** * 将字符串转换成对应的数组类型 * * @param str - 字符串 * @param type - 要转换的类型 * @param skipEmpty - 是否跳过空字串 * @param split - 数据切分 * @return - null:无数据,Exception:有错误,其他:数组类型数据 */ public static Object convStrToArray(String str, SMTConvType type, SMTConvEmpty skipEmpty, String split) { if(str == null) return null; List list = new ArrayList(); for(String value : str.split(split, -1)) { Object ovalue = convStrToValue(value, type, skipEmpty); if(ovalue == null) continue; if(ovalue instanceof Throwable) return ovalue; list.add(ovalue); } if(list.size() == 0) return null; Object[] ret = new Object[list.size()]; list.toArray(ret); return ret; } /** * 将字符串转换成指定的类型数据 * * @param str - 要转换的字符串 * @param type - 要转换的类型 * @param skipEmpty - 如果str为空是否返回null * @return - null:不需要转换,Throwable:转换出错,其他:正确的数据 */ public static Object convStrToValue(String str, SMTConvType type, SMTConvEmpty convEmpty) { try { if(str == null) return null; if(str.length() == 0) { if(convEmpty == SMTConvEmpty.SkipEmpty) return null; if(convEmpty == SMTConvEmpty.ErrorEmpty) throw new Exception("value is empty"); } if(type == SMTConvType.String) { return str; } else if(type == SMTConvType.MD5) { return SMTStatic.convStrToMD5(str); } if(str.length() == 0) { if(convEmpty == SMTConvEmpty.KeepEmpty) return null; throw new Exception("value is empty"); } if(type == SMTConvType.Integer) { return Integer.parseInt(str, 10); } else if(type == SMTConvType.Long) { return Long.parseLong(str, 10); } else if(type == SMTConvType.Float) { return Float.parseFloat(str); } else if(type == SMTConvType.Double) { return Double.parseDouble(str); } else if(type == SMTConvType.Date) { return SMTStatic.toDate(str); } else if(type == SMTConvType.MergeDate) { // 将当前字符串转换成日期 Date date = SMTStatic.toDate(str); // 如果当前字符串未设定时间,则将当前时间加入 if(str.indexOf(":") < 0) { Date now = new Date(); Calendar cal = Calendar.getInstance(); cal.setTime(now); date = SMTStatic.calculateTime(date, SMTCalcTime.SET_HOUR, cal.get(Calendar.HOUR_OF_DAY), SMTCalcTime.SET_MINUTE, cal.get(Calendar.MINUTE), SMTCalcTime.SET_SECOND, cal.get(Calendar.SECOND)); } return date; } throw new Exception("unsupport convert type:" + type.toString()); } catch(Exception ex) { return new Exception(String.format("convert [%s] to [%s] error:[%s]", str, type, ex.getMessage()), ex); } } /** * 将任意类型转换成int * * @param value - 要转换的类型 * @return - 转换后的结果 */ public static int toInt(Object value) { try { if(value instanceof Integer) return (Integer)value; if(value instanceof String) return Integer.parseInt((String)value); return (Integer)(value.getClass().getMethod("intValue").invoke(value)); } catch(Exception ex) { return Integer.parseInt(value.toString()); } } /** * 将字符串转换成MD5模式 * * @param text - 原始字符串 * @return - 转换后的MD5字符串 */ public static String convStrToMD5(String text) { try { StringBuilder sb = new StringBuilder(); sb.append("PA"); MessageDigest md = MessageDigest.getInstance("MD5"); md.update(text.getBytes("UTF8")); byte b[] = md.digest(); for(int i = 0; i < b.length; i ++) { sb.append(((int)b[i]) & 0xFF); } sb.append("SS"); return sb.toString(); } catch(Exception ex) { throw new RuntimeException(ex); } } /** * 生成唯一序列号 * * @return - 返回唯一序列号 */ public static synchronized String newSequence() { String time = _GuidFmtTime.get().format(new Date()); return time + UUID.randomUUID().toString().replace("-", "").substring(15); } /** * 生成uuid序列号 * * @return - uuid序列号 */ public static String newUUID() { return UUID.randomUUID().toString().replace("-", ""); } /** * 转换成C语言类型的字符串 * * @param str - 原始字符串 * @return - C语言类型字符串 */ public static String toCStr(String str) { return str.replace("\\", "\\\\").replace("\r", "\\r").replace("\n", "\\n").replace("\t", "\\t").replace("\"", "\\\""); } /** * 从json中获取字段名 * * @param jsonField - 要获取的json对象 * @param subKey - != null:子对象的路径,==null:获取当前对象 * @param defField - 缺省字段值 * @return - 返回取到的字段名或缺省字段名 */ public static String getFieldByJson(Json jsonField, String subKey, String defField) { if(subKey != null) { if(jsonField.has(subKey)) jsonField = jsonField.getJson(subKey); else return defField; } if(jsonField.isString()) return jsonField.asString(); if(jsonField.isObject() && jsonField.has("field")) return jsonField.getJson("field").asString(); return defField; } /** * 生成字典表的map list * * @param recs - 字典表对应的记录集 * @param typeKey - 类型字段名 * @param nameKey - 名称字段名 * @return - 返回创建后的列表 */ @SuppressWarnings("unchecked") public static Map>> getDictionaryMapList(List recs, String typeKey, String nameKey) { Map>> mapList = new HashMap>>(); for(Object rec : recs) { Map orec = (Map)rec; // 获取类型map表 String type = ((String)orec.get(typeKey)).toUpperCase(); Map> mapType = mapList.get(type); if(mapType == null) { mapType = new LinkedHashMap>(); mapList.put(type, mapType); } // 保存当前记录 Object key = orec.get(nameKey); orec.remove(typeKey); mapType.put(key, orec); } return mapList; } /** * 将字符串转换成值 * * @param value - 字符串表现的值 * @param type - 数据类型 * @param skipEmpty - 空值是否返回null * @param throwError - 出错是否抛异常 * @return - Exception:错误,null:忽略, 其他:返回转换后的值, */ public static Object convStringToValue(String value, SMTConvType type, SMTConvEmpty skipEmpty, boolean throwError) throws Exception { Object ret = convStrToValue(value == null ? "" : value, type, skipEmpty); if(throwError && ret instanceof Exception) throw (Exception)ret; return ret; } /** * 将字符串转换成数组 * * @param value - 字符串表现的值 * @param type - 数据类型 * @param split - 切分字符串 * @param skipEmpty - 空值是否返回null * @param throwError - 出错是否抛异常 * @return - Exception:错误,null:忽略, 其他:返回转换后的值, */ public static Object convStringToArray(String value, SMTConvType type, SMTConvEmpty skipEmpty, String split, boolean throwError) throws Exception { Object ret = convStrToArray(value == null ? "" : value, type, skipEmpty, split); if(throwError && ret instanceof Exception) throw (Exception)ret; return ret; } /** * 计算时间 * * @param date - 原始时间 * @param args - SMTCalcTime计算类型,要计算的值。。。 * @return - 计算后的时间 */ public static Date calculateTime(Date date, Object...args) { Calendar cal = Calendar.getInstance(); cal.setTime(date); for(int i = 0; i < args.length; i += 2) { SMTCalcTime type = (SMTCalcTime) args[i + 0]; int value = (Integer) args[i + 1]; switch(type) { case ADD_SECOND: cal.add(Calendar.SECOND, value); break; case ADD_MINUTE: cal.add(Calendar.MINUTE, value); break; case ADD_HOUR: cal.add(Calendar.HOUR_OF_DAY, value); break; case ADD_DATE: cal.add(Calendar.DATE, value); break; case ADD_MONTH: cal.add(Calendar.MONTH, value); break; case ADD_YEAR: cal.add(Calendar.YEAR, value); break; case SET_SECOND: cal.set(Calendar.SECOND, value); break; case SET_MINUTE: cal.set(Calendar.MINUTE, value); break; case SET_HOUR: cal.set(Calendar.HOUR_OF_DAY, value); break; case SET_DATE: cal.set(Calendar.DATE, value); break; case SET_MONTH: cal.set(Calendar.MONTH, value); break; case SET_YEAR: cal.set(Calendar.YEAR, value); break; case SET_MILLISECOND: cal.set(Calendar.MILLISECOND, value); break; case ZERO_TIME: cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); break; } } return cal.getTime(); } /** * 将时间间隔字符串转换成对应的秒值 * 时间格式: [数字][单位]..... * 单位格式: d:天,h:小时,m:分钟,s:秒 * * @param timeSpan * @return * @throws Exception */ public static long convTimeSpanToSecond(String timeSpan) throws Exception { Matcher m = _patTimeSpanFormat.matcher(timeSpan); int pos = 0; long retSecond = 0; while(m.find()) { if(pos != m.start()) throw new Exception("time span format is error"); pos += m.group().length(); long value = Integer.parseInt(m.group(1)); switch(m.group(2).charAt(0)) { case 'd': retSecond += value * 60 * 60 * 24; break; case 'h': retSecond += value * 60 * 60; break; case 'm': retSecond += value * 60; break; case 's': retSecond += value; break; } } return retSecond; } public static void loadJarPath(String filePath) { loadJarPath(filePath, null); } /** * 读取jar包的路径 * * @param filePath - 要读取的路径名 */ public static void loadJarPath(String filePath, URLClassLoader classLoader) { // 系统类库路径 File libPath = new File(filePath); // 获取所有的.jar和.zip文件 File[] jarFiles = libPath.listFiles(new FilenameFilter() { public boolean accept(File dir, String name) { return name.endsWith(".jar") || name.endsWith(".zip"); } }); loadJarFiles(jarFiles, classLoader); } /** * 将jar包文件列表读入系统 * @param jarFiles - 要读入的文件列表 */ public static void loadJarFiles(File[] jarFiles, URLClassLoader classLoader) { try { URL[] urls = new URL[jarFiles.length]; for(int i = 0; i < urls.length; i ++) { urls[i] = jarFiles[i].toURI().toURL(); } loadJarFiles(urls, classLoader); } catch(Exception ex) { throw new RuntimeException(ex); } } @SuppressWarnings("deprecation") public static void loadJarFiles(URL[] jarUrls, URLClassLoader classLoader) { try { if(classLoader == null) classLoader = (URLClassLoader)Thread.currentThread().getContextClassLoader(); if (jarUrls != null) { // 从URLClassLoader类中获取类所在文件夹的方法 // 对于jar文件,可以理解为一个存放class文件的文件夹 Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); boolean accessible = method.isAccessible(); // 获取方法的访问权限 try { if (accessible == false) { method.setAccessible(true); // 设置方法的访问权限 } // 获取系统类加载器 for (URL url : jarUrls) { try { method.invoke(classLoader, url); //LOG.debug("读取jar文件[name={}]", file.getName()); } catch (Exception e) { //LOG.error("读取jar文件[name={}]失败", file.getName()); } } } finally { method.setAccessible(accessible); } } } catch(Exception ex) { throw new RuntimeException(ex); } } public static String toString(Object value) { if(value == null) return ""; if(value instanceof Date) return _dateFmt.get().format(value); else if((value instanceof Float) || (value instanceof Double) || (value instanceof BigDecimal)) { String ret = String.format("%f", value); if(ret.indexOf('.') > 0) { for(int i = ret.length() - 1; i >= 0; i --) { char ch = ret.charAt(i); if(ch == '.') { return ret.substring(0, i); } else if(ch != '0') return ret.substring(0, i + 1); } } return ret; } else if(value instanceof Integer || value instanceof Long || value instanceof Short || value instanceof BigInteger) { String ret = String.format("%d", value); return ret; } else if(value instanceof Throwable) { ByteArrayOutputStream byteOS = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(byteOS); ((Throwable)value).printStackTrace(ps); String errMsg = new String(byteOS.toByteArray()); return errMsg; } else return value.toString(); } public static boolean checkFileName(String fileName, boolean incSubPath, boolean throwError) throws Exception { boolean check = fileName.indexOf("..") < 0; if(!incSubPath) check &= (fileName.indexOf("/") < 0 && fileName.indexOf("\\") < 0); if(!check && throwError) throw new Exception("file name include '..' : " + fileName); return check; } /** * 生成事件和响应函数的映射表 * 事件:在json的"event"的key中保存 * 函数:void EVENT_xxx(String eventName, Json jsonRecv, Object response) * * @param clsType - 函数对应的类 * @param args - n + 0 : 事件名称, n + 1 : 函数名称 * @return */ public static Map newEventMethodMap(String perfix, Class clsType, Class[] paramTypes, String...args) { Map map = new HashMap(); for(int i = 0; i < args.length; i += 2) { String eventName = args[i + 0].toUpperCase(); String methodName = args[i + 1]; try { Method method = clsType.getMethod(perfix + methodName, paramTypes); map.put(eventName, method); } catch(Exception ex) { ex.printStackTrace(); } } return map; } public static boolean moveFile(File fileSrc, File fileTag, boolean throwError) { // 如果文件名相同,则直接返回 if(fileSrc.toString().equals(fileTag.toString())) return true; // 删除目标文件 if(fileTag.exists()) fileTag.delete(); if(fileTag.exists()) { if(throwError) throw new RuntimeException("delete move tag file error"); return false; } // 尝试移动目标文件 fileSrc.renameTo(fileTag); // 如果移动成功,则返回成功 if(fileTag.exists()) return true; // 将文件复制到目标目录 File tempFile = new File(fileTag.getAbsolutePath() + ".temp"); byte[] data = new byte[1024 * 100]; int size; InputStream is = null; OutputStream os = null; try { // 复制文件 is = new FileInputStream(fileSrc); os = new FileOutputStream(tempFile); while((size = is.read(data)) > 0) { os.write(data, 0, size); } // 关闭文件 os.close(); os = null; is.close(); is = null; // 将临时文件改名 tempFile.renameTo(fileTag); if(!fileTag.exists()) { if(throwError) throw new RuntimeException("temp file can't not rename to tag file"); return false; } return true; } catch(Exception ex) { if(throwError) throw new RuntimeException("copy file error", ex); return false; } finally { try { if(is != null) is.close(); if(os != null) os.close(); } catch(Exception ex) { throw new RuntimeException("close file error", ex); } } } public static File getFilePath(File file) { String fileName = file.getAbsolutePath(); return new File(fileName.substring(0, fileName.length() - file.getName().length())); } public static Object unwrapObject(Object value) { if(value == null) return null; if(value instanceof Wrapper) value = ((Wrapper)value).unwrap(); if(value instanceof Undefined) return null; if(value instanceof ConsString) value = ((ConsString)value).toString(); return value; } public static void putJSNotNullValue(NativeObject nv, String key, Object value) { if(value == null) return; if(_patIsNumber.matcher(key).find()) nv.put(Integer.parseInt(key), nv, value); else nv.put(key, nv, value); } public static Object getJSValue(NativeObject nv, String key) throws Exception { if(!nv.containsKey(key)) throw new Exception("NativeObject can't find key : " + key); Object value = unwrapObject(nv.get(key)); if(value == null) throw new Exception("NativeObject can't find key : " + key); return value; } public static Object getJSValue(NativeObject nv, String key, Object defValue) throws Exception { Object okey; if(_patIsNumber.matcher(key).find()) okey = Long.parseLong(key); else okey = key; if(!nv.containsKey(okey)) return defValue; Object value = unwrapObject(nv.get(okey)); if(value == null) return defValue; return value; } public static String convJSString(Object value) { StringBuilder sb = new StringBuilder(); convString(value, false, false, sb); return sb.toString(); } private static void convString(Object value, boolean convStr, boolean mustStr, StringBuilder sb) { if(value == null) { sb.append("null"); return; } if(value instanceof Wrapper) value = ((Wrapper)value).unwrap(); if(value instanceof NativeObject) { sb.append("{"); for(Entry entry : ((NativeObject) value).entrySet()) { convString(entry.getKey(), true, true, sb); sb.append(":"); convString(entry.getValue(), true, false, sb); sb.append(","); } if(sb.charAt(sb.length() - 1) == ',') sb.setLength(sb.length() - 1); sb.append("}"); } else if(value instanceof NativeArray) { NativeArray arr = (NativeArray)value; sb.append("["); for(int i = 0; i < arr.size(); i ++) { convString(arr.get(i), true, false, sb); sb.append(","); } if(sb.charAt(sb.length() - 1) == ',') sb.setLength(sb.length() - 1); sb.append("]"); } else if(value instanceof NativeFunction) { sb.append("function(){}"); } else if(value instanceof Float || value instanceof Double || value instanceof Integer || value instanceof Short || value instanceof Long) { String strValue = SMTStatic.toString(value); if(mustStr) { sb.append("\"" + strValue + "\""); } else { sb.append(strValue); } } else if(value instanceof Boolean) { sb.append((Boolean)value ? "true" : "false"); } else { if(convStr) { sb.append("\"" + value.toString() .replace("\\", "\\\\") .replace("\"", "\\\"") .replace("\r", "\\r") .replace("\n", "\\n")+ "\""); } else { sb.append(value.toString()); } } } /** * 将任意类型转换成int * * @param value - 要转换的类型 * @return - 转换后的结果 */ public static long toLong(Object value) { try { if(value instanceof Long) return (Long)value; if(value instanceof Integer) return (long)(Integer)value; if(value instanceof String) return Long.parseLong((String)value); return (Long)(value.getClass().getMethod("longValue").invoke(value)); } catch(Exception ex) { return Long.parseLong(value.toString()); } } /** * 将任意类型转换成double * * @param value - 要转换的类型 * @return - 转换后的结果 */ public static double toDouble(Object value) { try { if(value instanceof Double) return (Double)value; if(value instanceof String) return Double.parseDouble((String)value); return (Double)(value.getClass().getMethod("doubleValue").invoke(value)); } catch(Exception ex) { return Double.parseDouble(value.toString()); } } public static Object convJsonToJS(Json json) { if(json.isObject()) { NativeObject nv = new NativeObject(); for(Entry entry : json.asJsonMap().entrySet()) { SMTStatic.putJSNotNullValue(nv, entry.getKey(), convJsonToJS(entry.getValue())); } return nv; } else if(json.isArray()) { List list = new ArrayList(); for(Json subJson : json.asJsonList()) { list.add(convJsonToJS(subJson)); } return new NativeArray(list.toArray(new Object[list.size()])); } else if(json.isNull()) return null; else return json.getValue(); } /** * 将文本数据以UTF-8格式写入文件 * * @param file - 要写入的文件名 * @param text - 要写入的内容 * @param append-是否要追加 */ public static void saveTextFile(File file, String text, boolean append) throws Exception { OutputStreamWriter wr = new OutputStreamWriter(new FileOutputStream(file, append), "UTF-8"); try { wr.write(text); } finally { wr.close(); } } public static double[] alignTimeRecordsToArray(TreeMap timeRecords, int fieldIndex, long timeS, long timeE, long timeStep) { double[] retValues = new double[(int)((timeE - timeS) / timeStep) + 1]; // 如果当前只有一个值,则全部对齐到这个值 if(timeRecords.size() == 1) { double value = 0; for(Object[] rec : timeRecords.values()) { value = SMTStatic.toDouble(rec[fieldIndex]); break; } for(long timeC = timeS; timeC <= timeE; timeC += timeStep) { retValues[(int)((timeC - timeS) / timeStep)] = value; } } // 如果当前有多个值,则进行插值 else { for(long timeC = timeS; timeC <= timeE; timeC += timeStep) { retValues[(int)((timeC - timeS) / timeStep)] = alignTimeRecordValue(timeRecords, timeC, fieldIndex); } } return retValues; } private static double alignTimeRecordValue(TreeMap timeRecords, long timeC, int fieldIndex) { // 尝试获取准点数据 Object[] rec = timeRecords.get(timeC); if(rec != null) return SMTStatic.toDouble(rec[fieldIndex]); // 获取左右数据 long timeS; long timeE; double valueS; double valueE; Entry entryL = timeRecords.lowerEntry(timeC); Entry entryR = timeRecords.higherEntry(timeC); // 如果没有左值,则取右右值 if(entryL == null) { Entry entryRR = timeRecords.higherEntry(entryR.getKey()); timeS = entryR.getKey(); timeE = entryRR.getKey(); valueS = SMTStatic.toDouble(entryR.getValue()[fieldIndex]); valueE = SMTStatic.toDouble(entryRR.getValue()[fieldIndex]); } // 如果没有右值,则取左左值 else if(entryR == null) { Entry entryLL = timeRecords.lowerEntry(entryL.getKey()); timeS = entryLL.getKey(); timeE = entryL.getKey(); valueS = SMTStatic.toDouble(entryLL.getValue()[fieldIndex]); valueE = SMTStatic.toDouble(entryL.getValue()[fieldIndex]); } // 左右插值 else { timeS = entryL.getKey(); timeE = entryR.getKey(); valueS = SMTStatic.toDouble(entryL.getValue()[fieldIndex]); valueE = SMTStatic.toDouble(entryR.getValue()[fieldIndex]); } // 计算插值 double valueC = (valueE - valueS) / (timeE - timeS) * (timeC - timeS) + valueS; return valueC; } public static long alignDayTimeTick(long time, long stepMS) { return (time - _baseTimeTick) / stepMS * stepMS + _baseTimeTick; } public static String getStdoutEncode() { String encoding = System.getProperty("sun.stdout.encoding"); if(!SMTStatic.isNullOrEmpty(encoding)) return encoding; String os = System.getProperty("os.name").toLowerCase(); if (os.contains("win")) return "GB2312"; else return "UTF-8"; } public static String getJavaExe() { String os = System.getProperty("os.name").toLowerCase(); if (os.contains("win")) return "java.exe"; else return "java"; } public static String[] convProcessArg(List args) { return convProcessArg(args.toArray(new String[args.size()])); } public static String[] convProcessArg(String[] args) { String os = System.getProperty("os.name").toLowerCase(); if (os.contains("win")) { for(int i = 0; i < args.length; i ++) { args[i] = args[i].replace("\"", "\\\""); } } return args; } }