/*
 * 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 org.apache.myfaces.test.config;

import java.io.IOException;
import java.net.URL;

import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.ApplicationFactory;
import javax.faces.render.ClientBehaviorRenderer;
import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
import javax.faces.render.Renderer;

import org.apache.commons.digester.Digester;
import org.apache.commons.digester.Rule;
import org.apache.myfaces.test.mock.MockRenderKit;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

/**
 * <p>Utility class to parse JavaServer Faces configuration resources, and
 * register JSF artifacts with the mock object hierarchy.</p>
 *
 * <p>The following artifacts are registered:</p>
 * <ul>
 *     <li><code>Converter</code> (by-id and by-class)</li>
 *     <li><code>RenderKit</code> and <code>Renderer</code></li>
 *     <li><code>UIComponent</code></li>
 *     <li><code>Validator</code></li>
 * </ul>
 *
 * <p>Note that any declared <em>factory</em> instances are explicitly
 * <strong>NOT</strong> registered, allowing the mock object hierarchy
 * of the Myfaces Test Framework to manage these APIs.</p>
 *
 * <p><strong>USAGE NOTE</strong> - If you are using an instance of this
 * class within a subclass of <code>AbstractJsfTestCase</code> or
 * <code>AbstractJmockJsfTestCase</code>, be sure you have completed the
 * <code>setUp()</code> processing in this base class before calling one
 * of the <code>parse()</code> methods.</p>
 *
 * @since 1.1
 */
public class ConfigParser {
    

    // ------------------------------------------------------------ Constructors


    /** Creates a new instance of ConfigParser */
    public ConfigParser() {
    }
    

    // ------------------------------------------------------ Manifest Constants


    /**
     * <p>Configuration resource URLs for the JSF RI.</p>
     */
    private static final String[] JSFRI_RESOURCES =
    { "/com/sun/faces/jsf-ri-runtime.xml",
    };


    /**
     * <p>Configuration resource URLs for Apache MyFaces.</p>
     */
    private static final String[] MYFACES_RESOURCES =
    { "/org/apache/myfaces/resource/standard-faces-config.xml",
    };

    /**
     * <p>Configuration resource URLs for Apache MyFaces 1.2.</p>
     */
    private static final String[] MYFACES_RESOURCES12 =
    { "/META-INF/standard-faces-config.xml",
    };    

    // ------------------------------------------------------ Instance Variables


    /**
     * <p>The <code>Digester</code> instance we will use for parsing.</p>
     */
    private Digester digester = null;


    // ------------------------------------------------------- Public Properties


    /**
     * <p>Return the URLs of the platform configuration resources for this
     * application.  The following platforms are currently supported:</p>
     * <ul>
     * <li>JavaServer Faces Reference Implementation (version 1.0 - 1.2)</li>
     * <li>MyFaces (version 1.1)</li>
     * </ul>
     *
     * <p>If MyFaces (version 1.2), currently under development, does not change
     * the name of the configuration resource, it will be supported as well.</p>
     */
    public URL[] getPlatformURLs() {

        URL[] urls = translate(JSFRI_RESOURCES);
        if (urls[0] == null) {
            urls = translate(MYFACES_RESOURCES12);
            if (urls[0] == null) {
                urls = translate(MYFACES_RESOURCES);
            }
        }
        return urls;

    }


    // ---------------------------------------------------------- Public Methods


    /**
     * <p>Parse the specified JavaServer Faces configuration resource, causing
     * the appropriate JSF artifacts to be registered with the mock object
     * hierarchy.</p>
     *
     * @param url <code>URL</code> of the configuration resource to parse
     *
     * @exception IOException if an input/output error occurs
     * @exception SAXException if a parsing error occurs
     */
    public void parse(URL url) throws IOException, SAXException {

        // Acquire and configure the Digester instance we will use
        Digester digester = digester();
        ApplicationFactory factory = (ApplicationFactory)
          FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
        Application application = factory.getApplication();
        digester.push(application);

        // Perform the required parsing
        try {
            digester.parse(url);
        } finally {
            digester.clear();
        }

    }


