// Find a node in our tree of logger nodes. // If necessary, create it. private LogNode findNode(String name) { if (name == null || name.equals("")) { return root; } LogNode node = root; while (name.length() > 0) { int ix = name.indexOf("."); String head; if (ix > 0) { head = name.substring(0,ix); name = name.substring(ix+1); } else { head = name; name = ""; } if (node.children == null) { node.children = new HashMap(); } LogNode child = (LogNode)node.children.get(head); if (child == null) { child = new LogNode(node); node.children.put(head, child); } node = child; } return node; }
/** * Add a named logger. This does nothing and returns false if a logger * with the same name is already registered. * <p> * The Logger factory methods call this method to register each * newly created Logger. * <p> * The application should retain its own reference to the Logger * object to avoid it being garbage collected. The LogManager * may only retain a weak reference. * * @param logger the new logger. * @return true if the argument logger was registered successfully, * false if a logger of that name already exists. * @exception NullPointerException if the logger name is null. */ public synchronized boolean addLogger(Logger logger) { String name = logger.getName(); if (name == null) { throw new NullPointerException(); } Logger old = (Logger) loggers.get(name); if (old != null) { // We already have a registered logger with the given name. return false; } // We're adding a new logger. // Note that we are creating a strong reference here that will // keep the Logger in existence indefinitely. loggers.put(name, logger); // Apply any initial level defined for the new logger. Level level = getLevelProperty(name+".level", null); if (level != null) { doSetLevel(logger, level); } // If any of the logger's parents have levels defined, // make sure they are instantiated. int ix = 1; for (;;) { int ix2 = name.indexOf(".", ix); if (ix2 < 0) { break; } String pname = name.substring(0,ix2); if (getProperty(pname+".level") != null) { // This pname has a level definition. Make sure it exists. Logger plogger = Logger.getLogger(pname); } ix = ix2+1; } // Find the new node and its parent. LogNode node = findNode(name); node.logger = logger; Logger parent = null; LogNode nodep = node.parent; while (nodep != null) { if (nodep.logger != null) { parent = nodep.logger; break; } nodep = nodep.parent; } if (parent != null) { doSetParent(logger, parent); } // Walk over the children and tell them we are their new parent. node.walkAndSetParent(logger); return true; }
// Recursive method to walk the tree below a node and set // a new parent logger. void walkAndSetParent(Logger parent) { if (children == null) { return; } Iterator values = children.values().iterator(); while (values.hasNext()) { LogNode node = (LogNode) values.next(); if (node.logger == null) { node.walkAndSetParent(parent); } else { doSetParent(node.logger, parent); } } }
// Recursive method to walk the tree below a node and set // a new parent logger. void walkAndSetParent(Logger parent) { if (children == null) { return; } Iterator<LogNode> values = children.values().iterator(); while (values.hasNext()) { LogNode node = values.next(); LoggerWeakRef ref = node.loggerRef; Logger logger = (ref == null) ? null : ref.get(); if (logger == null) { node.walkAndSetParent(parent); } else { doSetParent(logger, parent); } } }
// dispose of this LoggerWeakRef object void dispose() { if (node != null) { // if we have a LogNode, then we were a named Logger // so clear namedLoggers weak ref to us manager.namedLoggers.remove(name); name = null; // clear our ref to the Logger's name node.loggerRef = null; // clear LogNode's weak ref to us node = null; // clear our ref to LogNode } if (parentRef != null) { // this LoggerWeakRef has or had a parent Logger Logger parent = parentRef.get(); if (parent != null) { // the parent Logger is still there so clear the // parent Logger's weak ref to us parent.removeChildLogger(this); } parentRef = null; // clear our weak ref to the parent Logger } }
/** * Add a named logger. This does nothing and returns false if a logger with the same name is * already registered. * * <p>The Logger factory methods call this method to register each newly created Logger. * * <p>The application should retain its own reference to the Logger object to avoid it being * garbage collected. The LogManager may only retain a weak reference. * * @param logger the new logger. * @return true if the argument logger was registered successfully, false if a logger of that name * already exists. * @exception NullPointerException if the logger name is null. */ public synchronized boolean addLogger(Logger logger) { final String name = logger.getName(); if (name == null) { throw new NullPointerException(); } // cleanup some Loggers that have been GC'ed drainLoggerRefQueueBounded(); LoggerWeakRef ref = namedLoggers.get(name); if (ref != null) { if (ref.get() == null) { // It's possible that the Logger was GC'ed after the // drainLoggerRefQueueBounded() call above so allow // a new one to be registered. namedLoggers.remove(name); } else { // We already have a registered logger with the given name. return false; } } // We're adding a new logger. // Note that we are creating a weak reference here. ref = new LoggerWeakRef(logger); namedLoggers.put(name, ref); // Apply any initial level defined for the new logger. Level level = getLevelProperty(name + ".level", null); if (level != null) { doSetLevel(logger, level); } // Do we have a per logger handler too? // Note: this will add a 200ms penalty loadLoggerHandlers(logger, name, name + ".handlers"); processParentHandlers(logger, name); // Find the new node and its parent. LogNode node = findNode(name); node.loggerRef = ref; Logger parent = null; LogNode nodep = node.parent; while (nodep != null) { LoggerWeakRef nodeRef = nodep.loggerRef; if (nodeRef != null) { parent = nodeRef.get(); if (parent != null) { break; } } nodep = nodep.parent; } if (parent != null) { doSetParent(logger, parent); } // Walk over the children and tell them we are their new parent. node.walkAndSetParent(logger); // new LogNode is ready so tell the LoggerWeakRef about it ref.setNode(node); return true; }