View Javadoc

1   // 
2   // Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J. 
3   // All rights reserved. 
4   // 
5   // Redistribution and use in source and binary forms, with or without modification,  
6   // are permitted provided that the following conditions are met: 
7   // 
8   // * Redistributions of source code must retain the above copyright notice,  
9   //       this list of conditions and the following disclaimer. 
10  // * Redistributions in binary form must reproduce the above copyright notice,  
11  //       this list of conditions and the following disclaimer in the documentation  
12  //       and/or other materials provided with the distribution. 
13  // * Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.  
14  //       nor the names of its contributors may be used to endorse or promote products  
15  //       derived from this software without specific prior written permission. 
16  // 
17  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  
18  // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED  
19  // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
20  // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,  
21  // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  
22  // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
23  // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
24  // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)  
25  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  
26  // POSSIBILITY OF SUCH DAMAGE. 
27  // 
28  
29  package org.objectledge.logging;
30  
31  import org.jcontainer.dna.Logger;
32  import org.objectledge.pico.customization.CustomizedComponentProvider;
33  import org.objectledge.pico.customization.UnsupportedKeyTypeException;
34  import org.picocontainer.MutablePicoContainer;
35  import org.picocontainer.PicoContainer;
36  import org.picocontainer.PicoInitializationException;
37  import org.picocontainer.PicoIntrospectionException;
38  import org.picocontainer.PicoVerificationException;
39  import org.picocontainer.defaults.DefaultPicoContainer;
40  
41  /***
42   * Provides Logger objects to the components being initialized using Log4J.
43   * 
44   * <p>
45   * Logger factory plugs into the container using 
46   * {@link org.objectledge.pico.customization component customization} mechanism,
47   * and provides components that declare a dependency on a DNA Logger (using a
48   * <code>org.jcontainer.dna.Logger</code> component parameter) with an initialized
49   * and ready to go logger instance.
50   * </p>
51   * 
52   * <p>
53   * The default implementation creates Log4j loggers, but it can be easily extended to work
54   * with any other type of logger compatible with DNA.
55   * </p>
56   * 
57   * <p>
58   * The <code>LoggerFactory</code> component has the ability to transparently replace
59   * the logger used by a component with another logger.
60   * (This is done using Pico's <code>ImplementationHidingComponentAdapter</code>).
61   * This might be useful for run-time administraiton, especially in case of Logger
62   * objects that are immutable.
63   * </p>
64   *
65   * @author <a href="Rafal.Krzewski">rafal@caltha.pl</a>
66   * @version $Id: LoggerFactory.java,v 1.18 2005/10/09 19:12:04 rafal Exp $
67   */
68  public class LoggerFactory
69      implements CustomizedComponentProvider
70  {
71      private final LoggingConfigurator loggingConfigurator;
72      
73      private final MutablePicoContainer loggerContainer;
74  
75      /***
76       * Creates a new instance of Factory and installs apropriate component adapter.
77       * 
78       * <p>We depend LoggingConfigurator to make sure that logging is configured before we create any
79       * logs.</p>
80       * 
81       * @param loggingConfigurator the LoggingConfigurator.
82       */
83      public LoggerFactory(LoggingConfigurator loggingConfigurator)
84      {
85          this.loggingConfigurator = loggingConfigurator;
86          this.loggerContainer = new DefaultPicoContainer();
87      }
88  
89      /***
90       * Returns a logger for the specified component.
91       *
92       * @param key the component key.
93       * @return the logger.
94       */
95      public Logger getLogger(Object key)
96      {
97          String marker = getComponentMarker(key);
98          if(loggerContainer.getComponentInstance(marker) == null)
99          {
100             Logger logger = loggingConfigurator.createLogger(marker);
101             loggerContainer.registerComponentInstance(marker, logger);
102         }
103         return (Logger)loggerContainer.getComponentInstance(marker);
104     }
105     
106     /***
107      * Sets the logger for the specified component.
108      * 
109      * @param key the component key.
110      * @param logger the logger.
111      */
112     public void setLogger(Object key, Logger logger)
113     {
114         String marker = getComponentMarker(key);
115         if(loggerContainer.getComponentInstance(marker) != null)
116         {
117             loggerContainer.registerComponentInstance(marker, logger);
118         }
119         else
120         {   
121             // Swappable proxy = (Swappable)loggerContainer.getComponentInstance(marker);
122             // proxy.hotswap(logger);             
123         }
124     }
125 
126     // CustomizedComponentProvider interface ////////////////////////////////////////////////////
127 
128     /***
129      * {@inheritDoc}
130      */
131     public Object getCustomizedComponentInstance(PicoContainer container, 
132         Object componentKey, Class componentImplementaion)
133         throws PicoInitializationException, PicoIntrospectionException, UnsupportedKeyTypeException
134     {
135         return getLogger(getComponentMarker(componentKey));
136     }
137 
138     /***
139      * {@inheritDoc}
140      */
141     public Class getCustomizedComponentImplementation()
142     {
143         return Logger.class;
144     }
145 
146     /***
147      * {@inheritDoc}
148      */
149     public void verify(PicoContainer container) throws PicoVerificationException
150     {
151         // no dependencies
152     }
153     
154     // implementation ///////////////////////////////////////////////////////////////////////////
155 
156     /***
157      * Returns a marker for the component (used as key in the logger container).
158      * 
159      * @param key reqesting component key.
160      * @return key for the logger.
161      */
162     protected String getComponentMarker(Object key)
163     {
164         if(key instanceof Class)
165         {
166             return ((Class)key).getName();
167         }
168         else
169         {
170             return key.toString();
171         }
172     }
173 }