Search code examples
delegatesjavassistactivejdbc

How to understand this delegator


I'm reading the source of activejdbc, found these methods in ModelInstrumentation.

public void instrument(CtClass modelClass) throws Exception {
    addDelegates(modelClass);
    CtMethod m = CtNewMethod.make("public static String getClassName() { return \"" + modelClass.getName()
            + "\"; }", modelClass);
    CtMethod getClassNameMethod = modelClass.getDeclaredMethod("getClassName");
    modelClass.removeMethod(getClassNameMethod);
    modelClass.addMethod(m);
}

CtClass modelClass = ClassPool.getDefault().get("org.javalite.activejdbc.Model");

private void addDelegates(CtClass target) throws NotFoundException, CannotCompileException {
    CtMethod[] modelMethods = modelClass.getDeclaredMethods();
    CtMethod[] targetMethods = target.getDeclaredMethods();
    for (CtMethod method : modelMethods) {

        if (Modifier.PRIVATE == method.getModifiers()) {
            continue;
        }

        CtMethod newMethod = CtNewMethod.delegator(method, target);

        if (!targetHasMethod(targetMethods, newMethod)) {
            target.addMethod(newMethod);
        } else {
            System.out.println("Detected method: " + newMethod.getName() + ", skipping delegate.");
        }
    }

}

This class is used to enhance a model class, the first one instrument will firstly delegate all non-private methods from org.javalite.activejdbc.Model to its child model class, which means it will add such methods to the child:

public X f(...) {
    return super.f(...);
}

I don't understand why it does this, since we can invoke these methods even if there is no delegates.


Solution

  • Explanation of this can be found in this discussion:

    https://groups.google.com/forum/#!topic/activejdbc-group/l6KNBi5EPc0

    Basically, the main problem is that the methods in the Model class that we need in a child class are static. Static classes in Java are not inherited. This means that when you do this:

    Person.where(...)
    

    You will be executing the method Model.where(), not the Person.where(), hence the framework would have no idea what table to query. ActiveJDBC forces Model methods into child methods in order to at run time determine what table to go to for data.