KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > excalibur > logger > AbstractLoggerManager


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14  * implied.
15  *
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */

19 package org.apache.avalon.excalibur.logger;
20
21 import java.util.HashMap JavaDoc;
22 import java.util.Map JavaDoc;
23
24 import org.apache.avalon.excalibur.logger.util.LoggerSwitch;
25 import org.apache.avalon.excalibur.logger.util.LoggerUtil;
26 import org.apache.avalon.framework.logger.LogEnabled;
27 import org.apache.avalon.framework.logger.Logger;
28
29 /**
30  *
31  * This abstract class implements LogEnabled.
32  * A derived class is expected to obtain a logger via
33  * <code>getLogger()</code> and live with it.
34  * The <code>Logger</code> supplied via <code>enableLogging</code>
35  * will be used both as the "initial" and as the "fallback" logger.
36  * <ul><li>
37  * "initial" means that until a call to
38  * <code>start()</code> the messages logger via
39  * <code>getLogger().xxx()</code> will go to this logger</li><li>
40  * "fallback" means that if after a successfull <code>start</code>
41  * a recursive invocation of <code>getLogger().xxx()</code> will be detected
42  * the message will be logged via the initial logger as a fallback.</li></ul>
43  * See {@link org.apache.avalon.excalibur.logger.util.LoggerSwitch} for
44  * more details.
45  *
46  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
47  * @version CVS $Revision: 1.5 $ $Date: 2004/03/10 13:54:49 $
48  * @since 4.0
49  */