    /**
     * <p>Parse the specified set of JavaServer Faces configuration resources,
     * in the listed order, causing the appropriate JSF artifacts to be registered
     * with the mock object hierarchy.</p>
     *
     * @param urls <code>URL</code>s of the configuration resources to parse
     *
     * @exception IOException if an input/output error occurs
     * @exception SAXException if a parsing error occurs
     */
    public void parse(URL[] urls) throws IOException, SAXException {

        for (int i = 0; i < urls.length; i++) {
            parse(urls[i]);
        }

    }


    // --------------------------------------------------------- Private Methods


    /**
     * <p>Return the <code>Digester</code> instance we will use for parsing,
     * creating and configuring a new instance if necessary.</p>
     */
    private Digester digester() {

        if (this.digester == null) {
            this.digester = new Digester();
            digester.addRule("faces-config/component", new ComponentRule());
            digester.addCallMethod
              ("faces-config/component/component-type", "setComponentType", 0);
            digester.addCallMethod
              ("faces-config/component/component-class", "setComponentClass", 0);
            digester.addRule("faces-config/converter", new ConverterRule());
            digester.addCallMethod
              ("faces-config/converter/converter-id", "setConverterId", 0);
            digester.addCallMethod
              ("faces-config/converter/converter-class", "setConverterClass", 0);
            digester.addCallMethod
              ("faces-config/converter/converter-for-class", "setConverterForClass", 0);
            digester.addRule("faces-config/render-kit", new RenderKitRule());
            digester.addRule("faces-config/render-kit/render-kit-id", new RenderKitIdRule());
            digester.addRule("faces-config/render-kit/renderer", new RendererRule());
            digester.addCallMethod
              ("faces-config/render-kit/renderer/component-family", "setComponentFamily", 0);
            digester.addCallMethod
              ("faces-config/render-kit/renderer/renderer-class", "setRendererClass", 0);
            digester.addCallMethod
              ("faces-config/render-kit/renderer/renderer-type", "setRendererType", 0);
            digester.addRule("faces-config/render-kit/client-behavior-renderer", new ClientBehaviorRendererRule());
            digester.addCallMethod
              ("faces-config/render-kit/client-behavior-renderer/client-behavior-renderer-type", "setClientBehaviorRendererType", 0);
            digester.addCallMethod
              ("faces-config/render-kit/client-behavior-renderer/client-behavior-renderer-class", "setClientBehaviorRendererClass", 0);
            digester.addRule("faces-config/validator", new ValidatorRule());
            digester.addCallMethod
              ("faces-config/validator/validator-id", "setValidatorId", 0);
            digester.addCallMethod
              ("faces-config/validator/validator-class", "setValidatorClass", 0);
            digester.addRule("faces-config/behavior", new BehaviorRule());
            digester.addCallMethod
                ("faces-config/behavior/behavior-id", "setBehaviorId", 0);
            digester.addCallMethod
                ("faces-config/behavior/behavior-class", "setBehaviorClass", 0);
        }
        return this.digester;

    }


    /**
     * <p>Translate an array of resource names into an array of resource URLs.</p>
     *
     * @param names Resource names to translate
     */
    private URL[] translate(String[] names) {

        URL[] results = new URL[names.length];
        for (int i = 0; i < names.length; i++) {
            results[i] = this.getClass().getResource(names[i]);
        }
        return results;
        
    }


    // --------------------------------------------------------- Private Classes


    /**
     * <p>Data bean that stores information related to a component.</p>
     */
    class ComponentBean {

        private String componentClass;
        public String getComponentClass() {
            return this.componentClass;
        }
        public void setComponentClass(String componentClass) {
            this.componentClass = componentClass;
        }

        private String componentType;
        public String getComponentType() {
            return this.componentType;
        }
        public void setComponentType(String componentType) {
            this.componentType = componentType;
        }

    }


    /**
     * <p>Digester <code>Rule</code> for processing components.</p>
     */
    class ComponentRule extends Rule {

        public void begin(String namespace, String name, Attributes attributes) {
            getDigester().push(new ComponentBean());
        }

