| /* |
| * Copyright (c) 2004-2013 QOS.ch |
| * All rights reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining |
| * a copy of this software and associated documentation files (the |
| * "Software"), to deal in the Software without restriction, including |
| * without limitation the rights to use, copy, modify, merge, publish, |
| * distribute, sublicense, and/or sell copies of the Software, and to |
| * permit persons to whom the Software is furnished to do so, subject to |
| * the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be |
| * included in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
| * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
| * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
| * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| * |
| */ |
| package org.slf4j.impl; |
| |
| import org.slf4j.ILoggerFactory; |
| import org.slf4j.Logger; |
| |
| import java.util.concurrent.ConcurrentHashMap; |
| import java.util.concurrent.ConcurrentMap; |
| |
| /** |
| * AndroidLoggerFactory is an implementation of {@link ILoggerFactory} returning |
| * the appropriately named {@link AndroidLoggerFactory} instance. |
| * |
| * @author Andrey Korzhevskiy <a.korzhevskiy@gmail.com> |
| */ |
| class AndroidLoggerFactory implements ILoggerFactory { |
| static final String ANONYMOUS_TAG = "null"; |
| static final int TAG_MAX_LENGTH = 23; |
| |
| private final ConcurrentMap<String, Logger> loggerMap = new ConcurrentHashMap<String, Logger>(); |
| |
| /** |
| * Return an appropriate {@link AndroidLoggerAdapter} instance by name. |
| */ |
| public Logger getLogger(String name) { |
| String tag = loggerNameToTag(name); |
| Logger logger = loggerMap.get(tag); |
| if (logger == null) { |
| Logger newInstance = new AndroidLoggerAdapter(tag); |
| Logger oldInstance = loggerMap.putIfAbsent(tag, newInstance); |
| logger = oldInstance == null ? newInstance : oldInstance; |
| } |
| return logger; |
| } |
| |
| /** |
| * Tag names cannot be longer than {@value #TAG_MAX_LENGTH} characters on Android platform. |
| * |
| * Returns the short logger tag (up to {@value #TAG_MAX_LENGTH} characters) for the given logger name. |
| * Traditionally loggers are named by fully-qualified Java classes; this |
| * method attempts to return a concise identifying part of such names. |
| * |
| * See also: |
| * android/system/core/include/cutils/property.h |
| * android/frameworks/base/core/jni/android_util_Log.cpp |
| * dalvik.system.DalvikLogging |
| * |
| */ |
| static String loggerNameToTag(String loggerName) { |
| // Anonymous logger |
| if (loggerName == null) { |
| return ANONYMOUS_TAG; |
| } |
| |
| int length = loggerName.length(); |
| if (length <= TAG_MAX_LENGTH) { |
| return loggerName; |
| } |
| |
| int tagLength = 0; |
| int lastTokenIndex = 0; |
| int lastPeriodIndex; |
| StringBuilder tagName = new StringBuilder(TAG_MAX_LENGTH + 3); |
| while ((lastPeriodIndex = loggerName.indexOf('.', lastTokenIndex)) != -1) { |
| tagName.append(loggerName.charAt(lastTokenIndex)); |
| // token of one character appended as is otherwise truncate it to one character |
| int tokenLength = lastPeriodIndex - lastTokenIndex; |
| if (tokenLength > 1) { |
| tagName.append('*'); |
| } |
| tagName.append('.'); |
| lastTokenIndex = lastPeriodIndex + 1; |
| |
| // check if name is already too long |
| tagLength = tagName.length(); |
| if (tagLength > TAG_MAX_LENGTH) { |
| return getSimpleName(loggerName); |
| } |
| } |
| |
| // Either we had no useful dot location at all |
| // or last token would exceed TAG_MAX_LENGTH |
| int tokenLength = length - lastTokenIndex; |
| if (tagLength == 0 || (tagLength + tokenLength) > TAG_MAX_LENGTH) { |
| return getSimpleName(loggerName); |
| } |
| |
| // last token (usually class name) appended as is |
| tagName.append(loggerName, lastTokenIndex, length); |
| return tagName.toString(); |
| } |
| |
| private static String getSimpleName(String loggerName) { |
| // Take leading part and append '*' to indicate that it was truncated |
| int length = loggerName.length(); |
| int lastPeriodIndex = loggerName.lastIndexOf('.'); |
| return lastPeriodIndex != -1 && length - (lastPeriodIndex + 1) <= TAG_MAX_LENGTH |
| ? loggerName.substring(lastPeriodIndex + 1) |
| : '*' + loggerName.substring(length - TAG_MAX_LENGTH + 1); |
| } |
| } |