package php.runtime.ext.java; import php.runtime.annotation.Reflection; import php.runtime.env.Environment; import php.runtime.exceptions.CriticalException; import php.runtime.lang.BaseObject; import php.runtime.reflection.ClassEntity; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Reflection.Name("php\\lang\\JavaReflection") abstract public class JavaReflection extends BaseObject { protected static Map<Class<? extends JavaException>, Constructor<? extends JavaException>> constructors; protected static Map<Class<? extends Throwable>, Class<? extends JavaException>> cachedThClasses; public JavaReflection(Environment env) { super(env); } public JavaReflection(Environment env, ClassEntity clazz) { super(env, clazz); } public static void exception(Environment env, Throwable e) { if (cachedThClasses == null) cachedThClasses = new ConcurrentHashMap<Class<? extends Throwable>, Class<? extends JavaException>>(); if (constructors == null) constructors = new ConcurrentHashMap<Class<? extends JavaException>, Constructor<? extends JavaException>>(); Class tmp = e.getClass(); Class<? extends JavaException> clazz = cachedThClasses.get(tmp); if (clazz == null) { while (tmp != null) { clazz = env.scope.findJavaException(tmp); if (clazz != null) { cachedThClasses.put(e.getClass(), clazz); break; } tmp = tmp.getSuperclass(); } } if (clazz == null) { ClassEntity context = env.getLastClassOnStack(); while (context != null) { clazz = env.scope.findJavaExceptionForContext(context.getLowerName()); if (clazz != null) break; context = context.getParent(); } } JavaException exception; if (clazz == null) { exception = new JavaException(env, e); } else { try { Constructor<? extends JavaException> constructor = constructors.get(clazz); if (constructor == null) { constructors.put(clazz, constructor = clazz.getConstructor(Environment.class, Throwable.class)); } exception = constructor.newInstance(env, e); } catch (InvocationTargetException e1) { throw new CriticalException(e1.getCause()); } catch (Exception e1) { throw new CriticalException(e1); } } env.__throwException(exception, false); } }