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