50 public abstract class AbstractLoggerManager
51     implements LogEnabled, LoggerManager
52 {
53     /**
54      * Map for name to logger mapping.
55      * This instance variable is protected (not privated)
56      * so that it may be pre-filled at configuration stage.
57      */

58     final protected Map JavaDoc m_loggers = new HashMap JavaDoc();
59
60     /** The root logger to configure */
61     protected String JavaDoc m_prefix;
62
63     /**
64      * The object that wraps a swithing logger.
65      * The switching logger itself for security reasons
66      * has no methods of controlling it, but its wrapping
67      * object has.
68      */

69     private LoggerSwitch m_switch;
70
71     /** Always equals to m_switch.get() */
72     private Logger m_logger;
73
74     /**
75      * category we should switch our own loggin to
76      * on <code>start()</code>.
77      */

78     private String JavaDoc m_switchTo;
79
80     /** safeguards against double <code>enableLogging()</code> invocation. */
81     private boolean m_enableLoggingInvoked = false;
82
83     /** safeguards against double <code>start()</code> invocation. */
84     private boolean m_startInvoked = false;
85
86     /**
87      * The logger used to be returned from <code>getDefaultLogger()</code>
88      * and <code>getLoggerForCategory("")</code>,
89      * if one has been forcibly set via a constructor.
90      */

91     final private Logger m_defaultLoggerOverride;
92
93     /**
94      * Derived LoggerManager implementations should obtain
95      * a logger to log their own messages via this call.
96      * It is also safe to log messages about logging failures
97      * via this logger as it safeguards internally gainst
98      * recursion.
99      */

100     protected Logger getLogger()
101     {
102         return m_logger;
103     }
104
105     /**
106      * Initializes AbstractLoggerManager.
107      * @param prefix the prefix to prepended to the category name
108      * on each invocation of getLoggerForCategory before
109      * passing the category name on to the underlying logging
110      * system (currently LogKit or Log4J).
111      * @param switchTo fuel for the <code>start()</code> method;
112      * if null <code>start()</code> will do nothing;
113      * if empty <code>start()</code> will switch to
114      * <code>getLoggerForCategory("")</code>.
115      */

116     public AbstractLoggerManager( final String JavaDoc prefix, final String JavaDoc switchTo,
117             Logger defaultLoggerOverride )
118     {
119         m_prefix = prefix;
120         m_switchTo = switchTo;
121
122         m_switch = new LoggerSwitch( null, null );
123         m_logger = m_switch.get();
124
125         m_defaultLoggerOverride = defaultLoggerOverride;
126     }
127
128     /**
129      * Accept the logger we shall use as the initial and the fallback logger.
130      */

131     public void enableLogging( final Logger fallbackLogger )
132     {
133         if ( m_enableLoggingInvoked )
134         {
135             throw new IllegalStateException JavaDoc( "enableLogging() already called" );
136         }
137         m_switch.setFallback( fallbackLogger );
138         m_enableLoggingInvoked = true;
139     }
140
141     /**
142      * Get a logger from ourselves and pass it to <code>m_switch</code>.
143      */

144     public void start()
145     {
146         if ( m_startInvoked )
147         {
148             throw new IllegalStateException JavaDoc( "start() already invoked" );
149         }
150
151         if ( m_switchTo != null )
152         {
153             if ( m_logger.isDebugEnabled() )
154             {
155                 final String JavaDoc message = "LoggerManager: switching logging to " +
156                         "this.getLoggerForCategory('" +
157                         LoggerUtil.getFullCategoryName( m_prefix, m_switchTo) + "').";
158                 m_logger.debug( message );
159             }
160
161             final Logger ourOwn = this.getLoggerForCategory( m_switchTo );
162         
163             if ( ourOwn == null )
164             {
165                 throw new NullPointerException JavaDoc( "ourOwn" );
166             }
167             
168             m_switch.setPreferred( ourOwn );
169
170             if ( m_logger.isDebugEnabled() )
171             {
172                 final String JavaDoc message = "LoggerManager: have switched logging to " +
173                         "this.getLoggerForCategory('" +
174                         LoggerUtil.getFullCategoryName( m_prefix, m_switchTo) + "').";
175                 m_logger.debug( message );
176             }
177         }
178         else
179         {
180             if ( m_logger.isDebugEnabled() )
181             {
182                 final String JavaDoc message = "LoggerManager: switchTo is null, " +
183                         "no switch of our own logging.";
184                 m_logger.debug( message );
185             }
186         }
187         m_startInvoked = true;
188     }
189
190     /** Startable.stop() empty implementation. */
191     public void stop(){}
192
193     /**
194      * Retruns the logger for the <code>""</code> category.
195      */

196     public final Logger getDefaultLogger()
197     {
198         return getLoggerForCategory( null );
199     }
200
201     /**
202      * Actually create a logger wrapping underlying logger
203      * backed implementation for a give category. Bypasses the caching.
204      * Derived LoggerManager implementations should provide an implementation
205      * of this method.
206      */

207     protected abstract Logger doGetLoggerForCategory( final String JavaDoc fullCategoryName );
208
209     /**
210      * Retrieves a Logger from a category name. Usually
211      * the category name refers to a configuration attribute name. If
212      * this LogKitManager does not have the match the default Logger will
213      * be returned and a warning is issued.
214      */

215     public final Logger getLoggerForCategory( final String JavaDoc categoryName )
216     {
217         if ( m_defaultLoggerOverride != null &&
218                 ( categoryName == null || categoryName.length() == 0 ) )
219         {
220             return m_defaultLoggerOverride;
221         }
222
223         final String JavaDoc fullCategoryName =
224                 LoggerUtil.getFullCategoryName( m_prefix, categoryName );
225
226         final Logger logger;
227         final Logger newLogger;
228
229         synchronized( m_loggers )
230         {
231             logger = (Logger)m_loggers.get( fullCategoryName );
232             
233             if ( logger == null )
234             {
235                 newLogger = doGetLoggerForCategory( fullCategoryName );
236                 m_loggers.put( fullCategoryName, newLogger );
237             }
238             else
239             {
240                 /* Let's have no "variable might not have been initialized". */
241                 newLogger = null;
242             }
243         }
244
245         if( null != logger )
246         {
247             if( m_logger.isDebugEnabled() )
248             {
249                 m_logger.debug( "Logger for category " + fullCategoryName + " returned" );
250             }
251             return logger;
252         }
253
254         if( m_logger.isDebugEnabled() )
255         {
256             m_logger.debug( "Logger for category " + fullCategoryName + " not defined in "
257                             + "configuration. New Logger created and returned" );
258         }
259
260         return newLogger;
261     }
262 }
263
Popular Tags