factory additions
[IRC.git] / Robust / Transactions / dstm2 / src / dstm2 / factory / twophase / Adapter.java
1 /*
2  * Adapter.java
3  *
4  * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, Santa
5  * Clara, California 95054, U.S.A.  All rights reserved.  
6  * 
7  * Sun Microsystems, Inc. has intellectual property rights relating to
8  * technology embodied in the product that is described in this
9  * document.  In particular, and without limitation, these
10  * intellectual property rights may include one or more of the
11  * U.S. patents listed at http://www.sun.com/patents and one or more
12  * additional patents or pending patent applications in the U.S. and
13  * in other countries.
14  * 
15  * U.S. Government Rights - Commercial software.
16  * Government users are subject to the Sun Microsystems, Inc. standard
17  * license agreement and applicable provisions of the FAR and its
18  * supplements.  Use is subject to license terms.  Sun, Sun
19  * Microsystems, the Sun logo and Java are trademarks or registered
20  * trademarks of Sun Microsystems, Inc. in the U.S. and other
21  * countries.  
22  * 
23  * This product is covered and controlled by U.S. Export Control laws
24  * and may be subject to the export or import laws in other countries.
25  * Nuclear, missile, chemical biological weapons or nuclear maritime
26  * end uses or end users, whether direct or indirect, are strictly
27  * prohibited.  Export or reexport to countries subject to
28  * U.S. embargo or to entities identified on U.S. export exclusion
29  * lists, including, but not limited to, the denied persons and
30  * specially designated nationals lists is strictly prohibited.
31  */
32
33 package dstm2.factory.twophase;
34 import dstm2.ContentionManager;
35 import dstm2.Transaction;
36 import TransactionalIO.exceptions.AbortedException;
37 import TransactionalIO.exceptions.PanicException;
38 import TransactionalIO.exceptions.SnapshotException;
39 import dstm2.factory.Factory;
40 import dstm2.Thread;
41 import dstm2.factory.shadow.Recoverable;
42 import dstm2.factory.shadow.RecoverableFactory;
43 import java.lang.Class;
44 import java.lang.reflect.InvocationTargetException;
45 import java.lang.reflect.Method;
46 import java.util.HashMap;
47 import java.util.Map;
48 import java.util.Set;
49 import java.util.concurrent.atomic.AtomicReference;
50 import java.util.concurrent.locks.Lock;
51 import java.util.concurrent.locks.ReentrantLock;
52 import java.util.concurrent.TimeUnit;
53
54 /**
55  * Simple two-phase locking implementation.
56  * @author Maurice Herlihy
57  */
58 public class Adapter<T> implements dstm2.factory.Adapter<T> {
59   T version;
60   Lock lock;
61   boolean firstTime;
62   private final String FORMAT = "Unexpected transaction state: %s";
63   private static Map<Class,Factory> map = new HashMap<Class,Factory>();
64   
65   /**
66    * Creates a new instance of Adapter
67    */
68   public Adapter(Class<T> _class) {
69     lock = new ReentrantLock();
70     Factory<T> factory = map.get(_class);
71     if (factory == null) {
72       factory = new RecoverableFactory(_class);
73       map.put(_class, factory);
74     }
75     version = factory.create();
76     firstTime = true;
77   }
78   
79   public <V> Adapter.Getter<V> makeGetter(String methodName, Class<V> _class)  {
80     try {
81       final Method method = version.getClass().getMethod(methodName);
82       return new Adapter.Getter<V>() {
83         public V call() {
84           try{
85             lock.lock();
86             if (firstTime) {
87               ((Recoverable)version).backup();
88               firstTime = false;
89             }
90     Thread.onCommitOnce( new Runnable() {
91       public void run() {
92         lock.unlock();
93       }
94     });
95     Thread.onAbortOnce( new Runnable() {
96       public void run() {
97         lock.unlock();
98         ((Recoverable)version).recover();
99       }
100     });
101             return (V)method.invoke(version);
102           } catch (IllegalArgumentException ex) {
103             throw new PanicException(ex);
104           } catch (IllegalAccessException ex) {
105             throw new PanicException(ex);
106           } catch (InvocationTargetException ex) {
107             throw new PanicException(ex);
108           }
109         }};
110     } catch (NoSuchMethodException e) {
111       throw new PanicException(e);
112     }
113   }
114   
115   public <V> Adapter.Setter<V> makeSetter(String methodName, Class<V> _class)  {
116     try {
117       final Method method = version.getClass().getMethod(methodName, _class);
118       return new Adapter.Setter<V>() {
119         public void call(V value) {
120           try{
121             lock.lock();
122             if (firstTime) {
123               ((Recoverable)version).backup();
124               firstTime = false;
125             }
126     Thread.onCommitOnce( new Runnable() {
127       public void run() {
128         lock.unlock();
129       }
130     });
131     Thread.onAbortOnce( new Runnable() {
132       public void run() {
133         lock.unlock();
134         ((Recoverable)version).recover();
135       }
136     });
137             method.invoke(version, value);
138           } catch (IllegalArgumentException ex) {
139             throw new PanicException(ex);
140           } catch (IllegalAccessException ex) {
141             throw new PanicException(ex);
142           } catch (InvocationTargetException ex) {
143             throw new PanicException(ex);
144           }
145         }};
146     } catch (NoSuchMethodException e) {
147       throw new PanicException(e);
148     }
149   }
150 }
151