/*
 * 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.io.IOException;
import java.io.PrintWriter;

import org.apache.catalina.util.StringManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * StoreFactory saves spezial elements.
 * Output was generate with StoreAppenders.
 * 
 * @author Peter Rossbach
 * @version 1.0
 *  
 */
public class StoreFactoryBase implements IStoreFactory {
    private static Log log = LogFactory.getLog(StoreFactoryBase.class);

    private StoreRegistry registry;

    private StoreAppender storeAppender = new StoreAppender();

    /**
     * The string manager for this package.
     */
    protected static final StringManager sm = StringManager
            .getManager(Constants.Package);

    /**
     * The descriptive information string for this implementation.
     */
    private static final String info = "org.apache.catalina.config.StoreFactoryBase/1.0";

    /**
     * Return descriptive information about this Facotry implementation and the
     * corresponding version number, in the format
     * <code>&lt;description&gt;/&lt;version&gt;</code>.
     */
    public String getInfo() {

        return (info);

    }

    /**
     * @return Returns the storeAppender.
     */
    public StoreAppender getStoreAppender() {
        return storeAppender;
    }

    /**
     * @param storeAppender
     *            The storeAppender to set.
     */
    public void setStoreAppender(StoreAppender storeAppender) {
        this.storeAppender = storeAppender;
    }

    /*
     * set Registry
     * 
     * @see org.apache.catalina.config.IStoreFactory#setRegistry(org.apache.catalina.config.ConfigurationRegistry)
     */
    public void setRegistry(StoreRegistry aRegistry) {
        registry = aRegistry;

    }

    /*
     * get Registry
     * 
     * @see org.apache.catalina.config.IStoreFactory#getRegistry()
     */
    public StoreRegistry getRegistry() {

        return registry;
    }

    public void storeXMLHead(PrintWriter aWriter) {
        // Store the beginning of this element
        aWriter.print("<?xml version=\"1.0\" encoding=\"");
        aWriter.print(getRegistry().getEncoding());
        aWriter.println("\"?>");
    }

    /*
     * Store a server.xml element with attributes and childs
     * 
     * @see org.apache.catalina.storeconfig.IStoreFactory#store(java.io.PrintWriter,
     *      int, java.lang.Object)
     */
    public void store(PrintWriter aWriter, int indent, Object aElement)
            throws Exception {

        StoreDescription elementDesc = getRegistry().findDescription(
                aElement.getClass());

        if (elementDesc != null) {
            if (log.isDebugEnabled())
                log.debug(sm.getString("factory.storeTag",
                        elementDesc.getTag(), aElement));
            getStoreAppender().printIndent(aWriter, indent + 2);
            if (!elementDesc.isChilds()) {
                getStoreAppender().printTag(aWriter, indent, aElement,
                        elementDesc);
            } else {
                getStoreAppender().printOpenTag(aWriter, indent + 2, aElement,
                        elementDesc);
                storeChilds(aWriter, indent + 2, aElement, elementDesc);
                getStoreAppender().printIndent(aWriter, indent + 2);
                getStoreAppender().printCloseTag(aWriter, elementDesc);
            }
        } else
            log.warn(sm.getString("factory.storeNoDescriptor", aElement
                    .getClass()));
    }

    /**
     * Must Implement at subclass for sepzial store childs handling
     * 
     * @param aWriter
     * @param indent
     * @param aElement
     * @param elementDesc
     */
    public void storeChilds(PrintWriter aWriter, int indent, Object aElement,
            StoreDescription elementDesc) throws Exception {
    }

    /**
     * Store only elements from storeChilds methods that are not a transient
     * child.
     * 
     * @param aWriter current output writer
     * @param indent indentation level
     * @param aTagElement current tomcat element
     * @throws Exception
     */
    protected void storeElement(PrintWriter aWriter, int indent,
            Object aTagElement) throws Exception {
        if (aTagElement != null) {
            IStoreFactory elementFactory = getRegistry().findStoreFactory(
                    aTagElement.getClass());

            if (elementFactory != null) {
                StoreDescription desc = getRegistry().findDescription(
                        aTagElement.getClass());
                if (!desc.isTransientChild(aTagElement.getClass().getName()))
                    elementFactory.store(aWriter, indent, aTagElement);
            } else {
                log.warn(sm.getString("factory.storeNoDescriptor", aTagElement
                        .getClass()));
            }
        }
    }

    /*
     * Save a array of elements
     * @param aWriter current output writer
     * @param indent indentation level
     * @param elements list of child elments to store!
     */
    protected void storeElementArray(PrintWriter aWriter, int indent,
            Object[] elements) throws Exception {
        if (elements != null) {
            for (int i = 0; i < elements.length; i++) {
                try {
                    storeElement(aWriter, indent, elements[i]);
                } catch (IOException ioe) {
                    // ingore childs report error them self!
                    // see StandartContext.storeWithBackup()
                }
            }
        }
    }
}