View Javadoc

1   /*
2    * Copyright 2004 Charles Blaxland
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 mnemosyne.system;
17  
18  import mnemosyne.archiver.Archiver;
19  import mnemosyne.archiver.ArchiverException;
20  import mnemosyne.core.*;
21  import mnemosyne.util.PersistenceRuntimeException;
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  
25  /***
26   * @version $Id: LocalPersistentSystem.java,v 1.1.1.1 2004/08/07 06:41:22 charlesblaxland Exp $
27   */
28  public class LocalPersistentSystem implements PersistentSystem
29  {
30      private static final Log log = LogFactory.getLog(LocalPersistentSystem.class);
31  
32      private PersistentRoot root;
33  
34      private Archiver archiver;
35      private VersionManager versionMgr;
36  
37      public LocalPersistentSystem(Archiver archiver, VersionManager versionMgr) throws InitializationException
38      {
39          this.archiver = archiver;
40          this.versionMgr = versionMgr;
41          try
42          {
43              root = this.archiver.loadLatest();
44          }
45          catch (ArchiverException e)
46          {
47              throw new InitializationException("Unable to load persistent data from archiver", e);
48          }
49      }
50  
51      public void advanceVersion()
52      {
53          versionMgr.advanceThisThreadsVersion();
54      }
55  
56      public Object getPersistentRoot(String rootName)
57      {
58          return root.getPersistentRoot(rootName);
59      }
60  
61      public void setPersistentRoot(String rootName, Object value)
62      {
63          root.setPersistentRoot(rootName, value);
64      }
65  
66      public void removePersistentRoot(String rootName)
67      {
68          setPersistentRoot(rootName, null);
69      }
70  
71      public void beginTransaction()
72      {
73          log.info("beginTransaction");
74          PersistentContext context = PersistentContext.get(versionMgr);
75          if (context.isInTransaction())
76          {
77              throw new PersistenceRuntimeException("Nested transactions not supported");
78          }
79  
80          advanceVersion();
81          Transaction transaction = new StandardTransaction();
82          context.setTransaction(transaction);
83      }
84  
85      public void endTransaction() throws TransactionAbortedException
86      {
87          // TODO - review failure scenarios
88          log.info("endTransaction");
89          PersistentContext context = PersistentContext.get(versionMgr);
90          Transaction transaction = context.getTransaction();
91          if (transaction == null)
92          {
93              throw new PersistenceRuntimeException("endTransaction called when no transaction was active");
94          }
95  
96          try
97          {
98              transaction.prepareForCommit();
99              archiver.saveTransaction(transaction);
100         }
101         catch (ArchiverException e)
102         {
103             transaction.rollback();
104             throw new TransactionAbortedException("Unable to archive transaction", e);
105         }
106 
107         // At this point the transaction should be regarded as "successful" and should not fail!
108 
109         // TODO - could possibly get rid of this synchronized block if we do some trickiness with the version updating...
110         synchronized(this)
111         {
112             Version newVersion = versionMgr.getNextVersion();
113             log.debug("Assigned version " + newVersion + " to this transaction");
114             transaction.commit(newVersion);
115 
116             // Make this new data "visible" to everyone else
117             versionMgr.setLatestVersion(newVersion);
118         }
119 
120         context.setTransaction(null);
121         advanceVersion();
122         log.debug("Transaction committed");
123     }
124 }