sylvanaar

Can't be overridden - Doh!

Oct 9th, 2013
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5 6.97 KB | None | 0 0
  1. /*******************************************************************************
  2. * Copyright (c) 2009 Luaj.org. All rights reserved.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. * THE SOFTWARE.
  21. ******************************************************************************/
  22. package org.luaj.vm2.lib.jse;
  23.  
  24.  
  25. import org.luaj.vm2.LuaError;
  26. import org.luaj.vm2.LuaTable;
  27. import org.luaj.vm2.LuaValue;
  28. import org.luaj.vm2.Varargs;
  29. import org.luaj.vm2.compiler.LuaC;
  30. import org.luaj.vm2.lib.LibFunction;
  31. import org.luaj.vm2.lib.VarArgFunction;
  32.  
  33. import java.lang.reflect.*;
  34.  
  35. /**
  36.  * Subclass of {@link LibFunction} which implements the features of the luajava package.
  37.  * <p>
  38.  * Luajava is an approach to mixing lua and java using simple functions that bind
  39.  * java classes and methods to lua dynamically.  The API is documented on the
  40.  * <a href="http://www.keplerproject.org/luajava/">luajava</a> documentation pages.
  41.  * <p>
  42.  * Typically, this library is included as part of a call to either
  43.  * {@link JsePlatform#standardGlobals()}
  44.  * <p>
  45.  * To instantiate and use it directly,
  46.  * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as:
  47.  * <pre> {@code
  48.  * LuaTable _G = new LuaTable();
  49.  * LuaThread.setGlobals(_G);
  50.  * LuaC.install();
  51.  * _G.load(new BaseLib());
  52.  * _G.load(new PackageLib());
  53.  * _G.load(new LuajavaLib());
  54.  * _G.get("load").call( LuaValue.valueOf(
  55.  *      "sys = luajava.bindClass('java.lang.System')\n"+
  56.  *      "print ( sys:currentTimeMillis() )\n" ) ).call();
  57.  * } </pre>
  58.  * This example is not intended to be realistic - only to show how the {@link LuajavaLib}
  59.  * may be initialized by hand.  In practice, the {@code luajava} library is available
  60.  * on all JSE platforms via the call to {@link JsePlatform#standardGlobals()}
  61.  * and the luajava api's are simply invoked from lua.    
  62.  * <p>
  63.  * This has been implemented to match as closely as possible the behavior in the corresponding library in C.
  64.  * @see LibFunction
  65.  * @see org.luaj.vm2.lib.jse.JsePlatform
  66.  * @see org.luaj.vm2.lib.jme.JmePlatform
  67.  * @see LuaC
  68.  * @see <a href="http://www.keplerproject.org/luajava/manual.html#luareference">http://www.keplerproject.org/luajava/manual.html#luareference</a>
  69.  */
  70. public class LuajavaLib extends VarArgFunction {
  71.    
  72.     static final int INIT           = 0;
  73.     static final int BINDCLASS      = 1;
  74.     static final int NEWINSTANCE    = 2;
  75.     static final int NEW            = 3;
  76.     static final int CREATEPROXY    = 4;
  77.     static final int LOADLIB        = 5;
  78.  
  79.     static final String[] NAMES = {
  80.         "bindClass",
  81.         "newInstance",
  82.         "new",
  83.         "createProxy",
  84.         "loadLib",
  85.     };
  86.    
  87.     static final int METHOD_MODIFIERS_VARARGS = 0x80;
  88.  
  89.     public LuajavaLib() {
  90.     }
  91.  
  92.     public Varargs invoke(Varargs args) {
  93.         try {
  94.             switch ( opcode ) {
  95.             case INIT: {
  96.                 // LuaValue modname = args.arg1();
  97.                 LuaValue env = args.arg(2);
  98.                 LuaTable t = new LuaTable();
  99.                 bind( t, this.getClass(), NAMES, BINDCLASS );
  100.                 env.set("luajava", t);
  101.                 env.get("package").get("loaded").set("luajava", t);
  102.                 return t;
  103.             }
  104.             case BINDCLASS: {
  105.                 final Class clazz = classForName(args.checkjstring(1));
  106.                 return JavaClass.forClass(clazz);
  107.             }
  108.             case NEWINSTANCE:
  109.             case NEW: {
  110.                 // get constructor
  111.                 final LuaValue c = args.checkvalue(1);
  112.                 final Class clazz = (opcode==NEWINSTANCE? classForName(c.tojstring()): (Class) c.checkuserdata(Class.class));
  113.                 final Varargs consargs = args.subargs(2);
  114.                 return JavaClass.forClass(clazz).getConstructor().invoke(consargs);
  115.             }
  116.                
  117.             case CREATEPROXY: {            
  118.                 final int niface = args.narg()-1;
  119.                 if ( niface <= 0 )
  120.                     throw new LuaError("no interfaces");
  121.                 final LuaValue lobj = args.checktable(niface+1);
  122.                
  123.                 // get the interfaces
  124.                 final Class[] ifaces = new Class[niface];
  125.                 for ( int i=0; i<niface; i++ )
  126.                     ifaces[i] = classForName(args.checkjstring(i+1));
  127.                
  128.                 // create the invocation handler
  129.                 InvocationHandler handler = new InvocationHandler() {
  130.                     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  131.                         String name = method.getName();
  132.                         LuaValue func = lobj.get(name);
  133.                         if ( func.isnil() )
  134.                             return null;
  135.                         boolean isvarargs = ((method.getModifiers() & METHOD_MODIFIERS_VARARGS) != 0);
  136.                         int n = args!=null? args.length: 0;
  137.                         LuaValue[] v;
  138.                         if ( isvarargs ) {                             
  139.                             Object o = args[--n];
  140.                             int m = Array.getLength( o );
  141.                             v = new LuaValue[n+m];
  142.                             for ( int i=0; i<n; i++ )
  143.                                 v[i] = CoerceJavaToLua.coerce(args[i]);
  144.                             for ( int i=0; i<m; i++ )
  145.                                 v[i+n] = CoerceJavaToLua.coerce(Array.get(o,i));                               
  146.                         } else {
  147.                             v = new LuaValue[n];
  148.                             for ( int i=0; i<n; i++ )
  149.                                 v[i] = CoerceJavaToLua.coerce(args[i]);
  150.                         }
  151.                         LuaValue result = func.invoke(v).arg1();
  152.                         return CoerceLuaToJava.coerce(result, method.getReturnType());
  153.                     }
  154.                 };
  155.                
  156.                 // create the proxy object
  157.                 Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(), ifaces, handler);
  158.                
  159.                 // return the proxy
  160.                 return LuaValue.userdataOf( proxy );
  161.             }
  162.             case LOADLIB: {
  163.                 // get constructor
  164.                 String classname = args.checkjstring(1);
  165.                 String methodname = args.checkjstring(2);
  166.                 Class clazz = classForName(classname);
  167.                 Method method = clazz.getMethod(methodname, new Class[] {});
  168.                 Object result = method.invoke(clazz, new Object[] {});
  169.                 if ( result instanceof LuaValue ) {
  170.                     return (LuaValue) result;
  171.                 } else {
  172.                     return NIL;
  173.                 }
  174.             }
  175.             default:
  176.                 throw new LuaError("not yet supported: "+this);
  177.             }
  178.         } catch (LuaError e) {
  179.             throw e;
  180.         } catch (InvocationTargetException ite) {
  181.             throw new LuaError(ite.getTargetException());
  182.         } catch (Exception e) {
  183.             throw new LuaError(e);
  184.         }
  185.     }
  186.  
  187.     // load classes using app loader to allow luaj to be used as an extension
  188.     protected Class classForName(String name) throws ClassNotFoundException {
  189.         return Class.forName(name, true, ClassLoader.getSystemClassLoader());
  190.     }
  191. }
Advertisement
Add Comment
Please, Sign In to add comment