1 // 2 // Copyright (c) ZeroC, Inc. All rights reserved. 3 // 4 5 namespace Ice 6 { 7 using System.Collections.Generic; 8 using System.Threading; 9 10 // 11 // The base class for all ImplicitContext implementations 12 // 13 public abstract class ImplicitContextI : ImplicitContext 14 { create(string kind)15 public static ImplicitContextI create(string kind) 16 { 17 if(kind.Equals("None") || kind.Length == 0) 18 { 19 return null; 20 } 21 else if(kind.Equals("Shared")) 22 { 23 return new SharedImplicitContext(); 24 } 25 else if(kind.Equals("PerThread")) 26 { 27 return new PerThreadImplicitContext(); 28 } 29 else 30 { 31 throw new InitializationException("'" + kind + "' is not a valid value for Ice.ImplicitContext"); 32 } 33 } 34 getContext()35 public abstract Dictionary<string, string> getContext(); setContext(Dictionary<string, string> newContext)36 public abstract void setContext(Dictionary<string, string> newContext); containsKey(string key)37 public abstract bool containsKey(string key); get(string key)38 public abstract string get(string key); put(string key, string value)39 public abstract string put(string key, string value); remove(string key)40 public abstract string remove(string key); 41 write(Dictionary<string, string> prxContext, OutputStream os)42 abstract public void write(Dictionary<string, string> prxContext, OutputStream os); combine(Dictionary<string, string> prxContext)43 abstract internal Dictionary<string, string> combine(Dictionary<string, string> prxContext); 44 } 45 46 internal class SharedImplicitContext : ImplicitContextI 47 { getContext()48 public override Dictionary<string, string> getContext() 49 { 50 lock(this) 51 { 52 return new Dictionary<string, string>(_context); 53 } 54 } 55 setContext(Dictionary<string, string> context)56 public override void setContext(Dictionary<string, string> context) 57 { 58 lock(this) 59 { 60 if(context != null && context.Count != 0) 61 { 62 _context = new Dictionary<string, string>(context); 63 } 64 else 65 { 66 _context.Clear(); 67 } 68 } 69 } 70 containsKey(string key)71 public override bool containsKey(string key) 72 { 73 lock(this) 74 { 75 if(key == null) 76 { 77 key = ""; 78 } 79 80 return _context.ContainsKey(key); 81 } 82 } 83 get(string key)84 public override string get(string key) 85 { 86 lock(this) 87 { 88 if(key == null) 89 { 90 key = ""; 91 } 92 93 string val = _context[key]; 94 if(val == null) 95 { 96 val = ""; 97 } 98 return val; 99 } 100 } 101 put(string key, string value)102 public override string put(string key, string value) 103 { 104 lock(this) 105 { 106 if(key == null) 107 { 108 key = ""; 109 } 110 if(value == null) 111 { 112 value = ""; 113 } 114 115 string oldVal; 116 _context.TryGetValue(key, out oldVal); 117 if(oldVal == null) 118 { 119 oldVal = ""; 120 } 121 _context[key] = value; 122 123 return oldVal; 124 } 125 } 126 remove(string key)127 public override string remove(string key) 128 { 129 lock(this) 130 { 131 if(key == null) 132 { 133 key = ""; 134 } 135 136 string val = _context[key]; 137 138 if(val == null) 139 { 140 val = ""; 141 } 142 else 143 { 144 _context.Remove(key); 145 } 146 147 return val; 148 } 149 } 150 write(Dictionary<string, string> prxContext, OutputStream os)151 public override void write(Dictionary<string, string> prxContext, OutputStream os) 152 { 153 if(prxContext.Count == 0) 154 { 155 lock(this) 156 { 157 ContextHelper.write(os, _context); 158 } 159 } 160 else 161 { 162 Dictionary<string, string> ctx = null; 163 lock(this) 164 { 165 ctx = _context.Count == 0 ? prxContext : combine(prxContext); 166 } 167 ContextHelper.write(os, ctx); 168 } 169 } 170 combine(Dictionary<string, string> prxContext)171 internal override Dictionary<string, string> combine(Dictionary<string, string> prxContext) 172 { 173 lock(this) 174 { 175 Dictionary<string, string> combined = new Dictionary<string, string>(prxContext); 176 foreach(KeyValuePair<string, string> e in _context) 177 { 178 try 179 { 180 combined.Add(e.Key, e.Value); 181 } 182 catch(System.ArgumentException) 183 { 184 // Ignore. 185 } 186 } 187 return combined; 188 } 189 } 190 191 private Dictionary<string, string> _context = new Dictionary<string, string>(); 192 } 193 194 internal class PerThreadImplicitContext : ImplicitContextI 195 { getContext()196 public override Dictionary<string, string> getContext() 197 { 198 Dictionary<string, string> threadContext = null; 199 Thread currentThread = Thread.CurrentThread; 200 lock(this) 201 { 202 if(_map.ContainsKey(currentThread)) 203 { 204 threadContext = _map[currentThread]; 205 } 206 } 207 208 if(threadContext == null) 209 { 210 threadContext = new Dictionary<string, string>(); 211 } 212 return threadContext; 213 } 214 setContext(Dictionary<string, string> context)215 public override void setContext(Dictionary<string, string> context) 216 { 217 if(context == null || context.Count == 0) 218 { 219 lock(this) 220 { 221 _map.Remove(Thread.CurrentThread); 222 } 223 } 224 else 225 { 226 Dictionary<string, string> threadContext = new Dictionary<string, string>(context); 227 228 lock(this) 229 { 230 _map.Add(Thread.CurrentThread, threadContext); 231 } 232 } 233 } 234 containsKey(string key)235 public override bool containsKey(string key) 236 { 237 if(key == null) 238 { 239 key = ""; 240 } 241 242 Dictionary<string, string> threadContext = null; 243 lock(this) 244 { 245 if(!_map.TryGetValue(Thread.CurrentThread, out threadContext)) 246 { 247 return false; 248 } 249 } 250 251 return threadContext.ContainsKey(key); 252 } 253 get(string key)254 public override string get(string key) 255 { 256 if(key == null) 257 { 258 key = ""; 259 } 260 261 Dictionary<string, string> threadContext = null; 262 lock(this) 263 { 264 if(!_map.TryGetValue(Thread.CurrentThread, out threadContext)) 265 { 266 return ""; 267 } 268 } 269 270 string val = threadContext[key]; 271 if(val == null) 272 { 273 val = ""; 274 } 275 return val; 276 } 277 put(string key, string value)278 public override string put(string key, string value) 279 { 280 if(key == null) 281 { 282 key = ""; 283 } 284 if(value == null) 285 { 286 value = ""; 287 } 288 289 Dictionary<string, string> threadContext = null; 290 lock(this) 291 { 292 if(!_map.TryGetValue(Thread.CurrentThread, out threadContext)) 293 { 294 threadContext = new Dictionary<string, string>(); 295 _map.Add(Thread.CurrentThread, threadContext); 296 } 297 } 298 299 string oldVal; 300 if(!threadContext.TryGetValue(key, out oldVal)) 301 { 302 oldVal = ""; 303 } 304 305 threadContext[key] = value; 306 return oldVal; 307 } 308 remove(string key)309 public override string remove(string key) 310 { 311 if(key == null) 312 { 313 key = ""; 314 } 315 316 Dictionary<string, string> threadContext = null; 317 lock(this) 318 { 319 if(!_map.TryGetValue(Thread.CurrentThread, out threadContext)) 320 { 321 return ""; 322 } 323 } 324 325 string val = null; 326 if(!threadContext.TryGetValue(key, out val)) 327 { 328 val = ""; 329 } 330 else 331 { 332 threadContext.Remove(key); 333 } 334 return val; 335 } 336 write(Dictionary<string, string> prxContext, OutputStream os)337 public override void write(Dictionary<string, string> prxContext, OutputStream os) 338 { 339 Dictionary<string, string> threadContext = null; 340 lock(this) 341 { 342 _map.TryGetValue(Thread.CurrentThread, out threadContext); 343 } 344 345 if(threadContext == null || threadContext.Count == 0) 346 { 347 ContextHelper.write(os, prxContext); 348 } 349 else if(prxContext.Count == 0) 350 { 351 ContextHelper.write(os, threadContext); 352 } 353 else 354 { 355 Dictionary<string, string> combined = new Dictionary<string, string>(prxContext); 356 foreach(KeyValuePair<string, string> e in threadContext) 357 { 358 try 359 { 360 combined.Add(e.Key, e.Value); 361 } 362 catch(System.ArgumentException) 363 { 364 // Ignore. 365 } 366 } 367 ContextHelper.write(os, combined); 368 } 369 } 370 combine(Dictionary<string, string> prxContext)371 internal override Dictionary<string, string> combine(Dictionary<string, string> prxContext) 372 { 373 Dictionary<string, string> threadContext = null; 374 lock(this) 375 { 376 if(!_map.TryGetValue(Thread.CurrentThread, out threadContext)) 377 { 378 return new Dictionary<string, string>(prxContext); 379 } 380 } 381 382 Dictionary<string, string> combined = new Dictionary<string, string>(prxContext); 383 foreach(KeyValuePair<string, string> e in threadContext) 384 { 385 combined.Add(e.Key, e.Value); 386 } 387 return combined; 388 } 389 390 // 391 // map Thread -> Context 392 // 393 private Dictionary<Thread, Dictionary<string, string> > _map = 394 new Dictionary<Thread, Dictionary<string, string> >(); 395 } 396 } 397