Package org.apache.log4j.selector

Source Code of org.apache.log4j.selector.ContextJNDISelector

/*
* Copyright 1999,2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.log4j.selector;

import org.apache.log4j.Hierarchy;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.helpers.Constants;
import org.apache.log4j.helpers.IntializationUtil;
import org.apache.log4j.helpers.JNDIUtil;

import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.RepositorySelector;
import org.apache.log4j.spi.RootLogger;


import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.naming.Context;
import javax.naming.NamingException;


/**
* Log4j JNDI based Repository selector
*
* <p>based primarily on Ceki G&uuml;lc&uuml;'s article <h3>Supporting the Log4j
* <code>RepositorySelector</code> in Servlet Containers</h3> at:
* http://qos.ch/logging/sc.html</p>
*
* <p>By default, the class static <code>RepositorySelector</code> variable
* of the <code>LogManager</code> class is set to a trivial
* <code>{@link org.apache.log4j.spi.RepositorySelector RepositorySelector}</code>
* implementation which always returns the same logger repository. a.k.a.
* hierarchy. In other words, by default log4j will use one hierarchy, the
* default hierarchy. This behavior can be overridden via
* the <code>LogManager</code>'s
* <code>setRepositorySelector(RepositorySelector, Object)</code> method.</p>
*
* <p>That is where this class enters the picture.  It can be used to define a
* custom logger repository.  It makes use of the fact that in J2EE
* environments, each web-application is guaranteed to have its own JNDI
* context relative to the <code>java:comp/env</code> context. In EJBs, each
* enterprise bean (albeit not each application) has its own context relative
* to the <code>java:comp/env</code> context.  An <code>env-entry</code> in a
* deployment descriptor provides the information to the JNDI context.  Once the
* <code>env-entry</code> is set, a repository selector can query the JNDI
* application context to look up the value of the entry. The logging context of
* the web-application will depend on the value the env-entry.  The JNDI context
*  which is looked up by this class is
* <code>java:comp/env/log4j/context-name</code>.
*
* <p>Here is an example of an <code>env-entry<code>:
* <blockquote>
* <pre>
* &lt;env-entry&gt;
*   &lt;description&gt;JNDI logging context name for this app&lt;/description&gt;
*   &lt;env-entry-name&gt;log4j/context-name&lt;/env-entry-name&gt;
*   &lt;env-entry-value&gt;aDistinctiveLoggingContextName&lt;/env-entry-value&gt;
*   &lt;env-entry-type&gt;java.lang.String&lt;/env-entry-type&gt;
* &lt;/env-entry&gt;
* </pre>
* </blockquote>
* </p>
*
* <p><em>If multiple applications use the same logging context name, then they
* will share the same logging context.</em>
* </p>
*
*<p>You can also specify the URL for this context's configuration resource.
* This repository selector (ContextJNDISelector) will use this resource
* to automatically configure the log4j repository.
*</p>
** <blockquote>
* <pre>
* &lt;env-entry&gt;
*   &lt;description&gt;URL for configuring log4j context&lt;/description&gt;
*   &lt;env-entry-name&gt;log4j/configuration-resource&lt;/env-entry-name&gt;
*   &lt;env-entry-value&gt;urlOfConfigrationResource&lt;/env-entry-value&gt;
*   &lt;env-entry-type&gt;java.lang.String&lt;/env-entry-type&gt;
* &lt;/env-entry&gt;
* </pre>
* </blockquote>
*
* <p>It usually good practice for configuration resources of distinct
* applications to have distinct names. However, if this is not possible
* Naming
*
* <p>Note that in case no configuration resource is specified, then there will
* be <b>NO</b> attempt to search for the <em>default</em> configuration files
* <em>log4j.xml</em> and <em>log4j.properties</em>. This voluntary omission
* ensures that the configuration file for your application's logger repository
* will not be confused with the default configuration file for the default
* logger repository.
* </p>
*
* <p>Given that JNDI is part of the J2EE specification, the JNDI selector
* is the recommended context selector.
* </p>
*
* @author <a href="mailto:hoju@visi.com">Jacob Kjome</a>
* @author Ceki G&uuml;lc&uuml;
* @since  1.3
*/
public class ContextJNDISelector implements RepositorySelector {

  static String JNDI_CONFIGURATION_RESOURCE =
    "java:comp/env/log4j/configuration-resource";
  static String JNDI_CONFIGURATOR_CLASS =
    "java:comp/env/log4j/configurator-class";

  /**
   * key: name of logging context,
   * value: Hierarchy instance
   */
  private final Map hierMap;

  /**
   * public no-args constructor
   */
  public ContextJNDISelector() {
    hierMap = Collections.synchronizedMap(new HashMap());
  }

  /**
   * Return the repoistory selector based on the current JNDI environment.
   *
   * If the respository is retreived for the first time, then also configure
   * the repository using a user specified resource.
   *
   * @return the appropriate JNDI-keyed context name/LoggerRepository
   */
  public LoggerRepository getLoggerRepository() {
    String loggingContextName = null;
    Context ctx = null;

    try {
      ctx = JNDIUtil.getInitialContext();
      loggingContextName = (String) JNDIUtil.lookup(ctx, Constants.JNDI_CONTEXT_NAME);
    } catch (NamingException ne) {
      // we can't log here
    }

    if (loggingContextName == null || Constants.DEFAULT_REPOSITORY_NAME.equals(loggingContextName)) {
      return LogManager.defaultLoggerRepository;
    } else {
      //System.out.println("loggingContextName is ["+loggingContextName+"]");
      Hierarchy hierarchy = (Hierarchy) hierMap.get(loggingContextName);

      if (hierarchy == null) {
        // create new hierarchy
        hierarchy = new Hierarchy(new RootLogger(Level.DEBUG));
        hierarchy.setName(loggingContextName);
        hierMap.put(loggingContextName, hierarchy);

        // configure log4j internal logging
        IntializationUtil.log4jInternalConfiguration(hierarchy);

        // Check if Mrs. Piggy gave us explicit configration directives
        // regarding this directory.
        String configResourceStr = JNDIUtil.lookup(ctx, JNDI_CONFIGURATION_RESOURCE);
       
        // For non-default repositories we do not try to search for default
        // config files such as log4j.xml or log4j.properties because
        // we have no deterministic way of finding the right one
        if(configResourceStr != null) {
          String configuratorClassName = JNDIUtil.lookup(ctx, JNDI_CONFIGURATOR_CLASS);
          IntializationUtil.initialConfiguration(
           hierarchy, configResourceStr, configuratorClassName);
        }
      }

      return hierarchy;
    }
  }

  /**
   * Get the logger repository with the corresponding name.
   *
   * <p>Returned value can be null if the selector is unaware of the repository
   * with the given name.
   */
  public LoggerRepository getLoggerRepository(String name) {
    if(Constants.DEFAULT_REPOSITORY_NAME.equals(name)) {
      return LogManager.defaultLoggerRepository;
    } else {
      return (LoggerRepository) hierMap.get(name)
    }
  }
  /**
   * Remove the repository with the given name from the list of known
   * repositories.
   *
   * @return the detached repository
   */
  public LoggerRepository detachRepository(String contextName) {
    return (LoggerRepository) hierMap.remove(contextName)
  }
}
TOP

Related Classes of org.apache.log4j.selector.ContextJNDISelector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.