NashornScriptEngineFactory.java revision 953:221a84ef44c0
175584Sru/* 2104862Sru * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 375584Sru * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 475584Sru * 575584Sru * This code is free software; you can redistribute it and/or modify it 675584Sru * under the terms of the GNU General Public License version 2 only, as 775584Sru * published by the Free Software Foundation. Oracle designates this 875584Sru * particular file as subject to the "Classpath" exception as provided 975584Sru * by Oracle in the LICENSE file that accompanied this code. 1075584Sru * 1175584Sru * This code is distributed in the hope that it will be useful, but WITHOUT 1275584Sru * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1375584Sru * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1475584Sru * version 2 for more details (a copy is included in the LICENSE file that 1575584Sru * accompanied this code). 1675584Sru * 1775584Sru * You should have received a copy of the GNU General Public License version 1875584Sru * 2 along with this work; if not, write to the Free Software Foundation, 19151497Sru * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2075584Sru * 2175584Sru * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22104862Sru * or visit www.oracle.com if you need additional information or have any 2375584Sru * questions. 2475584Sru */ 2575584Sru 26104862Srupackage jdk.nashorn.api.scripting; 2775584Sru 2875584Sruimport java.util.Arrays; 2975584Sruimport java.util.Collections; 3075584Sruimport java.util.List; 3175584Sruimport javax.script.ScriptEngine; 3275584Sruimport javax.script.ScriptEngineFactory; 3375584Sruimport jdk.nashorn.internal.runtime.Context; 3475584Sruimport jdk.nashorn.internal.runtime.Version; 3575584Sru 36104862Sru/** 3775584Sru * JSR-223 compliant script engine factory for Nashorn. The engine answers for: 3875584Sru * <ul> 3975584Sru * <li>names {@code "nashorn"}, {@code "Nashorn"}, {@code "js"}, {@code "JS"}, {@code "JavaScript"}, 4075584Sru * {@code "javascript"}, {@code "ECMAScript"}, and {@code "ecmascript"};</li> 4175584Sru * <li>MIME types {@code "application/javascript"}, {@code "application/ecmascript"}, {@code "text/javascript"}, and 4275584Sru * {@code "text/ecmascript"};</li> 4375584Sru * <li>as well as for the extension {@code "js"}.</li> 4475584Sru * </ul> 4575584Sru * Programs executing in engines created using {@link #getScriptEngine(String[])} will have the passed arguments 4675584Sru * accessible as a global variable named {@code "arguments"}. 4775584Sru */ 48public final class NashornScriptEngineFactory implements ScriptEngineFactory { 49 @Override 50 public String getEngineName() { 51 return (String) getParameter(ScriptEngine.ENGINE); 52 } 53 54 @Override 55 public String getEngineVersion() { 56 return (String) getParameter(ScriptEngine.ENGINE_VERSION); 57 } 58 59 @Override 60 public List<String> getExtensions() { 61 return Collections.unmodifiableList(extensions); 62 } 63 64 @Override 65 public String getLanguageName() { 66 return (String) getParameter(ScriptEngine.LANGUAGE); 67 } 68 69 @Override 70 public String getLanguageVersion() { 71 return (String) getParameter(ScriptEngine.LANGUAGE_VERSION); 72 } 73 74 @Override 75 public String getMethodCallSyntax(final String obj, final String method, final String... args) { 76 final StringBuilder sb = new StringBuilder().append(obj).append('.').append(method).append('('); 77 final int len = args.length; 78 79 if (len > 0) { 80 sb.append(args[0]); 81 } 82 for (int i = 1; i < len; i++) { 83 sb.append(',').append(args[i]); 84 } 85 sb.append(')'); 86 87 return sb.toString(); 88 } 89 90 @Override 91 public List<String> getMimeTypes() { 92 return Collections.unmodifiableList(mimeTypes); 93 } 94 95 @Override 96 public List<String> getNames() { 97 return Collections.unmodifiableList(names); 98 } 99 100 @Override 101 public String getOutputStatement(final String toDisplay) { 102 return "print(" + toDisplay + ")"; 103 } 104 105 @Override 106 public Object getParameter(final String key) { 107 switch (key) { 108 case ScriptEngine.NAME: 109 return "javascript"; 110 case ScriptEngine.ENGINE: 111 return "Oracle Nashorn"; 112 case ScriptEngine.ENGINE_VERSION: 113 return Version.version(); 114 case ScriptEngine.LANGUAGE: 115 return "ECMAScript"; 116 case ScriptEngine.LANGUAGE_VERSION: 117 return "ECMA - 262 Edition 5.1"; 118 case "THREADING": 119 // The engine implementation is not thread-safe. Can't be 120 // used to execute scripts concurrently on multiple threads. 121 return null; 122 default: 123 throw new IllegalArgumentException("Invalid key"); 124 } 125 } 126 127 @Override 128 public String getProgram(final String... statements) { 129 final StringBuilder sb = new StringBuilder(); 130 131 for (final String statement : statements) { 132 sb.append(statement).append(';'); 133 } 134 135 return sb.toString(); 136 } 137 138 @Override 139 public ScriptEngine getScriptEngine() { 140 try { 141 return new NashornScriptEngine(this, getAppClassLoader()); 142 } catch (final RuntimeException e) { 143 if (Context.DEBUG) { 144 e.printStackTrace(); 145 } 146 throw e; 147 } 148 } 149 150 /** 151 * Create a new Script engine initialized by given class loader. 152 * 153 * @param appLoader class loader to be used as script "app" class loader. 154 * @return newly created script engine. 155 */ 156 public ScriptEngine getScriptEngine(final ClassLoader appLoader) { 157 checkConfigPermission(); 158 return new NashornScriptEngine(this, appLoader); 159 } 160 161 /** 162 * Create a new Script engine initialized by given arguments. 163 * 164 * @param args arguments array passed to script engine. 165 * @return newly created script engine. 166 */ 167 public ScriptEngine getScriptEngine(final String... args) { 168 checkConfigPermission(); 169 return new NashornScriptEngine(this, args, getAppClassLoader()); 170 } 171 172 /** 173 * Create a new Script engine initialized by given arguments. 174 * 175 * @param args arguments array passed to script engine. 176 * @param appLoader class loader to be used as script "app" class loader. 177 * @return newly created script engine. 178 */ 179 public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader) { 180 checkConfigPermission(); 181 return new NashornScriptEngine(this, args, appLoader); 182 } 183 184 // -- Internals only below this point 185 186 private static void checkConfigPermission() { 187 final SecurityManager sm = System.getSecurityManager(); 188 if (sm != null) { 189 sm.checkPermission(new RuntimePermission(Context.NASHORN_SET_CONFIG)); 190 } 191 } 192 193 private static final List<String> names; 194 private static final List<String> mimeTypes; 195 private static final List<String> extensions; 196 197 static { 198 names = immutableList( 199 "nashorn", "Nashorn", 200 "js", "JS", 201 "JavaScript", "javascript", 202 "ECMAScript", "ecmascript" 203 ); 204 205 mimeTypes = immutableList( 206 "application/javascript", 207 "application/ecmascript", 208 "text/javascript", 209 "text/ecmascript" 210 ); 211 212 extensions = immutableList("js"); 213 } 214 215 private static List<String> immutableList(final String... elements) { 216 return Collections.unmodifiableList(Arrays.asList(elements)); 217 } 218 219 private static ClassLoader getAppClassLoader() { 220 // Revisit: script engine implementation needs the capability to 221 // find the class loader of the context in which the script engine 222 // is running so that classes will be found and loaded properly 223 final ClassLoader ccl = Thread.currentThread().getContextClassLoader(); 224 return (ccl == null)? NashornScriptEngineFactory.class.getClassLoader() : ccl; 225 } 226} 227