001/*
002 * Copyright (c) 2010-2024 Mark Allen, Norbert Bartels.
003 *
004 * Permission is hereby granted, free of charge, to any person obtaining a copy
005 * of this software and associated documentation files (the "Software"), to deal
006 * in the Software without restriction, including without limitation the rights
007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008 * copies of the Software, and to permit persons to whom the Software is
009 * furnished to do so, subject to the following conditions:
010 *
011 * The above copyright notice and this permission notice shall be included in
012 * all copies or substantial portions of the Software.
013 *
014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
020 * THE SOFTWARE.
021 */
022package com.restfb.logging;
023
024import java.lang.reflect.Constructor;
025
026import com.restfb.exception.FacebookLoggerException;
027
028/**
029 * Abstract class that is the parent of all our logger implementations.
030 * <p>
031 * Normally RestFB uses java.util.logging for logging messages. But as soon as slf4j is found on the class path RestFB
032 * switches to this logger. With the slf4j facade more logger implementations are supported and the quasi standard for
033 * java logging is used.
034 * <p>
035 * In the rare case you have to switch to java.util.logging although slf4j is present on the class path we provide a
036 * system property to force java.util.logging to be used.
037 * <p>
038 * The system property is called <code>com.restfb.forceJUL</code> and can be set to {@code true} if jul should be
039 * forced.
040 */
041public abstract class RestFBLogger {
042
043  private static Class<? extends RestFBLogger> usedLoggerClass = null;
044
045  public static final RestFBLogger HTTP_LOGGER;
046
047  public static final RestFBLogger MAPPER_LOGGER;
048
049  public static final RestFBLogger UTILS_LOGGER;
050
051  public static final RestFBLogger CLIENT_LOGGER;
052
053  public static final RestFBLogger VALUE_FACTORY_LOGGER;
054
055  static {
056    Class<? extends RestFBLogger> loggerClass;
057
058    String forceJUL = System.getProperty("com.restfb.forceJUL", "false");
059    if (!Boolean.parseBoolean(forceJUL)) {
060      try {
061        RestFBLogger.class.getClassLoader().loadClass("org.slf4j.Logger");
062        loggerClass = com.restfb.logging.SLF4JLogger.class;
063      } catch (Exception e) {
064        loggerClass = com.restfb.logging.JulLogger.class;
065      }
066    } else {
067      loggerClass = com.restfb.logging.JulLogger.class;
068    }
069
070    // define our logger class
071    usedLoggerClass = loggerClass;
072
073    // create the loggers
074    HTTP_LOGGER = getLoggerInstance("com.restfb.HTTP");
075    MAPPER_LOGGER = getLoggerInstance("com.restfb.JSON_MAPPER");
076    UTILS_LOGGER = getLoggerInstance("com.restfb.UTILITY");
077    CLIENT_LOGGER = getLoggerInstance("com.restfb.CLIENT");
078    VALUE_FACTORY_LOGGER = getLoggerInstance("com.restfb.types.CHANGE_VALUE_FACTORY");
079  }
080
081  /**
082   * returns the instance of the logger that belongs to the category.
083   * 
084   * @param logCategory
085   *          the category of the logger
086   * @return a instance of the logger
087   */
088  public static RestFBLogger getLoggerInstance(String logCategory) {
089    Object obj;
090    Class[] ctrTypes = new Class[] { String.class };
091    Object[] ctrArgs = new Object[] { logCategory };
092    try {
093      Constructor<? extends RestFBLogger> loggerClassConstructor = usedLoggerClass.getConstructor(ctrTypes);
094      obj = loggerClassConstructor.newInstance(ctrArgs);
095    } catch (Exception e) {
096      throw new FacebookLoggerException("cannot create logger: " + logCategory);
097    }
098
099    return (RestFBLogger) obj;
100  }
101
102  /**
103   * Log a message at the TRACE level according to the specified format and arguments.
104   *
105   * @param msg
106   *          the log message
107   * @param args
108   *          optional arguments, the last argument may be an exception
109   */
110  public abstract void trace(String msg, Object... args);
111
112  /**
113   * Log a message at the DEBUG level according to the specified format and arguments.
114   *
115   * @param msg
116   *          the log message
117   * @param args
118   *          optional arguments, the last argument may be an exception
119   */
120  public abstract void debug(String msg, Object... args);
121
122  /**
123   * Log a message at the INFO level according to the specified format and arguments.
124   *
125   * @param msg
126   *          the log message
127   * @param args
128   *          optional arguments, the last argument may be an exception
129   */
130  public abstract void info(String msg, Object... args);
131
132  /**
133   * Log a message at the WARN level according to the specified format and arguments.
134   *
135   * @param msg
136   *          the log message
137   * @param args
138   *          optional arguments, the last argument may be an exception
139   */
140  public abstract void warn(String msg, Object... args);
141
142  /**
143   * Log a message at the ERROR level according to the specified format and arguments.
144   *
145   * @param msg
146   *          the log message
147   * @param args
148   *          optional arguments, the last argument may be an exception
149   */
150  public abstract void error(String msg, Object... args);
151
152  /**
153   * Log a message at the FATAL level according to the specified format and arguments.
154   *
155   * @param msg
156   *          the log message
157   * @param args
158   *          optional arguments, the last argument may be an exception
159   */
160  public abstract void fatal(String msg, Object... args);
161
162  /**
163   * Is the logger instance enabled for the DEBUG level?
164   * 
165   * @return {@code true} if it is enabled, {@code false} otherwise
166   */
167  public abstract boolean isDebugEnabled();
168
169  /**
170   * Is the logger instance enabled for the INFO level?
171   * 
172   * @return {@code true} if it is enabled, {@code false} otherwise
173   */
174  public abstract boolean isInfoEnabled();
175
176  /**
177   * Is the logger instance enabled for the TRACE level?
178   * 
179   * @return {@code true} if it is enabled, {@code false} otherwise
180   */
181  public abstract boolean isTraceEnabled();
182}