RSC  0.9.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LoggerTreeNode.cpp
Go to the documentation of this file.
1 /* ============================================================
2  *
3  * This file is a part of the RSC project.
4  *
5  * Copyright (C) 2011 by Johannes Wienke <jwienke at techfak dot uni-bielefeld dot de>
6  *
7  * This file may be licensed under the terms of the
8  * GNU Lesser General Public License Version 3 (the ``LGPL''),
9  * or (at your option) any later version.
10  *
11  * Software distributed under the License is distributed
12  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
13  * express or implied. See the LGPL for the specific language
14  * governing rights and limitations.
15  *
16  * You should have received a copy of the LGPL along with this
17  * program. If not, go to http://www.gnu.org/licenses/lgpl.html
18  * or write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  * The development of this software was supported by:
22  * CoR-Lab, Research Institute for Cognition and Robotics
23  * Bielefeld University
24  *
25  * ============================================================ */
26 
27 #include "LoggerTreeNode.h"
28 
29 #include <boost/format.hpp>
30 #include <boost/algorithm/string.hpp>
31 
33 
34 using namespace std;
35 
36 namespace rsc {
37 namespace logging {
38 
39 LoggerTreeNode::LoggerTreeNode(const string& name, LoggerTreeNodeWeakPtr parent) :
40  name(name), parent(parent) {
41 }
42 
43 LoggerTreeNode::LoggerTreeNode(const string& name, LoggerProxyPtr loggerProxy,
44  LoggerTreeNodeWeakPtr parent) :
45  name(name), loggerProxy(loggerProxy), parent(parent) {
46 }
47 
49  return parent.lock();
50 }
51 
52 string LoggerTreeNode::getName() const {
53  return name;
54 }
55 
57  return loggerProxy;
58 }
59 
61  this->loggerProxy = loggerProxy;
62 }
63 
65  // we rely on the fact that map only inserts if not present
66  return children.insert(make_pair(child->getName(), child)).second;
67 }
68 
70  CreateFunction createFn, const NamePath &processedPath) {
71 
72  if (path.size() == 0) {
73  throw invalid_argument("Empty path given");
74  }
75 
76  const string directChildName = path.front();
77  NamePath subPath = path;
78  subPath.erase(subPath.begin());
79  NamePath childPath = processedPath;
80  childPath.push_back(directChildName);
81 
82  if (!children.count(path.front())) {
83  children[path.front()] = LoggerTreeNodePtr(
84  new LoggerTreeNode(path.front(), shared_from_this()));
85  children[path.front()]->setLoggerProxy(
86  createFn(childPath, children[directChildName]));
87  }
88 
89  if (path.size() > 1) {
90  return children[directChildName]->addChildren(subPath, createFn,
91  childPath);
92  } else {
93  return children[directChildName];
94  }
95 
96 }
97 
99 }
100 
101 void LoggerTreeNode::visit(VisitorPtr visitor, const NamePath& thisPath) {
102 
103  for (map<string, LoggerTreeNodePtr>::const_iterator it = children.begin();
104  it != children.end(); ++it) {
105 
106  NamePath childPath = thisPath;
107  childPath.push_back(it->first);
108 
109  bool descend = visitor->visit(childPath, it->second,
110  loggerProxy->getLogger()->getLevel());
111  if (descend) {
112  it->second->visit(visitor, childPath);
113  }
114 
115  }
116 
117 }
118 
119 bool LoggerTreeNode::hasChild(const string& name) const {
120  return children.count(name) == 1;
121 }
122 
123 bool LoggerTreeNode::hasChild(const NamePath& path) const {
124  if (path.size() == 0) {
125  throw invalid_argument("Empty name path given");
126  }
127  map<string, LoggerTreeNodePtr>::const_iterator childIt = children.find(
128  path.front());
129  if (childIt == children.end()) {
130  return false;
131  }
132  NamePath subPath = path;
133  subPath.erase(subPath.begin());
134  return childIt->second->hasChild(subPath);
135 }
136 
138  map<string, LoggerTreeNodePtr>::const_iterator it = children.find(name);
139  if (it == children.end()) {
140  throw invalid_argument(
141  boost::str(
142  boost::format("No direct child with name %1 exists.")
143  % name));
144  }
145  return it->second;
146 }
147 
149  if (path.size() == 0) {
150  throw invalid_argument("Empty name path given");
151  }
152  map<string, LoggerTreeNodePtr>::const_iterator childIt = children.find(
153  path.front());
154  if (childIt == children.end()) {
155  throw invalid_argument(
156  boost::str(
157  boost::format("No direct child with name %1 exists.")
158  % name));
159  }
160  NamePath subPath = path;
161  subPath.erase(subPath.begin());
162  return childIt->second->getChild(subPath);
163 }
164 
166  children.clear();
167 }
168 
170  if (name.empty()) {
171  return NamePath();
172  }
173 
174  // TODO add checks which can be detected easiest in the string representation
175 
176  NamePath path;
177  string lowerName = name;
178  boost::algorithm::to_lower(lowerName);
179  boost::algorithm::split(path, lowerName, boost::algorithm::is_any_of("."));
180 
181  // Some consistency checks
182  assert(path.size() > 0);
183 
184  // avoid reserved keywords at the end
185  // TODO how to avoid string duplication with OptionBasedConfigurator?
186  // The configurator would be the place to store the two string constants in
187  // but I do not want to have a dependency from this class to the
188  // configurator.
189  if (path.back() == "level" || path.back() == "system") {
190  throw invalid_argument(
191  "Logger names must not end with system or level (case-insensitive), but I received: '"
192  + name + "'");
193  }
194 
195  return path;
196 }
197 
199  stringstream s;
200  for (NamePath::const_iterator it = path.begin(); it != path.end(); ++it) {
201  s << *it;
202  if (it != --path.end()) {
203  s << ".";
204  }
205  }
206  return s.str();
207 }
208 
209 boost::shared_ptr<Logger::Level> LoggerTreeNode::getAssignedLevel() const {
210  return assignedLevel;
211 }
212 
213 void LoggerTreeNode::setAssignedLevel(boost::shared_ptr<Logger::Level> level) {
214  this->assignedLevel = level;
215 }
216 
218  assignedLevel.reset(new Logger::Level(level));
219 }
220 
222  return assignedLevel;
223 }
224 
225 }
226 }