KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > aspects > versioned > LocalSynchronizationManager


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.aspects.versioned;
23
24 import org.jboss.logging.Logger;
25 import org.jboss.tm.TransactionLocal;
26 import org.jboss.util.id.GUID;
27
28 import javax.transaction.Status JavaDoc;
29 import javax.transaction.Synchronization JavaDoc;
30 import javax.transaction.Transaction JavaDoc;
31
32 import java.lang.ref.WeakReference JavaDoc;
33 import java.util.ArrayList JavaDoc;
34 import java.util.Collections JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.Hashtable JavaDoc;
37 import java.util.Iterator JavaDoc;
38 import java.util.List JavaDoc;
39
40
41 /**
42  *
43  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
44  * @version $Revision: 43756 $
45  */

46 public class LocalSynchronizationManager implements SynchronizationManager
47 {
48
49    protected static Logger log = Logger.getLogger(DistributedSynchronizationManager.class);
50    protected TransactionLocal txSynch = new TransactionLocal();
51
52    protected Object JavaDoc tableLock = new Object JavaDoc();
53    protected Hashtable JavaDoc objectTable = new Hashtable JavaDoc();
54    protected Hashtable JavaDoc stateTable = new Hashtable JavaDoc();
55    protected DistributedVersionManager versionManager;
56
57    public LocalSynchronizationManager(DistributedVersionManager versionManager)
58    {
59       this.versionManager = versionManager;
60    }
61
62    public Object JavaDoc getObject(GUID guid)
63    {
64       synchronized (tableLock)
65       {
66          WeakReference JavaDoc ref = (WeakReference JavaDoc)objectTable.get(guid);
67          if (ref != null)
68          {
69             return ref.get();
70          }
71          return null;
72       }
73    }
74
75    public void putObject(GUID guid, Object JavaDoc obj)
76    {
77       synchronized (tableLock)
78       {
79          objectTable.put(guid, new WeakReference JavaDoc(obj));
80       }
81    }
82
83    public DistributedState getState(GUID guid)
84    {
85       synchronized (tableLock)
86       {
87          return (DistributedState)stateTable.get(guid);
88       }
89    }
90
91    public void putState(GUID guid, Object JavaDoc obj)
92    {
93       synchronized (tableLock)
94       {
95          stateTable.put(guid, obj);
96       }
97    }
98
99    public void registerUpdate(Transaction JavaDoc tx, DistributedState state)
100       throws Exception JavaDoc
101    {
102       if (tx == null) return;
103       GUID guid = state.getGUID();
104       DistributedStateSynchronization synch = (DistributedStateSynchronization)txSynch.get(tx);
105       if (synch == null)
106       {
107          synch = new DistributedStateSynchronization(tx);
108          txSynch.set(tx, synch);
109          tx.registerSynchronization(synch);
110          synch.updates().put(guid, state);
111          return;
112       }
113       if (synch.updates().containsKey(guid)) return;
114       synch.updates().put(guid, state);
115    }
116
117    public void createObjects(List JavaDoc newObjects) throws Exception JavaDoc
118    {
119       log.trace("in create Objects");
120       for (int i = 0; i < newObjects.size(); i++)
121       {
122          DistributedState state = (DistributedState)newObjects.get(i);
123          synchronized (tableLock)
124          {
125             objectTable.put(state.getGUID(), new WeakReference JavaDoc(state.getObject()));
126             stateTable.put(state.getGUID(), state);
127          }
128       }
129       sendNewObjects(newObjects);
130    }
131
132    public void sendNewObjects(List JavaDoc newObjects) throws Exception JavaDoc
133    {
134       // NOT YET IMPLEMENTED
135
}
136
137    protected void sendClusterUpdatesAndRelease(GUID globalTxId, List JavaDoc clusterUpdates) throws Exception JavaDoc
138    {
139       // HOOKS FOR DISTRIBUTION
140
}
141    protected void acquireRemoteLocks(GUID globalTxId, List JavaDoc guids) throws Exception JavaDoc
142    {
143       // HOOKS FOR DISTRIBUTION
144
}
145
146    public void noTxUpdate(DistributedUpdate update) throws Exception JavaDoc
147    {
148       // HOOKS FOR DISTRIBUTION
149
}
150
151    protected void releaseHeldLocks(List JavaDoc locks)
152    {
153       log.trace("releaseHeldLocks");
154       for (int i = 0; i < locks.size(); i++)
155       {
156          try
157          {
158             DistributedState state = (DistributedState)locks.get(i);
159             state.releaseWriteLock();
160          }
161          catch (Exception JavaDoc ignored)
162          {
163             // ignore exception because we want to release everything no matter what
164
}
165       }
166       log.trace("end releaseHeldLocks");
167    }
168
169    private final class DistributedStateSynchronization implements Synchronization JavaDoc
170    {
171       final Transaction JavaDoc tx;
172       HashMap JavaDoc managers = new HashMap JavaDoc();
173       ArrayList JavaDoc locks; // quick lookup of locks for afterCompletion
174
boolean optimisticLockPassed = false;
175       ArrayList JavaDoc clusterUpdates;
176       GUID globalTxId;
177       public DistributedStateSynchronization(final Transaction JavaDoc tx)
178       {
179          this.tx = tx;
180       }
181
182       public HashMap JavaDoc updates() { return managers; }
183
184
185       public void beforeCompletion()
186       {
187          ArrayList JavaDoc guidList = new ArrayList JavaDoc(managers.keySet());
188
189          // Sort GUID list so that we have ordered locks and avoid deadlock
190
Collections.sort(guidList);
191          clusterUpdates = new ArrayList JavaDoc();
192          locks = new ArrayList JavaDoc(); // keep track of locks so that we can release later on
193
try
194          {
195             for (int i = 0; i < guidList.size(); i++)
196             {
197                GUID guid = (GUID)guidList.get(i);
198                DistributedState manager = (DistributedState)managers.get(guid);
199                log.trace("acquiring writelock in beforecompletion");
200                manager.acquireWriteLock();
201                // Remember lock so that we can release
202
locks.add(manager);
203                manager.checkOptimisticLock(tx);
204                clusterUpdates.add(manager.createTxUpdate(tx));
205             }
206             globalTxId = new GUID();
207             acquireRemoteLocks(globalTxId, guidList);
208          }
209          catch (RuntimeException JavaDoc ex)
210          {
211             // We need to release all locks that have been acquired
212
releaseHeldLocks(locks);
213             throw ex;
214          }
215          catch (Exception JavaDoc ex)
216          {
217             throw new RuntimeException JavaDoc(ex);
218          }
219          optimisticLockPassed = true;
220       }
221
222       public void afterCompletion(int status)
223       {
224          //possible statuses are committed and rolledback
225
if (status != Status.STATUS_ROLLEDBACK)
226          {
227             Iterator JavaDoc it = managers.values().iterator();
228             while (it.hasNext())
229             {
230                DistributedState manager = (DistributedState)it.next();
231                try
232                {
233                   manager.mergeState(tx);
234                }
235                catch (Exception JavaDoc ignored)
236                {
237                   // REVISIT
238
// not sure what to do if there is a failure
239
log.error("afterCompletion failed on mergeState, cache is probably inconsistent and should be flushed", ignored);
240                }
241             }
242             try
243             {
244                // an update should release the lock too
245
sendClusterUpdatesAndRelease(globalTxId, clusterUpdates);
246             }
247             catch (Exception JavaDoc ignored)
248             {
249                // REVISIT
250
// not sure what to do if there is a failure
251
log.error("afterCompletion failed on mergeState, cache is probably inconsistent and should be flushed", ignored);
252             }
253          }
254          if (optimisticLockPassed)
255          {
256             log.trace("afterCompletion releaseHeldLocks");
257             releaseHeldLocks(locks);
258          }
259       }
260    }
261 }
262
Popular Tags