?
Current File : /home/c/i/d/cideo/www/wp-includesVIp/js/crop/images/Server.php.tar
home/cideo/library/Zend/Amf/Server.php000066600000057706151253423710013633 0ustar00<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Amf
 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */

/** Zend_Server_Interface */
require_once 'Zend/Server/Interface.php';

/** Zend_Server_Reflection */
require_once 'Zend/Server/Reflection.php';

/** Zend_Amf_Constants */
require_once 'Zend/Amf/Constants.php';

/** Zend_Amf_Value_MessageBody */
require_once 'Zend/Amf/Value/MessageBody.php';

/** Zend_Amf_Value_MessageHeader */
require_once 'Zend/Amf/Value/MessageHeader.php';

/** Zend_Amf_Value_Messaging_CommandMessage */
require_once 'Zend/Amf/Value/Messaging/CommandMessage.php';

/**
 * An AMF gateway server implementation to allow the connection of the Adobe Flash Player to
 * Zend Framework
 *
 * @todo       Make the relection methods cache and autoload.
 * @package    Zend_Amf
 * @subpackage Server
 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Amf_Server implements Zend_Server_Interface
{
    /**
     * Array of dispatchables
     * @var array
     */
    protected $_methods = array();

    /**
     * Array of directories to search for loading classes dynamically
     * @var array
     */
    protected $_directories = array();

    /**
     * @var bool Production flag; whether or not to return exception messages
     */
    protected $_production = true;

    /**
     * Request processed
     * @var null|Zend_Amf_Request
     */
    protected $_request = null;

    /**
     * Class to use for responses
     * @var null|Zend_Amf_Response
     */
    protected $_response;

    /**
     * Dispatch table of name => method pairs
     * @var array
     */
    protected $_table = array();

    /**
     *
     * @var bool session flag; whether or not to add a session to each response.
     */
    protected $_session = false;

    /**
     * Namespace allows all AMF calls to not clobber other php session variables
     * @var Zend_Session_NameSpace default session namespace zend_amf
     */
    protected $_sesionNamespace = 'zend_amf';

    /**
     * Set the default session.name if php_
     * @var unknown_type
     */
    protected $_sessionName = 'PHPSESSID';

    /**
     * Set production flag
     *
     * @param  bool $flag
     * @return Zend_Amf_Server
     */
    public function setProduction($flag)
    {
        $this->_production = (bool) $flag;
        return $this;
    }

    /**
     * Whether or not the server is in production
     *
     * @return bool
     */
    public function isProduction()
    {
        return $this->_production;
    }


    /**
     * @param namespace of all incoming sessions defaults to Zend_Amf
     * @return Zend_Amf_Server
     */
    public function setSession($namespace = 'Zend_Amf')
    {
        require_once 'Zend/Session.php';
        $this->_session = true;
        $this->_sesionNamespace = new Zend_Session_Namespace($namespace);
        return $this;
    }

    /**
     * Whether of not the server is using sessions
     * @return bool
     */
    public function isSession()
    {
        return $this->_session;
    }

    /**
     * Loads a remote class or method and executes the function and returns
     * the result
     *
     * @param  string $method Is the method to execute
     * @param  mixed $param values for the method
     * @return mixed $response the result of executing the method
     * @throws Zend_Amf_Server_Exception
     */
    protected function _dispatch($method, $params = null, $source = null)
    {
        $qualifiedName = empty($source) ? $method : $source.".".$method;
        
        if (!isset($this->_table[$qualifiedName])) {
            // if source is null a method that was not defined was called.
            if ($source) {
                $classPath    = array();
                $path         = explode('.', $source);
                $className    = array_pop($path);
                $uriclasspath = implode('/', $path);

                // Take the user supplied directories and add the unique service path to the end.
                foreach ($this->_directories as $dir) {
                    $classPath[] = $dir . $uriclasspath;
                }

                require_once('Zend/Loader.php');
                try {
                    Zend_Loader::loadClass($className, $classPath);
                } catch (Exception $e) {
                    require_once 'Zend/Amf/Server/Exception.php';
                    throw new Zend_Amf_Server_Exception('Class "' . $className . '" does not exist');
                }
                // Add the new loaded class to the server.
                $this->setClass($className, $source);
            } else {
                require_once 'Zend/Amf/Server/Exception.php';
                throw new Zend_Amf_Server_Exception('Method "' . $method . '" does not exist');
            }
        }

        $info = $this->_table[$qualifiedName];
        $argv = $info->getInvokeArguments();
        
        if (0 < count($argv)) {
            $params = array_merge($params, $argv);
        }

        if ($info instanceof Zend_Server_Reflection_Function) {
            $func = $info->getName();
            $return = call_user_func_array($func, $params);
        } elseif ($info instanceof Zend_Server_Reflection_Method) {
            // Get class
            $class = $info->getDeclaringClass()->getName();
            if ('static' == $info->isStatic()) {
                // for some reason, invokeArgs() does not work the same as
                // invoke(), and expects the first argument to be an object.
                // So, using a callback if the method is static.
                $return = call_user_func_array(array($class, $info->getName()), $params);
            } else {
                // Object methods
                try {
                    $object = $info->getDeclaringClass()->newInstance();
                } catch (Exception $e) {
                    require_once 'Zend/Amf/Server/Exception.php';
                    throw new Zend_Amf_Server_Exception('Error instantiating class ' . $class . ' to invoke method ' . $info->getName(), 621);
                }
                $return = $info->invokeArgs($object, $params);
            }
        } else {
            require_once 'Zend/Amf/Server/Exception.php';
            throw new Zend_Amf_Server_Exception('Method missing implementation ' . get_class($info));
        }

        return $return;
    }

    /**
     * Handles each of the 11 different command message types.
     *
     * A command message is a flex.messaging.messages.CommandMessage
     *
     * @see    Zend_Amf_Value_Messaging_CommandMessage
     * @param  Zend_Amf_Value_Messaging_CommandMessage $message
     * @return Zend_Amf_Value_Messaging_AcknowledgeMessage
     */
    protected function _loadCommandMessage(Zend_Amf_Value_Messaging_CommandMessage $message)
    {
        switch($message->operation) {
            case Zend_Amf_Value_Messaging_CommandMessage::CLIENT_PING_OPERATION :
                require_once 'Zend/Amf/Value/Messaging/AcknowledgeMessage.php';
                $return = new Zend_Amf_Value_Messaging_AcknowledgeMessage($message);
                break;
            default :
                require_once 'Zend/Amf/Server/Exception.php';
                throw new Zend_Amf_Server_Exception('CommandMessage::' . $message->operation . ' not implemented');
                break;
        }
        return $return;
    }

    /**
     * Takes the deserialized AMF request and performs any operations.
     *
     * @todo   should implement and SPL observer pattern for custom AMF headers
     * @todo   implement AMF header authentication
     * @param  Zend_Amf_Request $request
     * @return Zend_Amf_Response
     * @throws Zend_Amf_server_Exception|Exception
     */
    protected function _handle(Zend_Amf_Request $request)
    {
        // Get the object encoding of the request.
        $objectEncoding = $request->getObjectEncoding();

        // create a response object to place the output from the services.
        $response = $this->getResponse();

        // set reponse encoding
        $response->setObjectEncoding($objectEncoding);

        $responseBody = $request->getAmfBodies();

        // Iterate through each of the service calls in the AMF request
        foreach($responseBody as $body)
        {
            try {
                if ($objectEncoding == Zend_Amf_Constants::AMF0_OBJECT_ENCODING) {
                    // AMF0 Object Encoding
                    $targetURI = $body->getTargetURI();

                    // Split the target string into its values.
                    $source = substr($targetURI, 0, strrpos($targetURI, '.'));

                    if ($source) {
                        // Break off method name from namespace into source
                        $method = substr(strrchr($targetURI, '.'), 1);
                        $return = $this->_dispatch($method, $body->getData(), $source);
                    } else {
                        // Just have a method name.
                        $return = $this->_dispatch($targetURI, $body->getData());
                    }
                } else {
                    // AMF3 read message type
                    $message = $body->getData();
                    if ($message instanceof Zend_Amf_Value_Messaging_CommandMessage) {
                        // async call with command message
                        $return = $this->_loadCommandMessage($message);
                    } elseif ($message instanceof Zend_Amf_Value_Messaging_RemotingMessage) {
                        require_once 'Zend/Amf/Value/Messaging/AcknowledgeMessage.php';
                        $return = new Zend_Amf_Value_Messaging_AcknowledgeMessage($message);
                        $return->body = $this->_dispatch($message->operation, $message->body, $message->source);
                    } else {
                        // Amf3 message sent with netConnection
                        $targetURI = $body->getTargetURI();

                        // Split the target string into its values.
                        $source = substr($targetURI, 0, strrpos($targetURI, '.'));

                        if ($source) {
                            // Break off method name from namespace into source
                            $method = substr(strrchr($targetURI, '.'), 1);
                            $return = $this->_dispatch($method, $body->getData(), $source);
                        } else {
                            // Just have a method name.
                            $return = $this->_dispatch($targetURI, $body->getData());
                        }
                    }
                }
                $responseType = Zend_AMF_Constants::RESULT_METHOD;
            } catch (Exception $e) {
                switch ($objectEncoding) {
                    case Zend_Amf_Constants::AMF0_OBJECT_ENCODING :
                        $return = array(
                            'description' => ($this->isProduction()) ? '' : $e->getMessage(),
                            'detail'      => ($this->isProduction()) ? '' : $e->getTraceAsString(),
                            'line'        => ($this->isProduction()) ? 0  : $e->getLine(),
                            'code'        => $e->getCode(),
                        );
                        break;
                    case Zend_Amf_Constants::AMF3_OBJECT_ENCODING :
                        require_once 'Zend/Amf/Value/Messaging/ErrorMessage.php';
                        $return = new Zend_Amf_Value_Messaging_ErrorMessage($message);
                        $return->faultString = $this->isProduction() ? '' : $e->getMessage();
                        $return->faultCode   = $e->getCode();
                        $return->faultDetail = $this->isProduction() ? '' : $e->getTraceAsString();
                        break;
                }
                $responseType = Zend_AMF_Constants::STATUS_METHOD;
            }

            $responseURI = $body->getResponseURI() . $responseType;
            $newBody     = new Zend_Amf_Value_MessageBody($responseURI, null, $return);
            $response->addAmfBody($newBody);
        }
        // Add a session header to the body if session is requested.
        if($this->isSession()) {
           $currentID = session_id();
           $joint = "?";
           if(isset($_SERVER['QUERY_STRING'])) {
               if(!strpos($_SERVER['QUERY_STRING'], $currentID) !== FALSE) {
                   if(strrpos($_SERVER['QUERY_STRING'], "?") !== FALSE) {
                       $joint = "&";
                   } 
               }    
           }
           
            // create a new AMF message header with the session id as a variable.
            $sessionValue = $joint . $this->_sessionName . "=" . $currentID;
            $sessionHeader = new Zend_Amf_Value_MessageHeader("AppendToGatewayUrl", false, $sessionValue);
            $response->addAmfHeader($sessionHeader);
        }

        // serialize the response and return serialized body.
        $response->finalize();
    }

    /**
     * Handle an AMF call from the gateway.
     *
     * @param  null|Zend_Amf_Request $request Optional
     * @return Zend_Amf_Response
     */
    public function handle($request = null)
    {
        // Check if request was passed otherwise get it from the server
        if (is_null($request) || !$request instanceof Zend_Amf_Request) {
            $request = $this->getRequest();
        } else {
            $this->setRequest($request);
        }
        if ($this->isSession()) {
             // Check if a session is being sent from the amf call
             if (isset($_COOKIE[$this->_sessionName])) {
                 session_id($_COOKIE[$this->_sessionName]);
             }
        }

        // Check for errors that may have happend in deserialization of Request.
        try {
            // Take converted PHP objects and handle service call.
            // Serialize to Zend_Amf_response for output stream
            $this->_handle($request);
            $response = $this->getResponse();
        } catch (Exception $e) {
            // Handle any errors in the serialization and service  calls.
            require_once 'Zend/Amf/Server/Exception.php';
            throw new Zend_Amf_Server_Exception('Handle error: ' . $e->getMessage() . ' ' . $e->getLine());
        }

        // Return the Amf serialized output string
        return $response;
    }

    /**
     * Set request object
     *
     * @param  string|Zend_Amf_Request $request
     * @return Zend_Amf_Server
     */
    public function setRequest($request)
    {
        if (is_string($request) && class_exists($request)) {
            $request = new $request();
            if (!$request instanceof Zend_Amf_Request) {
                require_once 'Zend/Amf/Server/Exception.php';
                throw new Zend_Amf_Server_Exception('Invalid request class');
            }
        } elseif (!$request instanceof Zend_Amf_Request) {
            require_once 'Zend/Amf/Server/Exception.php';
            throw new Zend_Amf_Server_Exception('Invalid request object');
        }
        $this->_request = $request;
        return $this;
    }

    /**
     * Return currently registered request object
     *
     * @return null|Zend_Amf_Request
     */
    public function getRequest()
    {
        if (null === $this->_request) {
            require_once 'Zend/Amf/Request/Http.php';
            $this->setRequest(new Zend_Amf_Request_Http());
        }

        return $this->_request;
    }

    /**
     * Public access method to private Zend_Amf_Server_Response refrence
     *
     * @param  string|Zend_Amf_Server_Response $response
     * @return Zend_Amf_Server
     */
    public function setResponse($response)
    {
        if (is_string($response) && class_exists($response)) {
            $response = new $response();
            if (!$response instanceof Zend_Amf_Response) {
                require_once 'Zend/Amf/Server/Exception.php';
                throw new Zend_Amf_Server_Exception('Invalid response class');
            }
        } elseif (!$response instanceof Zend_Amf_Response) {
            require_once 'Zend/Amf/Server/Exception.php';
            throw new Zend_Amf_Server_Exception('Invalid response object');
        }
        $this->_response = $response;
        return $this;
    }

    /**
     * get a refrence to the Zend_Amf_response instance
     *
     * @return Zend_Amf_Server_Response
     */
    public function getResponse()
    {
        if (null === ($response = $this->_response)) {
            require_once 'Zend/Amf/Response/Http.php';
            $this->setResponse(new Zend_Amf_Response_Http());
        }
        return $this->_response;
    }

    /**
     * Attach a class or object to the server
     *
     * Class may be either a class name or an instantiated object. Reflection
     * is done on the class or object to determine the available public
     * methods, and each is attached to the server as and available method. If
     * a $namespace has been provided, that namespace is used to prefix
     * AMF service call.
     *
     * @param  string|object $class
     * @param  string $namespace Optional
     * @param  mixed $arg Optional arguments to pass to a method
     * @return Zend_Amf_Server
     * @throws Zend_Amf_Server_Exception on invalid input
     */
    public function setClass($class, $namespace = '', $argv = null)
    {
        if (is_string($class) && !class_exists($class)){
            require_once 'Zend/Amf/Server/Exception.php';
            throw new Zend_Amf_Server_Exception('Invalid method or class');
        } elseif (!is_string($class) && !is_object($class)) {
            require_once 'Zend/Amf/Server/Exception.php';
            throw new Zend_Amf_Server_Exception('Invalid method or class; must be a classname or object');
        }

        $argv = null;
        if (2 < func_num_args()) {
            $argv = array_slice(func_get_args(), 2);
        }

        // Use the class name as the name space by default.
        
        if ($namespace == '') {
            $namespace = is_object($class) ? get_class($class) : $class;
        }
        

        $this->_methods[] = Zend_Server_Reflection::reflectClass($class, $argv, $namespace);
        $this->_buildDispatchTable();

        return $this;
    }

    /**
     * Attach a function to the server
     *
     * Additional arguments to pass to the function at dispatch may be passed;
     * any arguments following the namespace will be aggregated and passed at
     * dispatch time.
     *
     * @param  string|array $function Valid callback
     * @param  string $namespace Optional namespace prefix
     * @return Zend_Amf_Server
     * @throws Zend_Amf_Server_Exception
     */
    public function addFunction($function, $namespace = '')
    {
        if (!is_string($function) && !is_array($function)) {
            require_once 'Zend/Amf/Server/Exception.php';
            throw new Zend_Amf_Server_Exception('Unable to attach function');
        }

        $argv = null;
        if (2 < func_num_args()) {
            $argv = array_slice(func_get_args(), 2);
        }

        $function = (array) $function;
        foreach ($function as $func) {
            if (!is_string($func) || !function_exists($func)) {
                require_once 'Zend/Amf/Server/Exception.php';
                throw new Zend_Amf_Server_Exception('Unable to attach function');
            }
            $this->_methods[] = Zend_Server_Reflection::reflectFunction($func, $argv, $namespace);
        }

        $this->_buildDispatchTable();
        return $this;
    }


    /**
     * Creates an array of directories in which services can reside.
     *
     * @param string $dir
     */
    public function addDirectory($dir)
    {
        $this->_directories[] = $dir;
    }

    /**
     * Returns an array of directories that can hold services.
     *
     * @return array
     */
    public function getDirectory()
    {
        return $this->_directories;
    }

    /**
     * (Re)Build the dispatch table
     *
     * The dispatch table consists of a an array of method name =>
     * Zend_Server_Reflection_Function_Abstract pairs
     *
     * @return void
     */
    protected function _buildDispatchTable()
    {
        $table = array();
        foreach ($this->_methods as $key => $dispatchable) {
            if ($dispatchable instanceof Zend_Server_Reflection_Function_Abstract) {
                $ns   = $dispatchable->getNamespace();
                $name = $dispatchable->getName();
                $name = empty($ns) ? $name : $ns . '.' . $name;

                if (isset($table[$name])) {
                    require_once 'Zend/Amf/Server/Exception.php';
                    throw new Zend_Amf_Server_Exception('Duplicate method registered: ' . $name);
                }
                $table[$name] = $dispatchable;
                continue;
            }

            if ($dispatchable instanceof Zend_Server_Reflection_Class) {
                foreach ($dispatchable->getMethods() as $method) {
                    $ns   = $method->getNamespace();
                    $name = $method->getName();
                    $name = empty($ns) ? $name : $ns . '.' . $name;

                    if (isset($table[$name])) {
                        require_once 'Zend/Amf/Server/Exception.php';
                        throw new Zend_Amf_Server_Exception('Duplicate method registered: ' . $name);
                    }
                    $table[$name] = $method;
                    continue;
                }
            }
        }
        $this->_table = $table;
    }



    /**
     * Raise a server fault
     *
     * Unimplemented
     *
     * @param  string|Exception $fault
     * @return void
     */
    public function fault($fault = null, $code = 404)
    {
    }

    /**
     * Returns a list of registered methods
     *
     * Returns an array of dispatchables (Zend_Server_Reflection_Function,
     * _Method, and _Class items).
     *
     * @return array
     */
    public function getFunctions()
    {
        return $this->_table;
    }

    /**
     * Set server persistence
     *
     * Unimplemented
     *
     * @param  mixed $mode
     * @return void
     */
    public function setPersistence($mode)
    {
    }

    /**
     * Load server definition
     *
     * Unimplemented
     *
     * @param  array $definition
     * @return void
     */
    public function loadFunctions($definition)
    {
    }

    /**
     * Map ActionScript classes to PHP classes
     *
     * @param  string $asClass
     * @param  string $phpClass
     * @return Zend_Amf_Server
     */
    public function setClassMap($asClass, $phpClass)
    {
        require_once 'Zend/Amf/Parse/TypeLoader.php';
        Zend_Amf_Parse_TypeLoader::setMapping($asClass, $phpClass);
        return $this;
    }

    /**
     * List all available methods
     *
     * Returns an array of method names.
     *
     * @return array
     */
    public function listMethods()
    {
        return array_keys($this->_table);
    }
}home/cideo/library/Zend/Json/Server.php000066600000036631151253537410014036 0ustar00<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Json
 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */

