/**
 * 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.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.catalina.ha.util.IDynamicProperty;
import org.apache.tomcat.util.IntrospectionUtils;

/**
 * Store the IDynamicProperty attributes. 
 * 
 * @author Peter Rossbach
 *  
 */
public class IDynamicPropertyStoreAppender extends StoreAppender {

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

        if (bean instanceof IDynamicProperty) {
            List propertyKeys = getPropertyKeys((IDynamicProperty) bean);
            // Create blank instance
            Object bean2 = defaultInstance(bean);
            for (Iterator propertyIterator = propertyKeys.iterator(); propertyIterator
                    .hasNext();) {
                String key = (String) propertyIterator.next();
                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);
            }
        }
    }

    /**
     * Get all properties from ReplicationTransmitter (also dynamic properties)
     * 
     * @param bean
     * @return List of Connector Properties
     * @throws IntrospectionException
     */
    protected List getPropertyKeys(IDynamicProperty bean)
            throws IntrospectionException {
        ArrayList propertyKeys = new ArrayList();
        // 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
            }
            propertyKeys.add(descriptors[i].getName());
        }
        for (Iterator propertyIterator = bean.getPropertyNames(); propertyIterator
                .hasNext();) {
            Object key = propertyIterator.next();
            if (propertyKeys.contains(key))
                continue;
            if ("className".equals(key))
                continue;
            propertyKeys.add(key);
        }
        return propertyKeys;
    }

}