/*
 * 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.PrintWriter;

import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.Service;
import org.apache.catalina.core.StandardServer;
import org.apache.catalina.deploy.NamingResources;
import org.apache.catalina.mbeans.ServerLifecycleListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Store server.xml Server element and childs (
 * Listener,GlobalNamingResource,Service)
 * 
 * @author Peter Rossbach
 */
public class StandardServerSF extends StoreFactoryBase {

    private static Log log = LogFactory.getLog(StandardServerSF.class);

    /**
     * Store the specified Server properties.
     * 
     * @param aWriter
     *            PrintWriter to which we are storing
     * @param indent
     *            Number of spaces to indent this element
     * @param aServer
     *            Object to be stored
     * 
     * @exception Exception
     *                if an exception occurs while storing
     * @see org.apache.catalina.storeconfig.IStoreFactory#store(java.io.PrintWriter,
     *      int, java.lang.Object)
     */
    public void store(PrintWriter aWriter, int indent, Object aServer)
            throws Exception {
        storeXMLHead(aWriter);
        super.store(aWriter, indent, aServer);
    }

    /**
     * Store Childs from this StandardServer descrition
     * 
     * @param aWriter
     * @param indent
     * @param aObject
     * @param parentDesc
     * @throws Exception
     */
    public void storeChilds(PrintWriter aWriter, int indent, Object aObject,
            StoreDescription parentDesc) throws Exception {
        if (aObject instanceof StandardServer) {
            StandardServer server = (StandardServer) aObject;
            // Store nested <Listener> elements
            if (server instanceof Lifecycle) {
                LifecycleListener listeners[] = ((Lifecycle) server)
                        .findLifecycleListeners();
                storeElementArray(aWriter, indent, listeners);
                LifecycleListener listener = null;
                for (int i = 0; listener == null && i < listeners.length; i++)
                    if (listeners[i] instanceof ServerLifecycleListener)
                        listener = listeners[i];
                if (listener != null) {
                    StoreDescription elementDesc = getRegistry()
                            .findDescription(
                                    StandardServer.class.getName()
                                            + ".[ServerLifecycleListener]");
                    if (elementDesc != null) {
                        elementDesc.getStoreFactory().store(aWriter, indent,
                                listener);
                    }
                }
            }
            // Store nested <GlobalNamingResources> element
            NamingResources globalNamingResources = server
                    .getGlobalNamingResources();
            StoreDescription elementDesc = getRegistry().findDescription(
                    NamingResources.class.getName()
                            + ".[GlobalNamingResources]");
            if (elementDesc != null) {
                elementDesc.getStoreFactory().store(aWriter, indent,
                        globalNamingResources);
            }
            // Store nested <Service> elements
            Service services[] = server.findServices();
            storeElementArray(aWriter, indent, services);
        }
    }

}
