Skip to content

Commit 2bd80f9

Browse files
committed
8264326: Modernize javax.script.ScriptEngineManager and related classes' implementation
Reviewed-by: sundar
1 parent b08d638 commit 2bd80f9

File tree

5 files changed

+87
-187
lines changed

5 files changed

+87
-187
lines changed

src/java.scripting/share/classes/javax/script/AbstractScriptEngine.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525

2626
package javax.script;
2727
import java.io.Reader;
28-
import java.util.Map;
29-
import java.util.Iterator;
3028

3129
/**
3230
* Provides a standard implementation for several of the variants of the <code>eval</code>
@@ -141,9 +139,9 @@ public Bindings getBindings(int scope) {
141139
public void setBindings(Bindings bindings, int scope) {
142140

143141
if (scope == ScriptContext.GLOBAL_SCOPE) {
144-
context.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);;
142+
context.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
145143
} else if (scope == ScriptContext.ENGINE_SCOPE) {
146-
context.setBindings(bindings, ScriptContext.ENGINE_SCOPE);;
144+
context.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
147145
} else {
148146
throw new IllegalArgumentException("Invalid scope value.");
149147
}

src/java.scripting/share/classes/javax/script/ScriptEngineManager.java

Lines changed: 75 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import java.security.*;
2929
import java.util.ServiceLoader;
3030
import java.util.ServiceConfigurationError;
31+
import java.util.function.Function;
32+
import java.util.stream.Stream;
3133

3234
/**
3335
* The <code>ScriptEngineManager</code> implements a discovery and instantiation
@@ -58,8 +60,7 @@ public class ScriptEngineManager {
5860
* @see java.lang.Thread#getContextClassLoader
5961
*/
6062
public ScriptEngineManager() {
61-
ClassLoader ctxtLoader = Thread.currentThread().getContextClassLoader();
62-
init(ctxtLoader);
63+
this(Thread.currentThread().getContextClassLoader());
6364
}
6465

6566
/**
@@ -72,18 +73,6 @@ public ScriptEngineManager() {
7273
* @param loader ClassLoader used to discover script engine factories.
7374
*/
7475
public ScriptEngineManager(ClassLoader loader) {
75-
init(loader);
76-
}
77-
78-
private void init(final ClassLoader loader) {
79-
globalScope = new SimpleBindings();
80-
engineSpis = new TreeSet<ScriptEngineFactory>(Comparator.comparing(
81-
ScriptEngineFactory::getEngineName,
82-
Comparator.nullsLast(Comparator.naturalOrder()))
83-
);
84-
nameAssociations = new HashMap<String, ScriptEngineFactory>();
85-
extensionAssociations = new HashMap<String, ScriptEngineFactory>();
86-
mimeTypeAssociations = new HashMap<String, ScriptEngineFactory>();
8776
initEngines(loader);
8877
}
8978

@@ -96,23 +85,13 @@ private ServiceLoader<ScriptEngineFactory> getServiceLoader(final ClassLoader lo
9685
}
9786

9887
private void initEngines(final ClassLoader loader) {
99-
Iterator<ScriptEngineFactory> itr = null;
88+
Iterator<ScriptEngineFactory> itr;
10089
try {
101-
ServiceLoader<ScriptEngineFactory> sl = AccessController.doPrivileged(
102-
new PrivilegedAction<ServiceLoader<ScriptEngineFactory>>() {
103-
@Override
104-
public ServiceLoader<ScriptEngineFactory> run() {
105-
return getServiceLoader(loader);
106-
}
107-
});
108-
90+
var sl = AccessController.doPrivileged(
91+
(PrivilegedAction<ServiceLoader<ScriptEngineFactory>>)() -> getServiceLoader(loader));
10992
itr = sl.iterator();
11093
} catch (ServiceConfigurationError err) {
111-
System.err.println("Can't find ScriptEngineFactory providers: " +
112-
err.getMessage());
113-
if (DEBUG) {
114-
err.printStackTrace();
115-
}
94+
reportException("Can't find ScriptEngineFactory providers: ", err);
11695
// do not throw any exception here. user may want to
11796
// manage his/her own factories using this manager
11897
// by explicit registratation (by registerXXX) methods.
@@ -125,25 +104,15 @@ public ServiceLoader<ScriptEngineFactory> run() {
125104
ScriptEngineFactory fact = itr.next();
126105
engineSpis.add(fact);
127106
} catch (ServiceConfigurationError err) {
128-
System.err.println("ScriptEngineManager providers.next(): "
129-
+ err.getMessage());
130-
if (DEBUG) {
131-
err.printStackTrace();
132-
}
107+
reportException("ScriptEngineManager providers.next(): ", err);
133108
// one factory failed, but check other factories...
134-
continue;
135109
}
136110
}
137111
} catch (ServiceConfigurationError err) {
138-
System.err.println("ScriptEngineManager providers.hasNext(): "
139-
+ err.getMessage());
140-
if (DEBUG) {
141-
err.printStackTrace();
142-
}
112+
reportException("ScriptEngineManager providers.hasNext(): ", err);
143113
// do not throw any exception here. user may want to
144114
// manage his/her own factories using this manager
145115
// by explicit registratation (by registerXXX) methods.
146-
return;
147116
}
148117
}
149118

