<?php
/**
 * File containing the ezcReflectionClass class.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 * @package Reflection
 * @version //autogen//
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */

/**
 * Extends the ReflectionClass class to provide type information
 * using PHPDoc annotations.
 *
 * @package Reflection
 * @version //autogen//
 * @author Stefan Marr <mail@stefan-marr.de>
 * @author Falko Menge <mail@falko-menge.de>
 */
class ezcReflectionClass extends ReflectionClass
{
    /**
     * @var ezcReflectionDocCommentParser Parser for source code annotations
     */
    protected $docParser;

    /**
     * @var string|object|ReflectionClass
     *      Name, instance or ReflectionClass object of the class to be
     *      reflected
     */
    protected $reflectionSource;

    /**
     * Constructs a new ezcReflectionClass object.
     *
     * @param string|object|ReflectionClass $argument
     *        Name, instance or ReflectionClass object of the class to be
     *        reflected
     * @throws ReflectionException if the specified class doesn't exist
     */
    public function __construct( $argument )
    {
        if ( !$argument instanceof parent )
        {
            parent::__construct( $argument );
        }
        $this->reflectionSource = $argument;
        // TODO: Parse comment on demand to save CPU time and memory
        $this->docParser = ezcReflection::getDocCommentParser();
        $this->docParser->parse( $this->getDocComment() );
    }

    /**
     * Use overloading to call additional methods
     * of the ReflectionClass instance given to the constructor.
     *
     * @param string $method Method to be called
     * @param array  $arguments Arguments that were passed
     * @return mixed
     */
    public function __call( $method, $arguments )
    {
        $callback = array( $this->reflectionSource, $method );  
        if ( $this->reflectionSource instanceof parent
             and is_callable( $callback ) )
        {
            // query external reflection object
            return call_user_func_array( $callback, $arguments );
        }
        else
        {
            throw new ezcReflectionCallToUndefinedMethodException( __CLASS__, $method );
        }
    }

    /**
     * Forwards a method invocation to either the reflection source passed to
     * the constructor of this class when creating an instance or to the parent
     * class.
     *
     * This method is part of the dependency injection mechanism and serves as
     * a helper for implementing wrapper methods without code duplication.
     * @param string $method Name of the method to be invoked
     * @param mixed[] $arguments Arguments to be passed to the method
     * @return mixed Return value of the invoked method
     */
    protected function forwardCallToReflectionSource( $method, $arguments = array() ) {
        if ( $this->reflectionSource instanceof parent ) {
            return call_user_func_array( array( $this->reflectionSource, $method ), $arguments );
        } else {
            //*
            return call_user_func_array( array( $this, 'parent::' . $method ), $arguments );
            /*/
            $argumentStrings = array();
            foreach ( array_keys( $arguments ) as $key ) {
                $argumentStrings[] = '$arguments[' . var_export( $key, true ) . ']';
            }
            $cmd = 'return parent::$method( ' . implode( ', ', $argumentStrings ) . ' );';
            return eval( $cmd );
            //*/
        }
    }

    /**
     * Returns an ezcReflectionMethod object of the method specified by $name.
     *
     * @param string $name Name of the method
     * @return ezcReflectionMethod
     * @throws ReflectionException if method doesn't exist
     */
    public function getMethod( $name ) {
        $method = $this->forwardCallToReflectionSource( __FUNCTION__, array( $name ) );
        if ( $this->reflectionSource instanceof parent ) {
            return new ezcReflectionMethod( $this, $method );
        } else {
            return new ezcReflectionMethod( $this, $method->name );
        }
    }

    /**
     * Returns an ezcReflectionMethod object of the constructor method.
     *
     * @return ezcReflectionMethod
     */
    public function getConstructor() {
        $constructor = $this->forwardCallToReflectionSource( __FUNCTION__ );
        if ($constructor != null) {
            if ( $this->reflectionSource instanceof parent ) {
                return new ezcReflectionMethod( $this, $constructor );
            } else {
                return new ezcReflectionMethod( $this, $constructor->name );
            }
        } else {
            return null;
        }
    }

    /**
     * Returns the methods as an array of ezcReflectionMethod objects.
     *
     * @param integer $filter
     *        A combination of
     *        ReflectionMethod::IS_STATIC,
     *        ReflectionMethod::IS_PUBLIC,
     *        ReflectionMethod::IS_PROTECTED,
     *        ReflectionMethod::IS_PRIVATE,
     *        ReflectionMethod::IS_ABSTRACT and
     *        ReflectionMethod::IS_FINAL
     * @return ezcReflectionMethod[]
     */
    public function getMethods( $filter = -1 ) {
        $methods = $this->forwardCallToReflectionSource( __FUNCTION__, array( $filter ) );
        $extMethods = array();
        foreach ( $methods as $method ) {
            if ( $this->reflectionSource instanceof parent ) {
                $extMethods[] = new ezcReflectionMethod( $this, $method );
            } else {
                $extMethods[] = new ezcReflectionMethod( $this, $method->name );
            }
        }
        return $extMethods;
    }

