<?php
/**
 * File containing the ezcWebdavPluginRegistry 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 Webdav
 * @version //autogen//
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */
/**
 * Global plugin registry class.
 *
 * An instance of this class is request wide uniquely responsible for handling
 * plugins to the Webdav component. It has a number of different hooks
 * available of the server and transport layer of the component to allow
 * plugins to interact and integrate with these layers to add extended
 * funtionality.
 *
 * A good overview of the working of the plugin system can be found in its
 * design document {@link Webdav/design/extensibility.txt}.
 *
 * @see ezcWebdavServer
 * @see ezcWebdavTransport
 * @see ezcWebdavPropertyHandler
 * 
 * @package Webdav
 * @version //autogen//
 */
class ezcWebdavPluginRegistry
{
    /**
     * Known hooks. 
     * 
     * <code>
     *      array(
     *          '<class>' => array(
     *              '<method>' => true,
     *              // ...
     *          )
     *          // ...
     *      )
     * </code>
     *
     * @var array(string=>array(string=>bool))
     */
    private $hooks = array();

    /**
     * Registered plugins. 
     *
     * <code>
     *      array(
     *          '<namespace>' => '<config-object>',
     *          // ...
     *      )
     * </code>
     * 
     * @var array(string=>ezcWebdavPluginConfiguration)
     */
    private $plugins = array();
    

    /**
     * Assigned hooks.
     * <code>
     *      array(
     *          '<class name>' => array(
     *              '<hook name>' => array(
     *                  '<namespace>' => array(
     *                      <callback1>,
     *                      <callback2>,
     *                      // ...
     *                  ),
     *                  // ...
     *              ),
     *              // ...
     *          ),
     *          // ...
     *      )
     * </code>
     * 
     * @var array
     */
    private $assignedHooks = array();

    /**
     * Creates a new plugin registry.
     * 
     * @return void
     */
    public function __construct()
    {
        // Transport layer hooks
        $this->createHook( 'ezcWebdavTransport', 'beforeParseRequest' );
        $this->createHook( 'ezcWebdavTransport', 'afterProcessResponse' );

        $this->createHook( 'ezcWebdavTransport', 'parseUnknownRequest' );
        $this->createHook( 'ezcWebdavTransport', 'processUnknownResponse' );

        // Property related hooks
        $this->createHook( 'ezcWebdavPropertyHandler', 'extractDeadProperty' );
        $this->createHook( 'ezcWebdavPropertyHandler', 'serializeDeadProperty' );

        $this->createHook( 'ezcWebdavPropertyHandler', 'extractUnknownLiveProperty' );
        $this->createHook( 'ezcWebdavPropertyHandler', 'serializeUnknownLiveProperty' );

        // Server layer hooks
        $this->createHook( 'ezcWebdavServer', 'receivedRequest' );
        $this->createHook( 'ezcWebdavServer', 'generatedResponse' );
    }

    /**
     * Creates a new hook.
     * 
     * Helper method. Used in {@link __construct()} to create a hook. The
     * $class identifies the base class the hook is provided by, $method
     * specificies the name of the affected method of this class or a "pseudo
     * method name", if no such is available.
     * 
     * @param string $class 
     * @param string $hook 
     * @return void
     */
    private function createHook( $class, $hook )
    {
        $this->hooks[$class][$hook] = true;
    }

    /**
     * Registers a new plugin to be used.
     *
     * Receives an instance of {@link ezcWebdavPluginConfiguration}, which is
     * possible extended for internal use in the plugin. The 'namespace'
     * property of this class is used to register it internally. Multiple
     * registrations of the same namespace will lead to an exception.
     *
     * @param ezcWebdavPluginConfiguration $config
     * @return void
     *
     * @throws ezcWebdavPluginDoubleRegistrationException
     *         if the namespace of a plugin is registered twice.
     */
    public final function registerPlugin( ezcWebdavPluginConfiguration $config )
    {
        if ( !is_string( ( $namespace = $config->getNamespace() ) ) )
        {
            throw new ezcBaseValueException( 'namespace', $namespace, 'string' );
        }
        if ( isset( $this->plugins[$namespace] ) )
        {
            throw new ezcBaseValueException( 'namespace', $namespace, 'already registered' );
        }

        if ( !is_array( ( $hooks = $config->getHooks() ) ) )
        {
            throw new ezcBaseValueException( 'hooks', $hooks, 'array' );
        }
        // Validate hooks
        foreach ( $hooks as $class => $hookInfos )
        {
            if ( !isset( $this->hooks[$class] ) )
            {
                throw new ezcWebdavInvalidHookException( $class );
            }
            foreach ( $hookInfos as $hook => $callbacks )
            {
                if ( !isset( $this->hooks[$class][$hook] ) )
                {
                    throw new ezcWebdavInvalidHookException( $class, $hook );
                }
                foreach( $callbacks as $callback )
                {
                    if ( !is_callable( $callback ) )
                    {
                        throw new ezcWebdavInvalidCallbackException( $callback );
                    }
                }
            }
        }

        // Register namespace
        $this->plugins[$namespace] = $config;

        // Register Hooks
        foreach ( $hooks as $class => $hookInfos )
        {
            foreach ( $hookInfos as $hook => $callbacks )
            {
                $this->assignedHooks[$class][$hook][$namespace] = $callbacks;
            }
        }
    }

