/**
 * Copyright 1999-2001,2004 The Apache Software Foundation.
 * 
 * Licensed 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.catalina.storeconfig;

import java.beans.IndexedPropertyDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.apache.catalina.connector.Connector;
import org.apache.coyote.ProtocolHandler;
import org.apache.tomcat.util.IntrospectionUtils;

/**
 * Store the Connector attributes. Connector has really special design. A
 * Connector is only a startup Wrapper for a ProtocolHandler. This meant that
 * ProtocolHandler get all there attribtues from the Connector attribtue map.
 * Strange is that some attributes change there name and the attribute
 * sslProtocol need a sepzial handling
 * 
 * @author Peter Rossbach
 *  
 */
public class ConnectorStoreAppender extends StoreAppender {

    protected static HashMap replacements = new HashMap();
    static {
        replacements.put("backlog", "acceptCount");
        replacements.put("soLinger", "connectionLinger");
        replacements.put("soTimeout", "connectionTimeout");
        replacements.put("timeout", "connectionUploadTimeout");
        replacements.put("clientauth", "clientAuth");
        replacements.put("keystore", "keystoreFile");
        replacements.put("randomfile", "randomFile");
        replacements.put("rootfile", "rootFile");
        replacements.put("keypass", "keystorePass");
        replacements.put("keytype", "keystoreType");
        replacements.put("protocol", "sslProtocol");
        replacements.put("protocols", "sslProtocols");
    }

    /**
     * Store the relevant attributes of the specified JavaBean.
     * 
     * @param writer
     *            PrintWriter to which we are storing
     * @param include
     *            Should we include a <code>className</code> attribute?
     * @param bean
     *            Bean whose properties are to be rendered as attributes,
     * @param desc
     *            RegistryDescrpitor from this bean
     * 
     * @exception Exception
     *                if an exception occurs while storing
     */
    public void printAttributes(PrintWriter writer, int indent,
            boolean include, Object bean, StoreDescription desc)
            throws Exception {

        // Render the relevant properties of this bean
        String className = bean.getClass().getName();

        // Render a className attribute if requested
        if (include && desc != null && !desc.isStandard()) {
            writer.print(" className=\"");
            writer.print(bean.getClass().getName());
            writer.print("\"");
        }

        List propertyKeys = getPropertyKeys((Connector) bean);
        // Create blank instance
        Object bean2 = defaultInstance(bean);
        for (Iterator propertyIterator = propertyKeys.iterator(); propertyIterator
                .hasNext();) {
            String key = (String) propertyIterator.next();
            if (replacements.get(key) != null) {
                key = (String) replacements.get(key);
            }
            Object value = (Object) IntrospectionUtils.getProperty(bean, key);

            if (desc.isTransientAttribute(key)) {
                continue; // Skip the specified exceptions
            }
            if (value == null) {
                continue; // Null values are not persisted
            }
            if (!isPersistable(value.getClass())) {
                continue;
            }
            Object value2 = IntrospectionUtils.getProperty(bean2, key);
            if (value.equals(value2)) {
                // The property has its default value
                continue;
            }
            if (isPrintValue(bean, bean2, key, desc))
                printValue(writer, indent, key, value);
        }
        String protocol = ((Connector) bean).getProtocol();
        if (protocol != null && !"HTTP/1.1".equals(protocol))
            super.printValue(writer, indent, "protocol", protocol);

    }

    /**
     * Get all properties from Connector and current ProtocolHandler
     * 
     * @param bean
     * @return List of Connector Properties
     * @throws IntrospectionException
     */
    protected List getPropertyKeys(Connector bean)
            throws IntrospectionException {
        ArrayList propertyKeys = new ArrayList();
        // Acquire the list of properties for this bean
        ProtocolHandler protocolHandler = bean.getProtocolHandler();
        // Acquire the list of properties for this bean
        PropertyDescriptor descriptors[] = Introspector.getBeanInfo(
                bean.getClass()).getPropertyDescriptors();
        if (descriptors == null) {
            descriptors = new PropertyDescriptor[0];
        }
        for (int i = 0; i < descriptors.length; i++) {
            if (descriptors[i] instanceof IndexedPropertyDescriptor) {
                continue; // Indexed properties are not persisted
            }
            if (!isPersistable(descriptors[i].getPropertyType())
                    || (descriptors[i].getReadMethod() == null)
                    || (descriptors[i].getWriteMethod() == null)) {
                continue; // Must be a read-write primitive or String
            }
            if ("protocol".equals(descriptors[i].getName())
                    || "protocolHandlerClassName".equals(descriptors[i]
                            .getName()))
                continue;
            propertyKeys.add(descriptors[i].getName());
        }
        for (Iterator propertyIterator = protocolHandler.getAttributeNames(); propertyIterator
                .hasNext();) {
            Object key = propertyIterator.next();
            if (propertyKeys.contains(key))
                continue;
            propertyKeys.add(key);
        }
        return propertyKeys;
    }

    /**
     * print Attributes
     * 
     * @param aWriter
     * @param indent
     * @param bean
     * @param aDesc
     * @throws Exception
     */
    protected void storeConnectorAttribtues(PrintWriter aWriter, int indent,
            Object bean, StoreDescription aDesc) throws Exception {
        if (aDesc.isAttributes()) {
            printAttributes(aWriter, indent, false, bean, aDesc);
        }
    }

    /*
     * Print the open tag for connector attributes (override)
     * 
     * @see org.apache.catalina.storeconfig.StoreAppender#printOpenTag(java.io.PrintWriter,
     *      int, java.lang.Object,
     *      org.apache.catalina.storeconfig.StoreDescription)
     */
    public void printOpenTag(PrintWriter aWriter, int indent, Object bean,
            StoreDescription aDesc) throws Exception {
        aWriter.print("<");
        aWriter.print(aDesc.getTag());
        storeConnectorAttribtues(aWriter, indent, bean, aDesc);
        aWriter.println(">");
    }

    /**
     * print a tag for connector attributes (override)
     * 
     * @see org.apache.catalina.storeconfig.StoreAppender#printTag(java.io.PrintWriter,
     *      int, java.lang.Object,
     *      org.apache.catalina.storeconfig.StoreDescription)
     */
    public void printTag(PrintWriter aWriter, int indent, Object bean,
            StoreDescription aDesc) throws Exception {
        aWriter.print("<");
        aWriter.print(aDesc.getTag());
        storeConnectorAttribtues(aWriter, indent, bean, aDesc);
        aWriter.println("/>");
    }

    /**
     * print a value but replace attribute name
     * 
     * @param writer
     * @param name
     * @param value
     * @see org.apache.catalina.storeconfig.StoreAppender#printValue(java.io.PrintWriter,
     *      int, java.lang.String, java.lang.Object)
     */
    public void printValue(PrintWriter writer, int indent, String name,
            Object value) {
        String repl = name;
        if (replacements.get(name) != null) {
            repl = (String) replacements.get(name);
        }
        super.printValue(writer, indent, repl, value);
    }
    
    /*
     * Print Connector Values. <ul><li> Spezial handling to default jkHome.
     * </li><li> Don't save catalina.base path at server.xml</li><li></ul>
     * 
     * @see org.apache.catalina.config.StoreAppender#isPrintValue(java.lang.Object,
     *      java.lang.Object, java.lang.String,
     *      org.apache.catalina.config.StoreDescription)
     */
    public boolean isPrintValue(Object bean, Object bean2, String attrName,
            StoreDescription desc) {
        boolean isPrint = super.isPrintValue(bean, bean2, attrName, desc);
        if (isPrint) {
            if ("jkHome".equals(attrName)) {
                Connector connector = ((Connector) bean);
                File catalinaBase = getCatalinaBase();
                File jkHomeBase = getJkHomeBase((String) connector
                        .getProperty("jkHome"), catalinaBase);
                isPrint = !catalinaBase.equals(jkHomeBase);

            }
        }
        return isPrint;
    }

    protected File getCatalinaBase() {

        File appBase;
        File file = new File(System.getProperty("catalina.base"));
        try {
            file = file.getCanonicalFile();
        } catch (IOException e) {
        }
        return (file);
    }

    protected File getJkHomeBase(String jkHome, File appBase) {

        File jkHomeBase;
        File file = new File(jkHome);
        if (!file.isAbsolute())
            file = new File(appBase, jkHome);
        try {
            jkHomeBase = file.getCanonicalFile();
        } catch (IOException e) {
            jkHomeBase = file;
        }
        return (jkHomeBase);
    }

}