        public void end(String namespace, String name) {
            ComponentBean bean = (ComponentBean) getDigester().pop();
            Application application = (Application) getDigester().peek();
            application.addComponent(bean.getComponentType(), bean.getComponentClass());
        }

    }


    /**
     * <p>Data bean that stores information related to a converter.</p>
     */
    class ConverterBean {

        private String converterClass;
        public String getConverterClass() {
            return this.converterClass;
        }
        public void setConverterClass(String converterClass) {
            this.converterClass = converterClass;
        }

        private String converterForClass;
        public String getConverterForClass() {
            return this.converterForClass;
        }
        public void setConverterForClass(String converterForClass) {
            this.converterForClass = converterForClass;
        }

        private String converterId;
        public String getConverterId() {
            return this.converterId;
        }
        public void setConverterId(String converterId) {
            this.converterId = converterId;
        }

    }


    /**
     * <p>Digester <code>Rule</code> for processing converers.</p>
     */
    class ConverterRule extends Rule {

        public void begin(String namespace, String name, Attributes attributes) {
            getDigester().push(new ConverterBean());
        }

        public void end(String namespace, String name) {
            ConverterBean bean = (ConverterBean) getDigester().pop();
            Application application = (Application) getDigester().peek();
            if (bean.getConverterId() != null) {
                application.addConverter(bean.getConverterId(), bean.getConverterClass());
            } else {
                Class clazz = null;
                try {
                    clazz = this.getClass().getClassLoader().loadClass(bean.getConverterForClass());
                } catch (ClassNotFoundException e) {
                    throw new IllegalArgumentException("java.lang.ClassNotFoundException: "
                        + bean.getConverterForClass());
                }
                application.addConverter(clazz, bean.getConverterClass());
            }
        }

    }


    /**
     * <p>Digester <code>Rule</code> for processing render kits.</p>
     */
    class RenderKitRule extends Rule {

        public void begin(String namespace, String name, Attributes attributes) {
            RenderKitFactory factory = (RenderKitFactory)
              FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
            getDigester().push(factory.getRenderKit(null, RenderKitFactory.HTML_BASIC_RENDER_KIT));
        }

        public void end(String namespace, String name) {
            getDigester().pop();
        }

    }


    /**
     * <p>Digester <code>Rule</code> for processing render kit identifiers.</p>
     */
    class RenderKitIdRule extends Rule {

        public void body(String namespace, String name, String text) {
            String renderKitId = text.trim();
            RenderKitFactory factory = (RenderKitFactory)
              FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
            RenderKit renderKit = factory.getRenderKit(null, renderKitId);
            if (renderKit == null) {
                renderKit = new MockRenderKit();
                factory.addRenderKit(renderKitId, renderKit);
            }
            getDigester().pop();
            getDigester().push(renderKit);
        }

    }


    /**
     * <p>Data bean that stores information related to a renderer.</p>
     */
    class RendererBean {

        private String componentFamily;
        public String getComponentFamily() {
            return this.componentFamily;
        }
        public void setComponentFamily(String componentFamily) {
            this.componentFamily = componentFamily;
        }

        private String rendererClass;
        public String getRendererClass() {
            return this.rendererClass;
        }
        public void setRendererClass(String rendererClass) {
            this.rendererClass = rendererClass;
        }

        private String rendererType;
        public String getRendererType() {
            return this.rendererType;
        }
        public void setRendererType(String rendererType) {
            this.rendererType = rendererType;
        }

    }


    /**
     * <p>Digester <code>Rule</code> for processing renderers.</p>
     */
    class RendererRule extends Rule {

        public void begin(String namespace, String name, Attributes attributes) {
            getDigester().push(new RendererBean());
        }

        public void end(String namespace, String name) {
            RendererBean bean = (RendererBean) getDigester().pop();
            RenderKit kit = (RenderKit) getDigester().peek();
            Renderer renderer = null;
            Class clazz = null;
            try {
                clazz = this.getClass().getClassLoader().loadClass(bean.getRendererClass());
                renderer = (Renderer) clazz.newInstance();
            } catch (Exception e) {
                throw new IllegalArgumentException("Exception while trying to instantiate"
                    + " renderer class '" + bean.getRendererClass() + "' : "
                    + e.getMessage());
            }
            kit.addRenderer(bean.getComponentFamily(), bean.getRendererType(),
                            renderer);
        }

    }


