1 /* 2 * Copyright the original author or authors. 3 * 4 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.mozilla.org/MPL/MPL-1.1.html 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import org.as2lib.core.BasicClass; 18 import org.as2lib.env.reflect.ProxyFactory; 19 import org.as2lib.env.reflect.InvocationHandler; 20 21 /** 22 * {@code TypeProxyFactory} creates proxies of types, that means classes or 23 * interfaces. 24 * 25 * <p>If you know that you only need interface proxies you could think of using 26 * {@link InterfaceProxyFactory} because it offers better performance. 27 * 28 * @author Simon Wacker 29 */ 30 class org.as2lib.env.reflect.TypeProxyFactory extends BasicClass implements ProxyFactory { 31 32 /** 33 * Creates proxies for the passed-in {@code type}, that are classes and interfaces. 34 * 35 * <p>You can cast the returned proxy to the passed-in {@code type}. 36 * 37 * <p>{@code null} will be returned if the passed-in {@code type} is {@code null} 38 * or {@code undefined}. 39 * 40 * <p>This proxy catches method invocations by creating proxy methods for every 41 * method of the {@code type} that forward the invocations to the handler. Unknown, 42 * that means not declared or implemented methods are catched by {@code __resolve}. 43 * 44 * <p>Note that also methods that are not declared on the {@code type} but get 45 * invoked on the proxy, are forwarded to the passed-in {@code handler}. 46 * 47 * @param type the type to create the proxy for 48 * @param handler the handler to invoke on proxy method invocations 49 * @return the created type proxy 50 */ 51 public function createProxy(type:Function, handler:InvocationHandler) { 52 if (!type) return null; 53 var result:Object = new Object(); 54 result.__proto__ = type.prototype; 55 result.__constructor__ = type; 56 var prototype:Object = type.prototype; 57 while (prototype != Object.prototype) { 58 _global.ASSetPropFlags(prototype, null, 0, true); 59 _global.ASSetPropFlags(prototype, ["__proto__", "constructor", "__constructor__", "prototype"], 1, true); 60 for (var i:String in prototype) { 61 if (typeof(prototype[i]) == "function") { 62 result[i] = function() { 63 return handler.invoke(this, arguments.callee.methodName, arguments); 64 }; 65 result[i].methodName = i; 66 } 67 } 68 prototype = prototype.__proto__; 69 } 70 result.toString = function() { 71 return handler.invoke(this, "toString", arguments); 72 }; 73 result.__resolve = function(methodName:String):Function { 74 return (function() { 75 return handler.invoke(this, methodName, arguments); 76 }); 77 }; 78 return result; 79 } 80 81 }