Description:
|
ch.qos.logback.classic.LoggerContext.getLogger() is hard to understand; it can be shortend with a little recursion. Just a suggestion. I will have to run this modified code to see whether it works, I haven't done so yet.
Additionally, a few edge cases should be checked, right?
== Original ==
-------------------
public final Logger getLogger(final String name) {
if (name == null) {
throw new IllegalArgumentException("name argument cannot be null");
}
// if we are asking for the root logger, then let us return it without
// wasting time
if (Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(name)) {
return root;
}
int i = 0;
Logger logger = root;
// check if the desired logger exists, if it does, return it
// without further ado.
Logger childLogger = (Logger) loggerCache.get(name);
// if we have the child, then let us return it without wasting time
if (childLogger != null) {
return childLogger;
}
// if the desired logger does not exist, them create all the loggers
// in between as well (if they don't already exist)
String childName;
while (true) {
int h = LoggerNameUtil.getSeparatorIndexOf(name, i);
if (h == -1) {
childName = name;
} else {
childName = name.substring(0, h);
}
// move i left of the last point
i = h + 1;
synchronized (logger) {
childLogger = logger.getChildByName(childName);
if (childLogger == null) {
childLogger = logger.createChildByName(childName);
loggerCache.put(childName, childLogger);
incSize();
}
}
logger = childLogger;
if (h == -1) {
return childLogger;
}
}
}
-------------------
== With recursion ==
public final Logger getLogger(final String name) {
if (name == null) {
throw new IllegalArgumentException("name argument cannot be null");
// can it be empty though??
}
// if we are asking for the root logger, then let us return it without wasting time
// note that this is not the empty name but "ROOT"
if (Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(name)) {
return root;
}
// check if the desired logger exists, if it does, return it without further ado.
{
Logger childLogger = (Logger) loggerCache.get(name);
if (loggerCache.get(name) != null) {
return childLogger;
}
}
// if the desired logger does not exist, then create all the loggers in between as well (if they don't exist yet)
// this means
// 1) splitting the "name" along the DOT/DOLLAR separators (but refusing the empty string result)
// 2) creating all the loggers along that path if they don't exist yet
createLoggerPathRecursively(name, "", 0, root);
}
/**
* Recursively build logger path
* On the first call, "originalName" is the full logger name, "currentName" is the empty string,
* currentPos (the position beyond which to search for logger name components) is 0 and
* "parentLogger" is the "root"
*/
private void createLoggerPathRecursively(String originalName, String currentName, int currentPos, Logger parentLogger) {
assert originalName != null;
assert currentName != null;
assert currentPos >= 0;
assert parentLogger != null;
if (currentPos >= originalName.length()) {
throw new IllegalArgumentException("The logger name '" + originalName + "' is either empty or ends with a separator");
}
// find the next separator in "originalName" starting from "currentPos"
int ix = getSeparatorIndexOf(originalName, currentPos);
if (ix < 0) {
// No more separators, so we are done but still need to register this last logger.
// So let ix point past the end!
ix = originalName.length();
}
String nameComponent = originalName.substring(currentPos, ix);
// Depending on specification use one of the two below:
String childName = currentName + CoreConstants.DOT + nameComponent; // DOTify any DOLLAR
// String childName = originalName.substring(0, ix); // unmodified part of original
// Accept empty components? Nope!
if (nameComponent.isEmpty()) {
throw new IllegalArgumentException("The logger name '" + originalName + "' has an empty component starting at position " + currentPos);
}
// See whether the child logger exists, if not, create it
Logger childLogger;
synchronized (parentLogger) {
childLogger = parentLogger.getChildByName(childName); // does not check the childName; returns null if not found
if (childLogger == null) {
// Depending on taste use this (which dotifies any dollars)
// childLogger = parentLogger.createChildByLastNamePart(nameComponent); // checks that name component has no DOT or DOLLAR
// or this (which keeps the DOT or DOLLAR as is); this is in the original (this means that the root must have the empty name)
childLogger = parentLogger.createChildByName(childName); // checks that name component beyond parent's name has no DOT or DOLLAR
loggerCache.put(childName, childLogger);
incSize();
}
assert childLogger != null;
}
// (tail)-recursive call if not done
if (ix < originalName.length()) {
createLoggerPathRecursively(originalName, childName, ix + 1, childLogger);
}
}
|