KickJava   Java API By Example, From Geeks To Geeks.

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


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.aop.InstanceAdvised;
25 import org.jboss.aop.proxy.ClassProxy;
26 import org.jboss.aop.proxy.ClassProxyFactory;
27 import org.jboss.logging.Logger;
28 import org.jboss.tm.TransactionLocal;
29 import org.jboss.util.id.GUID;
30
31 import javax.naming.InitialContext JavaDoc;
32 import javax.transaction.Transaction JavaDoc;
33 import javax.transaction.TransactionManager JavaDoc;
34 import java.lang.reflect.Method JavaDoc;
35 import java.util.Collection JavaDoc;
36 import java.util.HashMap JavaDoc;
37 import java.util.Iterator JavaDoc;
38 import java.util.Map JavaDoc;
39 import java.util.Set JavaDoc;
40
41
42 /**
43  *
44  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
45  * @version $Revision: 37406 $
46  */

47 public class DistributedMapState extends CollectionStateManager implements Map JavaDoc, DistributedState, java.io.Externalizable JavaDoc
48 {
49    private static final long serialVersionUID = -5397547850033533784L;
50
51    private static HashMap JavaDoc mapMethodMap;
52
53    protected static Logger log = Logger.getLogger(DistributedMapState.class);
54    static
55    {
56       try
57       {
58          mapMethodMap = new HashMap JavaDoc();
59          Method JavaDoc[] methods = Map JavaDoc.class.getDeclaredMethods();
60          for (int i = 0; i < methods.length; i++)
61          {
62             long hash = org.jboss.aop.util.MethodHashing.methodHash(methods[i]);
63             mapMethodMap.put(new Long JavaDoc(hash), methods[i]);
64          }
65
66       }
67       catch (Exception JavaDoc ignored)
68       {
69          ignored.printStackTrace();
70       }
71    }
72
73    protected volatile long versionId;
74    protected HashMap JavaDoc updates;
75    protected String JavaDoc classname;
76    transient protected Map JavaDoc base;
77    transient protected TransactionLocal txState = new TransactionLocal();
78    transient protected TransactionLocal txVersion = new TransactionLocal();
79    transient protected DistributedVersionManager versionManager;
80    transient protected SynchronizationManager synchManager;
81    transient protected TransactionManager JavaDoc tm;
82    transient protected ClassProxy proxy;
83
84    /**
85     * For serialization
86     */

87    public DistributedMapState() {}
88
89
90    public DistributedMapState(GUID guid, long timeout, ClassProxy proxy, Map JavaDoc obj, DistributedVersionManager versionManager, SynchronizationManager synchManager)
91       throws Exception JavaDoc
92    {
93       super(guid, timeout, mapMethodMap);
94       this.base = obj;
95       this.classname = obj.getClass().getName();
96       this.versionManager = versionManager;
97       this.synchManager = synchManager;
98       this.proxy = proxy;
99       InitialContext JavaDoc ctx = new InitialContext JavaDoc();
100       this.tm = (TransactionManager JavaDoc)ctx.lookup("java:/TransactionManager");
101       this.updates = createMapUpdates(base);
102    }
103
104    public HashMap JavaDoc getMethodMap()
105    {
106       return ClassProxyFactory.getMethodMap(base.getClass().getName());
107    }
108
109    public InstanceAdvised getObject() { return proxy; }
110
111    // The Guts
112

113    protected Map JavaDoc getCurrentState(boolean forUpdate) throws Exception JavaDoc
114    {
115       Transaction JavaDoc tx = tm.getTransaction();
116       if (tx == null)
117       {
118          if (forUpdate) versionId++;
119          return base;
120       }
121
122       Map JavaDoc state = (Map JavaDoc)txState.get(tx);
123       if (state == null && forUpdate)
124       {
125          state = (Map JavaDoc)base.getClass().newInstance();
126          state.putAll(base);
127          txState.set(tx, state);
128          long newId = versionId + 1;
129          synchManager.registerUpdate(tx, this);
130          txVersion.set(tx, new Long JavaDoc(newId));
131          return state;
132       }
133       return base;
134    }
135
136
137    protected HashMap JavaDoc createMapUpdates(Map JavaDoc state)
138    {
139       HashMap JavaDoc mapUpdates = new HashMap JavaDoc();
140       Iterator JavaDoc it = state.entrySet().iterator();
141       while (it.hasNext())
142       {
143          Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
144          Object JavaDoc obj = entry.getValue();
145          if (versionManager.isVersioned(obj))
146          {
147             mapUpdates.put(entry.getKey(), new VersionReference(VersionManager.getGUID((InstanceAdvised)obj)));
148          }
149          else
150          {
151             mapUpdates.put(entry.getKey(), obj);
152          }
153       }
154       return mapUpdates;
155    }
156
157    public DistributedUpdate createTxUpdate(Transaction JavaDoc tx)
158    {
159       Map JavaDoc state = (Map JavaDoc)txState.get(tx);
160       long newId = ((Long JavaDoc)txVersion.get(tx)).longValue();
161       DistributedMapUpdate update = new DistributedMapUpdate(guid, createMapUpdates(state), newId);
162       return update;
163    }
164
165    public InstanceAdvised buildObject(SynchronizationManager manager, DistributedVersionManager versionManager)
166       throws Exception JavaDoc
167    {
168       log.trace("building a Map");
169       this.versionManager = versionManager;
170       this.synchManager = manager;
171       log.trace("DistributedMaptState: classname: " + classname);
172       Class JavaDoc clazz = Thread.currentThread().getContextClassLoader().loadClass(classname);
173       base = (Map JavaDoc)clazz.newInstance();
174       Iterator JavaDoc it = updates.entrySet().iterator();
175       while (it.hasNext())
176       {
177          Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
178          Object JavaDoc val = entry.getValue();
179          if (val instanceof VersionReference)
180          {
181             VersionReference ref = (VersionReference)val;
182             val = manager.getObject(ref.getGUID());
183             if (val == null)
184             {
185                DistributedState fieldVal = manager.getState(ref.getGUID());
186                val = fieldVal.buildObject(manager, versionManager);
187                ref.set((InstanceAdvised)val);
188             }
189          }
190          base.put(entry.getKey(), val);
191       }
192       proxy = versionManager.addMapVersioning(base, this);
193       return proxy;
194    }
195
196    public void checkOptimisticLock(Transaction JavaDoc tx)
197    {
198       // NOTE THIS CODE ASSUMES THAT A WRITELOCK HAS BEEN ACQUIRED!!!!
199
Long JavaDoc version = (Long JavaDoc)txVersion.get(tx);
200       if (version.longValue() <= versionId)
201          throw new OptimisticLockFailure("optimistic lock failure for list");
202    }
203
204    public void mergeState(Transaction JavaDoc tx) throws Exception JavaDoc
205    {
206       // NOTE THIS CODE ASSUMES THAT A WRITELOCK HAS BEEN ACQUIRED!!!!
207
Map JavaDoc current = (Map JavaDoc)txState.get(tx);
208       base = current;
209       Long JavaDoc version = (Long JavaDoc)txVersion.get(tx);
210       versionId = version.longValue();
211    }
212
213    public void mergeState(DistributedUpdate update) throws Exception JavaDoc
214    {
215       DistributedMapUpdate mapUpdate = (DistributedMapUpdate)update;
216       this.versionId = mapUpdate.versionId;
217       base.clear();
218       Iterator JavaDoc it = mapUpdate.mapUpdates.entrySet().iterator();
219       while (it.hasNext())
220       {
221          Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
222          Object JavaDoc val = entry.getValue();
223          if (val instanceof VersionReference)
224          {
225             VersionReference ref = (VersionReference)val;
226             val = synchManager.getObject(ref.getGUID());
227             ref.set((InstanceAdvised)val);
228          }
229          base.put(entry.getKey(), val);
230       }
231       updates = mapUpdate.mapUpdates;
232    }
233
234    // java.util.Map wrap
235

236    public void clear()
237    {
238       try
239       {
240          lock.readLock().acquire();
241          try
242          {
243             Map JavaDoc state = getCurrentState(true);
244             state.clear();
245          }
246          finally
247          {
248             lock.readLock().release();
249          }
250       }
251       catch (Exception JavaDoc ex)
252       {
253          throw new RuntimeException JavaDoc(ex);
254       }
255    }
256
257    public boolean containsKey(Object JavaDoc o)
258    {
259       try
260       {
261          lock.readLock().acquire();
262          try
263          {
264             Map JavaDoc state = getCurrentState(false);
265             return state.containsKey(o);
266          }
267          finally
268          {
269             lock.readLock().release();
270          }
271       }
272       catch (Exception JavaDoc ex)
273       {
274          throw new RuntimeException JavaDoc(ex);
275       }
276    }
277
278    public boolean containsValue(Object JavaDoc o)
279    {
280       try
281       {
282          lock.readLock().acquire();
283          try
284          {
285             Map JavaDoc state = getCurrentState(false);
286             return state.containsKey(o);
287          }
288          finally
289          {
290             lock.readLock().release();
291          }
292       }
293       catch (Exception JavaDoc ex)
294       {
295          throw new RuntimeException JavaDoc(ex);
296       }
297    }
298
299    public Set JavaDoc entrySet()
300    {
301       try
302       {
303          lock.readLock().acquire();
304          try
305          {
306             Map JavaDoc state = getCurrentState(false);
307             return state.entrySet();
308          }
309          finally
310          {
311             lock.readLock().release();
312          }
313       }
314       catch (Exception JavaDoc ex)
315       {
316          throw new RuntimeException JavaDoc(ex);
317       }
318    }
319
320    public boolean equals(Object JavaDoc o)
321    {
322       try
323       {
324          lock.readLock().acquire();
325          try
326          {
327             Map JavaDoc state = getCurrentState(false);
328             return state.equals(o);
329          }
330          finally
331          {
332             lock.readLock().release();
333          }
334       }
335       catch (Exception JavaDoc ex)
336       {
337          throw new RuntimeException JavaDoc(ex);
338       }
339    }
340
341    public Object JavaDoc get(Object JavaDoc o)
342    {
343       try
344       {
345          lock.readLock().acquire();
346          try
347          {
348             Map JavaDoc state = getCurrentState(false);
349             return state.get(o);
350          }
351          finally
352          {
353             lock.readLock().release();
354          }
355       }
356       catch (Exception JavaDoc ex)
357       {
358          throw new RuntimeException JavaDoc(ex);
359       }
360    }
361
362    public int hashCode()
363    {
364       try
365       {
366          lock.readLock().acquire();
367          try
368          {
369             Map JavaDoc state = getCurrentState(false);
370             return state.hashCode();
371          }
372          finally
373          {
374             lock.readLock().release();
375          }
376       }
377       catch (Exception JavaDoc ex)
378       {
379          throw new RuntimeException JavaDoc(ex);
380       }
381    }
382    public boolean isEmpty()
383    {
384       try
385       {
386          lock.readLock().acquire();
387          try
388          {
389             Map JavaDoc state = getCurrentState(false);
390             return state.isEmpty();
391          }
392          finally
393          {
394             lock.readLock().release();
395          }
396       }
397       catch (Exception JavaDoc ex)
398       {
399          throw new RuntimeException JavaDoc(ex);
400       }
401    }
402
403    public Set JavaDoc keySet()
404    {
405       try
406       {
407          lock.readLock().acquire();
408          try
409          {
410             Map JavaDoc state = getCurrentState(false);
411             return state.keySet();
412          }
413          finally
414          {
415             lock.readLock().release();
416          }
417       }
418       catch (Exception JavaDoc ex)
419       {
420          throw new RuntimeException JavaDoc(ex);
421       }
422    }
423
424    public Object JavaDoc put(Object JavaDoc key, Object JavaDoc val)
425    {
426       try
427       {
428          lock.readLock().acquire();
429          try
430          {
431             val = versionManager.makeVersioned(val);
432             Map JavaDoc state = getCurrentState(true);
433             return state.put(key, val);
434          }
435          finally
436          {
437             lock.readLock().release();
438          }
439       }
440       catch (Exception JavaDoc ex)
441       {
442          throw new RuntimeException JavaDoc(ex);
443       }
444    }
445
446    public void putAll(Map JavaDoc c)
447    {
448       try
449       {
450          lock.readLock().acquire();
451          try
452          {
453             Map JavaDoc state = getCurrentState(true);
454             Iterator JavaDoc it = state.entrySet().iterator();
455             while (it.hasNext())
456             {
457                Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
458                Object JavaDoc val = versionManager.makeVersioned(entry.getValue());
459                state.put(entry.getKey(), val);
460             }
461          }
462          finally
463          {
464             lock.readLock().release();
465          }
466       }
467       catch (Exception JavaDoc ex)
468       {
469          throw new RuntimeException JavaDoc(ex);
470       }
471    }
472    // REVISIT: On the remove stuff, we need to decide what happens
473
// does the object removed get unversioned? How is this handled
474
// within a transaction?
475
//
476
public Object JavaDoc remove(Object JavaDoc key)
477    {
478       try
479       {
480          lock.readLock().acquire();
481          try
482          {
483             Map JavaDoc state = getCurrentState(true);
484             return state.remove(key);
485          }
486          finally
487          {
488             lock.readLock().release();
489          }
490       }
491       catch (Exception JavaDoc ex)
492       {
493          throw new RuntimeException JavaDoc(ex);
494       }
495    }
496
497    public int size()
498    {
499       try
500       {
501          lock.readLock().acquire();
502          try
503          {
504             Map JavaDoc state = getCurrentState(false);
505             return state.size();
506          }
507          finally
508          {
509             lock.readLock().release();
510          }
511       }
512       catch (Exception JavaDoc ex)
513       {
514          throw new RuntimeException JavaDoc(ex);
515       }
516    }
517
518    public Collection JavaDoc values()
519    {
520       try
521       {
522          lock.readLock().acquire();
523          try
524          {
525             Map JavaDoc state = getCurrentState(false);
526             return state.values();
527          }
528          finally
529          {
530             lock.readLock().release();
531          }
532       }
533       catch (Exception JavaDoc ex)
534       {
535          throw new RuntimeException JavaDoc(ex);
536       }
537    }
538
539    public void writeExternal(java.io.ObjectOutput JavaDoc out)
540       throws java.io.IOException JavaDoc
541    {
542       super.writeExternal(out);
543       out.writeLong(versionId);
544       out.writeObject(updates);
545       out.writeObject(classname);
546    }
547
548    public void readExternal(java.io.ObjectInput JavaDoc in)
549       throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc
550    {
551       super.readExternal(in);
552       versionId = in.readLong();
553       this.updates = (HashMap JavaDoc)in.readObject();
554       this.classname = (String JavaDoc)in.readObject();
555       try
556       {
557          InitialContext JavaDoc ctx = new InitialContext JavaDoc();
558          this.tm = (TransactionManager JavaDoc)ctx.lookup("java:/TransactionManager");
559       }
560       catch (Exception JavaDoc ex)
561       {
562          throw new RuntimeException JavaDoc(ex);
563       }
564       this.txState = new TransactionLocal();
565       this.txVersion = new TransactionLocal();
566       this.methodMap = mapMethodMap;
567    }
568
569 }
570
Popular Tags