001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements. See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache license, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License. You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the license for the specific language governing permissions and
015     * limitations under the license.
016     */
017    package org.apache.log4j;
018    
019    import java.util.HashMap;
020    import java.util.Hashtable;
021    import java.util.Map;
022    
023    import org.apache.logging.log4j.ThreadContext;
024    
025    /**
026     * This class behaves just like Log4j's MDC would - and so can cause issues with the redeployment of web
027     * applications if the Objects stored in the threads Map cannot be garbage collected.
028     */
029    public final class MDC {
030    
031    
032        private static ThreadLocal<Map<String, Object>> localMap =
033            new InheritableThreadLocal<Map<String, Object>>() {
034                @Override
035                protected Map<String, Object> initialValue() {
036                    return new HashMap<String, Object>();
037                }
038    
039                @Override
040                protected Map<String, Object> childValue(final Map<String, Object> parentValue) {
041                    return parentValue == null ? new HashMap<String, Object>() : new HashMap<String, Object>(parentValue);
042                }
043            };
044    
045        private MDC() {
046        }
047    
048    
049        public static void put(final String key, final String value) {
050            localMap.get().put(key, value);
051            ThreadContext.put(key, value);
052        }
053    
054    
055        public static void put(final String key, final Object value) {
056            localMap.get().put(key, value);
057            ThreadContext.put(key, value.toString());
058        }
059    
060        public static Object get(final String key) {
061            return localMap.get().get(key);
062        }
063    
064        public static void remove(final String key) {
065            localMap.get().remove(key);
066            ThreadContext.remove(key);
067        }
068    
069        public static void clear() {
070            localMap.get().clear();
071            ThreadContext.clearMap();
072        }
073    
074        public static Hashtable<String, Object> getContext() {
075            return new Hashtable<String, Object>(localMap.get());
076        }
077    }