/*
 * Copyright (C) The Apache Software Foundation. All rights reserved.
 *
 * This software is published under the terms of the Apache Software License
 * version 1.1, a copy of which has been included with this distribution in
 * the LICENSE.txt file.
 */

package org.apache.avalon.excalibur.testcase;

import org.apache.avalon.excalibur.logger.LoggerManager;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.excalibur.fortress.AbstractContainer;

/**
 * A container that gives access to the service manager and
 * component manager similar to Fortress default container 
 * implementation.
 * @see org.apache.excalibur.fortress.container.DefaultContainer
 *
 * @version $Revision: 1.2 $
 * @author  <a href="mailto:mschier@earthlink.net">Marc Schier</a>
 */
public class FortressTestContainer
    extends AbstractContainer
    implements Configurable
{
    //------------------------- Configurable implementation
    /**
     * Process the configuration and set up the components 
     * and their mappings. At this point, all components are 
     * prepared and all mappings are made. However, nothing 
     * is initialized.
     * @since Aug 9, 2002
     * 
     * @param configElement
     *  The configuration for the container
     * @throws ConfigurationException
     *  If anything went wrong
     */
    public void configure(Configuration configElement)
        throws ConfigurationException
    {
        m_configuration = configElement;

        final Configuration elements[] = configElement.getChildren();

        for (int i = 0; i < elements.length; i++)
        {
            final Configuration component;

            if ("component".equals(elements[i].getName()))
            {
                component = elements[i];
            }
            else
            {
                // the component might need to be rewritten
                component = rewriteConfiguration(elements[i]);
            }

            addComponent(component, component.getAttribute("id", null));
        }
    }

    //------------------------- FortressTestContainer specific implementation
    /**
     * Handles when a configuration name is used that is not 
     * "component", so it makes it easier to handle ComponentSelector 
     * hierarchies. 
     * @since Aug 9, 2002
     * 
     * @param configItem
     *  The configuration item to rewrite into the container
     *  expected format.
     * @return 
     *  A rewritten configuration complying with the container's
     *  expected component configuration format.
     */
    protected Configuration rewriteConfiguration(final Configuration configItem)
        throws ConfigurationException
    {
        final DefaultConfiguration temp =
            new DefaultConfiguration(
                "component",
                "AbstractContainer-rewrite [name: "
                    + configItem.getName()
                    + ", location: "
                    + configItem.getLocation()
                    + "]");

        final Class klass = m_roleManager.getClassForName(configItem.getName());
        final Class handlerKlass = m_roleManager.getHandlerClassForClass(klass);
        final String role = m_roleManager.getRoleForClass(klass);

        if (null == klass)
        {
            throw new ConfigurationException(
                "No class found matching configuration name "
                    + "[name: "
                    + configItem.getName()
                    + ", location: "
                    + configItem.getLocation()
                    + "]");
        }

        //We set these before copying all other attributes so the class/
        //handler can be overriden if needed if the shorthand name is used
        temp.setAttribute("role", role);
        temp.setAttribute("class", klass.getName());
        temp.setAttribute("handler", handlerKlass.getName());

        // set the id as the name of the element
        temp.setAttribute("id", configItem.getName());

        temp.setValue(configItem.getValue(null));

        final String[] attributes = configItem.getAttributeNames();
        for (int i = 0; i < attributes.length; i++)
        {
            temp.setAttribute(
                attributes[i],
                configItem.getAttribute(attributes[i]));
        }

        final Configuration[] children = configItem.getChildren();
        for (int i = 0; i < children.length; i++)
        {
            temp.addChild(children[i]);
        }

        temp.makeReadOnly();
        return temp;
    }

    /**
     * Gives access to the component manager for this 
     * container.
     * @since Aug 9, 2002
     * 
     * @return ComponentManager
     *  The Component manager for this container used
     *  to look up Component implementing Components
     */
    public ComponentManager getComponentManager()
    {
        return super.getComponentManager();
    }

    /**
     * Gives access to the service manager for this container.
     * @since Aug 9, 2002
     * 
     * @return ServiceManager
     *  The Service manager for this container used
     *  to look up Components complying with the service
     *  model.
     */
    public ServiceManager getServiceManager()
    {
        return super.getServiceManager();
    }
    
    /**
     * Gives access to the logger manager for this container.
     * @since Aug 9, 2002
     * 
     * @return LoggerManager
     *  The Logger manager for this container used to look up 
     *  Loggers based on a category string. 
     */
    protected LoggerManager getLoggerManager()
    {
        return m_logManager;
    }
}

