private void initWrapFactory( ) { WrapFactory wrapFactory = new WrapFactory( ) { protected IJavascriptWrapper coreWrapper = new CoreJavaScriptWrapper( ); /** * wrapper an java object to javascript object. */ public Object wrap( Context cx, Scriptable scope, Object obj, Class staticType ) { Object object = coreWrapper.wrap( cx, scope, obj, staticType ); if ( object != obj ) { return object; } return super.wrap( cx, scope, obj, staticType ); } }; context.setWrapFactory( wrapFactory ); new CoreJavaScriptInitializer( ).initialize( context, global ); }
public void setParameter(String name, String value) { if ("wrapFactory".equals(name)) { if (StringUtil.isEmpty(value)) { throw new IllegalParameterValueException(getClass(), name); } Class clazz = ObjectUtil.loadClass(value, WrapFactory.class); setWrapFactory((WrapFactory) ObjectUtil.newInstance(clazz)); } else if ("blockSign".equals(name)) { if (StringUtil.isEmpty(value)) { throw new IllegalParameterValueException(getClass(), name); } setBlockSign(value); } else if ("useGetterScriptEmulation".equals("name")) { if (StringUtil.isEmpty(value)) { throw new IllegalParameterValueException(getClass(), name); } _useGetterScriptEmulation = ObjectUtil.booleanValue(value, false); } super.setParameter(name, value); }
/** * {@inheritDoc} */ @Override public Object convertValueForScript(final Object value, final ValueConverter globalDelegate, final Class<?> expectedClass) { // no further distinction - always delegate final Context currentContext = Context.getCurrentContext(); final WrapFactory factory = currentContext.getWrapFactory(); final Object result; // mark for recursion prevention (DelegatingWrapFactory may otherwise indirectly delegate back) this.currentConversions.get().add(value); try { Class<?> staticType = value.getClass(); if (WRAPPER_TO_PRIMITIVE.containsKey(staticType)) { staticType = WRAPPER_TO_PRIMITIVE.get(staticType); } // if conversion call is made in a scope-ful context, the caller needs to take care of setting parentScope for Scriptable result = factory.wrap(currentContext, null, value, staticType); } finally { this.currentConversions.get().remove(value); } // we tried to check in advance as best as possible in #canConvertValueForScript return expectedClass.isInstance(result) ? result : null; }
static synchronized WrapFactory getInstance() { if (theInstance == null) { theInstance = new RhinoWrapFactory(); } return theInstance; }
@Override protected TimeLimitContext makeContext() { TimeLimitContext context = new TimeLimitContext(); context.setWrapFactory(new WrapFactory() { @Override public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject, java.lang.Class<?> staticType) { return new NativeJavaObject(scope, javaObject, getClass()) { private static final long serialVersionUID = 1L; @Override public Object get(String name, Scriptable start) { if (name.equals("getClass")) return NOT_FOUND; return super.get(name, start); } }; } }); context.setClassShutter(new ClassShutter() { @Override public boolean visibleToScripts(String fullClassName) { Class<?> clz; try { clz = Class.forName(fullClassName); } catch (ClassNotFoundException e) { e.printStackTrace(); return false; } if(ScriptBinding.class.isAssignableFrom(clz)) return true; if(clz.equals(String.class)) return true; return false; } }); return context; }
/** * {@inheritDoc} */ @Override public Object invoke(final MethodInvocation invocation) throws Throwable { final Object[] arguments = invocation.getArguments(); Scriptable scope = null; for (int idx = 0; idx < arguments.length && scope == null; idx++) { if (arguments[idx] instanceof Scriptable) { scope = (Scriptable) arguments[idx]; } } final Context cx = Context.getCurrentContext(); final WrapFactory wrapFactory = cx.getWrapFactory(); // disabling before and enabling after invocation with manual wrapping "seems" pointless // this pattern is actually not meant for "this" invocation, but for any calls from Java code to any native script object to avoid // polluting Java scope with special AOP-enhanced script objects that Java code may not be able to handle if (wrapFactory instanceof DelegatingWrapFactory) { ((DelegatingWrapFactory) wrapFactory).disableWrap(); } Object result; try { result = invocation.proceed(); } finally { if (wrapFactory instanceof DelegatingWrapFactory) { ((DelegatingWrapFactory) wrapFactory).enableWrap(); } } if (result != null && Undefined.instance != result && Scriptable.NOT_FOUND != result) { result = Context.jsToJava(result, Object.class); // even if signature may not use primitve, we prefer them (this also avoids wrapping them) Class<?> staticType = result.getClass(); if (WRAPPER_TO_PRIMITIVE.containsKey(staticType)) { staticType = WRAPPER_TO_PRIMITIVE.get(staticType); } result = wrapFactory.wrap(cx, scope != null ? scope : DUMMY_SCOPE, result, staticType); } return result; }
static void setWrapFactory(WrapFactory wrap) { _wrap = wrap; }
static WrapFactory getWrapFactory() { return _wrap; }
/** * カレントスレッドに関連付いたContextを取得します。 * 同時にScriptEnvironmentからWrapFactoryを取得してContextにセットします。 * Rhinoスクリプト実行前に、Context.enter()の代わりに利用します。 * これを実行したあとは、try {} finally {} を使って Context.exit() を * 必ず実行する必要があります。 * * @return カレントスレッドに関連付いたContext */ public static Context enter() { Context cx = Context.enter(); WrapFactory factory = ScriptEnvironmentImpl.getWrapFactory(); if (factory != null) { cx.setWrapFactory(factory); } return cx; }