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.core.BasicClass; 18 import org.as2lib.env.log.Logger; 19 import org.as2lib.env.log.LoggerRepository; 20 import org.as2lib.env.log.repository.LoggerFactory; 21 22 /** 23 * {@code DynamicLoggerRepository} is used to obtain loggers. 24 * 25 * <p>The actual class of these loggers is determined by you at runtime. You can 26 * therefor either use the constructors logger class argument or the 27 * {@link #setLoggerFactory} method. 28 * 29 * <p>This repository is very performant. What it does is quite simple. It only 30 * instantiates logger instances passing-in the given name, stores these instances 31 * by name for retrieval later on and returns them. 32 * 33 * <p>When working with logger repositories you normally store them in the log 34 * manager using the static {@link LogManager#setLoggerRepository} method. You can 35 * then use the static {@link LogManager#getLogger} method to obtain loggers from 36 * the set repository. 37 * 38 * <p>Example: 39 * <code> 40 * // configuration: on system start-up 41 * var repository:LoggerRepository = new DynamicLoggerRepository(MyLogger); 42 * LogManager.setLoggerRepository(repository); 43 * // usage: in the org.mydomain.MyClass class 44 * var myLogger:Logger = LogManager.getLogger("org.mydomain.MyClass"); 45 * if (myLogger.isWarningEnabled()) { 46 * myLogger.warning("Pay attention please!"); 47 * } 48 * </code> 49 * 50 * @author Simon Wacker 51 */ 52 class org.as2lib.env.log.repository.DynamicLoggerRepository extends BasicClass implements LoggerRepository { 53 54 /** Already received loggers. */ 55 private var loggers:Object; 56 57 /** Creates loggers. */ 58 private var loggerFactory:LoggerFactory; 59 60 /** 61 * Constructs a new {@code DynamicLoggerRepository} instance. 62 * 63 * <p>If you do not pass a {@code loggerClass} you must set the logger factory via 64 * the {@link #setLoggerFactory} method. Otherwise the logger returned by 65 * {@link #getLogger} will always be {@code null}. 66 * 67 * <p>The logger is wrapped into a factory and the factory is set. The factory 68 * then instantiates the logger class passing-in the name of the logger on calls 69 * to {@link #getLogger}. 70 * 71 * <p>Already received loggers are cached by name. Thus there exists only one 72 * logger instance per name. 73 * 74 * @param loggerClass (optional) the class to create loggers of 75 */ 76 public function DynamicLoggerRepository(loggerClass:Function) { 77 if (loggerClass) { 78 loggerFactory = getDynamicLoggerFactory(loggerClass); 79 } 80 loggers = new Object(); 81 } 82 83 /** 84 * Returns a new dynamic logger factory. 85 * 86 * <p>This factory creates new instances of the passed-in {@code loggerClass}. It 87 * passes the logger name as parameter to the constructor of the class on creation. 88 * 89 * @return a new dynamic logger factory 90 */ 91 private function getDynamicLoggerFactory(loggerClass:Function):LoggerFactory { 92 var result:LoggerFactory = getBlankLoggerFactory(); 93 result.getLogger = function(loggerName:String):Logger { 94 return new loggerClass(loggerName); 95 }; 96 return result; 97 } 98 99 /** 100 * Returns a blank logger factory. 101 * 102 * <p>That is a factory without implemented methods. All methods have still to be 103 * set. 104 * 105 * @return a blank logger factory 106 */ 107 private function getBlankLoggerFactory(Void):LoggerFactory { 108 var result = new Object(); 109 result.__proto__ = LoggerFactory["prototype"]; 110 result.__constructor__ = LoggerFactory; 111 return result; 112 } 113 114 /** 115 * Returns the set logger factory. 116 * 117 * @return the set logger factory 118 */ 119 public function getLoggerFactory(Void):LoggerFactory { 120 return loggerFactory; 121 } 122 123 /** 124 * Sets a new logger factory. 125 * 126 * <p>This logger factory is used to create loggers for given names, that are 127 * returned by the {@link #getLogger} method. 128 * 129 * @param loggerFactory the new logger factory 130 */ 131 public function setLoggerFactory(loggerFactory:LoggerFactory):Void { 132 this.loggerFactory = loggerFactory; 133 } 134 135 /** 136 * Returns a pre-configured logger for the passed-in {@code name}. 137 * 138 * <p>A new logger is created for names to which no logger has been assigned yet. 139 * The new logger is configured with the {@code name}, either by the custom 140 * factory or by the default one, which passes the {@code name} as parameter to 141 * the constructor of the logger class. The logger is then cached by name and 142 * returned for usage. 143 * 144 * <p>{@code null} will be returned if: 145 * <ul> 146 * <li>No logger factory has been set.</li> 147 * <li>The set logger factory returns {@code null} or {@code undefined}.</li> 148 * </ul> 149 *ยด 150 * @param name the name of the logger to return 151 * @return the logger appropriate to the passed-in {@code name} 152 */ 153 public function getLogger(name:String):Logger { 154 if (loggers[name]) return loggers[name]; 155 if (loggerFactory) { 156 var result:Logger = loggerFactory.getLogger(name); 157 loggers[name] = result; 158 return result; 159 } 160 return null; 161 } 162 163 }