KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > log4j > or > RendererMap


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

16
17 package org.apache.log4j.or;
18
19 import org.apache.log4j.spi.RendererSupport;
20 import org.apache.log4j.helpers.LogLog;
21 import org.apache.log4j.helpers.Loader;
22 import org.apache.log4j.helpers.OptionConverter;
23 import java.util.Hashtable JavaDoc;
24
25 /**
26    Map class objects to an {@link ObjectRenderer}.
27
28    @author Ceki Gülcü
29    @since version 1.0 */

30 public class RendererMap {
31
32   Hashtable JavaDoc map;
33
34   static ObjectRenderer defaultRenderer = new DefaultRenderer();
35
36   public
37   RendererMap() {
38     map = new Hashtable JavaDoc();
39   }
40
41   /**
42      Add a renderer to a hierarchy passed as parameter.
43   */

44   static
45   public
46   void addRenderer(RendererSupport repository, String JavaDoc renderedClassName,
47            String JavaDoc renderingClassName) {
48     LogLog.debug("Rendering class: ["+renderingClassName+"], Rendered class: ["+
49          renderedClassName+"].");
50     ObjectRenderer renderer = (ObjectRenderer)
51              OptionConverter.instantiateByClassName(renderingClassName,
52                             ObjectRenderer.class,
53                             null);
54     if(renderer == null) {
55       LogLog.error("Could not instantiate renderer ["+renderingClassName+"].");
56       return;
57     } else {
58       try {
59     Class JavaDoc renderedClass = Loader.loadClass(renderedClassName);
60     repository.setRenderer(renderedClass, renderer);
61       } catch(ClassNotFoundException JavaDoc e) {
62     LogLog.error("Could not find class ["+renderedClassName+"].", e);
63       }
64     }
65   }
66
67
68   /**
69      Find the appropriate renderer for the class type of the
70      <code>o</code> parameter. This is accomplished by calling the
71      {@link #get(Class)} method. Once a renderer is found, it is
72      applied on the object <code>o</code> and the result is returned
73      as a {@link String}. */

74   public
75   String JavaDoc findAndRender(Object JavaDoc o) {
76     if(o == null)
77       return null;
78     else
79       return get(o.getClass()).doRender(o);
80   }
81
82
83   /**
84      Syntactic sugar method that calls {@link #get(Class)} with the
85      class of the object parameter. */

86   public
87   ObjectRenderer get(Object JavaDoc o) {
88     if(o == null)
89       return null;
90     else
91       return get(o.getClass());
92   }
93
94
95   /**
96      Search the parents of <code>clazz</code> for a renderer. The
97      renderer closest in the hierarchy will be returned. If no
98      renderers could be found, then the default renderer is returned.
99
100      <p>The search first looks for a renderer configured for
101      <code>clazz</code>. If a renderer could not be found, then the
102      search continues by looking at all the interfaces implemented by
103      <code>clazz</code> including the super-interfaces of each
104      interface. If a renderer cannot be found, then the search looks
105      for a renderer defined for the parent (superclass) of
106      <code>clazz</code>. If that fails, then all the interfaces
107      implemented by the parent of <code>clazz</code> are searched and
108      so on.
109
110      <p>For example, if A0, A1, A2 are classes and X0, X1, X2, Y0, Y1
111      are interfaces where A2 extends A1 which in turn extends A0 and
112      similarly X2 extends X1 which extends X0 and Y1 extends Y0. Let
113      us also assume that A1 implements the Y0 interface and that A2
114      implements the X2 interface.
115
116      <p>The table below shows the results returned by the
117      <code>get(A2.class)</code> method depending on the renderers
118      added to the map.
119
120      <p><table border="1">
121      <tr><th>Added renderers</th><th>Value returned by <code>get(A2.class)</code></th>
122
123      <tr><td><code>A0Renderer</code>
124          <td align="center"><code>A0Renderer</code>
125
126      <tr><td><code>A0Renderer, A1Renderer</code>
127          <td align="center"><code>A1Renderer</code>
128
129      <tr><td><code>X0Renderer</code>
130          <td align="center"><code>X0Renderer</code>
131
132      <tr><td><code>A1Renderer, X0Renderer</code>
133          <td align="center"><code>X0Renderer</code>
134
135      </table>
136
137      <p>This search algorithm is not the most natural, although it is
138      particularly easy to implement. Future log4j versions
139      <em>may</em> implement a more intuitive search
140      algorithm. However, the present algorithm should be acceptable in
141      the vast majority of circumstances.
142
143  */

144   public
145   ObjectRenderer get(Class JavaDoc clazz) {
146     //System.out.println("\nget: "+clazz);
147
ObjectRenderer r = null;
148     for(Class JavaDoc c = clazz; c != null; c = c.getSuperclass()) {
149       //System.out.println("Searching for class: "+c);
150
r = (ObjectRenderer) map.get(c);
151       if(r != null) {
152     return r;
153       }
154       r = searchInterfaces(c);
155       if(r != null)
156     return r;
157     }
158     return defaultRenderer;
159   }
160
161   ObjectRenderer searchInterfaces(Class JavaDoc c) {
162     //System.out.println("Searching interfaces of class: "+c);
163

164     ObjectRenderer r = (ObjectRenderer) map.get(c);
165     if(r != null) {
166       return r;
167     } else {
168       Class JavaDoc[] ia = c.getInterfaces();
169       for(int i = 0; i < ia.length; i++) {
170     r = searchInterfaces(ia[i]);
171     if(r != null)
172       return r;
173       }
174     }
175     return null;
176   }
177
178
179   public
180   ObjectRenderer getDefaultRenderer() {
181     return defaultRenderer;
182   }
183
184
185   public
186   void clear() {
187     map.clear();
188   }
189
190   /**
191      Register an {@link ObjectRenderer} for <code>clazz</code>.
192   */

193   public
194   void put(Class JavaDoc clazz, ObjectRenderer or) {
195     map.put(clazz, or);
196   }
197 }
198
Popular Tags