/******************************************************************************* * Copyright © 2011, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * *******************************************************************************/ package org.eclipse.edt.javart; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.eclipse.edt.javart.messages.Message; import eglx.lang.*; public class Delegate { private Object target; private Method method; private String signature; public static boolean ezeIsa( Object obj, String sig ) { if ( obj instanceof EAny ) { obj = ((EAny)obj).ezeUnbox(); } return obj instanceof Delegate && ((Delegate)obj).signature.equals( sig ); } public static Delegate ezeCast( Object obj, String sig ) throws TypeCastException { if ( obj instanceof EAny ) { obj = ((EAny)obj).ezeUnbox(); } if ( ezeIsa( obj, sig ) ) { return (Delegate)obj; } else { TypeCastException tcx = new TypeCastException(); tcx.castToName = sig; tcx.actualTypeName = obj == null ? "null" : obj.getClass().getName(); throw tcx.fillInMessage( Message.CONVERSION_ERROR, obj, tcx.actualTypeName, tcx.castToName ); } } public Delegate(String methodName, String signature, Object target, Class... argTypes) { this.target = target; this.signature = signature; try { this.method = target.getClass().getDeclaredMethod(methodName, argTypes); } catch (Exception ex) { DynamicAccessException dax = new DynamicAccessException(); dax.key = methodName; dax.initCause( ex ); throw dax.fillInMessage( Message.EXCEPTION_IN_DELEGATE_GET, methodName, ex ); } } public Object invoke(Object... args) throws AnyException { boolean accessibleSet = true; try { accessibleSet = method.isAccessible(); if (!accessibleSet) { method.setAccessible(true); Object ret = method.invoke(target, args); method.setAccessible(false); return ret; } else return method.invoke(target, args); } catch (Throwable problem) { if (!accessibleSet) method.setAccessible(false); if ( problem instanceof InvocationTargetException ) { problem = ((InvocationTargetException)problem).getTargetException(); if ( problem instanceof AnyException ) { throw (AnyException)problem; } } InvocationException ix = new InvocationException(); ix.name = method.getName(); ix.initCause( problem ); throw ix.fillInMessage( Message.EXCEPTION_IN_DELEGATE_INVOKE, ix.name, problem ); } } public Object getTarget() { return target; } public Method getMethod() { return method; } public String getSignature() { return signature; } /** * Added for an easy way to nicely display this in the debugger. */ @Override public String toString() { StringBuilder buf = new StringBuilder(100); buf.append(target.getClass().getCanonicalName()); buf.append('.'); buf.append(method.getName()); return buf.toString(); } }