package com.smtscript.lib; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Method; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.mozilla.javascript.NativeArray; import org.mozilla.javascript.NativeObject; import com.smtscript.utils.SMTStatic; public class JSStaticShell extends JSStaticAbstract { private Set _setLoadJarFiles = new HashSet<>(); public void executeMainInJar(String clzName, NativeObject nvDefines, NativeArray arrArgs) throws Exception { Class clzDefine = Class.forName(clzName); Method method = clzDefine.getMethod("main", String[].class); if(method == null) throw new Exception("can't find method : " + clzName + ".main(String[] args)"); if(nvDefines != null) { for(Entry entry : nvDefines.entrySet()) { String key = SMTStatic.toString(SMTStatic.unwrapObject(entry.getKey())); String value = SMTStatic.toString(SMTStatic.unwrapObject(entry.getValue())); System.setProperty(key, value); } } String[] args; if(arrArgs == null) { args = new String[0]; } else { args = new String[arrArgs.size()]; for(int i = 0; i < arrArgs.size(); i ++) { args[i] = SMTStatic.toString(SMTStatic.unwrapObject(arrArgs.get(i))); } } method.invoke(null, new Object[] {args}); } public void loadJarFiles(String basePath, NativeArray fileNames) throws IOException, Exception { List listFiles = new ArrayList<>(); for(int i = 0; i < fileNames.size(); i ++) { String fileName = SMTStatic.toString(SMTStatic.unwrapObject(fileNames.get(i))); File file = SMTStatic.isNullOrEmpty(basePath) ? new File(fileName) : new File(basePath, fileName); if(!file.exists()) throw new Exception("can't find jar file : " + file.getCanonicalPath()); if(_setLoadJarFiles.contains(file.getAbsolutePath())) continue; listFiles.add(file); _setLoadJarFiles.add(file.getAbsolutePath()); } SMTStatic.loadJarFiles(listFiles.toArray(new File[listFiles.size()]), (URLClassLoader)JSStaticShell.class.getClassLoader()); } @JSComment( "" + "@param nvConfig \n" + " cmd - String : command\n" + " args - String[] : arguments\n" + " path - String : current path\n" + " output - Boolean : output stdout and stderr (default false)\n" + " save - Boolean : save stdout and stderr for output (default true)\n" + " env - Object : key-value for env\n" + " nowait - Boolean : no wait procee exit (default false)\n" + " encode - String : encode for output (default GB2312)\n" + "@return\n" + " code- Integer: return code\n" + " stdout-String: stdout string\n" + " stderr-String: stderr string\n" + "" ) public NativeObject execute(NativeObject nvConfig) throws Exception { List params = new ArrayList(); params.add((String)SMTStatic.getJSValue(nvConfig, "cmd")); String encode = (String)SMTStatic.getJSValue(nvConfig, "encode", "GB2312"); NativeObject nvEnv = (NativeObject)SMTStatic.getJSValue(nvConfig, "env", null); boolean bOutput = (Boolean)SMTStatic.getJSValue(nvConfig, "output", false); boolean bSave = (Boolean)SMTStatic.getJSValue(nvConfig, "save", false); boolean bNoWait = (Boolean)SMTStatic.getJSValue(nvConfig, "nowait", false); NativeArray args = (NativeArray) SMTStatic.getJSValue(nvConfig, "args", null); if(args != null) { for(int i = 0; i < args.size(); i ++) { params.add((String)SMTStatic.unwrapObject(args.get(i))); } } ProcessBuilder pbuilder=new ProcessBuilder(SMTStatic.convProcessArg(params)); String workPath = (String) SMTStatic.getJSValue(nvConfig, "path", null); if(!SMTStatic.isNullOrEmpty(workPath)) pbuilder.directory(new File(workPath)); if(nvEnv != null) { Map runEnv = pbuilder.environment(); for(Entry entry : nvEnv.entrySet()) { runEnv.put(entry.getKey().toString(), entry.getValue().toString()); } } Process process = pbuilder.start(); if(bNoWait) return null; InputStream fis = process.getInputStream(); InputStream fes = process.getErrorStream(); try { BufferedReader bufferedStderr = new BufferedReader(new InputStreamReader(fes, encode)); BufferedReader bufferedStdout = new BufferedReader(new InputStreamReader(fis, encode)); char[] buf = new char[102400]; int size; StringBuilder sbStdout = new StringBuilder(); while((size = bufferedStdout.read(buf)) > 0) { if(bSave) sbStdout.append(buf, 0, size); if(bOutput) { for(int i = 0; i < size; i ++) System.out.print(buf[i]); } } StringBuilder sbError = new StringBuilder(); while((size = bufferedStderr.read(buf)) > 0) { if(bSave) sbError.append(buf, 0, size); if(bOutput) { for(int i = 0; i < size; i ++) System.out.print(buf[i]); } } int exitCode = process.waitFor(); NativeObject ret = new NativeObject(); SMTStatic.putJSNotNullValue(ret, "code", exitCode); SMTStatic.putJSNotNullValue(ret, "stdout", sbStdout.toString()); SMTStatic.putJSNotNullValue(ret, "stderr", sbError.toString()); return ret; } finally { fis.close(); fes.close(); } } }