/**
 * @see Zend_Server_Abstract
 */
require_once 'Zend/Server/Abstract.php';

/**
 * @category   Zend
 * @package    Zend_Json
 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Json_Server extends Zend_Server_Abstract
{
    /**#@+
     * Version Constants
     * @const string
     */
    const VERSION_1 = '1.0';
    const VERSION_2 = '2.0';
    /**#@-*/

    /**
     * Flag: whether or not to auto-emit the response
     * @var bool
     */
    protected $_autoEmitResponse = true;

    /**
     * @var bool Flag; allow overwriting existing methods when creating server definition
     */
    protected $_overwriteExistingMethods = true;

    /**
     * Request object
     * @var Zend_Json_Server_Request
     */
    protected $_request;

    /**
     * Response object
     * @var Zend_Json_Server_Response
     */
    protected $_response;

    /**
     * SMD object
     * @var Zend_Json_Server_Smd
     */
    protected $_serviceMap;

    /**
     * SMD class accessors
     * @var array
     */
    protected $_smdMethods;

    /**
     * @var Zend_Server_Description
     */
    protected $_table;

    /**
     * Attach a function or callback to the server
     * 
     * @param  string|array $function Valid PHP callback
     * @param  string $namespace  Ignored
     * @return Zend_Json_Server
     */
    public function addFunction($function, $namespace = '')
    {
        if (!is_string($function) && (!is_array($function) || (2 > count($function)))) {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception('Unable to attach function; invalid');
        }

        if (!is_callable($function)) {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception('Unable to attach function; does not exist');
        }

        $argv = null;
        if (2 < func_num_args()) {
            $argv = func_get_args();
            $argv = array_slice($argv, 2);
        }

        require_once 'Zend/Server/Reflection.php';
        if (is_string($function)) {
            $method = Zend_Server_Reflection::reflectFunction($function, $argv, $namespace);
        } else {
            $class  = array_shift($function);
            $action = array_shift($function);
            $reflection = Zend_Server_Reflection::reflectClass($class, $argv, $namespace);
            $methods = $reflection->getMethods();
            $found   = false;
            foreach ($methods as $method) {
                if ($action == $method->getName()) {
                    $found = true;
                    break;
                }
            }
            if (!$found) {
                $this->fault('Method not found', -32601);
                return $this;
            }
        }

        $definition = $this->_buildSignature($method);
        $this->_addMethodServiceMap($definition);

        return $this;
    }

    /**
     * Register a class with the server
     * 
     * @param  string $class 
     * @param  string $namespace Ignored
     * @param  mixed $argv Ignored
     * @return Zend_Json_Server
     */
    public function setClass($class, $namespace = '', $argv = null)
    {
        $argv = null;
        if (3 < func_num_args()) {
            $argv = func_get_args();
            $argv = array_slice($argv, 3);
        }

        require_once 'Zend/Server/Reflection.php';
        $reflection = Zend_Server_Reflection::reflectClass($class, $argv, $namespace);

        foreach ($reflection->getMethods() as $method) {
            $definition = $this->_buildSignature($method, $class);
            $this->_addMethodServiceMap($definition);
        }
        return $this;
    }

    /**
     * Indicate fault response
     * 
     * @param  string $fault 
     * @param  int $code 
     * @return false
     */
    public function fault($fault = null, $code = 404, $data = null)
    {
        require_once 'Zend/Json/Server/Error.php';
        $error = new Zend_Json_Server_Error($fault, $code, $data);
        $this->getResponse()->setError($error);
        return $error;
    }

    /**
     * Handle request
     * 
     * @param  Zend_Json_Server_Request $request 
     * @return null|Zend_Json_Server_Response
     */
    public function handle($request = false)
    {
        if ((false !== $request) && (!$request instanceof Zend_Json_Server_Request)) {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception('Invalid request type provided; cannot handle');
        } elseif ($request) {
            $this->setRequest($request);
        }

        // Handle request
        $this->_handle();

        // Get response
        $response = $this->_getReadyResponse();

        // Emit response?
        if ($this->autoEmitResponse()) {
            echo $response;
            return;
        }

        // or return it?
        return $response;
    }

    /**
     * Load function definitions
     * 
     * @param  array|Zend_Server_Definition $definition 
     * @return void
     */
    public function loadFunctions($definition)
    {
        if (!is_array($definition) && (!$definition instanceof Zend_Server_Definition)) {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception('Invalid definition provided to loadFunctions()');
        }

        foreach ($definition as $key => $method) {
            $this->_table->addMethod($method, $key);
            $this->_addMethodServiceMap($method);
        }
    }

    public function setPersistence($mode)
    {
    }

    /**
     * Set request object
     * 
     * @param  Zend_Json_Server_Request $request 
     * @return Zend_Json_Server
     */
    public function setRequest(Zend_Json_Server_Request $request)
    {
        $this->_request = $request;
        return $this;
    }

    /**
     * Get JSON-RPC request object
     * 
     * @return Zend_Json_Server_Request
     */
    public function getRequest()
    {
        if (null === ($request = $this->_request)) {
            require_once 'Zend/Json/Server/Request/Http.php';
            $this->setRequest(new Zend_Json_Server_Request_Http());
        }
        return $this->_request;
    }

    /**
     * Set response object
     * 
     * @param  Zend_Json_Server_Response $response 
     * @return Zend_Json_Server
     */
    public function setResponse(Zend_Json_Server_Response $response)
    {
        $this->_response = $response;
        return $this;
    }

    /**
     * Get response object
     * 
     * @return Zend_Json_Server_Response
     */
    public function getResponse()
    {
        if (null === ($response = $this->_response)) {
            require_once 'Zend/Json/Server/Response/Http.php';
            $this->setResponse(new Zend_Json_Server_Response_Http());
        }
        return $this->_response;
    }

    /**
     * Set flag indicating whether or not to auto-emit response
     * 
     * @param  bool $flag 
     * @return Zend_Json_Server
     */
    public function setAutoEmitResponse($flag)
    {
        $this->_autoEmitResponse = (bool) $flag;
        return $this;
    }

    /**
     * Will we auto-emit the response?
     * 
     * @return bool
     */
    public function autoEmitResponse()
    {
        return $this->_autoEmitResponse;
    }

    // overloading for SMD metadata
    /**
     * Overload to accessors of SMD object
     * 
     * @param  string $method 
     * @param  array $args 
     * @return mixed
     */
    public function __call($method, $args)
    {
        if (preg_match('/^(set|get)/', $method, $matches)) {
            if (in_array($method, $this->_getSmdMethods())) {
                if ('set' == $matches[1]) {
                    $value = array_shift($args);
                    $this->getServiceMap()->$method($value);
                    return $this;
                } else {
                    return $this->getServiceMap()->$method();
                }
            }
        }
        return null;
    }

    /**
     * Retrieve SMD object
     * 
     * @return Zend_Json_Server_Smd
     */
    public function getServiceMap()
    {
        if (null === $this->_serviceMap) {
            require_once 'Zend/Json/Server/Smd.php';
            $this->_serviceMap = new Zend_Json_Server_Smd();
        }
        return $this->_serviceMap;
    }

    /**
     * Add service method to service map
     * 
     * @param  Zend_Server_Reflection_Function $method 
     * @return void
     */
    protected function _addMethodServiceMap(Zend_Server_Method_Definition $method)
    {
        $serviceInfo = array(
            'name'   => $method->getName(),
            'return' => $this->_getReturnType($method),
        );
        $params = $this->_getParams($method);
        $serviceInfo['params'] = $params;
        $serviceMap = $this->getServiceMap();
        if (false !== $serviceMap->getService($serviceInfo['name'])) {
            $serviceMap->removeService($serviceInfo['name']);
        }
        $serviceMap->addService($serviceInfo);
    }

    /**
     * Translate PHP type to JSON type
     * 
     * @param  string $type 
     * @return string
     */
    protected function _fixType($type)
    {
        return $type;
    }

    /**
     * Get default params from signature
     * 
     * @param  array $args 
     * @param  array $params 
     * @return array
     */
    protected function _getDefaultParams(array $args, array $params)
    {
        $defaultParams = array_slice($params, count($args));
        foreach ($defaultParams as $param) {
            $value = null;
            if (array_key_exists('default', $param)) {
                $value = $param['default'];
            }
            array_push($args, $value);
        }
        return $args;
    }

    /**
     * Get method param type
     * 
     * @param  Zend_Server_Reflection_Function_Abstract $method 
     * @return string|array
     */
    protected function _getParams(Zend_Server_Method_Definition $method)
    {
        $params = array();
        foreach ($method->getPrototypes() as $prototype) {
            foreach ($prototype->getParameterObjects() as $key => $parameter) {
                if (!isset($params[$key])) {
                    $params[$key] = array(
                        'type'     => $parameter->getType(),
                        'name'     => $parameter->getName(),
                        'optional' => $parameter->isOptional(),
                    );
                    if (null !== ($default = $parameter->getDefaultValue())) {
                        $params[$key]['default'] = $default;
                    }
                    $description = $parameter->getDescription();
                    if (!empty($description)) {
                        $params[$key]['description'] = $description;
                    }
                    continue;
                }
                $newType = $parameter->getType();
                if (!is_array($params[$key]['type'])) {
                    if ($params[$key]['type'] == $newType) {
                        continue;
                    }
                    $params[$key]['type'] = (array) $params[$key]['type'];
                } elseif (in_array($newType, $params[$key]['type'])) {
                    continue;
                }
                array_push($params[$key]['type'], $parameter->getType());
            }
        }
        return $params;
    }

    /**
     * Set response state
     * 
     * @return Zend_Json_Server_Response
     */
    protected function _getReadyResponse()
    {
        $request  = $this->getRequest();
        $response = $this->getResponse();

        $response->setServiceMap($this->getServiceMap());
        if (null !== ($id = $request->getId())) {
            $response->setId($id);
        }
        if (null !== ($version = $request->getVersion())) {
            $response->setVersion($version);
        }

        return $response;
    }

    /**
     * Get method return type
     * 
     * @param  Zend_Server_Reflection_Function_Abstract $method 
     * @return string|array
     */
    protected function _getReturnType(Zend_Server_Method_Definition $method)
    {
        $return = array();
        foreach ($method->getPrototypes() as $prototype) {
            $return[] = $prototype->getReturnType();
        }
        if (1 == count($return)) {
            return $return[0];
        }
        return $return;
    }

    /**
     * Retrieve list of allowed SMD methods for proxying
     * 
     * @return array
     */
    protected function _getSmdMethods()
    {
        if (null === $this->_smdMethods) {
            $this->_smdMethods = array();
            require_once 'Zend/Json/Server/Smd.php';
            $methods = get_class_methods('Zend_Json_Server_Smd');
            foreach ($methods as $key => $method) {
                if (!preg_match('/^(set|get)/', $method)) {
                    continue;
                }
                if (strstr($method, 'Service')) {
                    continue;
                }
                $this->_smdMethods[] = $method;
            }
        }
        return $this->_smdMethods;
    }

    /**
     * Internal method for handling request
     * 
     * @return void
     */
    protected function _handle()
    {
        $request = $this->getRequest();

        if (!$request->isMethodError() && (null === $request->getMethod())) {
            return $this->fault('Invalid Request', -32600);
        }

        if ($request->isMethodError()) {
            return $this->fault('Invalid Request', -32600);
        }

        $method = $request->getMethod();
        if (!$this->_table->hasMethod($method)) {
            return $this->fault('Method not found', -32601);
        }

        $params        = $request->getParams();
        $invocable     = $this->_table->getMethod($method);
        $serviceMap    = $this->getServiceMap();
        $service       = $serviceMap->getService($method);
        $serviceParams = $service->getParams();

        if (count($params) < count($serviceParams)) {
            $params = $this->_getDefaultParams($params, $serviceParams);
        }

        try {
            $result = $this->_dispatch($invocable, $params);
        } catch (Exception $e) {
            return $this->fault($e->getMessage(), $e->getCode());
        }

        $this->getResponse()->setResult($result);
    }
}