<style>
/* Changing the layout to use less space for mobiles */
@media screen and (max-device-width: 480px), screen and (-webkit-min-device-pixel-ratio: 2) {
#email-body { min-width: 30em !important; }
#email-page { padding: 8px !important; }
#email-banner { padding: 8px 8px 0 8px !important; }
#email-avatar { margin: 1px 8px 8px 0 !important; padding: 0 !important; }
#email-fields { padding: 0 8px 8px 8px !important; }
#email-gutter { width: 0 !important; }
}
</style>
<div id="email-body">
<table id="email-wrap" align="center" border="0" cellpadding="0" cellspacing="0" style="background-color:#f0f0f0;color:#000000;width:100%;">
<tr valign="top">
<td id="email-page" style="padding:16px !important;">
<table align="center" border="0" cellpadding="0" cellspacing="0" style="background-color:#ffffff;border:1px solid #bbbbbb;color:#000000;width:100%;">
<tr valign="top">
<td bgcolor="#003366" style="background-color:#003366;color:#ffffff;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;line-height:1;"><img src="http://jira.qos.ch/s/en_USet69y6/731/19/_/jira-logo-scaled.png" alt="" style="vertical-align:top;" /></td>
</tr><tr valign="top">
<td id="email-banner" style="padding:32px 32px 0 32px;">
<table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" style="width:100%;">
<tr valign="top">
<td style="color:#505050;font-family:Arial,FreeSans,Helvetica,sans-serif;padding:0;">
<img id="email-avatar" src="http://jira.qos.ch/secure/useravatar?avatarId=10122" alt="" height="48" width="48" border="0" align="left" style="padding:0;margin: 0 16px 16px 0;" />
<div id="email-action" style="padding: 0 0 8px 0;font-size:12px;line-height:18px;">
<a class="user-hover" rel="dtonhofer" id="email_dtonhofer" href="http://jira.qos.ch/secure/ViewProfile.jspa?name=dtonhofer" style="color:#326ca6;">David Tonhofer</a>
created <img src="http://jira.qos.ch/images/icons/improvement.gif" height="16" width="16" border="0" align="absmiddle" alt="Improvement"> <a style='color:#326ca6;text-decoration:none;' href='http://jira.qos.ch/browse/LOGBACK-781'>LOGBACK-781</a>
</div>
<div id="email-summary" style="font-size:16px;line-height:20px;padding:2px 0 16px 0;">
<a style='color:#326ca6;text-decoration:none;' href='http://jira.qos.ch/browse/LOGBACK-781'><strong>ch.qos.logback.classic.LoggerContext.getLogger() is hard to understand; can be shortend with a little recursion</strong></a>
</div>
</td>
</tr>
</table>
</td>
</tr>
<tr valign="top">
<td id="email-fields" style="padding:0 32px 32px 32px;">
<table border="0" cellpadding="0" cellspacing="0" style="padding:0;text-align:left;width:100%;" width="100%">
<tr valign="top">
<td id="email-gutter" style="width:64px;white-space:nowrap;"></td>
<td>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr valign="top">
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 10px 10px 0;white-space:nowrap;">
<strong style="font-weight:normal;color:#505050;">Issue Type:</strong>
</td>
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 0 10px 0;width:100%;">
<img src="http://jira.qos.ch/images/icons/improvement.gif" height="16" width="16" border="0" align="absmiddle" alt="Improvement"> Improvement
</td>
</tr> <tr valign="top">
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 10px 10px 0;white-space:nowrap;">
<strong style="font-weight:normal;color:#505050;">Affects Versions:</strong>
</td>
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 0 10px 0;width:100%;">
1.0.9 </td>
</tr>
<tr valign="top">
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 10px 10px 0;white-space:nowrap;">
<strong style="font-weight:normal;color:#505050;">Assignee:</strong>
</td>
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 0 10px 0;width:100%;">
<a class="user-hover" rel="logback-dev@qos.ch" id="email_logback-dev@qos.ch" href="http://jira.qos.ch/secure/ViewProfile.jspa?name=logback-dev%40qos.ch" style="color:#326ca6;">Logback dev list</a>
</td>
</tr> <tr valign="top">
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 10px 10px 0;white-space:nowrap;">
<strong style="font-weight:normal;color:#505050;">Created:</strong>
</td>
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 0 10px 0;width:100%;">
20/Dec/12 7:39 PM
</td>
</tr> <tr valign="top">
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 10px 10px 0;white-space:nowrap;">
<strong style="font-weight:normal;color:#505050;">Description:</strong>
</td>
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 0 10px 0;width:100%;">
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.
<br/>
<br/>
Additionally, a few edge cases should be checked, right?
<br/>
<br/>
== Original ==
<br/>
<br/>
-------------------
<br/>
public final Logger getLogger(final String name) {
<br/>
<br/>
if (name == null) {
<br/>
throw new IllegalArgumentException("name argument cannot be null");
<br/>
}
<br/>
<br/>
// if we are asking for the root logger, then let us return it without
<br/>
// wasting time
<br/>
if (Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(name)) {
<br/>
return root;
<br/>
}
<br/>
<br/>
int i = 0;
<br/>
Logger logger = root;
<br/>
<br/>
// check if the desired logger exists, if it does, return it
<br/>
// without further ado.
<br/>
Logger childLogger = (Logger) loggerCache.get(name);
<br/>
// if we have the child, then let us return it without wasting time
<br/>
if (childLogger != null) {
<br/>
return childLogger;
<br/>
}
<br/>
<br/>
// if the desired logger does not exist, them create all the loggers
<br/>
// in between as well (if they don't already exist)
<br/>
String childName;
<br/>
while (true) {
<br/>
int h = LoggerNameUtil.getSeparatorIndexOf(name, i);
<br/>
if (h == -1) {
<br/>
childName = name;
<br/>
} else {
<br/>
childName = name.substring(0, h);
<br/>
}
<br/>
// move i left of the last point
<br/>
i = h + 1;
<br/>
synchronized (logger) {
<br/>
childLogger = logger.getChildByName(childName);
<br/>
if (childLogger == null) {
<br/>
childLogger = logger.createChildByName(childName);
<br/>
loggerCache.put(childName, childLogger);
<br/>
incSize();
<br/>
}
<br/>
}
<br/>
logger = childLogger;
<br/>
if (h == -1) {
<br/>
return childLogger;
<br/>
}
<br/>
}
<br/>
}
<br/>
-------------------
<br/>
<br/>
== With recursion ==
<br/>
<br/>
<br/>
public final Logger getLogger(final String name) {
<br/>
if (name == null) {
<br/>
throw new IllegalArgumentException("name argument cannot be null");
<br/>
// can it be empty though??
<br/>
}
<br/>
// if we are asking for the root logger, then let us return it without wasting time
<br/>
// note that this is not the empty name but "ROOT"
<br/>
if (Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(name)) {
<br/>
return root;
<br/>
}
<br/>
// check if the desired logger exists, if it does, return it without further ado.
<br/>
{
<br/>
Logger childLogger = (Logger) loggerCache.get(name);
<br/>
if (loggerCache.get(name) != null) {
<br/>
return childLogger;
<br/>
}
<br/>
}
<br/>
// if the desired logger does not exist, then create all the loggers in between as well (if they don't exist yet)
<br/>
// this means
<br/>
// 1) splitting the "name" along the DOT/DOLLAR separators (but refusing the empty string result)
<br/>
// 2) creating all the loggers along that path if they don't exist yet
<br/>
createLoggerPathRecursively(name, "", 0, root);
<br/>
}
<br/>
<br/>
/**
<br/>
* Recursively build logger path
<br/>
* On the first call, "originalName" is the full logger name, "currentName" is the empty string,
<br/>
* currentPos (the position beyond which to search for logger name components) is 0 and
<br/>
* "parentLogger" is the "root"
<br/>
*/
<br/>
<br/>
private void createLoggerPathRecursively(String originalName, String currentName, int currentPos, Logger parentLogger) {
<br/>
assert originalName != null;
<br/>
assert currentName != null;
<br/>
assert currentPos >= 0;
<br/>
assert parentLogger != null;
<br/>
if (currentPos >= originalName.length()) {
<br/>
throw new IllegalArgumentException("The logger name '" + originalName + "' is either empty or ends with a separator");
<br/>
}
<br/>
// find the next separator in "originalName" starting from "currentPos"
<br/>
int ix = getSeparatorIndexOf(originalName, currentPos);
<br/>
if (ix < 0) {
<br/>
// No more separators, so we are done but still need to register this last logger.
<br/>
// So let ix point past the end!
<br/>
ix = originalName.length();
<br/>
}
<br/>
String nameComponent = originalName.substring(currentPos, ix);
<br/>
// Depending on specification use one of the two below:
<br/>
String childName = currentName + CoreConstants.DOT + nameComponent; // DOTify any DOLLAR
<br/>
// String childName = originalName.substring(0, ix); // unmodified part of original
<br/>
// Accept empty components? Nope!
<br/>
if (nameComponent.isEmpty()) {
<br/>
throw new IllegalArgumentException("The logger name '" + originalName + "' has an empty component starting at position " + currentPos);
<br/>
}
<br/>
// See whether the child logger exists, if not, create it
<br/>
Logger childLogger;
<br/>
synchronized (parentLogger) {
<br/>
childLogger = parentLogger.getChildByName(childName); // does not check the childName; returns null if not found
<br/>
if (childLogger == null) {
<br/>
// Depending on taste use this (which dotifies any dollars)
<br/>
// childLogger = parentLogger.createChildByLastNamePart(nameComponent); // checks that name component has no DOT or DOLLAR
<br/>
// 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)
<br/>
childLogger = parentLogger.createChildByName(childName); // checks that name component beyond parent's name has no DOT or DOLLAR
<br/>
loggerCache.put(childName, childLogger);
<br/>
incSize();
<br/>
}
<br/>
assert childLogger != null;
<br/>
}
<br/>
// (tail)-recursive call if not done
<br/>
if (ix < originalName.length()) {
<br/>
createLoggerPathRecursively(originalName, childName, ix + 1, childLogger);
<br/>
}
<br/>
}
<br/>
</td>
</tr>
<tr valign="top">
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 10px 10px 0;white-space:nowrap;">
<strong style="font-weight:normal;color:#505050;">Project:</strong>
</td>
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 0 10px 0;width:100%;">
<a style="color:#326ca6;" href="http://jira.qos.ch/browse/LOGBACK">logback</a>
</td>
</tr> <tr valign="top">
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 10px 10px 0;white-space:nowrap;">
<strong style="font-weight:normal;color:#505050;">Priority:</strong>
</td>
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 0 10px 0;width:100%;">
<img src="http://jira.qos.ch/images/icons/priority_minor.gif" height="16" width="16" border="0" align="absmiddle" alt="Minor"> Minor
</td>
</tr> <tr valign="top">
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 10px 10px 0;white-space:nowrap;">
<strong style="font-weight:normal;color:#505050;">Reporter:</strong>
</td>
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 0 10px 0;width:100%;">
<a class="user-hover" rel="dtonhofer" id="email_dtonhofer" href="http://jira.qos.ch/secure/ViewProfile.jspa?name=dtonhofer" style="color:#326ca6;">David Tonhofer</a>
</td>
</tr> </table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td><!-- End #email-page -->
</tr>
<tr valign="top">
<td style="color:#505050;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:10px;line-height:14px;padding: 0 16px 16px 16px;text-align:center;">
This message is automatically generated by JIRA.<br />
If you think it was sent incorrectly, please contact your <a style='color:#326ca6;' href='http://jira.qos.ch/secure/ContactAdministrators!default.jspa'>JIRA administrators</a>.<br />
For more information on JIRA, see: <a style='color:#326ca6;' href='http://www.atlassian.com/software/jira'>http://www.atlassian.com/software/jira</a>
</td>
</tr>
</table><!-- End #email-wrap -->
</div><!-- End #email-body -->