// -*- C++ -*-
// Module:  Log4CPLUS
// File:    hierarchy.h
// Created: 6/2001
// Author:  Tad E. Smith
//
//
// Copyright 2001-2010 Tad E. Smith
//
// 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.
/** @file */
#ifndef LOG4CPLUS_HIERARCHY_HEADER_
#define LOG4CPLUS_HIERARCHY_HEADER_
#include 
#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
#pragma once
#endif
#include 
#include 
#include 
         */
        virtual void resetConfiguration(); 
        /**
         * Set the default LoggerFactory instance.
         */
        virtual void setLoggerFactory(std::auto_ptr factory);
        
        /**
         * Returns the default LoggerFactory instance.
         */
        virtual spi::LoggerFactory* getLoggerFactory();
        /**
         * Shutting down a hierarchy will safely close and remove
         * all appenders in all loggers including the root logger.
         *                
         * Some appenders such as SocketAppender need to be closed before the
         * application exits. Otherwise, pending logging events might be
         * lost.
         *
         * The shutdown method is careful to close nested
         * appenders before closing regular appenders. This is allows
         * configurations where a regular appender is attached to a logger
         * and again to a nested appender.
         */
        virtual void shutdown();
    private:
      // Types
        typedef std::vector ProvisionNode;
        typedef std::map ProvisionNodeMap;
        typedef std::map LoggerMap;
      // Methods
        /**
         * This is the implementation of the getInstance() method.
         * NOTE: This method does not lock the hashtable_mutex.
         */
        LOG4CPLUS_PRIVATE
        virtual Logger getInstanceImpl(const log4cplus::tstring& name, 
            spi::LoggerFactory& factory);
        
        /**
         * This is the implementation of the getCurrentLoggers().
         * NOTE: This method does not lock the hashtable_mutex.
         */
        LOG4CPLUS_PRIVATE
        virtual void initializeLoggerList(LoggerList& list) const;
        
        /**
         * This method loops through all the *potential* parents of
         * logger'. There 3 possible cases:
         *
         * 1) No entry for the potential parent of 'logger' exists
         *
         *    We create a ProvisionNode for this potential parent and insert
         *    'logger' in that provision node.
         *
         * 2) There is an entry of type Logger for the potential parent.
         *
         *    The entry is 'logger's nearest existing parent. We update logger's
         *    parent field with this entry. We also break from the loop
         *    because updating our parent's parent is our parent's
         *    responsibility.
         *
         * 3) There entry is of type ProvisionNode for this potential parent.
         *
         *    We add 'logger' to the list of children for this potential parent.
         */
        LOG4CPLUS_PRIVATE void updateParents(Logger const & logger);
        /**
         * We update the links for all the children that placed themselves
         * in the provision node 'pn'. The second argument 'logger' is a
         * reference for the newly created Logger, parent of all the
         * children in 'pn'
         *
         * We loop on all the children 'c' in 'pn':
         *
         *    If the child 'c' has been already linked to a child of
         *    'logger' then there is no need to update 'c'.
         *
         *   Otherwise, we set logger's parent field to c's parent and set
         *   c's parent field to logger.
         */
        LOG4CPLUS_PRIVATE void updateChildren(ProvisionNode& pn,
            Logger const & logger);
     // Data
        thread::Mutex hashtable_mutex;
        std::auto_ptr defaultFactory;
        ProvisionNodeMap provisionNodes;
        LoggerMap loggerPtrs;
        Logger root;
        int disableValue;
        bool emittedNoAppenderWarning;
        // Disallow copying of instances of this class
        Hierarchy(const Hierarchy&);
        Hierarchy& operator=(const Hierarchy&);
     // Friends
        friend class log4cplus::spi::LoggerImpl;
        friend class log4cplus::HierarchyLocker;
    };
    LOG4CPLUS_EXPORT Hierarchy & getDefaultHierarchy ();
} // end namespace log4cplus
#endif // LOG4CPLUS_HIERARCHY_HEADER_