Source code: org/apache/slide/store/StandardStore.java
1 /*
2 * $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/store/StandardStore.java,v 1.23 2004/07/28 09:34:40 ib Exp $
3 * $Revision: 1.23 $
4 * $Date: 2004/07/28 09:34:40 $
5 *
6 * ====================================================================
7 *
8 * Copyright 1999-2002 The Apache Software Foundation
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 *
22 */
23
24 package org.apache.slide.store;
25
26 import java.util.Enumeration;
27 import java.util.Vector;
28
29 import org.apache.slide.common.NamespaceAccessToken;
30 import org.apache.slide.common.Service;
31 import org.apache.slide.common.ServiceAccessException;
32 import org.apache.slide.common.ServiceInitializationFailedException;
33 import org.apache.slide.common.Uri;
34 import org.apache.slide.content.NodeRevisionContent;
35 import org.apache.slide.content.NodeRevisionDescriptor;
36 import org.apache.slide.content.NodeRevisionDescriptors;
37 import org.apache.slide.content.NodeRevisionNumber;
38 import org.apache.slide.content.RevisionAlreadyExistException;
39 import org.apache.slide.content.RevisionDescriptorNotFoundException;
40 import org.apache.slide.content.RevisionNotFoundException;
41 import org.apache.slide.lock.LockTokenNotFoundException;
42 import org.apache.slide.lock.NodeLock;
43 import org.apache.slide.security.NodePermission;
44 import org.apache.slide.structure.ObjectAlreadyExistsException;
45 import org.apache.slide.structure.ObjectNode;
46 import org.apache.slide.structure.ObjectNotFoundException;
47 import org.apache.slide.util.HashMapObjectCache;
48 import org.apache.slide.util.ObjectCache;
49
50 /**
51 * Abstract implementation of a store. Handles all caching operations.
52 *
53 * @deprecated This store is deprecated as it has no reasonable transaction support, use ExtendedStore instead.
54 * @version $Revision: 1.23 $
55 */
56 public class StandardStore extends AbstractStore {
57
58
59 // ----------------------------------------------------------- Constructors
60
61
62 /**
63 * Constructor. Handles caches initialization.
64 */
65 public StandardStore() {
66 super();
67
68 objectsCache = new HashMapObjectCache(1000, 10000, 0.95);
69 permissionsCache = new HashMapObjectCache(1000, 10000, 0.95);
70 locksCache = new HashMapObjectCache(1000, 10000, 0.95);
71 descriptorsCache = new HashMapObjectCache(1000, 10000, 0.95);
72 descriptorCache = new HashMapObjectCache(1000, 10000, 0.8);
73 }
74
75 // ----------------------------------------------------- Instance Variables
76
77
78 /**
79 * Nodes cache.
80 */
81 protected ObjectCache objectsCache;
82
83
84 /**
85 * Permissions cache.
86 */
87 protected ObjectCache permissionsCache;
88
89
90 /**
91 * Locks cache.
92 */
93 protected ObjectCache locksCache;
94
95
96 /**
97 * Revision descriptors cache.
98 */
99 protected ObjectCache descriptorsCache;
100
101
102 /**
103 * Revision descriptor cache.
104 */
105 protected ObjectCache descriptorCache;
106
107
108 // ---------------------------------------------------- ServiceImpl Methods
109
110
111 /**
112 * Initializes descriptors store.
113 *
114 * @exception ServiceInitializationFailedException Throws an exception
115 * if the descriptors store has already been initialized before
116 */
117 public void initialize(NamespaceAccessToken token)
118 throws ServiceInitializationFailedException {
119 super.initialize(token);
120 }
121
122
123 // ----------------------------------------------- DescriptorsStore Methods
124
125
126 /**
127 * Retrive an object from the Descriptors Store.
128 *
129 * @param uri Uri of the object we want to retrieve
130 * @exception ServiceAccessException Error accessing the Descriptors Store
131 * @exception ObjectNotFoundException The object to retrieve was not found
132 */
133 public ObjectNode retrieveObject(Uri uri)
134 throws ServiceAccessException, ObjectNotFoundException {
135 if (nodeStore.cacheResults()) {
136 Object tempObject = objectsCache.get(uri.toString());
137 if (tempObject != null) {
138 return ((ObjectNode) tempObject).cloneObject();
139 } else {
140 ObjectNode objectNode = nodeStore.retrieveObject(uri);
141 objectNode.validate(uri.toString());
142 objectsCache.put(uri.toString(), objectNode.cloneObject());
143 return objectNode;
144 }
145 } else {
146 return super.retrieveObject(uri);
147 }
148 }
149
150
151 /**
152 * Store an object in the Descriptors Store.
153 *
154 * @param object Object to update
155 * @exception ServiceAccessException Error accessing the Descriptors Store
156 * @exception ObjectNotFoundException The object to update was not found
157 */
158 public void storeObject(Uri uri, ObjectNode object)
159 throws ServiceAccessException, ObjectNotFoundException {
160 super.storeObject(uri, object);
161 if (nodeStore.cacheResults()) {
162 objectsCache.put(uri.toString(), object.cloneObject());
163 }
164 }
165
166
167 /**
168 * Create a new object in the Descriptors Store.
169 *
170 * @param object SlideObject
171 * @param uri Uri of the object we want to create
172 * @exception ServiceAccessException Error accessing the Descriptors Store
173 * @exception ObjectAlreadyExistsException An object already exists
174 * at this Uri
175 */
176 public void createObject(Uri uri, ObjectNode object)
177 throws ServiceAccessException, ObjectAlreadyExistsException {
178 super.createObject(uri, object);
179 if (nodeStore.cacheResults()) {
180 objectsCache.put(uri.toString(), object.cloneObject());
181 }
182 }
183
184
185 /**
186 * Remove an object from the Descriptors Store.
187 *
188 * @param object Object to remove
189 * @exception ServiceAccessException Error accessing the Descriptors Store
190 * @exception ObjectNotFoundException The object to remove was not found
191 */
192 public void removeObject(Uri uri, ObjectNode object)
193 throws ServiceAccessException, ObjectNotFoundException {
194 super.removeObject(uri, object);
195 if (nodeStore.cacheResults()) {
196 objectsCache.remove(uri.toString());
197 }
198 }
199
200
201 /**
202 * Store an object permissions in the Descriptors Store.
203 *
204 * @param permission Permission we want to create
205 * @exception ServiceAccessException Error accessing the Descriptors Store
206 */
207 public void grantPermission(Uri uri, NodePermission permission)
208 throws ServiceAccessException {
209 super.grantPermission(uri, permission);
210 if (securityStore.cacheResults()) {
211 NodePermission tempPermission = permission.cloneObject();
212 Object value = permissionsCache.get(uri.toString());
213 if (value == null) {
214 // populate the cache with the existing entries
215 enumeratePermissions(uri);
216 // and check if the cache contains a corresponding entry now
217 value = permissionsCache.get(uri.toString());
218 if (value == null) {
219 // no permissions for the Uri in the cache, so create a new
220 // entry
221 Vector permissionsVector = new Vector();
222 permissionsVector.addElement(tempPermission);
223 permissionsCache.put(uri.toString(), permissionsVector);
224 }
225 } else {
226 Vector permissionsVector = (Vector) value;
227 permissionsVector.addElement(tempPermission);
228 }
229 }
230 }
231
232
233 /**
234 * Store an object permissions in the Descriptors Store.
235 *
236 * @param permission Permission we want to create
237 * @exception ServiceAccessException Error accessing the Descriptors Store
238 */
239 public void revokePermission(Uri uri, NodePermission permission)
240 throws ServiceAccessException {
241 super.revokePermission(uri, permission);
242 if (securityStore.cacheResults()) {
243 Object value = permissionsCache.get(uri.toString());
244 Vector permissionsVector = null;
245 if (value != null) {
246 permissionsVector = (Vector) value;
247 permissionsVector.removeElement(permission);
248 }
249 }
250 }
251
252
253 /**
254 * Revoke all the permissions on the object.
255 *
256 * @param uri The uri of the object
257 * @exception ServiceAccessException Error accessing the Descriptors Store
258 */
259 public void revokePermissions(Uri uri)
260 throws ServiceAccessException {
261 super.revokePermissions(uri);
262 if (securityStore.cacheResults()) {
263 Object value = permissionsCache.get(uri.toString());
264 Vector permissionsVector = null;
265 if (value != null) {
266 permissionsVector = (Vector) value;
267 permissionsVector.removeAllElements();
268 }
269 }
270 }
271
272
273 /**
274 * Enumerate an object permissions.
275 *
276 * @param uri The uri of the object
277 * @exception ServiceAccessException Error accessing the Descriptors Store
278 * @return A enumeration of all
279 * {@link org.apache.slide.security.NodePermission permissions} on this object.
280 */
281 public Enumeration enumeratePermissions(Uri uri)
282 throws ServiceAccessException {
283 // TODO : The vectors elements MUST be cloned for non chached Results
284 if (securityStore.cacheResults()) {
285 Object value = permissionsCache.get(uri.toString());
286 Vector permissionsVector = null;
287 if (value != null) {
288 permissionsVector = (Vector) value;
289 } else {
290 permissionsVector = new Vector();
291 Enumeration tempEnum = securityStore.enumeratePermissions(uri);
292 while (tempEnum.hasMoreElements()) {
293 NodePermission tempPermission =
294 (NodePermission) tempEnum.nextElement();
295 tempPermission.validate(uri.toString());
296 permissionsVector.addElement(tempPermission);
297 }
298 permissionsCache.put(uri.toString(), permissionsVector);
299 }
300 return ((Vector) permissionsVector.clone()).elements();
301 } else {
302 return super.enumeratePermissions(uri);
303 }
304 }
305
306
307 /**
308 * Puts a lock on a subject.
309 *
310 * @param lock Lock token
311 * @exception ServiceAccessException Service access error
312 */
313 public void putLock(Uri uri, NodeLock lock)
314 throws ServiceAccessException {
315 super.putLock(uri, lock);
316 if (lockStore.cacheResults()) {
317 Object value = locksCache.get(uri.toString());
318 Vector locksVector = null;
319 if (value == null) {
320 locksVector = new Vector();
321 locksCache.put(uri.toString(), locksVector);
322 } else {
323 locksVector = (Vector) value;
324 }
325 locksVector.addElement(lock.cloneObject());
326 }
327 }
328
329
330 /**
331 * Renews a lock.
332 *
333 * @param lock Token to renew
334 * @exception ServiceAccessException Service access error
335 * @exception LockTokenNotFoundException Lock token was not found
336 */
337 public void renewLock(Uri uri, NodeLock lock)
338 throws ServiceAccessException, LockTokenNotFoundException {
339 super.renewLock(uri, lock);
340 if (lockStore.cacheResults()) {
341 Object value = locksCache.get(uri.toString());
342 Vector locksVector = null;
343 if (value != null) {
344 locksVector = (Vector) value;
345 boolean wasPresent = locksVector.removeElement(lock);
346 if (!wasPresent) {
347 throw new LockTokenNotFoundException(lock);
348 }
349 locksVector.addElement(lock.cloneObject());
350 }
351 }
352 }
353
354
355 /**
356 * Removes (cancels) a lock.
357 *
358 * @param lock Token to remove
359 * @exception ServiceAccessException Service access error
360 * @exception LockTokenNotFoundException Lock token was not found
361 */
362 public void removeLock(Uri uri, NodeLock lock)
363 throws ServiceAccessException, LockTokenNotFoundException {
364 super.removeLock(uri, lock);
365 if (lockStore.cacheResults()) {
366 Object value = locksCache.get(uri.toString());
367 Vector locksVector = null;
368 if (value != null) {
369 locksVector = (Vector) value;
370 boolean wasPresent = locksVector.removeElement(lock);
371 if (!wasPresent) {
372 throw new LockTokenNotFoundException(lock);
373 }
374 }
375 }
376 }
377
378
379 /**
380 * Kills a lock.
381 *
382 * @param lock Token to remove
383 * @exception ServiceAccessException Service access error
384 * @exception LockTokenNotFoundException Lock token was not found
385 */
386 public void killLock(Uri uri, NodeLock lock)
387 throws ServiceAccessException, LockTokenNotFoundException {
388 super.killLock(uri, lock);
389 if (lockStore.cacheResults()) {
390 Object value = locksCache.get(uri.toString());
391 Vector locksVector = null;
392 if (value != null) {
393 locksVector = (Vector) value;
394 boolean wasPresent = locksVector.removeElement(lock);
395 if (!wasPresent) {
396 throw new LockTokenNotFoundException(lock);
397 }
398 }
399 }
400 }
401
402
403 /**
404 * Enumerate locks on an object.
405 *
406 * @param uri Uri of the subject
407 * @return Enumeration List of {@link org.apache.slide.lock.NodeLock locks}
408 * which have been put on the subject
409 * @exception ServiceAccessException Service access error
410 */
411 public Enumeration enumerateLocks(Uri uri)
412 throws ServiceAccessException {
413 if (lockStore.cacheResults()) {
414 Object value = locksCache.get(uri.toString());
415 Vector locksVector = null;
416 if (value == null) {
417 locksVector = new Vector();
418 Enumeration lockList = lockStore.enumerateLocks(uri);
419 while (lockList.hasMoreElements()) {
420 NodeLock tempLock = (NodeLock) lockList.nextElement();
421 tempLock.validate(uri.toString());
422 locksVector.addElement(tempLock);
423 }
424 locksCache.put(uri.toString(), locksVector);
425 } else {
426 locksVector = (Vector) value;
427 }
428 return ((Vector) locksVector.clone()).elements();
429 } else {
430 return super.enumerateLocks(uri);
431 }
432 }
433
434
435 /**
436 * Retrieve a revision descriptors.
437 *
438 * @param uri Uri
439 * @exception ServiceAccessException Service access error
440 * @exception RevisionDescriptorNotFoundException Revision descriptor
441 * was not found
442 */
443 public NodeRevisionDescriptors retrieveRevisionDescriptors(Uri uri)
444 throws ServiceAccessException, RevisionDescriptorNotFoundException {
445 if (revisionDescriptorsStore.cacheResults()) {
446 Object tempObject = descriptorsCache.get(uri.toString());
447 if (tempObject != null) {
448 return ((NodeRevisionDescriptors) tempObject).cloneObject();
449 } else {
450 NodeRevisionDescriptors revisionDescriptors =
451 revisionDescriptorsStore.retrieveRevisionDescriptors(uri);
452 revisionDescriptors = revisionDescriptors.cloneObject();
453 descriptorsCache.put(uri.toString(),
454 revisionDescriptors);
455 revisionDescriptors.validate(uri.toString());
456 return revisionDescriptors;
457 }
458 } else {
459 return super.retrieveRevisionDescriptors(uri);
460 }
461 }
462
463
464 /**
465 * Create new revision descriptors.
466 *
467 * @param uri Uri
468 * @param revisionDescriptors Node revision descriptors
469 * @exception ServiceAccessException Service access error
470 */
471 public void createRevisionDescriptors
472 (Uri uri, NodeRevisionDescriptors revisionDescriptors)
473 throws ServiceAccessException {
474 super.createRevisionDescriptors(uri, revisionDescriptors);
475 if (revisionDescriptorsStore.cacheResults()) {
476 descriptorsCache.put(uri.toString(),
477 revisionDescriptors.cloneObject());
478 }
479 }
480
481
482 /**
483 * Update revision descriptors.
484 *
485 * @param uri Uri
486 * @param revisionDescriptors Node revision descriptors
487 * @exception ServiceAccessException Service access error
488 * @exception RevisionDescriptorNotFoundException Revision descriptor
489 * was not found
490 */
491 public void storeRevisionDescriptors
492 (Uri uri, NodeRevisionDescriptors revisionDescriptors)
493 throws ServiceAccessException, RevisionDescriptorNotFoundException {
494 super.storeRevisionDescriptors(uri, revisionDescriptors);
495 if (revisionDescriptorsStore.cacheResults()) {
496 descriptorsCache.put(uri.toString(),
497 revisionDescriptors.cloneObject());
498 }
499 }
500
501
502 /**
503 * Remove revision descriptors.
504 *
505 * @param uri Uri
506 * @exception ServiceAccessException Service access error
507 */
508 public void removeRevisionDescriptors(Uri uri)
509 throws ServiceAccessException {
510 if (revisionDescriptorsStore.cacheResults()) {
511 descriptorsCache.remove(uri.toString());
512 }
513 super.removeRevisionDescriptors(uri);
514 }
515
516
517 /**
518 * Retrieve revision descriptor.
519 *
520 * @param uri Uri
521 * @param revisionNumber Node revision number
522 */
523 public NodeRevisionDescriptor retrieveRevisionDescriptor
524 (Uri uri, NodeRevisionNumber revisionNumber)
525 throws ServiceAccessException, RevisionDescriptorNotFoundException {
526 if (revisionDescriptorStore.cacheResults()) {
527 Object result = descriptorCache.get(uri + "-" + revisionNumber);
528 if (result != null) {
529 return ((NodeRevisionDescriptor) result).cloneObject();
530 } else {
531 NodeRevisionDescriptor revisionDescriptor =
532 revisionDescriptorStore
533 .retrieveRevisionDescriptor(uri, revisionNumber)
534 .cloneObject();
535 revisionDescriptor.validate();
536 descriptorCache.put(uri + "-" + revisionNumber,
537 revisionDescriptor);
538 return revisionDescriptor;
539 }
540 } else {
541 return super.retrieveRevisionDescriptor(uri, revisionNumber);
542 }
543 }
544
545
546 /**
547 * Create new revision descriptor.
548 *
549 * @param uri Uri
550 * @param revisionDescriptor Node revision descriptor
551 * @exception ServiceAccessException Service access error
552 */
553 public void createRevisionDescriptor
554 (Uri uri, NodeRevisionDescriptor revisionDescriptor)
555 throws ServiceAccessException {
556 super.createRevisionDescriptor(uri, revisionDescriptor);
557 if (revisionDescriptorStore.cacheResults()) {
558 descriptorCache.put(uri + "-"
559 + revisionDescriptor.getRevisionNumber(),
560 revisionDescriptor.cloneObject());
561 }
562 }
563
564
565 /**
566 * Update revision descriptor.
567 *
568 * @param uri Uri
569 * @param revisionDescriptor Node revision descriptor
570 * @exception ServiceAccessException Service access error
571 * @exception RevisionDescriptorNotFoundException Revision descriptor
572 * was not found
573 */
574 public void storeRevisionDescriptor
575 (Uri uri, NodeRevisionDescriptor revisionDescriptor)
576 throws ServiceAccessException, RevisionDescriptorNotFoundException {
577 super.storeRevisionDescriptor(uri, revisionDescriptor);
578 if (revisionDescriptorStore.cacheResults()) {
579 String key = uri + "-" + revisionDescriptor.getRevisionNumber();
580 descriptorCache.put(key, revisionDescriptor.cloneObject());
581 }
582 }
583
584
585 /**
586 * Remove revision descriptor.
587 *
588 * @param uri Uri
589 * @param number Revision number
590 * @exception ServiceAccessException Service access error
591 */
592 public void removeRevisionDescriptor(Uri uri, NodeRevisionNumber number)
593 throws ServiceAccessException {
594 super.removeRevisionDescriptor(uri, number);
595 if (revisionDescriptorStore.cacheResults()) {
596 descriptorCache.remove(uri + "-" + number);
597 }
598 }
599
600
601 /**
602 * Retrive revision content.
603 *
604 * @param uri Uri
605 * @param revisionDescriptor Node revision descriptor
606 */
607 public NodeRevisionContent retrieveRevisionContent
608 (Uri uri, NodeRevisionDescriptor revisionDescriptor)
609 throws ServiceAccessException, RevisionNotFoundException {
610 return super.retrieveRevisionContent(uri, revisionDescriptor);
611 }
612
613
614 /**
615 * Create a new revision
616 *
617 * @param uri Uri
618 * @param revisionDescriptor Node revision descriptor
619 * @param revisionContent Node revision content
620 */
621 public void createRevisionContent
622 (Uri uri, NodeRevisionDescriptor revisionDescriptor,
623 NodeRevisionContent revisionContent)
624 throws ServiceAccessException, RevisionAlreadyExistException {
625 super.createRevisionContent(uri, revisionDescriptor, revisionContent);
626 }
627
628
629 /**
630 * Modify the latest revision of an object.
631 *
632 * @param uri Uri
633 * @param revisionDescriptor Node revision descriptor
634 * @param revisionContent Node revision content
635 */
636 public void storeRevisionContent
637 (Uri uri, NodeRevisionDescriptor revisionDescriptor,
638 NodeRevisionContent revisionContent)
639 throws ServiceAccessException, RevisionNotFoundException {
640 super.storeRevisionContent(uri, revisionDescriptor, revisionContent);
641 }
642
643
644 /**
645 * Remove revision.
646 *
647 * @param uri Uri
648 * @param revisionDescriptor Node revision descriptor
649 */
650 public void removeRevisionContent(Uri uri,
651 NodeRevisionDescriptor revisionDescriptor)
652 throws ServiceAccessException {
653 super.removeRevisionContent(uri, revisionDescriptor);
654 }
655
656
657 /**
658 * Return the name of this store
659 *
660 */
661 public String toString() {
662 return getName() + "(" + getClass().getName() + ")";
663 }
664
665
666 // ------------------------------------------------------ Protected Methods
667
668
669 /**
670 * Delist (suspend) the resource manager in the current transaction.
671 */
672 protected void delist(Service service, boolean success)
673 throws ServiceAccessException {
674 if (!success) {
675 // If there's a failure which will cause the transaction to be
676 // rollbacked, flush the caches
677 resetCaches();
678 }
679 super.delist(service, success);
680 }
681
682
683 /**
684 * Reset the caches.
685 */
686 protected void resetCaches() {
687 objectsCache.clear();
688 permissionsCache.clear();
689 locksCache.clear();
690 descriptorsCache.clear();
691 descriptorCache.clear();
692 }
693
694
695 }