1  /*
     2   * Copyright the original author or authors.
     3   * 
     4   * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   * 
     8   *      http://www.mozilla.org/MPL/MPL-1.1.html
     9   * 
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  import org.as2lib.env.log.Logger;
    18  import org.as2lib.env.log.LogLevel;
    19  import org.as2lib.env.log.LogMessage;
    20  import org.as2lib.env.log.logger.AbstractLogger;
    21  
    22  /**
    23   * {@code MusicTheoryLogger} writes messages to the SWF Console from Ricci Adams'
    24   * Musictheory.
    25   *
    26   * <p>Using this class to log messages instead of logging them directly to the
    27   * Musictheory SWF Console enables you to switch between differnt ouput devices and
    28   * Logging APIs without the need to change any logging calls in your application.
    29   * This class also gives you the ability to log at differnt log levels and decorates
    30   * log messages with a date-time, the level and the logger's name if wished. Refer
    31   * to {@link LogMessage} on how to edit the decoration.
    32   * 
    33   * <p>The basic methods to write log messages are {@link #log}, {@link #debug},
    34   * {@link #info}, {@link #warning} and {@link #fatal}.
    35   *
    36   * <p>The first thing to note is that you can log messages at different levels.
    37   * These levels are {@code DEBUG}, {@code INFO}, {@code WARNING}, {@code ERROR}
    38   * and {@code FATAL}. Depending on what level has been set only messages at a
    39   * given level are logged. The levels are organized in a hierarchical manner. That
    40   * means if you set the log level to {@code ALL} every messages is logged. If you
    41   * set it to {@code ERROR} only messages at {@code ERROR} and {@code FATAL} level
    42   * are logged and so on.
    43   *
    44   * <p>To do not waste unnecessary performance in constructing log messages that are
    45   * not logged you can use the {@link #isDebugEnabled}, {@link #isInfoEnabled},
    46   * {@link #isWarningEnabled}, {@link #isErrorEnabled} and {@link #isFatalEnabled}
    47   * methods.
    48   *
    49   * <p>Note that the message does in neither case have to be a string. That means
    50   * you can pass-in messages and let the actual handler or logger decide how to
    51   * produce a string representation of the message. That is in most cases done by
    52   * using the {@code toString} method of the specific message. You can use this
    53   * method to do not lose performance in cases where the message is not logged.
    54   *
    55   * <p>Example:
    56   * <code>
    57   *   var logger:MusicTheoryLogger = new MusicTheoryLogger("myLogger");
    58   *   // checks if the message is actually logged
    59   *   if (logger.isInfoEnabled()) {
    60  	     // logs the message at info level
    61   *       logger.info("This is a informative log message.");
    62   *   }
    63   * </code>
    64   * 
    65   * <p>This logger cannot be used with the {@ling LoggerHierarchy} because it does
    66   * not offer hierarchy support. If you want to use your logger in a hierarchy use
    67   * the {@link SimpleHierarchicalLogger} instead, together with a log handler.
    68   *
    69   * @author Simon Wacker
    70   * @see org.as2lib.env.log.handler.MusicTheoryHandler
    71   * @see <a href="http://source.musictheory.net/swfconsole">SWF Console</a>
    72   */
    73  class org.as2lib.env.log.logger.MusicTheoryLogger extends AbstractLogger implements Logger {
    74  	
    75  	/** Makes the static variables of the super-class accessible through this class. */
    76  	private static var __proto__:Function = AbstractLogger;
    77  	
    78  	/** The set level. */
    79  	private var level:LogLevel;
    80  	
    81  	/** The set level as number. */
    82  	private var levelAsNumber:Number;
    83  	
    84  	/** The name of this logger. */
    85  	private var name:String;
    86  	
    87  	/**
    88  	 * Constructs a new {@code MusicTheoryLogger} instance.
    89  	 *
    90  	 * <p>The default log level is {@code ALL}. This means all messages regardless of
    91  	 * their level are logged.
    92  	 *
    93  	 * <p>The {@code name} is by default shown in the log message to identify where
    94  	 * the message came from.
    95  	 *
    96  	 * @param name (optional) the name of this logger
    97  	 */
    98  	public function MusicTheoryLogger(name:String) {
    99  		this.name = name;
   100  		level = ALL;
   101  		levelAsNumber = level.toNumber();
   102  	}
   103  	
   104  	/**
   105  	 * Returns the name of this logger.
   106  	 *
   107  	 * <p>This method returns {@code null} if no name has been set via the
   108  	 * {@link #setName} method nor on construction.
   109  	 *
   110  	 * @return the name of this logger
   111  	 */
   112  	public function getName(Void):String {
   113  		return name;
   114  	}
   115  	
   116  	/**
   117  	 * Sets the name of this logger.
   118  	 *
   119  	 * <p>The name is by default shown in the log message.
   120  	 *
   121  	 * @param name the new name of this logger
   122  	 */
   123  	public function setName(name:String):Void {
   124  		this.name = name;
   125  	}
   126  	
   127  	/**
   128  	 * Sets the log level.
   129  	 *
   130  	 * <p>The log level determines which messages are logged and which are not.
   131  	 *
   132  	 * <p>A level of value {@code null} or {@code undefined} is interpreted as level
   133  	 * {@code ALL} which is also the default level.
   134  	 *
   135  	 * @param level the new log level
   136  	 */
   137  	public function setLevel(level:LogLevel):Void {
   138  		if (level) {
   139  			this.level = level;
   140  		} else {
   141  			this.level = ALL;
   142  		}
   143  		this.levelAsNumber = this.level.toNumber();
   144  	}
   145  	
   146  	/**
   147  	 * Returns the set level.
   148  	 *
   149  	 * @return the set level
   150  	 */
   151  	public function getLevel(Void):LogLevel {
   152  		return level;
   153  	}
   154  	
   155  	/**
   156  	 * Checks whether this logger is enabled for the passed-in {@code level}.
   157  	 *
   158  	 * <p>{@code false} will be returned if:
   159  	 * <ul>
   160  	 *   <li>This logger is not enabled for the passed-in {@code level}.</li>
   161  	 *   <li>The passed-in {@code level} is {@code null} or {@code undefined}.</li>
   162  	 * </ul>
   163  	 *
   164  	 * <p>Using this method as shown in the class documentation may improve performance
   165  	 * depending on how long the log message construction takes.
   166  	 *
   167  	 * @param level the level to make the check upon
   168  	 * @return {@code true} if this logger is enabled for the given {@code level} else
   169  	 * {@code false}
   170  	 * @see #log
   171  	 */
   172  	public function isEnabled(level:LogLevel):Boolean {
   173  		if (!level) return false;
   174  		return (levelAsNumber >= level.toNumber());
   175  	}
   176  	
   177  	/**
   178  	 * Checks if this logger is enabled for debug level log messages.
   179  	 *
   180  	 * <p>Using this method as shown in the class documentation may improve performance
   181  	 * depending on how long the log message construction takes.
   182  	 *
   183  	 * @return {@code true} if debug messages are logged
   184  	 * @see org.as2lib.env.log.level.AbstractLogLevel#DEBUG
   185  	 * @see #debug
   186  	 */
   187  	public function isDebugEnabled(Void):Boolean {
   188  		return (levelAsNumber >= debugLevelAsNumber);
   189  	}
   190  	
   191  	/**
   192  	 * Checks if this logger is enabled for info level log messages.
   193  	 *
   194  	 * <p>Using this method as shown in the class documentation may improve performance
   195  	 * depending on how long the log message construction takes.
   196  	 *
   197  	 * @return {@code true} if info messages are logged
   198  	 * @see org.as2lib.env.log.level.AbstractLogLevel#INFO
   199  	 * @see #info
   200  	 */
   201  	public function isInfoEnabled(Void):Boolean {
   202  		return (levelAsNumber >= infoLevelAsNumber);
   203  	}
   204  	
   205  	/**
   206  	 * Checks if this logger is enabled for warning level log messages.
   207  	 *
   208  	 * <p>Using this method as shown in the class documentation may improve performance
   209  	 * depending on how long the log message construction takes.
   210  	 *
   211  	 * @return {@code true} if warning messages are logged
   212  	 * @see org.as2lib.env.log.level.AbstractLogLevel#WARNING
   213  	 * @see #warning
   214  	 */
   215  	public function isWarningEnabled(Void):Boolean {
   216  		return (levelAsNumber >= warningLevelAsNumber);
   217  	}
   218  	
   219  	/**
   220  	 * Checks if this logger is enabled for error level log messages.
   221  	 *
   222  	 * <p>Using this method as shown in the class documentation may improve performance
   223  	 * depending on how long the log message construction takes.
   224  	 *
   225  	 * @return {@code true} if error messages are logged
   226  	 * @see org.as2lib.env.log.level.AbstractLogLevel#ERROR
   227  	 * @see #error
   228  	 */
   229  	public function isErrorEnabled(Void):Boolean {
   230  		return (levelAsNumber >= errorLevelAsNumber);
   231  	}
   232  	
   233  	/**
   234  	 * Checks if this logger is enabled for fatal level log messages.
   235  	 *
   236  	 * <p>Using this method as shown in the class documentation may improve performance
   237  	 * depending on how long the log message construction takes.
   238  	 *
   239  	 * @return {@code true} if fatal messages are logged
   240  	 * @see org.as2lib.env.log.level.AbstractLogLevel#FATAL
   241  	 * @see #fatal
   242  	 */
   243  	public function isFatalEnabled(Void):Boolean {
   244  		return (levelAsNumber >= fatalLevelAsNumber);
   245  	}
   246  	
   247  	/**
   248  	 * Logs the passed-in {@code message} at the given {@code level}.
   249  	 *
   250  	 * <p>The {@code message} is only logged when this logger is enabled for the
   251  	 * passed-in {@code level}.
   252  	 *
   253  	 * <p>The {@code message} is logged to the Musictheory SWF Console.
   254  	 *
   255  	 * @param message the message object to log
   256  	 * @param level the specific level at which the {@code message} shall be logged
   257  	 * @see #isEnabled
   258  	 */
   259  	public function log(message, level:LogLevel):Void {
   260  		if (isEnabled(level)) {
   261  			var m:LogMessage = new LogMessage(message, level, name);
   262  			getURL("javascript:showText('" + m + "')");
   263  		}
   264  	}
   265  	
   266  	/**
   267  	 * Logs the passed-in {@code message} at debug level.
   268  	 *
   269  	 * <p>The {@code message} is only logged when the level is set to {@code DEBUG} or
   270  	 * a level above.
   271  	 *
   272  	 * @param message the message object to log
   273  	 * @see #isDebugEnabled
   274  	 */
   275  	public function debug(message):Void {
   276  		if (isDebugEnabled()) {
   277  			log(message, debugLevel);
   278  		}
   279  	}
   280  	
   281  	/**
   282  	 * Logs the passed-in {@code message} at info level.
   283  	 *
   284  	 * <p>The {@code message} is only logged when the level is set to {@code INFO} or
   285  	 * a level above.
   286  	 *
   287  	 * @param message the message object to log
   288  	 * @see #isInfoEnabled
   289  	 */
   290  	public function info(message):Void {
   291  		if (isInfoEnabled()) {
   292  			log(message, infoLevel);
   293  		}
   294  	}
   295  	
   296  	/**
   297  	 * Logs the passed-in {@code message} at warning level.
   298  	 *
   299  	 * <p>The {@code message} is only logged when the level is set to {@code WARNING}
   300  	 * or a level above.
   301  	 *
   302  	 * @param message the message object to log
   303  	 * @see #isWarningEnabled
   304  	 */
   305  	public function warning(message):Void {
   306  		if (isWarningEnabled()) {
   307  			log(message, warningLevel);
   308  		}
   309  	}
   310  	
   311  	/**
   312  	 * Logs the passed-in {@code message} at error level.
   313  	 *
   314  	 * <p>The {@code message} is only logged when the level is set to {@code ERROR} or
   315  	 * a level above.
   316  	 *
   317  	 * @param message the message object to log
   318  	 * @see #isErrorEnabled
   319  	 */
   320  	public function error(message):Void {
   321  		if (isErrorEnabled()) {
   322  			log(message, errorLevel);
   323  		}
   324  	}
   325  	
   326  	/**
   327  	 * Logs the passed-in {@code message} at fatal level.
   328  	 *
   329  	 * <p>The {@code message} is only logged when the level is set to {@code FATAL} or
   330  	 * a level above.
   331  	 *
   332  	 * @param message the message object to log
   333  	 * @see #isFatalEnabled
   334  	 */
   335  	public function fatal(message):Void {
   336  		if (isFatalEnabled()) {
   337  			log(message, fatalLevel);
   338  		}
   339  	}
   340  	
   341  }