001package com.killcoding.jsplus; 002 003import javax.script.ScriptEngine; 004import javax.script.ScriptEngineManager; 005import javax.script.ScriptEngineFactory; 006import javax.script.Invocable; 007import javax.script.Bindings; 008import javax.script.ScriptContext; 009import javax.script.SimpleScriptContext; 010import com.killcoding.jsplus.JsPlusContext; 011import com.killcoding.tool.CommonTools; 012import java.nio.file.Files; 013import java.util.List; 014import java.nio.file.Paths; 015import com.killcoding.tool.FileTools; 016import java.io.File; 017import com.killcoding.file.DiskFile; 018import com.killcoding.tool.CipherTools; 019import com.killcoding.file.BaseFile; 020import com.killcoding.jsplus.ScriptConsole; 021 022public class JsContext extends JsPlusContext { 023 024 private ScriptEngineManager scriptEngineManager = null; 025 private Invocable invocable = null; 026 private ScriptEngine scriptEngine = null; 027 private ScriptContext context = null; 028 private Bindings bindings = null; 029 030 public JsContext(String engineName){ 031 super(engineName); 032 } 033 034 @Override 035 public Object getBindings(){ 036 return bindings; 037 } 038 039 @Override 040 public ScriptEngineManager getEngine(){ 041 return scriptEngineManager; 042 } 043 044 @Override 045 public ScriptContext getContext(){ 046 return context; 047 } 048 049 @Override 050 public void remove(String name){ 051 bindings.remove(name); 052 } 053 054 @Override 055 public void put(String name,Object value){ 056 bindings.put(name,value); 057 } 058 059 @Override 060 public Object get(String name){ 061 return bindings.get(name); 062 } 063 064 @Override 065 public void initScriptEngineManager() throws Exception { 066 ClassLoader classLoader = null; 067 classLoader = ClassLoader.getSystemClassLoader(); 068 scriptEngineManager = new ScriptEngineManager(); 069 List<ScriptEngineFactory> factories = scriptEngineManager.getEngineFactories(); 070 for (ScriptEngineFactory factory : factories) { 071 System.out.println( 072 String.format("%s %s %s", factory.getEngineName(), factory.getEngineVersion(), factory.getNames())); 073 } 074 if (factories.isEmpty()) { 075 System.out.println("No script engines found"); 076 } else { 077 scriptEngine = scriptEngineManager.getEngineByName(engineName); 078 if(scriptEngine == null){ 079 throw new Exception(String.format("Missing engine '%s'.",engineName)); 080 } 081 context = new SimpleScriptContext(); 082 context.setBindings(scriptEngine.createBindings(), ScriptContext.ENGINE_SCOPE); 083 bindings = context.getBindings(ScriptContext.ENGINE_SCOPE); 084 bindings.put("ScriptClassLoader", classLoader); 085 disableAllowAllAccess(); 086 invocable = (Invocable) scriptEngine; 087 } 088 } 089 090 @Override 091 public void setAllowAllAccess(boolean allowAllAccess){ 092 this.allowAllAccess = allowAllAccess; 093 disableAllowAllAccess(); 094 } 095 096 @Override 097 public Object eval(String scriptPath) throws Exception { 098 return eval(new File(scriptPath)); 099 } 100 101 @Override 102 public Object eval(File scriptPath) throws Exception { 103 String script = null; 104 if(CommonTools.isBlank(scriptCipherAesKey)){ 105 script = FileTools.text(scriptPath); 106 }else{ 107 DiskFile df = new DiskFile(scriptPath); 108 byte[] encryptBytes = df.readAllBytes(); 109 byte[] decryptBytes = CipherTools.AESDecrypt(scriptCipherAesKey,encryptBytes); 110 script = new String(decryptBytes,BaseFile.CHARSET); 111 } 112 Object result = scriptEngine.eval(script, context); 113 scriptEngine.setContext(context); 114 invocable = (Invocable) scriptEngine; 115 return result; 116 } 117 118 @Override 119 public Object evalScript(String script) throws Exception { 120 Object result = scriptEngine.eval(script, context); 121 scriptEngine.setContext(context); 122 invocable = (Invocable) scriptEngine; 123 return result; 124 } 125 126 @Override 127 public void close(){ 128 bindings.clear(); 129 bindings = null; 130 context = null; 131 } 132 133 @Override 134 public String getEngineName(){ 135 return engineName; 136 } 137 138 protected void disableAllowAllAccess(){ 139 if(!this.allowAllAccess && bindings != null){ 140 bindings.put("Java", null); 141 bindings.put("JavaImporter", null); 142 bindings.put("java", null); 143 bindings.put("javax", null); 144 bindings.put("app", null); 145 bindings.put("com", null); 146 bindings.put("org", null); 147 bindings.put("net", null); 148 bindings.put("sun", null); 149 bindings.put("android", null); 150 bindings.put("oracle", null); 151 bindings.put("ibm", null); 152 bindings.put("io", null); 153 bindings.put("jdk", null); 154 bindings.put("jakarta", null); 155 } 156 } 157 158}