All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.log4j.or.RendererMap Maven / Gradle / Ivy

There is a newer version: 6.1.2
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.or;

import org.apache.log4j.spi.RendererSupport;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.helpers.Loader;
import org.apache.log4j.helpers.OptionConverter;

import java.util.Hashtable;

/**
 * Map class objects to an {@link ObjectRenderer}.
 *
 * @author Ceki Gülcü
 * @since version 1.0
 */
public class RendererMap {

    Hashtable map;

    static ObjectRenderer defaultRenderer = new DefaultRenderer();

    public RendererMap() {
        map = new Hashtable();
    }

    /**
     * Add a renderer to a hierarchy passed as parameter.
     */
    static public void addRenderer(RendererSupport repository, String renderedClassName, String renderingClassName) {
        LogLog.debug("Rendering class: [" + renderingClassName + "], Rendered class: [" + renderedClassName + "].");
        ObjectRenderer renderer = (ObjectRenderer) OptionConverter.instantiateByClassName(renderingClassName,
                ObjectRenderer.class, null);
        if (renderer == null) {
            LogLog.error("Could not instantiate renderer [" + renderingClassName + "].");
            return;
        } else {
            try {
                Class renderedClass = Loader.loadClass(renderedClassName);
                repository.setRenderer(renderedClass, renderer);
            } catch (ClassNotFoundException e) {
                LogLog.error("Could not find class [" + renderedClassName + "].", e);
            }
        }
    }

    /**
     * Find the appropriate renderer for the class type of the o parameter. This is accomplished by calling
     * the {@link #get(Class)} method. Once a renderer is found, it is applied on the object o and the
     * result is returned as a {@link String}.
     */
    public String findAndRender(Object o) {
        if (o == null)
            return null;
        else
            return get(o.getClass()).doRender(o);
    }

    /**
     * Syntactic sugar method that calls {@link #get(Class)} with the class of the object parameter.
     */
    public ObjectRenderer get(Object o) {
        if (o == null)
            return null;
        else
            return get(o.getClass());
    }

    /**
     * Search the parents of clazz for a renderer. The renderer closest in the hierarchy will be returned.
     * If no renderers could be found, then the default renderer is returned.
     *
     * 

* The search first looks for a renderer configured for clazz. If a renderer could not be found, then * the search continues by looking at all the interfaces implemented by clazz including the * super-interfaces of each interface. If a renderer cannot be found, then the search looks for a renderer defined * for the parent (superclass) of clazz. If that fails, then all the interfaces implemented by the * parent of * clazz are searched and so on. * *

* For example, if A0, A1, A2 are classes and X0, X1, X2, Y0, Y1 are interfaces where A2 extends A1 which in turn * extends A0 and similarly X2 extends X1 which extends X0 and Y1 extends Y0. Let us also assume that A1 implements * the Y0 interface and that A2 implements the X2 interface. * *

* The table below shows the results returned by the get(A2.class) method depending on the renderers * added to the map. * *

*

* * * * * * * * *
Added renderersValue returned by get(A2.class)
A0Renderer * A0Renderer * *
A0Renderer, A1Renderer * A1Renderer * *
X0Renderer * X0Renderer * *
A1Renderer, X0Renderer * X0Renderer * *
* *

* This search algorithm is not the most natural, although it is particularly * easy to implement. Future log4j versions may implement a more * intuitive search algorithm. However, the present algorithm should be * acceptable in the vast majority of circumstances. */ public ObjectRenderer get(Class clazz) { // System.out.println("\nget: "+clazz); ObjectRenderer r = null; for (Class c = clazz; c != null; c = c.getSuperclass()) { // System.out.println("Searching for class: "+c); r = (ObjectRenderer) map.get(c); if (r != null) { return r; } r = searchInterfaces(c); if (r != null) return r; } return defaultRenderer; } ObjectRenderer searchInterfaces(Class c) { // System.out.println("Searching interfaces of class: "+c); ObjectRenderer r = (ObjectRenderer) map.get(c); if (r != null) { return r; } else { Class[] ia = c.getInterfaces(); for (int i = 0; i < ia.length; i++) { r = searchInterfaces(ia[i]); if (r != null) return r; } } return null; } public ObjectRenderer getDefaultRenderer() { return defaultRenderer; } public void clear() { map.clear(); } /** * Register an {@link ObjectRenderer} for clazz. */ public void put(Class clazz, ObjectRenderer or) { map.put(clazz, or); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy