// // Copyright (c) ZeroC, Inc. All rights reserved. // namespace Ice { using System.Collections.Generic; using System.Threading; // // The base class for all ImplicitContext implementations // public abstract class ImplicitContextI : ImplicitContext { public static ImplicitContextI create(string kind) { if(kind.Equals("None") || kind.Length == 0) { return null; } else if(kind.Equals("Shared")) { return new SharedImplicitContext(); } else if(kind.Equals("PerThread")) { return new PerThreadImplicitContext(); } else { throw new InitializationException("'" + kind + "' is not a valid value for Ice.ImplicitContext"); } } public abstract Dictionary getContext(); public abstract void setContext(Dictionary newContext); public abstract bool containsKey(string key); public abstract string get(string key); public abstract string put(string key, string value); public abstract string remove(string key); abstract public void write(Dictionary prxContext, OutputStream os); abstract internal Dictionary combine(Dictionary prxContext); } internal class SharedImplicitContext : ImplicitContextI { public override Dictionary getContext() { lock(this) { return new Dictionary(_context); } } public override void setContext(Dictionary context) { lock(this) { if(context != null && context.Count != 0) { _context = new Dictionary(context); } else { _context.Clear(); } } } public override bool containsKey(string key) { lock(this) { if(key == null) { key = ""; } return _context.ContainsKey(key); } } public override string get(string key) { lock(this) { if(key == null) { key = ""; } string val = _context[key]; if(val == null) { val = ""; } return val; } } public override string put(string key, string value) { lock(this) { if(key == null) { key = ""; } if(value == null) { value = ""; } string oldVal; _context.TryGetValue(key, out oldVal); if(oldVal == null) { oldVal = ""; } _context[key] = value; return oldVal; } } public override string remove(string key) { lock(this) { if(key == null) { key = ""; } string val = _context[key]; if(val == null) { val = ""; } else { _context.Remove(key); } return val; } } public override void write(Dictionary prxContext, OutputStream os) { if(prxContext.Count == 0) { lock(this) { ContextHelper.write(os, _context); } } else { Dictionary ctx = null; lock(this) { ctx = _context.Count == 0 ? prxContext : combine(prxContext); } ContextHelper.write(os, ctx); } } internal override Dictionary combine(Dictionary prxContext) { lock(this) { Dictionary combined = new Dictionary(prxContext); foreach(KeyValuePair e in _context) { try { combined.Add(e.Key, e.Value); } catch(System.ArgumentException) { // Ignore. } } return combined; } } private Dictionary _context = new Dictionary(); } internal class PerThreadImplicitContext : ImplicitContextI { public override Dictionary getContext() { Dictionary threadContext = null; Thread currentThread = Thread.CurrentThread; lock(this) { if(_map.ContainsKey(currentThread)) { threadContext = _map[currentThread]; } } if(threadContext == null) { threadContext = new Dictionary(); } return threadContext; } public override void setContext(Dictionary context) { if(context == null || context.Count == 0) { lock(this) { _map.Remove(Thread.CurrentThread); } } else { Dictionary threadContext = new Dictionary(context); lock(this) { _map.Add(Thread.CurrentThread, threadContext); } } } public override bool containsKey(string key) { if(key == null) { key = ""; } Dictionary threadContext = null; lock(this) { if(!_map.TryGetValue(Thread.CurrentThread, out threadContext)) { return false; } } return threadContext.ContainsKey(key); } public override string get(string key) { if(key == null) { key = ""; } Dictionary threadContext = null; lock(this) { if(!_map.TryGetValue(Thread.CurrentThread, out threadContext)) { return ""; } } string val = threadContext[key]; if(val == null) { val = ""; } return val; } public override string put(string key, string value) { if(key == null) { key = ""; } if(value == null) { value = ""; } Dictionary threadContext = null; lock(this) { if(!_map.TryGetValue(Thread.CurrentThread, out threadContext)) { threadContext = new Dictionary(); _map.Add(Thread.CurrentThread, threadContext); } } string oldVal; if(!threadContext.TryGetValue(key, out oldVal)) { oldVal = ""; } threadContext[key] = value; return oldVal; } public override string remove(string key) { if(key == null) { key = ""; } Dictionary threadContext = null; lock(this) { if(!_map.TryGetValue(Thread.CurrentThread, out threadContext)) { return ""; } } string val = null; if(!threadContext.TryGetValue(key, out val)) { val = ""; } else { threadContext.Remove(key); } return val; } public override void write(Dictionary prxContext, OutputStream os) { Dictionary threadContext = null; lock(this) { _map.TryGetValue(Thread.CurrentThread, out threadContext); } if(threadContext == null || threadContext.Count == 0) { ContextHelper.write(os, prxContext); } else if(prxContext.Count == 0) { ContextHelper.write(os, threadContext); } else { Dictionary combined = new Dictionary(prxContext); foreach(KeyValuePair e in threadContext) { try { combined.Add(e.Key, e.Value); } catch(System.ArgumentException) { // Ignore. } } ContextHelper.write(os, combined); } } internal override Dictionary combine(Dictionary prxContext) { Dictionary threadContext = null; lock(this) { if(!_map.TryGetValue(Thread.CurrentThread, out threadContext)) { return new Dictionary(prxContext); } } Dictionary combined = new Dictionary(prxContext); foreach(KeyValuePair e in threadContext) { combined.Add(e.Key, e.Value); } return combined; } // // map Thread -> Context // private Dictionary > _map = new Dictionary >(); } }