$search
00001 /* 00002 * HierarchyMaintainer.cpp 00003 * 00004 * Copyright 2000, LifeLine Networks BV (www.lifeline.nl). All rights reserved. 00005 * Copyright 2000, Bastiaan Bakker. All rights reserved. 00006 * 00007 * See the COPYING file for the terms of usage and distribution. 00008 */ 00009 00010 #include "PortabilityImpl.hh" 00011 00012 #ifdef LOG4CPP_HAVE_IO_H 00013 # include <io.h> 00014 #endif 00015 #ifdef LOG4CPP_HAVE_UNISTD_H 00016 # include <unistd.h> 00017 #endif 00018 00019 #include <cstdio> 00020 #include <cassert> 00021 #include <log4cpp/HierarchyMaintainer.hh> 00022 #include <log4cpp/FileAppender.hh> 00023 00024 namespace log4cpp { 00025 00026 HierarchyMaintainer::creator_function_t HierarchyMaintainer::_creator_function = 0; 00027 00028 HierarchyMaintainer& HierarchyMaintainer::getDefaultMaintainer() { 00029 static HierarchyMaintainer defaultMaintainer; 00030 00031 return defaultMaintainer; 00032 } 00033 00034 HierarchyMaintainer::HierarchyMaintainer() { 00035 } 00036 00037 HierarchyMaintainer::~HierarchyMaintainer() { 00038 shutdown(); 00039 deleteAllCategories(); 00040 } 00041 00042 Category* HierarchyMaintainer::getExistingInstance(const std::string& name) { 00043 threading::ScopedLock lock(_categoryMutex); 00044 return _getExistingInstance(name); 00045 } 00046 00047 Category* HierarchyMaintainer::_getExistingInstance(const std::string& name) { 00048 Category* result = NULL; 00049 00050 CategoryMap::iterator i = _categoryMap.find(name); 00051 if (_categoryMap.end() != i) { 00052 result = (*i).second; 00053 } 00054 00055 return result; 00056 } 00057 00058 Category& HierarchyMaintainer::getInstance(const std::string& name) { 00059 threading::ScopedLock lock(_categoryMutex); 00060 return _getInstance(name); 00061 } 00062 00063 /* assume lock is held */ 00064 Category& HierarchyMaintainer::_getInstance(const std::string& name) { 00065 Category* result; 00066 result = _getExistingInstance(name); 00067 00068 if (NULL == result) { 00069 if (name == "") { 00070 result = make_category(name, NULL, Priority::INFO); 00071 } else { 00072 std::string parentName; 00073 size_t dotIndex = name.find_last_of('.'); 00074 if (name.length() <= dotIndex) { 00075 parentName = ""; 00076 } else { 00077 parentName = name.substr(0, dotIndex); 00078 } 00079 Category& parent = _getInstance(parentName); 00080 result = make_category(name, &parent, Priority::NOTSET); 00081 } 00082 _categoryMap[name] = result; 00083 } 00084 return *result; 00085 } 00086 00087 std::vector<Category*>* HierarchyMaintainer::getCurrentCategories() const { 00088 std::vector<Category*>* categories = new std::vector<Category*>; 00089 00090 threading::ScopedLock lock(_categoryMutex); 00091 { 00092 for(CategoryMap::const_iterator i = _categoryMap.begin(); i != _categoryMap.end(); i++) { 00093 categories->push_back((*i).second); 00094 } 00095 } 00096 00097 return categories; 00098 } 00099 00100 void HierarchyMaintainer::shutdown() { 00101 threading::ScopedLock lock(_categoryMutex); 00102 { 00103 for(CategoryMap::const_iterator i = _categoryMap.begin(); i != _categoryMap.end(); i++) { 00104 ((*i).second)->removeAllAppenders(); 00105 } 00106 } 00107 00108 try 00109 { 00110 for(handlers_t::const_iterator i = handlers_.begin(), last = handlers_.end(); i != last; ++i) 00111 (**i)(); 00112 } 00113 catch(...) 00114 { 00115 } 00116 00117 } 00118 00119 void HierarchyMaintainer::register_shutdown_handler(shutdown_fun_ptr handler) 00120 { 00121 handlers_.push_back(handler); 00122 } 00123 00124 void HierarchyMaintainer::deleteAllCategories() { 00125 threading::ScopedLock lock(_categoryMutex); 00126 { 00127 for(CategoryMap::const_iterator i = _categoryMap.begin(); i != _categoryMap.end(); i++) { 00128 delete ((*i).second); 00129 } 00130 _categoryMap.erase(_categoryMap.begin(), _categoryMap.end()); 00131 } 00132 } 00133 00134 void HierarchyMaintainer::set_category_factory(creator_function_t creator_function) 00135 { 00136 assert(0 != creator_function); 00137 _creator_function = creator_function; 00138 } 00139 00140 Category* HierarchyMaintainer::make_category(const std::string& name, 00141 Category* parent, 00142 Priority::Value priority) 00143 { 00144 if (_creator_function) 00145 { 00146 return (*_creator_function)(name, parent, priority); 00147 } 00148 else 00149 { 00150 return new Category(name, parent, priority); 00151 } 00152 } 00153 }