src/jdk/nashorn/api/scripting/NashornScriptEngine.java

Print this page




 298         }
 299 
 300         // perform security access check as early as possible
 301         final SecurityManager sm = System.getSecurityManager();
 302         if (sm != null) {
 303             if (! Modifier.isPublic(clazz.getModifiers())) {
 304                 throw new SecurityException(getMessage("implementing.non.public.interface", clazz.getName()));
 305             }
 306             Context.checkPackageAccess(clazz.getName());
 307         }
 308 
 309         ScriptObject realSelf = null;
 310         ScriptObject realGlobal = null;
 311         if(thiz == null) {
 312             // making interface out of global functions
 313             realSelf = realGlobal = getNashornGlobalFrom(context);
 314         } else if (thiz instanceof ScriptObjectMirror) {
 315             final ScriptObjectMirror mirror = (ScriptObjectMirror)thiz;
 316             realSelf = mirror.getScriptObject();
 317             realGlobal = mirror.getHomeGlobal();
 318             if (! realGlobal.isOfContext(nashornContext)) {
 319                 throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
 320             }
 321         } else if (thiz instanceof ScriptObject) {
 322             // called from script code.
 323             realSelf = (ScriptObject)thiz;
 324             realGlobal = Context.getGlobal();
 325             if (realGlobal == null) {
 326                 throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
 327             }
 328 
 329             if (! realGlobal.isOfContext(nashornContext)) {
 330                 throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
 331             }
 332         }
 333 
 334         if (realSelf == null) {
 335             throw new IllegalArgumentException(getMessage("interface.on.non.script.object"));
 336         }
 337 
 338         try {
 339             final ScriptObject oldGlobal = Context.getGlobal();
 340             final boolean globalChanged = (oldGlobal != realGlobal);
 341             try {
 342                 if (globalChanged) {
 343                     Context.setGlobal(realGlobal);
 344                 }
 345 
 346                 if (! isInterfaceImplemented(clazz, realSelf)) {
 347                     return null;
 348                 }
 349                 return clazz.cast(JavaAdapterFactory.getConstructor(realSelf.getClass(), clazz).invoke(realSelf));


 377 
 378         // Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it!
 379         Object scope = bindings.get(NASHORN_GLOBAL);
 380         if (scope instanceof ScriptObjectMirror) {
 381             final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)scope);
 382             if (sobj != null) {
 383                 return sobj;
 384             }
 385         }
 386 
 387         // We didn't find associated nashorn global mirror in the Bindings given!
 388         // Create new global instance mirror and associate with the Bindings.
 389         final ScriptObjectMirror mirror = createGlobalMirror(ctxt);
 390         bindings.put(NASHORN_GLOBAL, mirror);
 391         return mirror.getScriptObject();
 392     }
 393 
 394     // Retrieve nashorn Global object from a given ScriptObjectMirror
 395     private ScriptObject globalFromMirror(final ScriptObjectMirror mirror) {
 396         ScriptObject sobj = mirror.getScriptObject();
 397         if (sobj instanceof GlobalObject && sobj.isOfContext(nashornContext)) {
 398             return sobj;
 399         }
 400 
 401         return null;
 402     }
 403 
 404     // Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object
 405     private ScriptObjectMirror createGlobalMirror(final ScriptContext ctxt) {
 406         final ScriptObject newGlobal = createNashornGlobal(ctxt);
 407         return new ScriptObjectMirror(newGlobal, newGlobal);
 408     }
 409 
 410     // Create a new Nashorn Global object
 411     private ScriptObject createNashornGlobal(final ScriptContext ctxt) {
 412         final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() {
 413             @Override
 414             public ScriptObject run() {
 415                 try {
 416                     return nashornContext.newGlobal();
 417                 } catch (final RuntimeException e) {


 453         // set "context" global variable via contextProperty - because this
 454         // property is non-writable
 455         contextProperty.setObjectValue(ctxtGlobal, ctxtGlobal, ctxt, false);
 456         Object args = ScriptObjectMirror.unwrap(ctxt.getAttribute("arguments"), ctxtGlobal);
 457         if (args == null || args == UNDEFINED) {
 458             args = ScriptRuntime.EMPTY_ARRAY;
 459         }
 460         // if no arguments passed, expose it
 461         if (! (args instanceof ScriptObject)) {
 462             args = ((GlobalObject)ctxtGlobal).wrapAsObject(args);
 463             ctxtGlobal.set("arguments", args, false);
 464         }
 465     }
 466 
 467     private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
 468         name.getClass(); // null check
 469 
 470         ScriptObjectMirror selfMirror = null;
 471         if (selfObject instanceof ScriptObjectMirror) {
 472             selfMirror = (ScriptObjectMirror)selfObject;
 473             if (! selfMirror.getHomeGlobal().isOfContext(nashornContext)) {
 474                 throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
 475             }
 476         } else if (selfObject instanceof ScriptObject) {
 477             // invokeMethod called from script code - in which case we may get 'naked' ScriptObject
 478             // Wrap it with oldGlobal to make a ScriptObjectMirror for the same.
 479             final ScriptObject oldGlobal = Context.getGlobal();
 480             if (oldGlobal == null) {
 481                 throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
 482             }
 483 
 484             if (! oldGlobal.isOfContext(nashornContext)) {
 485                 throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
 486             }
 487 
 488             selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal);
 489         } else if (selfObject == null) {
 490             // selfObject is null => global function call
 491             final ScriptObject ctxtGlobal = getNashornGlobalFrom(context);
 492             selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(ctxtGlobal, ctxtGlobal);
 493         }
 494 
 495         if (selfMirror != null) {
 496             try {
 497                 return ScriptObjectMirror.translateUndefined(selfMirror.call(name, args));
 498             } catch (final Exception e) {
 499                 final Throwable cause = e.getCause();
 500                 if (cause instanceof NoSuchMethodException) {
 501                     throw (NoSuchMethodException)cause;
 502                 }
 503                 throwAsScriptException(e);
 504                 throw new AssertionError("should not reach here");


 599         } finally {
 600             if (globalChanged) {
 601                 Context.setGlobal(oldGlobal);
 602             }
 603         }
 604     }
 605 
 606     private static boolean isInterfaceImplemented(final Class<?> iface, final ScriptObject sobj) {
 607         for (final Method method : iface.getMethods()) {
 608             // ignore methods of java.lang.Object class
 609             if (method.getDeclaringClass() == Object.class) {
 610                 continue;
 611             }
 612 
 613             Object obj = sobj.get(method.getName());
 614             if (! (obj instanceof ScriptFunction)) {
 615                 return false;
 616             }
 617         }
 618         return true;





 619     }
 620 }


 298         }
 299 
 300         // perform security access check as early as possible
 301         final SecurityManager sm = System.getSecurityManager();
 302         if (sm != null) {
 303             if (! Modifier.isPublic(clazz.getModifiers())) {
 304                 throw new SecurityException(getMessage("implementing.non.public.interface", clazz.getName()));
 305             }
 306             Context.checkPackageAccess(clazz.getName());
 307         }
 308 
 309         ScriptObject realSelf = null;
 310         ScriptObject realGlobal = null;
 311         if(thiz == null) {
 312             // making interface out of global functions
 313             realSelf = realGlobal = getNashornGlobalFrom(context);
 314         } else if (thiz instanceof ScriptObjectMirror) {
 315             final ScriptObjectMirror mirror = (ScriptObjectMirror)thiz;
 316             realSelf = mirror.getScriptObject();
 317             realGlobal = mirror.getHomeGlobal();
 318             if (! isOfContext(realGlobal, nashornContext)) {
 319                 throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
 320             }
 321         } else if (thiz instanceof ScriptObject) {
 322             // called from script code.
 323             realSelf = (ScriptObject)thiz;
 324             realGlobal = Context.getGlobal();
 325             if (realGlobal == null) {
 326                 throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
 327             }
 328 
 329             if (! isOfContext(realGlobal, nashornContext)) {
 330                 throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
 331             }
 332         }
 333 
 334         if (realSelf == null) {
 335             throw new IllegalArgumentException(getMessage("interface.on.non.script.object"));
 336         }
 337 
 338         try {
 339             final ScriptObject oldGlobal = Context.getGlobal();
 340             final boolean globalChanged = (oldGlobal != realGlobal);
 341             try {
 342                 if (globalChanged) {
 343                     Context.setGlobal(realGlobal);
 344                 }
 345 
 346                 if (! isInterfaceImplemented(clazz, realSelf)) {
 347                     return null;
 348                 }
 349                 return clazz.cast(JavaAdapterFactory.getConstructor(realSelf.getClass(), clazz).invoke(realSelf));


 377 
 378         // Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it!
 379         Object scope = bindings.get(NASHORN_GLOBAL);
 380         if (scope instanceof ScriptObjectMirror) {
 381             final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)scope);
 382             if (sobj != null) {
 383                 return sobj;
 384             }
 385         }
 386 
 387         // We didn't find associated nashorn global mirror in the Bindings given!
 388         // Create new global instance mirror and associate with the Bindings.
 389         final ScriptObjectMirror mirror = createGlobalMirror(ctxt);
 390         bindings.put(NASHORN_GLOBAL, mirror);
 391         return mirror.getScriptObject();
 392     }
 393 
 394     // Retrieve nashorn Global object from a given ScriptObjectMirror
 395     private ScriptObject globalFromMirror(final ScriptObjectMirror mirror) {
 396         ScriptObject sobj = mirror.getScriptObject();
 397         if (sobj instanceof GlobalObject && isOfContext(sobj, nashornContext)) {
 398             return sobj;
 399         }
 400 
 401         return null;
 402     }
 403 
 404     // Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object
 405     private ScriptObjectMirror createGlobalMirror(final ScriptContext ctxt) {
 406         final ScriptObject newGlobal = createNashornGlobal(ctxt);
 407         return new ScriptObjectMirror(newGlobal, newGlobal);
 408     }
 409 
 410     // Create a new Nashorn Global object
 411     private ScriptObject createNashornGlobal(final ScriptContext ctxt) {
 412         final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() {
 413             @Override
 414             public ScriptObject run() {
 415                 try {
 416                     return nashornContext.newGlobal();
 417                 } catch (final RuntimeException e) {


 453         // set "context" global variable via contextProperty - because this
 454         // property is non-writable
 455         contextProperty.setObjectValue(ctxtGlobal, ctxtGlobal, ctxt, false);
 456         Object args = ScriptObjectMirror.unwrap(ctxt.getAttribute("arguments"), ctxtGlobal);
 457         if (args == null || args == UNDEFINED) {
 458             args = ScriptRuntime.EMPTY_ARRAY;
 459         }
 460         // if no arguments passed, expose it
 461         if (! (args instanceof ScriptObject)) {
 462             args = ((GlobalObject)ctxtGlobal).wrapAsObject(args);
 463             ctxtGlobal.set("arguments", args, false);
 464         }
 465     }
 466 
 467     private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
 468         name.getClass(); // null check
 469 
 470         ScriptObjectMirror selfMirror = null;
 471         if (selfObject instanceof ScriptObjectMirror) {
 472             selfMirror = (ScriptObjectMirror)selfObject;
 473             if (! isOfContext(selfMirror.getHomeGlobal(), nashornContext)) {
 474                 throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
 475             }
 476         } else if (selfObject instanceof ScriptObject) {
 477             // invokeMethod called from script code - in which case we may get 'naked' ScriptObject
 478             // Wrap it with oldGlobal to make a ScriptObjectMirror for the same.
 479             final ScriptObject oldGlobal = Context.getGlobal();
 480             if (oldGlobal == null) {
 481                 throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
 482             }
 483 
 484             if (! isOfContext(oldGlobal, nashornContext)) {
 485                 throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
 486             }
 487 
 488             selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal);
 489         } else if (selfObject == null) {
 490             // selfObject is null => global function call
 491             final ScriptObject ctxtGlobal = getNashornGlobalFrom(context);
 492             selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(ctxtGlobal, ctxtGlobal);
 493         }
 494 
 495         if (selfMirror != null) {
 496             try {
 497                 return ScriptObjectMirror.translateUndefined(selfMirror.call(name, args));
 498             } catch (final Exception e) {
 499                 final Throwable cause = e.getCause();
 500                 if (cause instanceof NoSuchMethodException) {
 501                     throw (NoSuchMethodException)cause;
 502                 }
 503                 throwAsScriptException(e);
 504                 throw new AssertionError("should not reach here");


 599         } finally {
 600             if (globalChanged) {
 601                 Context.setGlobal(oldGlobal);
 602             }
 603         }
 604     }
 605 
 606     private static boolean isInterfaceImplemented(final Class<?> iface, final ScriptObject sobj) {
 607         for (final Method method : iface.getMethods()) {
 608             // ignore methods of java.lang.Object class
 609             if (method.getDeclaringClass() == Object.class) {
 610                 continue;
 611             }
 612 
 613             Object obj = sobj.get(method.getName());
 614             if (! (obj instanceof ScriptFunction)) {
 615                 return false;
 616             }
 617         }
 618         return true;
 619     }
 620 
 621     private static boolean isOfContext(final ScriptObject global, final Context context) {
 622         assert global instanceof GlobalObject: "Not a Global object";
 623         return ((GlobalObject)global).isOfContext(context);
 624     }
 625 }