/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