home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Narzedzia / AIMP2 / aimp_2.61.583.exe / $TEMP / YandexPackSetup.msi / filF4B45AB2FEC8DC27D7F19CE2F2C97C4A < prev    next >
Text File  |  2010-07-12  |  15KB  |  562 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is log4moz
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * Michael Johnston
  18.  * Portions created by the Initial Developer are Copyright (C) 2006
  19.  * the Initial Developer. All Rights Reserved.
  20.  *
  21.  * Contributor(s):
  22.  * Michael Johnston <special.michael@gmail.com>
  23.  * Dan Mills <thunder@mozilla.com>
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  27.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the MPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the GPL or the LGPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the MPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38.  
  39. const EXPORTED_SYMBOLS = ['Log4Moz'];
  40.  
  41. const Cc = Components.classes;
  42. const Ci = Components.interfaces;
  43. const Cr = Components.results;
  44. const Cu = Components.utils;
  45.  
  46. Cu.import("resource://gre/modules/XPCOMUtils.jsm");
  47.  
  48. const MODE_RDONLY   = 0x01;
  49. const MODE_WRONLY   = 0x02;
  50. const MODE_CREATE   = 0x08;
  51. const MODE_APPEND   = 0x10;
  52. const MODE_TRUNCATE = 0x20;
  53.  
  54. const PERMS_FILE      = 0644;
  55. const PERMS_DIRECTORY = 0755;
  56.  
  57. const ONE_BYTE = 1;
  58. const ONE_KILOBYTE = 1024 * ONE_BYTE;
  59. const ONE_MEGABYTE = 1024 * ONE_KILOBYTE;
  60.  
  61. let Log4Moz = {
  62.   Level: {
  63.     Fatal:  70,
  64.     Error:  60,
  65.     Warn:   50,
  66.     Info:   40,
  67.     Config: 30,
  68.     Debug:  20,
  69.     Trace:  10,
  70.     All:    0,
  71.     Desc: {
  72.       70: "FATAL",
  73.       60: "ERROR",
  74.       50: "WARN",
  75.       40: "INFO",
  76.       30: "CONFIG",
  77.       20: "DEBUG",
  78.       10: "TRACE",
  79.       0:  "ALL"
  80.     }
  81.   },
  82.  
  83.   get repository() {
  84.     delete Log4Moz.repository;
  85.     Log4Moz.repository = new LoggerRepository();
  86.     return Log4Moz.repository;
  87.   },
  88.   set repository(value) {
  89.     delete Log4Moz.repository;
  90.     Log4Moz.repository = value;
  91.   },
  92.  
  93.   get LogMessage() { return LogMessage; },
  94.   get Logger() { return Logger; },
  95.   get LoggerRepository() { return LoggerRepository; },
  96.  
  97.   get Formatter() { return Formatter; },
  98.   get BasicFormatter() { return BasicFormatter; },
  99.  
  100.   get Appender() { return Appender; },
  101.   get DumpAppender() { return DumpAppender; },
  102.   get ConsoleAppender() { return ConsoleAppender; },
  103.   get FileAppender() { return FileAppender; },
  104.   get RotatingFileAppender() { return RotatingFileAppender; },
  105.  
  106.   // Logging helper:
  107.   // let logger = Log4Moz.repository.getLogger("foo");
  108.   // logger.info(Log4Moz.enumerateInterfaces(someObject).join(","));
  109.   enumerateInterfaces: function Log4Moz_enumerateInterfaces(aObject) {
  110.     let interfaces = [];
  111.  
  112.     for (i in Ci) {
  113.       try {
  114.         aObject.QueryInterface(Ci[i]);
  115.         interfaces.push(i);
  116.       }
  117.       catch(ex) {}
  118.     }
  119.  
  120.     return interfaces;
  121.   },
  122.  
  123.   // Logging helper:
  124.   // let logger = Log4Moz.repository.getLogger("foo");
  125.   // logger.info(Log4Moz.enumerateProperties(someObject).join(","));
  126.   enumerateProperties: function Log4Moz_enumerateProps(aObject,
  127.                                                        aExcludeComplexTypes) {
  128.     let properties = [];
  129.  
  130.     for (p in aObject) {
  131.       try {
  132.         if (aExcludeComplexTypes &&
  133.             (typeof aObject[p] == "object" || typeof aObject[p] == "function"))
  134.           continue;
  135.         properties.push(p + " = " + aObject[p]);
  136.       }
  137.       catch(ex) {
  138.         properties.push(p + " = " + ex);
  139.       }
  140.     }
  141.  
  142.     return properties;
  143.   }
  144. };
  145.  
  146.  
  147. /*
  148.  * LogMessage
  149.  * Encapsulates a single log event's data
  150.  */
  151. function LogMessage(loggerName, level, message){
  152.   this.loggerName = loggerName;
  153.   this.message = message;
  154.   this.level = level;
  155.   this.time = Date.now();
  156. }
  157. LogMessage.prototype = {
  158.   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
  159.  
  160.   get levelDesc() {
  161.     if (this.level in Log4Moz.Level.Desc)
  162.       return Log4Moz.Level.Desc[this.level];
  163.     return "UNKNOWN";
  164.   },
  165.  
  166.   toString: function LogMsg_toString(){
  167.     return "LogMessage [" + this.time + " " + this.level + " " +
  168.       this.message + "]";
  169.   }
  170. };
  171.  
  172. /*
  173.  * Logger
  174.  * Hierarchical version.  Logs to all appenders, assigned or inherited
  175.  */
  176.  
  177. function Logger(name, repository) {
  178.   this._init(name, repository);
  179. }
  180. Logger.prototype = {
  181.   _init: function Logger__init(name, repository) {
  182.     if (!repository)
  183.       repository = Log4Moz.repository;
  184.     this._name = name;
  185.     this._appenders = [];
  186.     this._repository = repository;
  187.   },
  188.  
  189.   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
  190.  
  191.   parent: null,
  192.  
  193.   get name() {
  194.     return this._name;
  195.   },
  196.  
  197.   _level: null,
  198.   get level() {
  199.     if (this._level != null)
  200.       return this._level;
  201.     if (this.parent)
  202.       return this.parent.level;
  203.     dump("log4moz warning: root logger configuration error: no level defined\n");
  204.     return Log4Moz.Level.All;
  205.   },
  206.   set level(level) {
  207.     this._level = level;
  208.   },
  209.  
  210.   _appenders: null,
  211.   get appenders() {
  212.     if (!this.parent)
  213.       return this._appenders;
  214.     return this._appenders.concat(this.parent.appenders);
  215.   },
  216.  
  217.   addAppender: function Logger_addAppender(appender) {
  218.     for (let i = 0; i < this._appenders.length; i++) {
  219.       if (this._appenders[i] == appender)
  220.         return;
  221.     }
  222.     this._appenders.push(appender);
  223.   },
  224.  
  225.   removeAppender: function Logger_removeAppender(appender) {
  226.     let newAppenders = [];
  227.     for (let i = 0; i < this._appenders.length; i++) {
  228.       if (this._appenders[i] != appender)
  229.         newAppenders.push(this._appenders[i]);
  230.     }
  231.     this._appenders = newAppenders;
  232.   },
  233.  
  234.   log: function Logger_log(message) {
  235.     if (this.level > message.level)
  236.       return;
  237.     let appenders = this.appenders;
  238.     for (let i = 0; i < appenders.length; i++){
  239.       appenders[i].append(message);
  240.     }
  241.   },
  242.  
  243.   fatal: function Logger_fatal(string) {
  244.     this.log(new LogMessage(this._name, Log4Moz.Level.Fatal, string));
  245.   },
  246.   error: function Logger_error(string) {
  247.     this.log(new LogMessage(this._name, Log4Moz.Level.Error, string));
  248.   },
  249.   warn: function Logger_warn(string) {
  250.     this.log(new LogMessage(this._name, Log4Moz.Level.Warn, string));
  251.   },
  252.   info: function Logger_info(string) {
  253.     this.log(new LogMessage(this._name, Log4Moz.Level.Info, string));
  254.   },
  255.   config: function Logger_config(string) {
  256.     this.log(new LogMessage(this._name, Log4Moz.Level.Config, string));
  257.   },
  258.   debug: function Logger_debug(string) {
  259.     this.log(new LogMessage(this._name, Log4Moz.Level.Debug, string));
  260.   },
  261.   trace: function Logger_trace(string) {
  262.     this.log(new LogMessage(this._name, Log4Moz.Level.Trace, string));
  263.   }
  264. };
  265.  
  266. /*
  267.  * LoggerRepository
  268.  * Implements a hierarchy of Loggers
  269.  */
  270.  
  271. function LoggerRepository() {}
  272. LoggerRepository.prototype = {
  273.   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
  274.  
  275.   _loggers: {},
  276.  
  277.   _rootLogger: null,
  278.   get rootLogger() {
  279.     if (!this._rootLogger) {
  280.       this._rootLogger = new Logger("root", this);
  281.       this._rootLogger.level = Log4Moz.Level.All;
  282.     }
  283.     return this._rootLogger;
  284.   },
  285.   // FIXME: need to update all parent values if we do this
  286.   //set rootLogger(logger) {
  287.   //  this._rootLogger = logger;
  288.   //},
  289.  
  290.   _updateParents: function LogRep__updateParents(name) {
  291.     let pieces = name.split('.');
  292.     let cur, parent;
  293.  
  294.     // find the closest parent
  295.     // don't test for the logger name itself, as there's a chance it's already
  296.     // there in this._loggers
  297.     for (let i = 0; i < pieces.length - 1; i++) {
  298.       if (cur)
  299.         cur += '.' + pieces[i];
  300.       else
  301.         cur = pieces[i];
  302.       if (cur in this._loggers)
  303.         parent = cur;
  304.     }
  305.  
  306.     // if we didn't assign a parent above, there is no parent
  307.     if (!parent)
  308.       this._loggers[name].parent = this.rootLogger;
  309.     else
  310.       this._loggers[name].parent = this._loggers[parent];
  311.  
  312.     // trigger updates for any possible descendants of this logger
  313.     for (let logger in this._loggers) {
  314.       if (logger != name && logger.indexOf(name) == 0)
  315.         this._updateParents(logger);
  316.     }
  317.   },
  318.  
  319.   getLogger: function LogRep_getLogger(name) {
  320.     if (!name)
  321.       name = this.getLogger.caller.name;
  322.     if (name in this._loggers)
  323.       return this._loggers[name];
  324.     this._loggers[name] = new Logger(name, this);
  325.     this._updateParents(name);
  326.     return this._loggers[name];
  327.   }
  328. };
  329.  
  330. /*
  331.  * Formatters
  332.  * These massage a LogMessage into whatever output is desired
  333.  * Only the BasicFormatter is currently implemented
  334.  */
  335.  
  336. // Abstract formatter
  337. function Formatter() {}
  338. Formatter.prototype = {
  339.   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
  340.   format: function Formatter_format(message) {}
  341. };
  342.  
  343. // FIXME: should allow for formatting the whole string, not just the date
  344. function BasicFormatter(dateFormat) {
  345.   if (dateFormat)
  346.     this.dateFormat = dateFormat;
  347. }
  348. BasicFormatter.prototype = {
  349.   __proto__: Formatter.prototype,
  350.  
  351.   _dateFormat: null,
  352.  
  353.   get dateFormat() {
  354.     if (!this._dateFormat)
  355.       this._dateFormat = "%Y-%m-%d %H:%M:%S";
  356.     return this._dateFormat;
  357.   },
  358.  
  359.   set dateFormat(format) {
  360.     this._dateFormat = format;
  361.   },
  362.  
  363.   format: function BF_format(message) {
  364.     let date = new Date(message.time);
  365.  
  366.     // Pad a string to a certain length (20) with a character (space)
  367.     let pad = function BF__pad(str, len, chr) str +
  368.       new Array(Math.max((len || 20) - str.length + 1, 0)).join(chr || " ");
  369.  
  370.     return date.toLocaleFormat(this.dateFormat) + "\t" +
  371.       pad(message.loggerName) + " " + message.levelDesc + "\t" +
  372.       message.message + "\n";
  373.   }
  374. };
  375.  
  376. /*
  377.  * Appenders
  378.  * These can be attached to Loggers to log to different places
  379.  * Simply subclass and override doAppend to implement a new one
  380.  */
  381.  
  382. function Appender(formatter) {
  383.   this._name = "Appender";
  384.   this._formatter = formatter? formatter : new BasicFormatter();
  385. }
  386. Appender.prototype = {
  387.   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
  388.  
  389.   _level: Log4Moz.Level.All,
  390.   get level() { return this._level; },
  391.   set level(level) { this._level = level; },
  392.  
  393.   append: function App_append(message) {
  394.     if(this._level <= message.level)
  395.       this.doAppend(this._formatter.format(message));
  396.   },
  397.   toString: function App_toString() {
  398.     return this._name + " [level=" + this._level +
  399.       ", formatter=" + this._formatter + "]";
  400.   },
  401.   doAppend: function App_doAppend(message) {}
  402. };
  403.  
  404. /*
  405.  * DumpAppender
  406.  * Logs to standard out
  407.  */
  408.  
  409. function DumpAppender(formatter) {
  410.   this._name = "DumpAppender";
  411.   this._formatter = formatter? formatter : new BasicFormatter();
  412. }
  413. DumpAppender.prototype = {
  414.   __proto__: Appender.prototype,
  415.  
  416.   doAppend: function DApp_doAppend(message) {
  417.     dump(message);
  418.   }
  419. };
  420.  
  421. /*
  422.  * ConsoleAppender
  423.  * Logs to the javascript console
  424.  */
  425.  
  426. function ConsoleAppender(formatter) {
  427.   this._name = "ConsoleAppender";
  428.   this._formatter = formatter;
  429. }
  430. ConsoleAppender.prototype = {
  431.   __proto__: Appender.prototype,
  432.  
  433.   doAppend: function CApp_doAppend(message) {
  434.     if (message.level > Log4Moz.Level.Warn) {
  435.       Cu.reportError(message);
  436.       return;
  437.     }
  438.     Cc["@mozilla.org/consoleservice;1"].
  439.       getService(Ci.nsIConsoleService).logStringMessage(message);
  440.   }
  441. };
  442.  
  443. /*
  444.  * FileAppender
  445.  * Logs to a file
  446.  */
  447.  
  448. function FileAppender(file, formatter) {
  449.   this._name = "FileAppender";
  450.   this._file = file; // nsIFile
  451.   this._formatter = formatter? formatter : new BasicFormatter();
  452. }
  453. FileAppender.prototype = {
  454.   __proto__: Appender.prototype,
  455.   __fos: null,
  456.   get _fos() {
  457.     if (!this.__fos)
  458.       this.openStream();
  459.     return this.__fos;
  460.   },
  461.  
  462.   openStream: function FApp_openStream() {
  463.     try {
  464.       let __fos = Cc["@mozilla.org/network/file-output-stream;1"].
  465.         createInstance(Ci.nsIFileOutputStream);
  466.       let flags = MODE_WRONLY | MODE_CREATE | MODE_APPEND;
  467.       __fos.init(this._file, flags, PERMS_FILE, 0);
  468.  
  469.       this.__fos = Cc["@mozilla.org/intl/converter-output-stream;1"]
  470.             .createInstance(Ci.nsIConverterOutputStream);
  471.       this.__fos.init(__fos, "UTF-8", 4096,
  472.             Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
  473.     } catch(e) {
  474.       dump("Error opening stream:\n" + e);
  475.     }
  476.   },
  477.  
  478.   closeStream: function FApp_closeStream() {
  479.     if (!this.__fos)
  480.       return;
  481.     try {
  482.       this.__fos.close();
  483.       this.__fos = null;
  484.     } catch(e) {
  485.       dump("Failed to close file output stream\n" + e);
  486.     }
  487.   },
  488.  
  489.   doAppend: function FApp_doAppend(message) {
  490.     if (message === null || message.length <= 0)
  491.       return;
  492.     try {
  493.       this._fos.writeString(message);
  494.     } catch(e) {
  495.       dump("Error writing file:\n" + e);
  496.     }
  497.   },
  498.  
  499.   clear: function FApp_clear() {
  500.     this.closeStream();
  501.     try {
  502.       this._file.remove(false);
  503.     } catch (e) {
  504.       // XXX do something?
  505.     }
  506.   }
  507. };
  508.  
  509. /*
  510.  * RotatingFileAppender
  511.  * Similar to FileAppender, but rotates logs when they become too large
  512.  */
  513.  
  514. function RotatingFileAppender(file, formatter, maxSize, maxBackups) {
  515.   if (maxSize === undefined)
  516.     maxSize = ONE_MEGABYTE * 2;
  517.  
  518.   if (maxBackups === undefined)
  519.     maxBackups = 0;
  520.  
  521.   this._name = "RotatingFileAppender";
  522.   this._file = file; // nsIFile
  523.   this._formatter = formatter? formatter : new BasicFormatter();
  524.   this._maxSize = maxSize;
  525.   this._maxBackups = maxBackups;
  526. }
  527. RotatingFileAppender.prototype = {
  528.   __proto__: FileAppender.prototype,
  529.  
  530.   doAppend: function RFApp_doAppend(message) {
  531.     if (message === null || message.length <= 0)
  532.       return;
  533.     try {
  534.       this.rotateLogs();
  535.       FileAppender.prototype.doAppend.call(this, message);
  536.     } catch(e) {
  537.       dump("Error writing file:" + e + "\n");
  538.     }
  539.   },
  540.  
  541.   rotateLogs: function RFApp_rotateLogs() {
  542.     if(this._file.exists() &&
  543.        this._file.fileSize < this._maxSize)
  544.       return;
  545.  
  546.     this.closeStream();
  547.  
  548.     for (let i = this.maxBackups - 1; i > 0; i--){
  549.       let backup = this._file.parent.clone();
  550.       backup.append(this._file.leafName + "." + i);
  551.       if (backup.exists())
  552.         backup.moveTo(this._file.parent, this._file.leafName + "." + (i + 1));
  553.     }
  554.  
  555.     let cur = this._file.clone();
  556.     if (cur.exists())
  557.       cur.moveTo(cur.parent, cur.leafName + ".1");
  558.  
  559.     // Note: this._file still points to the same file
  560.   }
  561. };
  562.