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