Source code: org/apache/axis/utils/LockableHashtable.java
1 /*
2 * Copyright 2001-2004 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.apache.axis.utils ;
17
18 import java.util.Hashtable;
19 import java.util.Vector;
20 import java.util.Set;
21 import java.util.HashSet;
22
23 // fixme: Is there a reason to use Hashtable rather than Map here?
24 /**
25 * This subclass of the java Hashtable allows individual
26 * entries to be "locked" so that their values cannot be
27 * overwritten or removed.
28 *
29 * Note, only the put() and remove() methods have been
30 * overridden. The clear() method still removes all
31 * entries whether they've been locked or not.
32 *
33 * @author James Snell (jasnell@us.ibm.com)
34 */
35 public class LockableHashtable extends Hashtable {
36
37 // fixme - we are potentialy synchronizing on /both/ the current Hashtable
38 // and also the Vector - a non-synchronizing List impl such as ArrayList
39 // may give better performance. We are doing lots of .contains on this
40 // Vector - it would probably be better to use a Set impl
41 /**
42 * Stores the keys of the locked entries
43 */
44 Vector lockedEntries;
45
46 /** Place to look for properties which we don't find locally. */
47 private Hashtable parent = null;
48
49 public LockableHashtable() {
50 super();
51 }
52
53 public LockableHashtable(int p1, float p2) {
54 super(p1, p2);
55 }
56
57 public LockableHashtable(java.util.Map p1) {
58 super(p1);
59 }
60
61 public LockableHashtable(int p1) {
62 super(p1);
63 }
64
65 /**
66 * Set the parent Hashtable for this object
67 */
68 public synchronized void setParent(Hashtable parent)
69 {
70 this.parent = parent;
71 }
72
73 /**
74 * Gets the parent Hashtable for this object (if any)
75 */
76 public synchronized Hashtable getParent() {
77 return parent;
78 }
79
80 /**
81 * Returns the keys in this hashtable, and its parent chain
82 */
83 public Set getAllKeys() {
84 HashSet set = new HashSet();
85 set.addAll(super.keySet());
86 Hashtable p = parent;
87 while (p != null) {
88 set.addAll(p.keySet());
89 if (p instanceof LockableHashtable) {
90 p = ((LockableHashtable) p).getParent();
91 } else {
92 p = null;
93 }
94 }
95 return set;
96 }
97
98 /**
99 * Get an entry from this hashtable, and if we don't find anything,
100 * defer to our parent, if any.
101 */
102 public synchronized Object get(Object key) {
103 Object ret = super.get(key);
104 if ((ret == null) && (parent != null)) {
105 ret = parent.get(key);
106 }
107 return ret;
108 }
109 /**
110 * New version of the put() method that allows for explicitly marking
111 * items added to the hashtable as locked.
112 */
113 public synchronized Object put(Object p1, Object p2, boolean locked) {
114 if (lockedEntries != null &&
115 this.containsKey(p1) &&
116 lockedEntries.contains(p1)) {
117 return null;
118 }
119 if (locked) {
120 if (lockedEntries == null) {
121 lockedEntries = new Vector();
122 }
123 lockedEntries.add(p1);
124 }
125 return super.put(p1, p2);
126 }
127
128 /**
129 * Overrides the Hashtable.put() method to mark items as not being locked.
130 */
131 public synchronized Object put(Object p1, Object p2) {
132 return put(p1, p2, false);
133 }
134
135 /**
136 * Checks to see if an item is locked before it is removed.
137 */
138 public synchronized Object remove(Object p1) {
139 if (lockedEntries != null && lockedEntries.contains(p1)) {
140 return null;
141 }
142 return super.remove(p1);
143 }
144
145 /**
146 * Returns true if a given key is in our locked list
147 */
148 public boolean isKeyLocked(Object key)
149 {
150 return lockedEntries != null && lockedEntries.contains(key);
151 }
152 }