/Users/lyon/j4p/src/javassist/sample/evolve/VersionManager.java

1    package javassist.sample.evolve; 
2     
3    import java.util.Hashtable; 
4    import java.lang.reflect.*; 
5     
6    import javassist.CtClass; 
7     
8    /** 
9     * Runtime system for class evolution 
10    */ 
11   public class VersionManager { 
12       private static Hashtable versionNo = new Hashtable(); 
13       public final static String latestVersionField = "_version"; 
14    
15       /** 
16        * For updating the definition of class my.X, say: 
17        * 
18        * VersionManager.update("my.X"); 
19        */ 
20       public static void update(String qualifiedClassname) 
21               throws CannotUpdateException { 
22           try { 
23               Class c = getUpdatedClass(qualifiedClassname); 
24               Field f = c.getField(latestVersionField); 
25               f.set(null, c); 
26           } catch (ClassNotFoundException e) { 
27               throw new CannotUpdateException("cannot update class: " 
28                       + qualifiedClassname); 
29           } catch (Exception e) { 
30               throw new CannotUpdateException(e); 
31           } 
32       } 
33    
34       private static Class getUpdatedClass(String qualifiedClassname) 
35               throws ClassNotFoundException { 
36           int version; 
37           Object found = versionNo.get(qualifiedClassname); 
38           if (found == null) 
39               version = 0; 
40           else 
41               version = ((Integer) found).intValue() + 1; 
42    
43           Class c = Class.forName(qualifiedClassname + '$' + version); 
44           versionNo.put(qualifiedClassname, new Integer(version)); 
45           return c; 
46       } 
47    
48       /* initiaVersion() is used to initialize the _version field of 
49        * the updatable classes. 
50        */ 
51       public static Class initialVersion(String[] params) { 
52           try { 
53               return getUpdatedClass(params[0]); 
54           } catch (ClassNotFoundException e) { 
55               throw new RuntimeException("cannot initialize " + params[0]); 
56           } 
57       } 
58    
59       /** make() performs the object creation of the updatable classes. 
60        * The expression "new <updatable class>" is replaced with a call 
61        * to this method. 
62        */ 
63       public static Object make(Class clazz, Object[] args) { 
64           Constructor[] constructors = clazz.getConstructors(); 
65           int n = constructors.length; 
66           for (int i = 0; i < n; ++i) { 
67               try { 
68                   return constructors[i].newInstance(args); 
69               } catch (IllegalArgumentException e) { 
70                   // try again 
71               } catch (InstantiationException e) { 
72                   throw new CannotCreateException(e); 
73               } catch (IllegalAccessException e) { 
74                   throw new CannotCreateException(e); 
75               } catch (InvocationTargetException e) { 
76                   throw new CannotCreateException(e); 
77               } 
78           } 
79    
80           throw new CannotCreateException("no constructor matches"); 
81       } 
82   } 
83