/*
 * Copyright 2004-2005 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.Introspector;
import java.beans.PropertyDescriptor;
import java.io.PrintWriter;
import java.util.Iterator;

import org.apache.catalina.deploy.ResourceBase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tomcat.util.IntrospectionUtils;

/**
 * StoreAppends generate really the xml tag elements
 * 
 * @author Peter Rossbach
 *  
 */
public class StoreAppender {
    private static Log log = LogFactory.getLog(StoreAppender.class);

    /**
     * The set of classes that represent persistable properties.
     */
    private static Class persistables[] = { String.class, Integer.class,
            Integer.TYPE, Boolean.class, Boolean.TYPE, Byte.class, Byte.TYPE,
            Character.class, Character.TYPE, Double.class, Double.TYPE,
            Float.class, Float.TYPE, Long.class, Long.TYPE, Short.class,
            Short.TYPE, };

    /**
     * print the closing tag
     * 
     * @param aWriter
     * @param aDesc
     * @throws Exception
     */
    public void printCloseTag(PrintWriter aWriter, StoreDescription aDesc)
            throws Exception {
        aWriter.print("</");
        aWriter.print(aDesc.getTag());
        aWriter.println(">");
    }

    /**
     * print only the open tag with all attributes
     * 
     * @param aWriter
     * @param indent
     * @param bean
     * @param aDesc
     * @throws Exception
     */
    public void printOpenTag(PrintWriter aWriter, int indent, Object bean,
            StoreDescription aDesc) throws Exception {
        aWriter.print("<");
        aWriter.print(aDesc.getTag());
        if (aDesc.isAttributes() && bean != null)
            printAttributes(aWriter, indent, bean, aDesc);
        aWriter.println(">");
    }

    /**
     * Print tag with all attributes
     * 
     * @param aWriter
     * @param indent
     * @param bean
     * @param aDesc
     * @throws Exception
     */
    public void printTag(PrintWriter aWriter, int indent, Object bean,
            StoreDescription aDesc) throws Exception {
        aWriter.print("<");
        aWriter.print(aDesc.getTag());
        if (aDesc.isAttributes() && bean != null)
            printAttributes(aWriter, indent, bean, aDesc);
        aWriter.println("/>");
    }

    /**
     * print the value from tag as content
     * 
     * @param aWriter
     * @param tag
     * @param content
     * @throws Exception
     */
    public void printTagContent(PrintWriter aWriter, String tag, String content)
            throws Exception {
        aWriter.print("<");
        aWriter.print(tag);
        aWriter.print(">");
        aWriter.print(convertStr(content));
        aWriter.print("</");
        aWriter.print(tag);
        aWriter.println(">");
    }

    /**
     * print an array of values
     * 
     * @param aWriter
     * @param tag
     * @param indent
     * @param elements
     */
    public void printTagValueArray(PrintWriter aWriter, String tag, int indent,
            String[] elements) {
        if (elements != null && elements.length > 0) {
            printIndent(aWriter, indent + 2);
            aWriter.print("<");
            aWriter.print(tag);
            aWriter.print(">");
            for (int i = 0; i < elements.length; i++) {
                printIndent(aWriter, indent + 4);
                aWriter.print(elements[i]);
                if (i + 1 < elements.length)
                    aWriter.println(",");
            }
            printIndent(aWriter, indent + 2);
            aWriter.print("</");
            aWriter.print(tag);
            aWriter.println(">");
        }
    }

    /**
     * print a array of elements
     * 
     * @param aWriter
     * @param tag
     * @param indent
     * @param elements
     */
    public void printTagArray(PrintWriter aWriter, String tag, int indent,
            String[] elements) throws Exception {
        if (elements != null) {
            for (int i = 0; i < elements.length; i++) {
                printIndent(aWriter, indent);
                printTagContent(aWriter, tag, elements[i]);
            }
        }
    }

    /**
     * Print some spaces
     * 
     * @param aWriter
     * @param indent
     *            number of spaces
     */
    public void printIndent(PrintWriter aWriter, int indent) {
        for (int i = 0; i < indent; i++) {
            aWriter.print(' ');
        }
    }

