KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > slide > store > txfile > TxXMLFileDescriptorsStore


1 /*
2  * $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/store/txfile/TxXMLFileDescriptorsStore.java,v 1.19.2.1 2004/09/22 09:24:31 luetzkendorf Exp $
3  * $Revision: 1.19.2.1 $
4  * $Date: 2004/09/22 09:24:31 $
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.txfile;
25
26 import org.apache.commons.transaction.file.ResourceManager;
27 import org.apache.commons.transaction.file.ResourceManagerException;
28 import org.apache.slide.common.*;
29 import org.apache.slide.store.*;
30 import org.apache.slide.structure.*;
31
32 import org.apache.slide.security.*;
33 import org.apache.slide.util.logger.Logger;
34 import org.apache.slide.lock.*;
35 import org.apache.slide.content.*;
36
37 import java.util.Collection JavaDoc;
38 import java.util.Enumeration JavaDoc;
39 import java.util.HashMap JavaDoc;
40 import java.util.Hashtable JavaDoc;
41 import java.util.Iterator JavaDoc;
42 import java.util.Map JavaDoc;
43
44 import javax.transaction.xa.XAException JavaDoc;
45 import javax.transaction.xa.Xid JavaDoc;
46
47 /**
48  * Transactional descriptors file store.
49  * Represents descriptor data as XML using {@link XMLResourceDescriptor}.
50  *
51  * <br><br>
52  * <em>Note</em>: To achieve search performance on properties comparable to a RDBMS some sort of index will be needed.
53  *
54  * @see XMLResourceDescriptor
55  */

