package com.smtscript.lib; import java.io.ByteArrayOutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Field; import java.net.URLDecoder; import java.security.MessageDigest; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.mozilla.javascript.Context; import org.mozilla.javascript.NativeArray; import org.mozilla.javascript.NativeFunction; import org.mozilla.javascript.NativeObject; import org.mozilla.javascript.Wrapper; import com.smtscript.utils.Json; import com.smtscript.utils.SMTStatic; import com.smtscript.utils.SMTStatic.StringNamedFormat; public class JSStaticString extends JSStaticAbstract { private static Pattern _patTime2Second = Pattern.compile("^(\\d+)\\:(\\d+)(?:\\:(\\d+))?"); public String decodeURL(String str) throws Exception { return URLDecoder.decode(str, "UTF-8"); } public String toUpperCase(String str) { return str.toUpperCase(); } public String toLowerCase(String str) { return str.toLowerCase(); } public String trim(String str) { return str.trim(); } public int length(String str) { return str.length(); } public boolean startWith(String str, String prefix) { return str.startsWith(prefix); } public boolean endWith(String str, String suffix) { return str.endsWith(suffix); } public String replace(String str, String...replaces) { for(int i = 0; i < replaces.length; i += 2) { str = str.replace(replaces[i + 0], replaces[i + 1]); } return str; } public NativeArray splitLine(String str) { String[] sp = str.replace("\r", "").split("\n", -1); return new NativeArray(sp); } public String join(NativeArray arr, String joinStr) { StringBuilder sb = new StringBuilder(); if(arr.size() > 0) { sb.append(arr.get(0).toString()); for(int i = 1; i < arr.size(); i ++) { if(joinStr.length() > 0) sb.append(joinStr); sb.append(arr.get(i).toString()); } } return sb.toString(); } public NativeArray split(String str, String split) { String[] sp = str.split(split); return new NativeArray(sp); } public NativeArray split(String str, String split, int limit) { String[] sp = str.split(split, limit); return new NativeArray(sp); } public String md5(String str, String encode, boolean lowcase) throws Exception { // 初始化md5引擎 MessageDigest m = MessageDigest.getInstance("MD5"); m.update(str.getBytes(encode)); byte sign[] = m.digest(); StringBuilder sbSign = new StringBuilder(); for(byte c : sign) { sbSign.append(String.format(lowcase ? "%02x" : "%02X", c)); } return sbSign.toString(); } public String printfs(String fmt, String[] sargs) throws Exception { Object[] oargs = new Object[sargs.length]; for(int i = 0; i < sargs.length; i ++) { String value = sargs[i].substring(1); switch(sargs[i].charAt(0)) { case 'S': oargs[i] = value; break; case 'I': oargs[i] = Integer.parseInt(value); break; case 'L': oargs[i] = Long.parseLong(value); break; case 'D': oargs[i] = Double.parseDouble(value); break; default: throw new Exception("con't conv type : " + sargs[i]); } } return String.format(fmt, oargs); } public String printf(String fmt, Object...args) { return String.format(fmt, args); } @JSComment( "
\n" +
		"@param args - \n" +
		"    array      : array params\n" +
		"    map        : named map params params\n" +
		"    function(name): named function params params\n" +
		"
" ) public String format(String fmt, Object...args) { final Context[] cx = new Context[]{null}; try { if(args.length == 0) return fmt; List params = new ArrayList(); if(args[0] instanceof NativeObject) { List nameList = new ArrayList(); NativeObject nat = (NativeObject)args[0]; for(Object id : nat.getAllIds()) { nameList.add(new StringNamedFormat(id.toString(), params.size())); params.add(nat.get(id)); } params.add(nameList.toArray(new StringNamedFormat[nameList.size()])); } else if(args[0] instanceof NativeFunction) { cx[0] = this._parentScope.__runtime__().entryContext(); final NativeFunction func = (NativeFunction) args[0]; params.add(new SMTStatic.StringNamedNotify(){ @Override public Object getNamedValue(final String name, Object[] args) throws Exception { try { Object value = func.call(cx[0], func, null, new Object[]{name}); if(value instanceof Wrapper) return ((Wrapper)value).unwrap(); return value.toString(); } catch(Exception ex) { return null; } }; }); } else { for(Object value : args) { if(value instanceof Wrapper) params.add(((Wrapper)value).unwrap()); else params.add(value); } } return SMTStatic.stringFormat(fmt, params.toArray(new Object[params.size()])); } finally { if(cx[0] != null) Context.exit(); } } public Object toJson(String jsonStr) throws Exception { Json json = Json.read(jsonStr); Object ret = SMTStatic.convJsonToJS(json); return ret; } public int toInt(String str) { return Integer.parseInt(str); } public double toDouble(String str) { return Double.parseDouble(str); } public String addSecond(String date, int second) { Date time = SMTStatic.toDate(date); return SMTStatic.toString(new Date(time.getTime() + second * 1000)); } public String getToday() { return SMTStatic.toString(new Date()); } public String formatDate(String date, String format) { SimpleDateFormat sdf = new SimpleDateFormat(format); return sdf.format(SMTStatic.toDate(date)); } public String timeToString(Object time) throws Exception { long ltime = SMTStatic.toLong(SMTStatic.unwrapObject(time)); return SMTStatic.toString(new Date(ltime * 1000)); } public double stringToTime(String str) throws Exception { return (double)(SMTStatic.toDate(str).getTime() / 1000); } public String parseDate(String date, String format) throws Exception { if("Long".equalsIgnoreCase(format)) { return SMTStatic.toString(new Date(SMTStatic.toLong(date) * 1000)); } else { SimpleDateFormat sdf = new SimpleDateFormat(format); return SMTStatic.toString(sdf.parse(date)); } } public String stackTrace(Object value) throws Exception { if(value == null) return ""; if("org.mozilla.javascript.NativeError".equals(value.getClass().getName())) { Field field = value.getClass().getDeclaredField("stackProvider"); field.setAccessible(true); Object oo = field.get(value); if(oo != null && oo instanceof Throwable) { StringWriter sr = new StringWriter(); PrintWriter out = new PrintWriter(sr); ((Throwable)oo).printStackTrace(out); return sr.toString(); } } return value.toString(); } public void test1() throws Exception { throw new Exception("我们都是木头人"); } public String toString(Object obj) throws Exception { if(obj == null) return null; if("org.mozilla.javascript.NativeError".equals(obj.getClass().getName())) { Field field = obj.getClass().getDeclaredField("stackProvider"); field.setAccessible(true); Exception exception = (Exception) field.get(obj); ByteArrayOutputStream bos = new ByteArrayOutputStream(); PrintWriter pw = new PrintWriter(bos); exception.printStackTrace(pw); pw.close(); String str = new String(bos.toByteArray()); return str; } return SMTStatic.toString(obj); } public String formatJson(Object json) { StringBuilder sb = new StringBuilder(); convJsonToString(0, json, "", sb); return sb.toString(); } private static void convJsonToString(int level, Object json, String tailStr, StringBuilder sbRet) { String space = " "; String perfix = ""; for(int i = 0; i < level; i ++) { perfix += space; } if(json == null) { sbRet.append(perfix); sbRet.append("null" + tailStr + "\n"); } else if(json instanceof NativeObject) { //sbRet.append(perfix); if(sbRet.length() > 0) { char lastChar = sbRet.charAt(sbRet.length() - 1); if(lastChar == '\n') sbRet.append(perfix); } sbRet.append("{\n"); int curCount = 0; int totalCount = ((NativeObject)json).size(); for(Entry entry : ((NativeObject)json).entrySet()) { String curTailStr = (curCount < (totalCount - 1)) ? "," : ""; sbRet.append(perfix + space); sbRet.append("\"" + SMTStatic.toCStr(entry.getKey().toString()) + "\":"); Object value = SMTStatic.unwrapObject(entry.getValue()); if(value instanceof NativeObject || value instanceof NativeArray) { convJsonToString(level + 1, value, curTailStr, sbRet); } else { convJsonToString(0, value, curTailStr, sbRet); } if(curTailStr.length() == 0) curTailStr = ","; curCount ++; } sbRet.append(perfix); sbRet.append("}" + tailStr + "\n"); } else if(json instanceof NativeArray) { NativeArray naJson = (NativeArray)json; if(sbRet.length() > 0) { char lastChar = sbRet.charAt(sbRet.length() - 1); if(lastChar == '\n') sbRet.append(perfix); } sbRet.append("[\n"); for(int i = 0; i < naJson.size(); i ++) { String curTailStr = (i < (naJson.size() - 1)) ? "," : ""; Object value = SMTStatic.unwrapObject(naJson.get(i)); if(value instanceof NativeObject || value instanceof NativeArray) { convJsonToString(level + 1, value, curTailStr, sbRet); } else { convJsonToString(level + 1, value, curTailStr, sbRet); } } sbRet.append(perfix); sbRet.append("]" + tailStr + "\n"); } else if(json instanceof String) { sbRet.append(perfix); sbRet.append("\"" + SMTStatic.toCStr(json.toString()) + "\"" + tailStr + "\n"); } else { sbRet.append(perfix); sbRet.append(SMTStatic.toString(json) + tailStr + "\n"); } } public int timeToSeconds(String time, boolean lastIsSecond) throws Exception { Matcher m = _patTime2Second.matcher(time); if(!m.find()) throw new Exception("unknow time format : " + time); int second = Integer.parseInt(m.group(1)); second = second * 60 + Integer.parseInt(m.group(2)); if(lastIsSecond) { if(SMTStatic.isNullOrEmpty(m.group(3))) return second; else return second * 60 + Integer.parseInt(m.group(3)); } else { if(SMTStatic.isNullOrEmpty(m.group(3))) return second * 60; else throw new Exception("error format for minute : " + time); } } public String secondsToTime(int time, boolean lastIsSecond) { if(lastIsSecond) { int second = time % 60; int minuteV = time / 60; int minute = minuteV % 60; int hour = minuteV / 60; return String.format("%02d:%02d:%02d", hour, minute, second); } else { int minuteV = time / 60; int minute = minuteV % 60; int hour = minuteV / 60; return String.format("%02d:%02d", hour, minute); } } public String Str2Hex(String str) { int size = str.length(); StringBuilder sb = new StringBuilder(); for(int i = 0; i < size; i ++) { sb.append(String.format("%04X", (int)str.charAt(i))); } return sb.toString(); } }