    /**
     * Store the relevant attributes of the specified JavaBean, plus a
     * <code>className</code> attribute defining the fully qualified Java
     * class name of the bean.
     * 
     * @param writer
     *            PrintWriter to which we are storing
     * @param bean
     *            Bean whose properties are to be rendered as attributes,
     * 
     * @exception Exception
     *                if an exception occurs while storing
     */
    public void printAttributes(PrintWriter writer, int indent, Object bean,
            StoreDescription desc) throws Exception {

        printAttributes(writer, indent, true, bean, desc);

    }

    /**
     * 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("\"");
        }

        // Acquire the list of properties for this bean
        PropertyDescriptor descriptors[] = Introspector.getBeanInfo(
                bean.getClass()).getPropertyDescriptors();
        if (descriptors == null) {
            descriptors = new PropertyDescriptor[0];
        }

        // Create blank instance
        Object bean2 = defaultInstance(bean);
        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 (desc.isTransientAttribute(descriptors[i].getName())) {
                continue; // Skip the specified exceptions
            }
            Object value = IntrospectionUtils.getProperty(bean, descriptors[i]
                    .getName());
            if (value == null) {
                continue; // Null values are not persisted
            }
            Object value2 = IntrospectionUtils.getProperty(bean2,
                    descriptors[i].getName());
            if (value.equals(value2)) {
                // The property has its default value
                continue;
            }
            if (isPrintValue(bean, bean2, descriptors[i].getName(), desc))
                printValue(writer, indent, descriptors[i].getName(), value);
        }

        if (bean instanceof ResourceBase) {
            ResourceBase resource = (ResourceBase) bean;
            for (Iterator iter = resource.listProperties(); iter.hasNext();) {
                String name = (String) iter.next();
                Object value = resource.getProperty(name);
                if (!isPersistable(value.getClass())) {
                    continue;
                }
                if (desc.isTransientAttribute(name)) {
                    continue; // Skip the specified exceptions
                }
                printValue(writer, indent, name, value);

            }
        }
    }

    /**
     * print this Attribute value or not
     * 
     * @param bean
     *            orginal bean
     * @param bean2
     *            default bean
     * @param attrName
     *            attribute name
     * @param desc
     *            StoreDescription from bean
     * @return True if it's a printing value
     */
    public boolean isPrintValue(Object bean, Object bean2, String attrName,
            StoreDescription desc) {
        boolean printValue = false;

        Object value = IntrospectionUtils.getProperty(bean, attrName);
        if (value != null) {
            Object value2 = IntrospectionUtils.getProperty(bean2, attrName);
            printValue = !value.equals(value2);

        }
        return printValue;
    }

    /**
     * generate default Instance
     * 
     * @param bean
     * @return an object from same class as bean parameter
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    public Object defaultInstance(Object bean) throws InstantiationException,
            IllegalAccessException {
        return bean.getClass().newInstance();
    }

    /**
     * print an attribute value
     * 
     * @param writer
     * @param name
     * @param value
     */
    public void printValue(PrintWriter writer, int indent, String name,
            Object value) {
        if (!(value instanceof String)) {
            value = value.toString();
        }
        writer.println();
        printIndent(writer, indent + 4);
        writer.print(name);
        writer.print("=\"");
        String strValue = convertStr((String) value);
        writer.print(strValue);
        writer.print("\"");
    }

    /**
     * Given a string, this method replaces all occurrences of ' <', '>', '&',
     * and '"'.
     */
    public String convertStr(String input) {

        StringBuffer filtered = new StringBuffer(input.length());
        char c;
        for (int i = 0; i < input.length(); i++) {
            c = input.charAt(i);
            if (c == '<') {
                filtered.append("&lt;");
            } else if (c == '>') {
                filtered.append("&gt;");
            } else if (c == '\'') {
                filtered.append("&apos;");
            } else if (c == '"') {
                filtered.append("&quot;");
            } else if (c == '&') {
                filtered.append("&amp;");
            } else {
                filtered.append(c);
            }
        }
        return (filtered.toString());
    }

    /**
     * Is the specified property type one for which we should generate a
     * persistence attribute?
     * 
     * @param clazz
     *            Java class to be tested
     */
    protected boolean isPersistable(Class clazz) {

        for (int i = 0; i < persistables.length; i++) {
            if (persistables[i] == clazz) {
                return (true);
            }
        }
        return (false);

    }
}
