diff options
Diffstat (limited to 'sample/evolve/VersionManager.java')
-rw-r--r-- | sample/evolve/VersionManager.java | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/sample/evolve/VersionManager.java b/sample/evolve/VersionManager.java new file mode 100644 index 00000000..d95268b8 --- /dev/null +++ b/sample/evolve/VersionManager.java @@ -0,0 +1,90 @@ +package sample.evolve;
+
+import java.util.Hashtable;
+import java.lang.reflect.*;
+import javassist.CtClass;
+
+/**
+ * Runtime system for class evolution
+ */
+public class VersionManager {
+ private static Hashtable versionNo = new Hashtable();
+ public final static String latestVersionField = "_version";
+
+ /**
+ * For updating the definition of class my.X, say:
+ *
+ * VersionManager.update("my.X");
+ */
+ public static void update(String qualifiedClassname)
+ throws CannotUpdateException
+ {
+ try {
+ Class c = getUpdatedClass(qualifiedClassname);
+ Field f = c.getField(latestVersionField);
+ f.set(null, c);
+ }
+ catch (ClassNotFoundException e) {
+ throw new CannotUpdateException("cannot update class: "
+ + qualifiedClassname);
+ }
+ catch (Exception e) {
+ throw new CannotUpdateException(e);
+ }
+ }
+
+ private static Class getUpdatedClass(String qualifiedClassname)
+ throws ClassNotFoundException
+ {
+ int version;
+ Object found = versionNo.get(qualifiedClassname);
+ if (found == null)
+ version = 0;
+ else
+ version = ((Integer)found).intValue() + 1;
+
+ Class c = Class.forName(qualifiedClassname + '$' + version);
+ versionNo.put(qualifiedClassname, new Integer(version));
+ return c;
+ }
+
+ /* initiaVersion() is used to initialize the _version field of
+ * the updatable classes.
+ */
+ public static Class initialVersion(String[] params) {
+ try {
+ return getUpdatedClass(params[0]);
+ }
+ catch (ClassNotFoundException e) {
+ throw new RuntimeException("cannot initialize " + params[0]);
+ }
+ }
+
+ /** make() performs the object creation of the updatable classes.
+ * The expression "new <updatable class>" is replaced with a call
+ * to this method.
+ */
+ public static Object make(Class clazz, Object[] args) {
+ Constructor[] constructors = clazz.getConstructors();
+ int n = constructors.length;
+ for (int i = 0; i < n; ++i) {
+ try {
+ return constructors[i].newInstance(args);
+ }
+ catch (IllegalArgumentException e) {
+ // try again
+ }
+ catch (InstantiationException e) {
+ throw new CannotCreateException(e);
+ }
+ catch (IllegalAccessException e) {
+ throw new CannotCreateException(e);
+ }
+ catch (InvocationTargetException e) {
+ throw new CannotCreateException(e);
+ }
+ }
+
+ throw new CannotCreateException("no constructor matches");
+ }
+}
|