    /**
     * Can be used to deactivate a plugin.
     *
     * Receives an instance of {@link ezcWebdavPluginConfiguration}, which is
     * possible extended for internal use in the plugin. The 'namespace'
     * property of this class is used to unregister it internally.
     * Unregistration of a notregistered $config object will be silently
     * ignored.
     *
     * @param ezcWebdavPluginConfiguration $config
     * @return void
     */
    public final function unregisterPlugin( ezcWebdavPluginConfiguration $config )
    {
        if ( !is_string( ( $namespace = $config->getNamespace() ) ) )
        {
            throw new ezcBaseValueException( 'namespace', $namespace, 'string' );
        }
        if ( !isset( $this->plugins[$namespace] ) )
        {
            throw new ezcBaseValueException( 'namespace', $namespace, 'registered' );
        }

        // Unregister namespace
        unset( $this->plugins[$namespace] );

        // Unregister hooks
        foreach ( $this->assignedHooks as $class => $hookInfos )
        {
            foreach ( $hookInfos as $hook => $pluginInfos )
            {
                if ( isset( $pluginInfos[$namespace] ) )
                {
                    unset( $this->assignedHooks[$class][$hook][$namespace] );
                }
            }
        }
    }

    /**
     * Returns a plugins configuration object.
     *
     * Returns the instance of {@link ezcWebdavPluginConfiguration} used for
     * the plugin with a given $namespace. Throws an exception, if the plugin
     * was not found.
     * 
     * @param string $namespace 
     * @return ezcWebdavPluginConfiguration
     */
    public final function getPluginConfig( $namespace )
    {
        if ( !isset( $this->plugins[$namespace] ) )
        {
            throw new ezcBaseValueException( 'namespace', $namespace, 'registered' );
        }

        return $this->plugins[$namespace];
    }

    /**
     * Returns if a plugin is active in the server.
     *
     * Checks if a configuration with the given $namespace exists and returns
     * this information as a boolean value.
     * 
     * @param string $namespace 
     * @return bool
     */
    public final function hasPlugin( $namespace )
    {
        return isset( $this->plugins[$namespace] );
    }

    /**
     * Announces the given hook.
     *
     * This class may only be used by {@link ezcWebdavServer} and {@link
     * ezcWebdavTransport} to announce the reaching of a hook. Therefore, this
     * method is marked private. Receives the name of the class issuing the
     * $hook and the $params that may be used for information extraction and
     * _careful_ possible manipulation.
     *
     * This method is declared private, because the announcement of hooks is
     * only allowed by component internal classes.
     * 
     * @param string $class
     * @param string $hook 
     * @param ezcWebdavPluginParameters $params 
     * @return void
     *
     * @throws ezcWebdavPluginFailureException
     *         in case a plugin threw an exception. The original one can be
     *         accessed for processing through the public $originalException
     *         attribute.
     *
     * @access private
     */
    public final function announceHook( $class, $hook, ezcWebdavPluginParameters $params )
    {
        // Sanity check
        if ( !isset( $this->hooks[$class][$hook] ) )
        {
            throw new RuntimeException(
                "Internal error in Webdav component. Announced non-existent hook: {$class}->{$hook}."
            );
        }

        if ( !isset( $this->assignedHooks[$class][$hook] ) )
        {
            // No plugins assigned
            return;
        }
        foreach ( $this->assignedHooks[$class][$hook] as $namespace => $callbacks )
        {
            foreach ( $callbacks as $callback )
            {
                $res = call_user_func( $callback, $params );
                // If the plugin produced a result, we terminate and return the result
                if ( $res !== null )
                {
                    return $res;
                }
            }
        }
    }

    /**
     * Initializes all registered plugins.
     *
     * This method calls the {@link ezcWebdavPluginConfiguration::init()}
     * method for each registered plugin. The method is marked as private,
     * because it is not intended for external use, but may only be called from
     * {@link ezcWebdavServer}.
     * 
     * @return void
     *
     * @access private
     */
    public final function initPlugins()
    {
        foreach ( $this->plugins as $namespace => $config )
        {
            $config->init();
        }
    }
}

?>