    /**
     * Returns an array of all interfaces implemented by the class.
     *
     * @return ezcReflectionClass[]
     */
    public function getInterfaces() {
        $ifaces = $this->forwardCallToReflectionSource( __FUNCTION__ );
    	$result = array();
    	foreach ($ifaces as $i) {
    		$result[] = new ezcReflectionClass( $i );
    	}
    	return $result;
    }

    /**
     * Returns the class' parent class, or, if none exists, FALSE
     *
     * @return ezcReflectionClass|boolean
     */
    public function getParentClass()
    {
        $parentClass = $this->forwardCallToReflectionSource( __FUNCTION__ );
        if ( is_object( $parentClass ) ) {
            return new ezcReflectionClass( $parentClass );
        }
        else {
            return false;
        }
    }

    /**
     * Returns the class' property specified by its name
     *
     * @param string $name Name of the property
     * @return ezcReflectionProperty
     * @throws RelectionException if property doesn't exist
     */
    public function getProperty($name) {
        $prop = $this->forwardCallToReflectionSource( __FUNCTION__, array( $name ) );
        return new ezcReflectionProperty($prop, $name);
    }

    /**
     * Returns an array of this class' properties
     *
     * @param integer $filter
     *        A combination of
     *        ReflectionProperty::IS_STATIC,
     *        ReflectionProperty::IS_PUBLIC,
     *        ReflectionProperty::IS_PROTECTED and
     *        ReflectionProperty::IS_PRIVATE
     * @return ezcReflectionProperty[] Properties of the class
     */
    public function getProperties($filter = -1) {
        $props = $this->forwardCallToReflectionSource( __FUNCTION__, array( $filter ) );
        $extProps = array();
        foreach ($props as $prop) {
            $extProps[] = new ezcReflectionProperty( $prop );
        }
        return $extProps;
    }

    /**
     * Returns the short description of the class from the source code
     * documentation
     *
     * @return string short description of the class
     * @since PHP 5.1.0
     */
    public function getShortDescription() {
        return $this->docParser->getShortDescription();
    }

    /**
     * Returns the long description of the class from the source code
     * documentation
     *
     * @return string Long description of the class
     * @since PHP 5.1.0
     */
    public function getLongDescription() {
        return $this->docParser->getLongDescription();
    }

    /**
     * Checks whether the class is annotated with the annotation $annotation
     *
     * @param string $annotation Name of the annotation
     * @return boolean
     * @since PHP 5.1.0
     */
    public function hasAnnotation($annotation) {
        return $this->docParser->hasAnnotation($annotation);
    }

    /**
     * Returns an array of annotations (optinally only annotations of a given name)
     *
     * @param string $name Name of the annotations
     * @return ezcReflectionAnnotation[] Annotations
     * @since PHP 5.1.0
     */
    public function getAnnotations( $name = '' ) {
        if ( $name == '' ) {
            return $this->docParser->getAnnotations();
        }
        else {
            return $this->docParser->getAnnotationsByName($name);
        }
    }

    /**
     * Returns NULL or the extension the class belongs to
     *
     * @return ezcReflectionExtension
     */
    public function getExtension() {
        $ext = $this->forwardCallToReflectionSource( __FUNCTION__ );
        if ($ext) {
            return new ezcReflectionExtension($ext);
        } else {
            return null;
        }
    }


    // only pure wrapper methods follow bellow this line

    /**
     * Returns FALSE or the name of the extension the class belongs to
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return string|boolean Extension name or FALSE
     */
    public function getExtensionName() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns the name of the class.
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return string Class name
     */
    public function getName() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns the doc comment for the class.
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return string Doc comment
     * @since PHP 5.1.0
     */
    public function getDocComment() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns the class' constant specified by its name
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @param string $name Name of the constant
     * @return mixed
     */
    public function getConstant( $name ) {
        return $this->forwardCallToReflectionSource( __FUNCTION__, array( $name ) );
    }

    /**
     * Returns an associative array containing this class' constants and their
     * values.
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return array<string, mixed> Constants and their values
     */
    public function getConstants() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns an associative array containing copies of all default property
     * values of the class.
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return array<string, mixed> Copies of all default property values
     */
    public function getDefaultProperties() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns the line this class' declaration ends at
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return integer Line this class' declaration ends at
     */
    public function getEndLine() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns the filename of the file this class was declared in
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return string The filename of the file this class was declared in
     */
    public function getFileName() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns an array of names of interfaces this class implements
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return string[] Array of names of interfaces this class implements
     */
    public function getInterfaceNames() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns a bitfield of the access modifiers for this class
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return integer Bitfield of the access modifiers for this method
     */
    public function getModifiers() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns the line this class' declaration starts at
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return integer The line this class' declaration starts at
     */
    public function getStartLine() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns an associative array containing all static property values of
     * the class
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return array<string,mixed>
     *         An associative array containing all static property values of
     *         the class
     */
    public function getStaticProperties() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns the value of a static property
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @param string $name Name of the static property
     * @param mixed $default Default value
     * @return mixed Value of a static property
     * @since PHP 5.1.0
     */
    public function getStaticPropertyValue( $name, $default = null ) {
        return $this->forwardCallToReflectionSource( __FUNCTION__, array( $name, $default ) );
    }

