1
2
3
4
5
6
7
8
9
10
11
12
13 package org.abstracthorizon.danube.webdav.lock.impl;
14
15 import org.abstracthorizon.danube.webdav.lock.Lock;
16 import org.abstracthorizon.danube.webdav.lock.LockingMechanism;
17 import org.abstracthorizon.danube.webdav.util.Timeout;
18
19 import java.util.Collection;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.Iterator;
23 import java.util.Map;
24
25
26
27
28
29
30 public class SimpleInMemoryLockingMechanism implements LockingMechanism {
31
32
33 protected Map<String, Lock> tokenLocks = new HashMap<String, Lock>();
34
35
36 protected Map<Lock, Collection<Object>> lockResources = new HashMap<Lock, Collection<Object>>();
37
38
39 protected Map<Object, Collection<Lock>> resourcesLocks = new HashMap<Object, Collection<Lock>>();
40
41
42 protected int harvestMinimumInterval = 10000;
43
44
45 protected long nextHarvested;
46
47
48
49
50 public SimpleInMemoryLockingMechanism() {
51 }
52
53
54
55
56
57
58
59
60
61 public synchronized Lock createLock(int type, int scope, Object owner, Timeout timeout, int depth) {
62 Lock lock = createLockImpl(type, scope, owner, timeout, depth);
63 tokenLocks.put(lock.getToken(), lock);
64 harvestLocks();
65 return lock;
66 }
67
68
69
70
71
72
73
74
75
76
77 protected Lock createLockImpl(int type, int scope, Object owner, Timeout timeout, int depth) {
78 return new Lock(type, scope, owner, timeout, depth);
79 }
80
81
82
83
84
85
86 public synchronized Lock findLock(String token) {
87 return tokenLocks.get(token);
88 }
89
90
91
92
93
94
95
96 public synchronized boolean lockResource(Lock lock, Object resource) {
97 Collection<Lock> locks = resourcesLocks.get(resource);
98 if ((locks != null) && locks.contains(lock)) {
99 return false;
100 }
101 Collection<Object> rs = lockResources.get(lock);
102 if (rs == null) {
103 rs = new HashSet<Object>();
104 lockResources.put(lock, rs);
105 }
106 rs.add(resource);
107 if (locks == null) {
108 locks = new HashSet<Lock>();
109 resourcesLocks.put(resource, locks);
110 }
111 locks.add(lock);
112 return true;
113 }
114
115
116
117
118
119 public synchronized void unlockResources(Lock lock) {
120 tokenLocks.remove(lock.getToken());
121 removeLock(lock);
122 }
123
124
125
126
127
128 public void removeLocks(Object resource) {
129 Collection<Lock> locks = resourcesLocks.remove(resource);
130 if (locks != null) {
131 for (Lock lock : locks) {
132 Collection<Object> resources = lockResources.get(lock);
133 resources.remove(resource);
134 if (resources.size() == 0) {
135 tokenLocks.remove(lock);
136 lockResources.remove(lock);
137 }
138 }
139 }
140 }
141
142
143
144
145
146
147 public Lock[] getLocks(Object resource) {
148 Collection<Lock> locks = resourcesLocks.get(resource);
149 if ((locks != null) && (locks.size() > 0)) {
150 Lock[] res = new Lock[locks.size()];
151 return locks.toArray(res);
152 }
153 return null;
154 }
155
156
157
158
159
160
161 public Object[] getResources(Lock lock) {
162 Collection<Object> resources = lockResources.get(lock);
163 if ((resources != null) && (resources.size() > 0)) {
164 Object[] res = new Object[resources.size()];
165 return resources.toArray(res);
166 }
167 return null;
168 }
169
170
171
172
173
174
175 public synchronized boolean isLocked(Object resource) {
176 harvestLocks();
177 Collection<Lock> locks = resourcesLocks.get(resource);
178 return ((locks != null) && (locks.size() > 0));
179 }
180
181
182
183
184
185
186
187 public synchronized boolean isAccessAllowed(Object resource, String token) {
188 harvestLocks();
189 Collection<Lock> locks = resourcesLocks.get(resource);
190 if ((locks != null) && (locks.size() > 0)) {
191 if (token != null) {
192 for (Lock lock : locks) {
193 if (lock.getToken().equals(token)) {
194 return true;
195 }
196 }
197 }
198 return false;
199 } else {
200 return true;
201 }
202 }
203
204
205
206
207
208 public int[] getSupportedLockScopes(Object resource) {
209 return new int[]{LockingMechanism.SCOPE_EXCLUSIVE, LockingMechanism.SCOPE_SHARED};
210 }
211
212
213
214
215 protected synchronized void harvestLocks() {
216 long now = System.currentTimeMillis();
217 if (nextHarvested < now) {
218 nextHarvested = now + harvestMinimumInterval;
219
220 Iterator<Lock> iterator = tokenLocks.values().iterator();
221 while (iterator.hasNext()) {
222 Lock lock = iterator.next();
223 if (lock.getValidUntil() < now) {
224 iterator.remove();
225 removeLock(lock);
226 }
227 }
228
229 }
230 }
231
232
233
234
235
236 protected void removeLock(Lock lock) {
237 Collection<Object> resources = lockResources.get(lock);
238 if (resources != null) {
239 for (Object resource : resources) {
240 Collection<Lock> locks = resourcesLocks.get(resource);
241 if (locks != null) {
242 locks.remove(lock);
243 if (locks.size() == 0) {
244 resourcesLocks.remove(resource);
245 }
246 }
247 }
248 }
249 lockResources.remove(lock);
250 lock.freeLock();
251 }
252
253
254
255
256
257 public int getHarvestMinimumInterval() {
258 return harvestMinimumInterval;
259 }
260
261
262
263
264
265 public void setHarvestMinimumInterval(int harvestMinimumInterval) {
266 this.harvestMinimumInterval = harvestMinimumInterval;
267 }
268 }