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: 1.0.0-beta2
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 java.util.Hashtable;

import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.spi.RendererSupport;
import org.apache.logging.log4j.core.util.Loader;
import org.apache.logging.log4j.status.StatusLogger;

/**
 * Map class objects to an {@link ObjectRenderer}.
 * 
 * @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) {
        StatusLogger.getLogger().debug("Rendering class: [" + renderingClassName + "], Rendered class: [" + renderedClassName + "].");
        ObjectRenderer renderer = (ObjectRenderer) OptionConverter.instantiateByClassName(renderingClassName, ObjectRenderer.class, null);
        if (renderer == null) {
            StatusLogger.getLogger().error("Could not instantiate renderer [" + renderingClassName + "].");
            return;
        }
        try {
            Class renderedClass = Loader.loadClass(renderedClassName);
            repository.setRenderer(renderedClass, renderer);
        } catch (ClassNotFoundException e) {
            StatusLogger.getLogger().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; } 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