/**
 * 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.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.net.InetAddress;
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 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
            }
            // Convert IP addresses to strings so they will be persisted
            if (value instanceof InetAddress) {
                value = ((InetAddress) value).getHostAddress();
            }
            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 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);
    }

}