    /**
     * Returns whether a constant exists or not
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @param string $name Name of the constant
     * @return boolean Whether a constant exists or not
     * @since PHP 5.1.0
     */
    public function hasConstant( $name ) {
        return $this->forwardCallToReflectionSource( __FUNCTION__, array( $name ) );
    }

    /**
     * Returns whether a method exists or not
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @param string $name Name of the method
     * @return boolean Whether a method exists or not
     * @since PHP 5.1.0
     */
    public function hasMethod( $name ) {
        return $this->forwardCallToReflectionSource( __FUNCTION__, array( $name ) );
    }

    /**
     * Returns whether a property exists or not
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @param string $name Name of the property
     * @return boolean Whether a property exists or not
     * @since PHP 5.1.0
     */
    public function hasProperty( $name ) {
        return $this->forwardCallToReflectionSource( __FUNCTION__, array( $name ) );
    }

    /**
     * Returns whether this class is a subclass of another class
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @param string|ReflectionClass $class
     *        Name or ReflectionClass object of the super class
     * @return boolean Whether this class is a subclass of the given super lass
     */
    public function isSubclassOf( $class ) {
        return $this->forwardCallToReflectionSource( __FUNCTION__, array( $class ) );
    }

    /**
     * Returns whether this class implements a given interface
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @param string|ReflectionClass $interface
     *        Name or ReflectionClass object of the interface
     * @return boolean Whether the given interface is implemented or not
     */
    public function implementsInterface( $interface ) {
        return $this->forwardCallToReflectionSource( __FUNCTION__, array( $interface ) );
    }

    /**
     * Returns whether this class is abstract
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return boolean Whether this class is abstract
     */
    public function isAbstract() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns whether this class is final
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return boolean Whether this class is final
     */
    public function isFinal() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns whether this class is instantiable
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return boolean Whether this class is instantiable
     */
    public function isInstantiable() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns whether this class is an interface
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return boolean Whether this class is an interface
     */
    public function isInterface() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns whether this class is an internal class
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return boolean Whether this class is an internal class
     */
    public function isInternal() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns whether this class is iterateable (can be used inside foreach)
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return boolean
     *         Whether this class is iterateable (can be used inside foreach)
     */
    public function isIterateable() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns whether this class is user-defined
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return boolean Whether this class is user-defined
     */
    public function isUserDefined() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns whether the given object is an instance of this class
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @param object $object An object to be checked
     * @return boolean Whether the given object is an instance of this class
     */
    public function isInstance( $object ) {
        return $this->forwardCallToReflectionSource( __FUNCTION__, array( $object ) );
    }

    /**
     * Returns an instance of this class
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @param mixed $argument,...  Arguments
     * @return object An instance of this class
     */
    public function newInstance( $arguments ) {
        /**
         * Note from PHP Manual: func_get_args() returns a copy of the passed
         * arguments only, and does not account for default (non-passed)
         * arguments.
         */
        $arguments = func_get_args();
        return $this->forwardCallToReflectionSource( __FUNCTION__, $arguments );
    }

    /**
     * Returns an instance of this class
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @param array<integer,mixed> $arguments Arguments
     * @return object An instance of this class
     * @since PHP 5.1.3
     */
    public function newInstanceArgs( array $arguments = null ) {
        return $this->forwardCallToReflectionSource( __FUNCTION__, array( $arguments ) );
    }

    /**
     * Sets the value of a static property
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @param string $name Name of the static property
     * @param mixed $default Value
     * @return void
     * @since PHP 5.1.0
     */
    public function setStaticPropertyValue( $name, $value ) {
        $this->forwardCallToReflectionSource( __FUNCTION__, array( $name, $value ) );
    }

    /**
     * Returns the name of namespace where this class is defined
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return string The name of namespace where this class is defined
     * @since PHP 5.3.0
     */
    public function getNamespaceName() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns whether this class is defined in a namespace
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return boolean Whether this class is defined in a namespace
     * @since PHP 5.3.0
     */
    public function inNamespace() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns the short name of the class (without namespace part)
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return string
     *         Returns the short name of the class (without namespace part)
     * @since PHP 5.3.0
     */
    public function getShortName() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Returns a string representation
     *
     * This is purely a wrapper method, which either calls the corresponding
     * method of the parent class or forwards the call to the ReflectionClass
     * instance passed to the constructor.
     * @return string A string representation
     */
    public function __toString() {
        return $this->forwardCallToReflectionSource( __FUNCTION__ );
    }

    /**
     * Exports a ReflectionClass instance.
     *
     * Returns the output if TRUE is specified for $return, printing it otherwise.
     * This is purely a wrapper method, which calls the corresponding method of
     * the parent class (ReflectionClass::export()).
     * @param ReflectionClass|string $class
     *        ReflectionClass object or name of the class
     * @param boolean $return
     *        Whether to return (TRUE) or print (FALSE) the output
     * @return mixed
     */
    public static function export($class, $return = false) {
        return parent::export($class, $return);
    }

}
?>