    /**
     * <p>Data bean that stores information related to a validator.</p>
     */
    class ValidatorBean {

        private String validatorClass;
        public String getValidatorClass() {
            return this.validatorClass;
        }
        public void setValidatorClass(String validatorClass) {
            this.validatorClass = validatorClass;
        }

        private String validatorId;
        public String getValidatorId() {
            return this.validatorId;
        }
        public void setValidatorId(String validatorId) {
            this.validatorId = validatorId;
        }

    }


    /**
     * <p>Digester <code>Rule</code> for processing validators.</p>
     */
    class ValidatorRule extends Rule {

        public void begin(String namespace, String name, Attributes attributes) {
            getDigester().push(new ValidatorBean());
        }

        public void end(String namespace, String name) {
            ValidatorBean bean = (ValidatorBean) getDigester().pop();
            Application application = (Application) getDigester().peek();
            application.addValidator(bean.getValidatorId(), bean.getValidatorClass());
        }

    }

    class ClientBehaviorRendererBean
    {
        private String clientBehaviorRendererType;
        
        private String clientBehaviorRendererClass;
        
        public String getClientBehaviorRendererType()
        {
            return clientBehaviorRendererType;
        }

        public void setClientBehaviorRendererType(String clientBehaviorRendererType)
        {
            this.clientBehaviorRendererType = clientBehaviorRendererType;
        }

        public String getClientBehaviorRendererClass()
        {
            return clientBehaviorRendererClass;
        }

        public void setClientBehaviorRendererClass(String clientBehaviorRendererClass)
        {
            this.clientBehaviorRendererClass = clientBehaviorRendererClass;
        }
    }
    
    class ClientBehaviorRendererRule extends Rule
    {
        public void begin(String namespace, String name, Attributes attributes)
        {
            getDigester().push(new ClientBehaviorRendererBean());
        }

        public void end(String namespace, String name) {
            ClientBehaviorRendererBean bean = (ClientBehaviorRendererBean) getDigester().pop();
            RenderKit kit = (RenderKit) getDigester().peek();
            ClientBehaviorRenderer renderer = null;
            Class clazz = null;
            try {
                clazz = this.getClass().getClassLoader().loadClass(bean.getClientBehaviorRendererClass());
                renderer = (ClientBehaviorRenderer) clazz.newInstance();
            } catch (Exception e) {
                throw new IllegalArgumentException("Exception while trying to instantiate"
                    + " client behavior renderer class '" + bean.getClientBehaviorRendererClass() + "' : "
                    + e.getMessage());
            }
            kit.addClientBehaviorRenderer(bean.getClientBehaviorRendererType(), 
                            renderer);
        }
    }

    /**
     * <p>Data bean that stores information related to a behavior.</p>
     */
    class BehaviorBean
    {

        private String behaviorClass;

        public String getBehaviorClass()
        {
            return this.behaviorClass;
        }

        @SuppressWarnings("unused")
        public void setBehaviorClass(String behaviorClass)
        {
            this.behaviorClass = behaviorClass;
        }

        private String behaviorId;

        public String getBehaviorId()
        {
            return this.behaviorId;
        }

        @SuppressWarnings("unused")
        public void setBehaviorId(String behaviorId)
        {
            this.behaviorId = behaviorId;
        }

    }


    /**
     * <p>Digester <code>Rule</code> for processing behaviors.</p>
     */
    class BehaviorRule extends Rule
    {

        public void begin(String namespace, String name, Attributes attributes)
        {
            getDigester().push(new BehaviorBean());
        }

        public void end(String namespace, String name)
        {
            BehaviorBean bean = (BehaviorBean) getDigester().pop();
            Application application = (Application) getDigester().peek();
            application.addBehavior(bean.getBehaviorId(), bean.getBehaviorClass());
        }

    }
}
