/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */ package com.caucho.quercus.lib; import com.caucho.quercus.annotation.Optional; import com.caucho.quercus.annotation.ReadOnly; import com.caucho.quercus.annotation.ReturnNullAsFalse; import com.caucho.quercus.env.*; import com.caucho.quercus.expr.Expr; import com.caucho.quercus.module.AbstractQuercusModule; import com.caucho.quercus.function.AbstractFunction; import java.util.HashSet; import java.util.Iterator; import java.util.Map; /** * Quercus class information */ public class ClassesModule extends AbstractQuercusModule { /** * Calls an object method. */ public static Value call_user_method(Env env, String name, Value obj, Value []args) { if (obj.isObject()) { AbstractFunction fun = obj.findFunction(name); return fun.callMethod(env, obj, args).copyReturn(); } else { QuercusClass cls = env.findClass(obj.toString()); AbstractFunction fun = cls.findFunction(name); return fun.call(env, args).copyReturn(); } } /* * Calls a object method with arguments in an array. */ public static Value call_user_method_array(Env env, String methodName, Value obj, ArrayValue params) { Value []args = params.valuesToArray(); return call_user_method(env, methodName, obj, args); } /** * returns true if the class exists. */ public boolean class_exists(Env env, String className, @Optional("true") boolean useAutoload) { if (className == null) return false; QuercusClass cl = env.findClass(className, useAutoload, true); // php/[03]9m1 return cl != null && ! cl.isInterface(); } /** * Returns the object's class name */ public Value get_class(Env env, Value value) { if (value instanceof ObjectValue) { ObjectValue obj = (ObjectValue) value; return env.createStringOld(obj.getName()); } else if (value instanceof JavaValue) { JavaValue obj = (JavaValue) value; return env.createStringOld(obj.getClassName()); } else return BooleanValue.FALSE; } /* * Returns the calling class name. */ @ReturnNullAsFalse public String get_called_class(Env env) { QuercusClass cls = env.getCallingClass(); if (cls == null) { env.warning("called from outside class scope"); return null; } return cls.getName(); } /** * Returns an array of method names * * @param clss the name of the class, or an instance of a class * * @return an array of method names */ public static Value get_class_methods(Env env, Value cls) { // php/1j11 QuercusClass cl; if (cls.isObject()) cl = ((ObjectValue) cls).getQuercusClass(); else cl = env.findClass(cls.toString()); if (cl == null) return NullValue.NULL; ArrayValue array = new ArrayValueImpl(); HashSet<String> set = new HashSet<String>(); // to combine __construct and class name constructors for (AbstractFunction fun : cl.getClassMethods()) { set.add(fun.getName()); } for (String name : set) { array.put(name); } return array; } /** * Returns an array of member names and values * * @param clss the name of the class, or an instance of a class * * @return an array of member names and values */ public static Value get_class_vars(Env env, Value clss) { // php/1j10 QuercusClass cl; if (clss instanceof ObjectValue) cl = ((ObjectValue) clss).getQuercusClass(); else cl = env.findClass(clss.toString()); if (cl == null) return BooleanValue.FALSE; ArrayValue varArray = new ArrayValueImpl(); for (Map.Entry<StringValue,Expr> entry : cl.getClassVars().entrySet()) { Value key = entry.getKey(); Value value = entry.getValue().eval(env); varArray.append(key, value); } ArrayModule.ksort(env, varArray, ArrayModule.SORT_STRING); return varArray; } /** * Returns the declared classes */ public static Value get_declared_classes(Env env) { return env.getDeclaredClasses(); } // XXX: get_declared_interfaces /** * Returns the object's variables */ public static Value get_object_vars(Env env, Value obj) { ArrayValue result = new ArrayValueImpl(); // #3253, php/4as7 - XXX: needs cleanup if (obj instanceof ObjectValue) { for (Map.Entry<Value,Value> entry : ((ObjectValue) obj).entrySet()) { result.put(entry.getKey(), entry.getValue()); } } else { Iterator<Map.Entry<Value,Value>> iter = obj.getIterator(env); while (iter.hasNext()) { Map.Entry<Value,Value> entry = iter.next(); result.put(entry.getKey(), entry.getValue()); } } return result; } /** * Returns the object's class name */ public Value get_parent_class(Env env, @ReadOnly Value value) { if (value instanceof ObjectValue) { ObjectValue obj = (ObjectValue) value; String parent = obj.getParentClassName(); if (parent != null) return env.createStringOld(parent); } else if (value.isString()) { String className = value.toString(); QuercusClass cl = env.findClass(className); if (cl != null) { String parent = cl.getParentName(); if (parent != null) return env.createStringOld(parent); } } return BooleanValue.FALSE; } /** * Returns true if the class exists. */ public boolean interface_exists(Env env, String interfaceName, @Optional("true") boolean useAutoload) { QuercusClass cl = env.findClass(interfaceName, useAutoload, true); // php/[03]9m0 return cl != null && cl.isInterface(); } /** * Returns true if the object implements the given class. */ public static boolean is_a(@ReadOnly Value value, String name) { return value.isA(name); } /** * Returns true if the argument is an object. */ public static boolean is_object(@ReadOnly Value value) { return value.isObject(); } /** * Returns true if the object implements the given class. */ public static boolean is_subclass_of(Env env, @ReadOnly Value value, String name) { if (value instanceof StringValue) { QuercusClass cl = env.findClass(value.toString()); return cl.isA(name) && !cl.getName().equalsIgnoreCase(name); } else return value.isA(name) && !value.getClassName().equalsIgnoreCase(name); } /** * Returns true if the named method exists on the object. * * @param obj the object to test * @param methodName the name of the method */ public static boolean method_exists(Value obj, String methodName) { return obj.findFunction(methodName.intern()) != null; } /** * Returns true if the named property exists on the object. */ public static Value property_exists(Env env, Value obj, StringValue name) { QuercusClass cls; if (obj.isString()) cls = env.findClass(obj.toString()); else if (obj.isObject()) cls = ((ObjectValue) obj.toValue()).getQuercusClass(); else { env.warning("must pass in object or name of class"); return NullValue.NULL; } if (cls != null && cls.findFieldIndex(name) >= 0) return BooleanValue.TRUE; else return BooleanValue.FALSE; } }