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.2.25
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