56 public class TxXMLFileDescriptorsStore
57     extends AbstractTxFileStoreService
58     implements NodeStore, LockStore, RevisionDescriptorsStore, RevisionDescriptorStore, SecurityStore {
59
60     protected static final String JavaDoc LOG_CHANNEL = "file-meta-store";
61     
62     protected static final int DEBUG_LEVEL = Logger.DEBUG;
63
64     protected static final String JavaDoc ENCODING_PARAMETER = "encoding";
65
66     protected static final String JavaDoc DEFER_SAVING_PARAMETER = "defer-saving";
67
68     protected String JavaDoc characterEncoding = "UTF-8"; // a save choice
69
protected boolean deferSaving = false; // the save choice
70

71     protected Map JavaDoc suspendedContexts = new HashMap JavaDoc();
72     protected Map JavaDoc activeContexts = new HashMap JavaDoc();
73
74     public void setParameters(Hashtable JavaDoc parameters)
75         throws ServiceParameterErrorException, ServiceParameterMissingException {
76
77         super.setParameters(parameters);
78
79         String JavaDoc encoding = (String JavaDoc) parameters.get(ENCODING_PARAMETER);
80         if (encoding != null) {
81             characterEncoding = encoding;
82         }
83         
84         String JavaDoc deferSavingString = (String JavaDoc) parameters.get(DEFER_SAVING_PARAMETER);
85         if (deferSavingString != null) {
86             deferSaving = Boolean.valueOf(deferSavingString).booleanValue();
87             if (deferSaving) {
88                 getLogger().log(
89                     "Enabling deferred saving",
90                     LOG_CHANNEL,
91                     Logger.INFO);
92             }
93         }
94     }
95
96     /*
97      * --- public methods of interface NodeStore ---
98      *
99      *
100      */

101
102     public ObjectNode retrieveObject(Uri uri) throws ServiceAccessException, ObjectNotFoundException {
103         XMLResourceDescriptor xfd = getFileDescriptor(uri);
104         ObjectNode object = xfd.retrieveObject();
105         return object;
106     }
107
108     public void storeObject(Uri uri, ObjectNode object) throws ServiceAccessException, ObjectNotFoundException {
109         XMLResourceDescriptor xfd = getFileDescriptor(uri);
110         xfd.storeObject(object);
111         if (deferSaving) {
112             xfd.registerForSaving();
113         } else {
114             xfd.save();
115         }
116     }
117
118     public void createObject(Uri uri, ObjectNode object) throws ServiceAccessException, ObjectAlreadyExistsException {
119         try {
120             XMLResourceDescriptor xfd = getFileDescriptor(uri);
121             xfd.create();
122             xfd.storeObject(object);
123             if (deferSaving) {
124                 xfd.registerForSaving();
125                 TxContext txContext = getActiveTxContext();
126                 if (txContext != null) {
127                     txContext.register(uri, xfd);
128                 }
129             } else {
130                 xfd.save();
131             }
132         } catch (ObjectNotFoundException e) {
133             // should not happen, if it does, it is an error inside this store:
134
throwInternalError("Newly created file vanished");
135         }
136     }
137
138     public void removeObject(Uri uri, ObjectNode object) throws ServiceAccessException, ObjectNotFoundException {
139         XMLResourceDescriptor xfd = getFileDescriptor(uri);
140         xfd.delete();
141         if (deferSaving) {
142             TxContext txContext = getActiveTxContext();
143             if (txContext != null) {
144                 txContext.deregister(uri);
145             }
146         }
147     }
148
149     /*
150      * --- public methods of interface SecurityStore ---
151      *
152      *
153      */

154
155     public void grantPermission(Uri uri, NodePermission permission) throws ServiceAccessException {
156         try {
157             XMLResourceDescriptor xfd = getFileDescriptor(uri);
158             xfd.grantPermission(permission);
159             if (deferSaving) {
160                 xfd.registerForSaving();
161             } else {
162                 xfd.save();
163             }
164         } catch (ObjectNotFoundException e) {
165             throwInternalError(e);
166         }
167     }
168
169     public void revokePermission(Uri uri, NodePermission permission) throws ServiceAccessException {
170         try {
171             XMLResourceDescriptor xfd = getFileDescriptor(uri);
172             xfd.revokePermission(permission);
173             if (deferSaving) {
174                 xfd.registerForSaving();
175             } else {
176                 xfd.save();
177             }
178         } catch (ObjectNotFoundException e) {
179             throwInternalError(e);
180         }
181     }
182
183     public void revokePermissions(Uri uri) throws ServiceAccessException {
184         try {
185             XMLResourceDescriptor xfd = getFileDescriptor(uri);
186             xfd.revokePermissions();
187             if (deferSaving) {
188                 xfd.registerForSaving();
189             } else {
190                 xfd.save();
191             }
192         } catch (ObjectNotFoundException e) {
193             throwInternalError(e);
194         }
195     }
196
197     public Enumeration JavaDoc enumeratePermissions(Uri uri) throws ServiceAccessException {
198         try {
199             XMLResourceDescriptor xfd = getFileDescriptor(uri);
200             return xfd.enumeratePermissions();
201         } catch (ObjectNotFoundException e) {
202             throwInternalError(e);
203             return null; // XXX fake (is never called)
204
}
205     }
206
207     /*
208      * --- public methods of interface LockStore ---
209      *
210      *
211      */

212
213     public void putLock(Uri uri, NodeLock lock) throws ServiceAccessException {
214         try {
215             XMLResourceDescriptor xfd = getFileDescriptor(uri);
216             xfd.putLock(lock);
217             if (deferSaving) {
218                 xfd.registerForSaving();
219             } else {
220                 xfd.save();
221             }
222         } catch (ObjectNotFoundException e) {
223             throwInternalError(e);
224         }
225     }
226
227     public void renewLock(Uri uri, NodeLock lock) throws ServiceAccessException, LockTokenNotFoundException {
228         try {
229             XMLResourceDescriptor xfd = getFileDescriptor(uri);
230             xfd.renewLock(lock);
231             if (deferSaving) {
232                 xfd.registerForSaving();
233             } else {
234                 xfd.save();
235             }
236         } catch (ObjectNotFoundException e) {
237             throwInternalError(e);
238         }
239     }
240
241     public void removeLock(Uri uri, NodeLock lock) throws ServiceAccessException, LockTokenNotFoundException {
242         try {
243             XMLResourceDescriptor xfd = getFileDescriptor(uri);
244             xfd.removeLock(lock);
245             if (deferSaving) {
246                 xfd.registerForSaving();
247             } else {
248                 xfd.save();
249             }
250         } catch (ObjectNotFoundException e) {
251             throw new LockTokenNotFoundException(lock);
252         }
253     }
254
255     public void killLock(Uri uri, NodeLock lock) throws ServiceAccessException, LockTokenNotFoundException {
256         removeLock(uri, lock);
257     }
258
259     public Enumeration JavaDoc enumerateLocks(Uri uri) throws ServiceAccessException {
260         try {
261             XMLResourceDescriptor xfd = getFileDescriptor(uri);
262             return xfd.enumerateLocks();
263         } catch (ObjectNotFoundException e) {
264             throwInternalError(e);
265             return null; // XXX fake (is never called)
266
}
267     }
268
269     /*
270      * --- public methods of interface RevisionDescriptorsStore ---
271      *
272      *
273      */

274
275     public NodeRevisionDescriptors retrieveRevisionDescriptors(Uri uri)
276         throws ServiceAccessException, RevisionDescriptorNotFoundException {
277         try {
278             XMLResourceDescriptor xfd = getFileDescriptor(uri);
279             return xfd.retrieveRevisionDescriptors();
280         } catch (ObjectNotFoundException e) {
281             throw new RevisionDescriptorNotFoundException(uri.toString());
282         }
283     }
284
285     public void createRevisionDescriptors(Uri uri, NodeRevisionDescriptors revisionDescriptors)
286         throws ServiceAccessException {
287         try {
288             XMLResourceDescriptor xfd = getFileDescriptor(uri);
289             xfd.createRevisionDescriptors(revisionDescriptors);
290             if (deferSaving) {
291                 xfd.registerForSaving();
292             } else {
293                 xfd.save();
294             }
295         } catch (ObjectNotFoundException e) {
296             throwInternalError(e);
297         }
298     }
299
300     public void storeRevisionDescriptors(Uri uri, NodeRevisionDescriptors revisionDescriptors)
301         throws ServiceAccessException, RevisionDescriptorNotFoundException {
302         try {
303             XMLResourceDescriptor xfd = getFileDescriptor(uri);
304             xfd.storeRevisionDescriptors(revisionDescriptors);
305             if (deferSaving) {
306                 xfd.registerForSaving();
307             } else {
308                 xfd.save();
309             }
310         } catch (ObjectNotFoundException e) {
311             throw new RevisionDescriptorNotFoundException(uri.toString());
312         }
313     }
314
315     public void removeRevisionDescriptors(Uri uri) throws ServiceAccessException {
316         try {
317             XMLResourceDescriptor xfd = getFileDescriptor(uri);
318             xfd.removeRevisionDescriptors();
319             if (deferSaving) {
320                 xfd.registerForSaving();
321             } else {
322                 xfd.save();
323             }
324         } catch (ObjectNotFoundException e) {
325             throwInternalError(e);
326         }
327     }
328
329     /*
330      * --- public methods of interface RevisionDescriptorStore ---
331      *
332      *
333      */

334
335     public NodeRevisionDescriptor retrieveRevisionDescriptor(Uri uri, NodeRevisionNumber revisionNumber)
336         throws ServiceAccessException, RevisionDescriptorNotFoundException {
337         try {
338             XMLResourceDescriptor xfd = getFileDescriptor(uri);
339             return xfd.retrieveRevisionDescriptor(revisionNumber);
340         } catch (ObjectNotFoundException e) {
341             throw new RevisionDescriptorNotFoundException(uri.toString());
342         }
343     }
344
345     public void createRevisionDescriptor(Uri uri, NodeRevisionDescriptor revisionDescriptor)
346         throws ServiceAccessException {
347         try {
348             XMLResourceDescriptor xfd = getFileDescriptor(uri);
349             xfd.createRevisionDescriptor(revisionDescriptor);
350             if (deferSaving) {
351                 xfd.registerForSaving();
352             } else {
353                 xfd.save();
354             }
355         } catch (ObjectNotFoundException e) {
356             throwInternalError(e);
357         }
358     }
359
360     public void storeRevisionDescriptor(Uri uri, NodeRevisionDescriptor revisionDescriptor)
361         throws ServiceAccessException, RevisionDescriptorNotFoundException {
362         try {
363             XMLResourceDescriptor xfd = getFileDescriptor(uri);
364             xfd.storeRevisionDescriptor(revisionDescriptor);
365             if (deferSaving) {
366                 xfd.registerForSaving();
367             } else {
368                 xfd.save();
369             }
370         } catch (ObjectNotFoundException e) {
371             throw new RevisionDescriptorNotFoundException(uri.toString());
372         }
373     }
374
375     public void removeRevisionDescriptor(Uri uri, NodeRevisionNumber number) throws ServiceAccessException {
376         try {
377             XMLResourceDescriptor xfd = getFileDescriptor(uri);
378             xfd.removeRevisionDescriptor(number);
379             if (deferSaving) {
380                 xfd.registerForSaving();
381             } else {
382                 xfd.save();
383             }
384         } catch (ObjectNotFoundException e) {
385             throwInternalError(e);
386         }
387     }
388
389     public String JavaDoc toString() {
390         return "TxXMLFileDescriptorsStore at " + storeDir + " working on " + workDir;
391     }
392
393     public synchronized void commit(Xid JavaDoc xid, boolean onePhase) throws XAException JavaDoc {
394         try {
395             super.commit(xid, onePhase);
396         } finally {
397             Object JavaDoc txId = wrap(xid);
398             activeContexts.remove(txId);
399             suspendedContexts.remove(txId);
400             activeTransactionBranch.set(null);
401         }
402     }
403
404     public synchronized void rollback(Xid JavaDoc xid) throws XAException JavaDoc {
405         try {
406             super.rollback(xid);
407         } finally {
408             Object JavaDoc txId = wrap(xid);
409             activeContexts.remove(txId);
410             suspendedContexts.remove(txId);
411             activeTransactionBranch.set(null);
412         }
413     }
414     
415     public synchronized int prepare(Xid JavaDoc xid) throws XAException JavaDoc {
416         Object JavaDoc txId = wrap(xid);
417         getLogger().log(
418             "Thread " + Thread.currentThread() + " prepares transaction branch " + txId,
419             LOG_CHANNEL,
420             Logger.DEBUG);
421         try {
422             if (deferSaving) {
423                 // save all descriptors registered for saving
424
TxContext txContext = (TxContext) activeContexts.get(txId);
425                 if (txContext == null) txContext = (TxContext) suspendedContexts.get(txId);
426                 // really should not, but only to be sure...
427
if (txContext != null) {
428                     try {
429                         txContext.saveDescriptors();
430                     } catch (ObjectNotFoundException onfe) {
431                         getLogger().log(
432                             "Thread " + Thread.currentThread() + " failed to prepare transaction branch " + txId,
433                             onfe,
434                             LOG_CHANNEL,
435                             Logger.CRITICAL);
436                         throw new XAException JavaDoc(onfe.toString());
437                     } catch (ServiceAccessException sae) {
438                         getLogger().log(
439                             "Thread " + Thread.currentThread() + " failed to prepare transaction branch " + txId,
440                             sae,
441                             LOG_CHANNEL,
442                             Logger.CRITICAL);
443                         throw new XAException JavaDoc(sae.toString());
444                     }
445                 } else {
446                     getLogger().log(
447                         "Thread " + Thread.currentThread() + " could prepare *unknown* transaction branch " + txId,
448                         LOG_CHANNEL,
449                         Logger.WARNING);
450                 }
451             }
452             int status = rm.prepareTransaction(txId);
453             switch (status) {
454                 case ResourceManager.PREPARE_SUCCESS_READONLY :
455                     return XA_RDONLY;
456                 case ResourceManager.PREPARE_SUCCESS :
457                     return XA_OK;
458                 default :
459                     throw new XAException JavaDoc(XAException.XA_RBROLLBACK);
460             }
461         } catch (ResourceManagerException e) {
462             getLogger().log(
463                 "Thread " + Thread.currentThread() + " failed to prepare transaction branch " + txId,
464                 e,
465                 LOG_CHANNEL,
466                 Logger.CRITICAL);
467             throw createXAException(e);
468         }
469     }
470
471     public synchronized void end(Xid JavaDoc xid, int flags) throws XAException JavaDoc {
472         if (getActiveTxId() == null) {
473             throw new XAException JavaDoc(XAException.XAER_INVAL);
474         }
475         Object JavaDoc txId = wrap(xid);
476         Thread JavaDoc currentThread = Thread.currentThread();
477         getLogger().log(
478             "Thread "
479                 + currentThread
480                 + (flags == TMSUSPEND ? " suspends" : flags == TMFAIL ? " fails" : " ends")
481                 + " work on behalf of transaction branch "
482                 + txId,
483             LOG_CHANNEL,
484             DEBUG_LEVEL);
485
486         switch (flags) {
487             case TMSUSPEND :
488                 suspendedContexts.put(txId, getActiveTxContext());
489                 activeContexts.remove(txId);
490                 activeTransactionBranch.set(null);
491                 break;
492             case TMFAIL :
493                 try {
494                     rm.markTransactionForRollback(wrap(xid));
495                 } catch (ResourceManagerException e) {
496                     throw createXAException(e);
497                 }
498                 activeTransactionBranch.set(null);
499                 break;
500             case TMSUCCESS :
501                 activeTransactionBranch.set(null);
502                 break;
503         }
504     }
505
506     public synchronized void start(Xid JavaDoc xid, int flags) throws XAException JavaDoc {
507         Object JavaDoc txId = wrap(xid);
508         Thread JavaDoc currentThread = Thread.currentThread();
509         getLogger().log(
510             "Thread "
511                 + currentThread
512                 + (flags == TMNOFLAGS ? " starts" : flags == TMJOIN ? " joins" : " resumes")
513                 + " work on behalf of transaction branch "
514                 + txId,
515             LOG_CHANNEL,
516             DEBUG_LEVEL);
517
518         switch (flags) {
519             // a new transaction
520
case TMNOFLAGS :
521                 if (getActiveTxId() != null) {
522                     throw new XAException JavaDoc(XAException.XAER_INVAL);
523                 }
524                 try {
525                     rm.startTransaction(txId);
526                     TxContext txContext = new TxContext(txId);
527                     activeTransactionBranch.set(txContext);
528                     activeContexts.put(txId, txContext);
529                 } catch (ResourceManagerException e) {
530                     throw createXAException(e);
531                 }
532                 break;
533             case TMJOIN :
534                 if (getActiveTxId() != null) {
535                     throw new XAException JavaDoc(XAException.XAER_INVAL);
536                 }
537                 try {
538                     if (rm.getTransactionState(txId) == STATUS_NO_TRANSACTION) {
539                         throw new XAException JavaDoc(XAException.XAER_INVAL);
540                     }
541                 } catch (ResourceManagerException e) {
542                     throw createXAException(e);
543                 }
544                 TxContext txContext = new TxContext(txId);
545                 activeTransactionBranch.set(txContext);
546                 activeContexts.put(txId, txContext);
547                 break;
548             case TMRESUME :
549                 if (getActiveTxId() != null) {
550                     throw new XAException JavaDoc(XAException.XAER_INVAL);
551                 }
552                 txContext = (TxContext) suspendedContexts.remove(txId);
553                 if (txContext == null) {
554                     throw new XAException JavaDoc(XAException.XAER_NOTA);
555                 }
556                 activeTransactionBranch.set(txContext);
557                 break;
558         }
559     }
560
561     /*
562      * --- XMLFileDescriptor access and caching methods ---
563      *
564      *
565      */

566
567     /**
568      * Either returns a cached file descriptor or loads it from DB
569      */

570     protected XMLResourceDescriptor getFileDescriptor(Uri uri) throws ServiceAccessException, ObjectNotFoundException {
571         TxContext txContext = getActiveTxContext();
572         XMLResourceDescriptor xfd;
573         if (txContext != null) {
574             xfd = txContext.lookup(uri);
575             if (xfd == null) {
576                 Object JavaDoc txId = txContext.xid;
577                 xfd = new XMLResourceDescriptor(uri, this, rm, txId, characterEncoding);
578                 xfd.load();
579                 if (txId != null) {
580                     txContext.register(uri, xfd);
581                 }
582             }
583         } else {
584             xfd = new XMLResourceDescriptor(uri, this, rm, null, characterEncoding);
585             xfd.load();
586         }
587         if (!xfd.getUri().equals(uri.toString())) {
588            // this may happen with files systems that don't operate case sensitive
589
// e.g. requested uri /files/test.doc but found /files/TEST.DOC
590
throw new ObjectNotFoundException(uri);
591         }
592         return xfd;
593     }
594     
595     protected TxContext getActiveTxContext() {
596         TxContext context = (TxContext)activeTransactionBranch.get();
597         return context;
598     }
599
600     protected Object JavaDoc getActiveTxId() {
601         TxContext context = (TxContext) activeTransactionBranch.get();
602         return (context == null ? null : context.xid);
603     }
604
605     protected String JavaDoc getLogChannel() {
606         return LOG_CHANNEL;
607     }
608
609     private static class TxContext {
610         public Object JavaDoc xid;
611         public Map JavaDoc descriptors = new HashMap JavaDoc();
612         
613         public TxContext(Object JavaDoc xid) {
614             this.xid = xid;
615         }
616         
617         public void register(Uri uri, XMLResourceDescriptor xfd) {
618             descriptors.put(uri.toString(), xfd);
619         }
620         
621         public void deregister(Uri uri) {
622             descriptors.remove(uri.toString());
623         }
624         
625         public XMLResourceDescriptor lookup(Uri uri) {
626             return (XMLResourceDescriptor) descriptors.get(uri.toString());
627         }
628
629         public Collection JavaDoc list() {
630             return descriptors.values();
631         }
632
633         public void saveDescriptors() throws ObjectNotFoundException, ServiceAccessException {
634             for (Iterator JavaDoc it = list().iterator(); it.hasNext();) {
635                 XMLResourceDescriptor xfd = (XMLResourceDescriptor) it.next();
636                 if (xfd.isRegisteredForSaving()) xfd.save();
637             }
638         }
639
640     }
641 }
642
Popular Tags