@@ -212,44 +181,7 @@ public Object get(String key) {
212181
* @throws NullPointerException if shortName is null.
213182
*/
214183
public ScriptEngine getEngineByName(String shortName) {
215-
if (shortName == null) throw new NullPointerException();
216-
//look for registered name first
217-
Object obj;
218-
if (null != (obj = nameAssociations.get(shortName))) {
219-
ScriptEngineFactory spi = (ScriptEngineFactory)obj;
220-
try {
221-
ScriptEngine engine = spi.getScriptEngine();
222-
engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
223-
return engine;
224-
} catch (Exception exp) {
225-
if (DEBUG) exp.printStackTrace();
226-
}
227-
}
228-
229-
for (ScriptEngineFactory spi : engineSpis) {
230-
List<String> names = null;
231-
try {
232-
names = spi.getNames();
233-
} catch (Exception exp) {
234-
if (DEBUG) exp.printStackTrace();
235-
}
236-
237-
if (names != null) {
238-
for (String name : names) {
239-
if (shortName.equals(name)) {
240-
try {
241-
ScriptEngine engine = spi.getScriptEngine();
242-
engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
243-
return engine;
244-
} catch (Exception exp) {
245-
if (DEBUG) exp.printStackTrace();
246-
}
247-
}
248-
}
249-
}
250-
}
251-
252-
return null;
184+
return getEngineBy(shortName, nameAssociations, ScriptEngineFactory::getNames);
253185
}
254186

255187
/**
@@ -263,41 +195,7 @@ public ScriptEngine getEngineByName(String shortName) {
263195
* @throws NullPointerException if extension is null.
264196
*/
265197
public ScriptEngine getEngineByExtension(String extension) {
266-
if (extension == null) throw new NullPointerException();
267-
//look for registered extension first
268-
Object obj;
269-
if (null != (obj = extensionAssociations.get(extension))) {
270-
ScriptEngineFactory spi = (ScriptEngineFactory)obj;
271-
try {
272-
ScriptEngine engine = spi.getScriptEngine();
273-
engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
274-
return engine;
275-
} catch (Exception exp) {
276-
if (DEBUG) exp.printStackTrace();
277-
}
278-
}
279-
280-
for (ScriptEngineFactory spi : engineSpis) {
281-
List<String> exts = null;
282-
try {
283-
exts = spi.getExtensions();
284-
} catch (Exception exp) {
285-
if (DEBUG) exp.printStackTrace();
286-
}
287-
if (exts == null) continue;
288-
for (String ext : exts) {
289-
if (extension.equals(ext)) {
290-
try {
291-
ScriptEngine engine = spi.getScriptEngine();
292-
engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
293-
return engine;
294-
} catch (Exception exp) {
295-
if (DEBUG) exp.printStackTrace();
296-
}
297-
}
298-
}
299-
}
300-
return null;
198+
return getEngineBy(extension, extensionAssociations, ScriptEngineFactory::getExtensions);
301199
}
302200

303201
/**
@@ -311,41 +209,52 @@ public ScriptEngine getEngineByExtension(String extension) {
311209
* @throws NullPointerException if mimeType is null.
312210
*/
313211
public ScriptEngine getEngineByMimeType(String mimeType) {
314-
if (mimeType == null) throw new NullPointerException();
315-
//look for registered types first
316-
Object obj;
317-
if (null != (obj = mimeTypeAssociations.get(mimeType))) {
318-
ScriptEngineFactory spi = (ScriptEngineFactory)obj;
319-
try {
320-
ScriptEngine engine = spi.getScriptEngine();
321-
engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
322-
return engine;
323-
} catch (Exception exp) {
324-
if (DEBUG) exp.printStackTrace();
325-
}
326-
}
212+
return getEngineBy(mimeType, mimeTypeAssociations, ScriptEngineFactory::getMimeTypes);
213+
}
327214

328-
for (ScriptEngineFactory spi : engineSpis) {
329-
List<String> types = null;
330-
try {
331-
types = spi.getMimeTypes();
332-
} catch (Exception exp) {
333-
if (DEBUG) exp.printStackTrace();
334-
}
335-
if (types == null) continue;
336-
for (String type : types) {
337-
if (mimeType.equals(type)) {
338-
try {
339-
ScriptEngine engine = spi.getScriptEngine();
340-
engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
341-
return engine;
342-
} catch (Exception exp) {
343-
if (DEBUG) exp.printStackTrace();
344-
}
215+
private ScriptEngine getEngineBy(String selector, Map<String, ScriptEngineFactory> associations,
216+
Function<ScriptEngineFactory, List<String>> valuesFn)
217+
{
218+
Objects.requireNonNull(selector);
219+
Stream<ScriptEngineFactory> spis = Stream.concat(
220+
//look for registered types first
221+
Stream.ofNullable(associations.get(selector)),
222+
223+
engineSpis.stream().filter(spi -> {
224+
try {
225+
List<String> matches = valuesFn.apply(spi);
226+
return matches != null && matches.contains(selector);
227+
} catch (Exception exp) {
228+
debugPrint(exp);
229+
return false;
345230
}
346-
}
231+
})
232+
);
233+
return spis
234+
.map(spi -> {
235+
try {
236+
ScriptEngine engine = spi.getScriptEngine();
237+
engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
238+
return engine;
239+
} catch (Exception exp) {
240+
debugPrint(exp);
241+
return null;
242+
}
243+
})
244+
.filter(Objects::nonNull)
245+
.findFirst()
246+
.orElse(null);
247+
}
248+
249+
private static void reportException(String msg, Throwable exp) {
250+
System.err.println(msg + exp.getMessage());
251+
debugPrint(exp);
252+
}
253+
254+
private static void debugPrint(Throwable exp) {
255+
if (DEBUG) {
256+
exp.printStackTrace();
347257
}
348-
return null;
349258
}
350259

351260
/**
@@ -354,11 +263,7 @@ public ScriptEngine getEngineByMimeType(String mimeType) {
354263
* @return List of all discovered <code>ScriptEngineFactory</code>s.
355264
*/
356265
public List<ScriptEngineFactory> getEngineFactories() {
357-
List<ScriptEngineFactory> res = new ArrayList<ScriptEngineFactory>(engineSpis.size());
358-
for (ScriptEngineFactory spi : engineSpis) {
359-
res.add(spi);
360-
}
361-
return Collections.unmodifiableList(res);
266+
return List.copyOf(engineSpis);
362267
}
363268

364269
/**
@@ -369,8 +274,7 @@ public List<ScriptEngineFactory> getEngineFactories() {
369274
* @throws NullPointerException if any of the parameters is null.
370275
*/
371276
public void registerEngineName(String name, ScriptEngineFactory factory) {
372-
if (name == null || factory == null) throw new NullPointerException();
373-
nameAssociations.put(name, factory);
277+
associateFactory(nameAssociations, name, factory);
374278
}
375279

376280
/**
@@ -384,8 +288,7 @@ public void registerEngineName(String name, ScriptEngineFactory factory) {
384288
* @throws NullPointerException if any of the parameters is null.
385289
*/
386290
public void registerEngineMimeType(String type, ScriptEngineFactory factory) {
387-
if (type == null || factory == null) throw new NullPointerException();
388-
mimeTypeAssociations.put(type, factory);
291+
associateFactory(mimeTypeAssociations, type, factory);
389292
}
390293

391294
/**
@@ -398,22 +301,33 @@ public void registerEngineMimeType(String type, ScriptEngineFactory factory) {
398301
* @throws NullPointerException if any of the parameters is null.
399302
*/
400303
public void registerEngineExtension(String extension, ScriptEngineFactory factory) {
401-
if (extension == null || factory == null) throw new NullPointerException();
402-
extensionAssociations.put(extension, factory);
304+
associateFactory(extensionAssociations, extension, factory);
403305
}
404306

307+
private static void associateFactory(Map<String, ScriptEngineFactory> associations, String association,
308+
ScriptEngineFactory factory)
309+
{
310+
if (association == null || factory == null) throw new NullPointerException();
311+
associations.put(association, factory);
312+
}
313+
314+
private static final Comparator<ScriptEngineFactory> COMPARATOR = Comparator.comparing(
315+
ScriptEngineFactory::getEngineName,
316+
Comparator.nullsLast(Comparator.naturalOrder())
317+
);
318+
405319
/** Set of script engine factories discovered. */
406-
private TreeSet<ScriptEngineFactory> engineSpis;
320+
private final TreeSet<ScriptEngineFactory> engineSpis = new TreeSet<>(COMPARATOR);
407321

408322
/** Map of engine name to script engine factory. */
409-
private HashMap<String, ScriptEngineFactory> nameAssociations;
323+
private final HashMap<String, ScriptEngineFactory> nameAssociations = new HashMap<>();
410324

411325
/** Map of script file extension to script engine factory. */
412-
private HashMap<String, ScriptEngineFactory> extensionAssociations;
326+
private final HashMap<String, ScriptEngineFactory> extensionAssociations = new HashMap<>();
413327

414328
/** Map of script MIME type to script engine factory. */
415-
private HashMap<String, ScriptEngineFactory> mimeTypeAssociations;
329+
private final HashMap<String, ScriptEngineFactory> mimeTypeAssociations = new HashMap<>();
416330

417331
/** Global bindings associated with script engines created by this manager. */
418-
private Bindings globalScope;
332+
private Bindings globalScope = new SimpleBindings();
419333
}

src/java.scripting/share/classes/javax/script/ScriptException.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ public class ScriptException extends Exception {
3838

3939
private static final long serialVersionUID = 8265071037049225001L;
4040

41-
private String fileName;
42-
private int lineNumber;
43-
private int columnNumber;
41+
private final String fileName;
42+
private final int lineNumber;
43+
private final int columnNumber;
4444

4545
/**
4646
* Creates a <code>ScriptException</code> with a String to be used in its message.

0 commit comments

Comments
 (0)