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.logging.log4j.spi; 018 019 import java.util.HashMap; 020 import java.util.Map; 021 022 /** 023 * 024 */ 025 public class DefaultThreadContextMap implements ThreadContextMap { 026 027 private final boolean useMap; 028 029 private final ThreadLocal<Map<String, String>> localMap = 030 new InheritableThreadLocal<Map<String, String>>() { 031 @Override 032 protected Map<String, String> childValue(final Map<String, String> parentValue) { 033 return parentValue == null || !useMap ? null : new HashMap<String, String>(parentValue); 034 } 035 }; 036 037 public DefaultThreadContextMap(final boolean useMap) { 038 this.useMap = useMap; 039 } 040 041 /** 042 * Put a context value (the <code>o</code> parameter) as identified 043 * with the <code>key</code> parameter into the current thread's 044 * context map. 045 * <p/> 046 * <p>If the current thread does not have a context map it is 047 * created as a side effect. 048 * @param key The key name. 049 * @param value The key value. 050 */ 051 public void put(final String key, final String value) { 052 if (!useMap) { 053 return; 054 } 055 Map<String, String> map = localMap.get(); 056 if (map == null) { 057 map = new HashMap<String, String>(); 058 localMap.set(map); 059 } 060 map.put(key, value); 061 } 062 063 /** 064 * Get the context identified by the <code>key</code> parameter. 065 * <p/> 066 * <p>This method has no side effects. 067 * @param key The key to locate. 068 * @return The value associated with the key or null. 069 */ 070 public String get(final String key) { 071 final Map<String, String> map = localMap.get(); 072 return map == null ? null : map.get(key); 073 } 074 075 /** 076 * Remove the the context identified by the <code>key</code> 077 * parameter. 078 * @param key The key to remove. 079 */ 080 public void remove(final String key) { 081 final Map<String, String> map = localMap.get(); 082 if (map != null) { 083 map.remove(key); 084 } 085 } 086 087 /** 088 * Clear the context. 089 */ 090 public void clear() { 091 localMap.remove(); 092 } 093 094 /** 095 * Determine if the key is in the context. 096 * @param key The key to locate. 097 * @return True if the key is in the context, false otherwise. 098 */ 099 public boolean containsKey(final String key) { 100 final Map<String, String> map = localMap.get(); 101 return map == null ? false : map.containsKey(key); 102 } 103 104 /** 105 * Get a copy of current thread's context Map. 106 * @return a copy of the context. 107 */ 108 public Map<String, String> getContext() { 109 final Map<String, String> map = localMap.get(); 110 return map == null ? new HashMap<String, String>() : new HashMap<String, String>(map); 111 } 112 113 /** 114 * Return the context Map. 115 * @return the Context Map. 116 */ 117 public Map<String, String> get() { 118 return localMap.get(); 119 } 120 121 /** 122 * Returns true if the Map is empty. 123 * @return true if the Map is empty, false otherwise. 124 */ 125 public boolean isEmpty() { 126 final Map<String, String> map = localMap.get(); 127 return map == null || map.size() == 0; 128 } 129 }