2 // Mainsoft.Web.Hosting.AbstractAttributeMap.cs
\r
5 // Konstantin Triger <kostat@mainsoft.com>
\r
7 // (C) 2008 Mainsoft Co. (http://www.mainsoft.com)
\r
11 // Permission is hereby granted, free of charge, to any person obtaining
\r
12 // a copy of this software and associated documentation files (the
\r
13 // "Software"), to deal in the Software without restriction, including
\r
14 // without limitation the rights to use, copy, modify, merge, publish,
\r
15 // distribute, sublicense, and/or sell copies of the Software, and to
\r
16 // permit persons to whom the Software is furnished to do so, subject to
\r
17 // the following conditions:
\r
19 // The above copyright notice and this permission notice shall be
\r
20 // included in all copies or substantial portions of the Software.
\r
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
34 namespace Mainsoft.Web.Hosting
\r
36 partial class BaseExternalContext
\r
38 public abstract class AbstractAttributeMap : AbstractMap
\r
40 private Set _keySet;
\r
41 private Collection _values;
\r
42 private Set _entrySet;
\r
44 public override void clear () {
\r
45 List names = new ArrayList ();
\r
46 for (Enumeration e = getAttributeNames (); e.hasMoreElements (); ) {
\r
47 names.add (e.nextElement ());
\r
50 for (Iterator it = names.iterator (); it.hasNext (); ) {
\r
51 removeAttribute ((String) it.next ());
\r
55 public override bool containsKey (Object key) {
\r
56 return getAttribute (key.ToString ()) != null;
\r
59 public override bool containsValue (Object findValue) {
\r
60 if (findValue == null) {
\r
64 for (Enumeration e = getAttributeNames (); e.hasMoreElements (); ) {
\r
65 Object value = getAttribute ((String) e.nextElement ());
\r
66 if (findValue.Equals (value)) {
\r
74 public override Set entrySet () {
\r
75 return (_entrySet != null) ? _entrySet : (_entrySet = new EntrySet (this));
\r
78 public override Object get (Object key) {
\r
79 return getAttribute (key.ToString ());
\r
82 public override bool isEmpty () {
\r
83 return !getAttributeNames ().hasMoreElements ();
\r
86 public override Set keySet () {
\r
87 return (_keySet != null) ? _keySet : (_keySet = new KeySet (this));
\r
90 public override Object put (Object key, Object value) {
\r
91 String key_ = key.ToString ();
\r
92 Object retval = getAttribute (key_);
\r
93 setAttribute (key_, value);
\r
97 public override void putAll (Map t) {
\r
98 for (Iterator it = t.entrySet ().iterator (); it.hasNext (); ) {
\r
99 Map.Entry entry = (Map.Entry) it.next ();
\r
100 setAttribute (entry.getKey ().ToString (), entry.getValue ());
\r
104 public override Object remove (Object key) {
\r
105 String key_ = key.ToString ();
\r
106 Object retval = getAttribute (key_);
\r
107 removeAttribute (key_);
\r
111 public override int size () {
\r
113 for (Enumeration e = getAttributeNames (); e.hasMoreElements (); ) {
\r
120 public override Collection values () {
\r
121 return (_values != null) ? _values : (_values = new Values (this));
\r
125 abstract protected Object getAttribute (string key);
\r
127 abstract protected void setAttribute (string key, Object value);
\r
129 abstract protected void removeAttribute (string key);
\r
131 abstract protected Enumeration getAttributeNames ();
\r
134 private class KeySet : AbstractSet
\r
136 protected readonly AbstractAttributeMap _owner;
\r
137 public KeySet (AbstractAttributeMap owner) {
\r
141 public override Iterator iterator () {
\r
142 return new KeyIterator (_owner);
\r
145 public override bool isEmpty () {
\r
146 return _owner.isEmpty ();
\r
149 public override int size () {
\r
150 return _owner.size ();
\r
153 public override bool contains (Object o) {
\r
154 return _owner.containsKey (o);
\r
157 public override bool remove (Object o) {
\r
158 return _owner.remove (o) != null;
\r
161 public override void clear () {
\r
166 private class KeyIterator : Iterator
\r
168 protected readonly AbstractAttributeMap _owner;
\r
169 protected readonly Enumeration _e;
\r
171 public KeyIterator (AbstractAttributeMap owner) {
\r
173 _e = _owner.getAttributeNames ();
\r
176 protected Object _currentKey;
\r
178 public virtual void remove () {
\r
179 // remove() may cause ConcurrentModificationException.
\r
180 // We could throw an exception here, but not throwing an exception
\r
181 // allows one call to remove() to succeed
\r
182 if (_currentKey == null) {
\r
183 throw new NoSuchElementException (
\r
184 "You must call next() at least once");
\r
186 _owner.remove (_currentKey);
\r
189 public bool hasNext () {
\r
190 return _e.hasMoreElements ();
\r
193 public virtual Object next () {
\r
194 return _currentKey = _e.nextElement ();
\r
198 private class Values : KeySet
\r
201 public Values (AbstractAttributeMap owner)
\r
205 public override Iterator iterator () {
\r
206 return new ValuesIterator (_owner);
\r
209 public override bool contains (Object o) {
\r
210 return _owner.containsValue (o);
\r
213 public override bool remove (Object o) {
\r
218 for (Iterator it = iterator (); it.hasNext (); ) {
\r
219 if (o.Equals (it.next ())) {
\r
229 private class ValuesIterator : KeyIterator
\r
231 public ValuesIterator (AbstractAttributeMap owner)
\r
233 public override Object next () {
\r
235 return _owner.get (_currentKey);
\r
239 private class EntrySet : KeySet
\r
241 public EntrySet (AbstractAttributeMap owner) : base (owner) { }
\r
243 public override Iterator iterator () {
\r
244 return new EntryIterator (_owner);
\r
247 public override bool contains (Object o) {
\r
248 if (!(o is Map.Entry)) {
\r
252 Map.Entry entry = (Map.Entry) o;
\r
253 Object key = entry.getKey ();
\r
254 Object value = entry.getValue ();
\r
255 if (key == null || value == null) {
\r
259 return value.Equals (_owner.get (key));
\r
262 public override bool remove (Object o) {
\r
263 if (!(o is Map.Entry)) {
\r
267 Map.Entry entry = (Map.Entry) o;
\r
268 Object key = entry.getKey ();
\r
269 Object value = entry.getValue ();
\r
270 if (key == null || value == null
\r
271 || !value.Equals (_owner.get (key))) {
\r
275 return _owner.remove (((Map.Entry) o).getKey ()) != null;
\r
280 * Not very efficient since it generates a new instance of <code>Entry</code>
\r
281 * for each element and still internaly uses the <code>KeyIterator</code>.
\r
282 * It is more efficient to use the <code>KeyIterator</code> directly.
\r
284 private class EntryIterator : KeyIterator
\r
286 public EntryIterator (AbstractAttributeMap owner) : base (owner) { }
\r
287 public override Object next () {
\r
289 // Must create new Entry every time--value of the entry must stay
\r
290 // linked to the same attribute name
\r
291 return new EntrySetEntry (_currentKey);
\r
295 private class EntrySetEntry : Map.Entry
\r
297 readonly AbstractAttributeMap _owner;
\r
299 public EntrySetEntry (AbstractAttributeMap owner) {
\r
303 private readonly Object _currentKey;
\r
305 public EntrySetEntry (Object currentKey) {
\r
306 _currentKey = currentKey;
\r
309 public Object getKey () {
\r
310 return _currentKey;
\r
313 public Object getValue () {
\r
314 return _owner.get (_currentKey);
\r
317 public Object setValue (Object value) {
\r
318 return _owner.put (_currentKey, value);
\r
321 public int hashCode () {
\r
322 return _currentKey == null ? 0 : _currentKey.GetHashCode ();
\r
325 public bool equals (Object obj) {
\r
326 if (!(obj is EntrySetEntry))
\r
328 return _currentKey != null && _currentKey.Equals (obj);
\r