View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.log4j;
19  
20  import java.util.Hashtable;
21  import org.apache.log4j.helpers.Loader;
22  import org.apache.log4j.helpers.ThreadLocalMap;
23  
24  /***
25     The MDC class is similar to the {@link NDC} class except that it is
26     based on a map instead of a stack. It provides <em>mapped
27     diagnostic contexts</em>. A <em>Mapped Diagnostic Context</em>, or
28     MDC in short, is an instrument for distinguishing interleaved log
29     output from different sources. Log output is typically interleaved
30     when a server handles multiple clients near-simultaneously.
31  
32     <p><b><em>The MDC is managed on a per thread basis</em></b>. A
33     child thread automatically inherits a <em>copy</em> of the mapped
34     diagnostic context of its parent.
35    
36     <p>The MDC class requires JDK 1.2 or above. Under JDK 1.1 the MDC
37     will always return empty values but otherwise will not affect or
38     harm your application.
39     
40     @since 1.2
41  
42     @author Ceki G&uuml;lc&uuml; */
43  public class MDC {
44    
45    final static MDC mdc = new MDC();
46    
47    static final int HT_SIZE = 7;
48  
49    boolean java1;
50    
51    Object tlm;
52    
53    private
54    MDC() {
55      java1 = Loader.isJava1();
56      if(!java1) {
57        tlm = new ThreadLocalMap();
58      }
59    }
60  
61    /***
62       Put a context value (the <code>o</code> parameter) as identified
63       with the <code>key</code> parameter into the current thread's
64       context map.
65  
66       <p>If the current thread does not have a context map it is
67       created as a side effect.
68      
69     */
70    static
71    public
72    void put(String key, Object o) {
73       if (mdc != null) {
74           mdc.put0(key, o);
75       }
76    }
77    
78    /***
79       Get the context identified by the <code>key</code> parameter.
80  
81       <p>This method has no side effects.
82     */
83    static 
84    public
85    Object get(String key) {
86      if (mdc != null) {
87          return mdc.get0(key);
88      }
89      return null;
90    }
91  
92    /***
93       Remove the the context identified by the <code>key</code>
94       parameter.
95  
96    */
97    static 
98    public
99    void remove(String key) {
100     if (mdc != null) {
101         mdc.remove0(key);
102     }
103   }
104 
105 
106   /***
107    * Get the current thread's MDC as a hashtable. This method is
108    * intended to be used internally.  
109    * */
110   public static Hashtable getContext() {
111     if (mdc != null) {
112         return mdc.getContext0();
113     } else {
114         return null;
115     }
116   }
117 
118 
119   private
120   void put0(String key, Object o) {
121     if(java1 || tlm == null) {
122       return;
123     } else {
124       Hashtable ht = (Hashtable) ((ThreadLocalMap)tlm).get();
125       if(ht == null) {
126         ht = new Hashtable(HT_SIZE);
127         ((ThreadLocalMap)tlm).set(ht);
128       }    
129       ht.put(key, o);
130     }
131   }
132   
133   private
134   Object get0(String key) {
135     if(java1 || tlm == null) {
136       return null;
137     } else {       
138       Hashtable ht = (Hashtable) ((ThreadLocalMap)tlm).get();
139       if(ht != null && key != null) {
140         return ht.get(key);
141       } else {
142         return null;
143       }
144     }
145   }
146 
147   private
148   void remove0(String key) {
149     if(!java1 && tlm != null) {
150       Hashtable ht = (Hashtable) ((ThreadLocalMap)tlm).get();
151       if(ht != null) {
152         ht.remove(key);
153       } 
154     }
155   }
156 
157 
158   private
159   Hashtable getContext0() {
160      if(java1 || tlm == null) {
161       return null;
162     } else {       
163       return (Hashtable) ((ThreadLocalMap)tlm).get();
164     }
165   }
166 }