Q:

Java - Using Proxy Classes

So I have a couple of classes ClassA through ClassC (not implemented by myself, so I can't modify their source). Each class implements some common functions, and some unique ones. These classes are used to provide different types of authentication behavior to a datasource. So for instance, here is an example of what each class implements:
// Uses pre-configured privileged user credentials to get data
ClassA.getUsers(...)

// Saves session to allow user to log-in once and perform any operation after that without repeated authentication
ClassB.login(Username, Password)
ClassB.logout()
ClassB.getUsers(..., Username, Password)

// Uses given token to authenticate user and get data
ClassC.getUsers(..., Token)

I am trying to develop a ProxyClass for these classes such that I can make calls like so:
ProxyClass
  .getUsers(...);                     => calls ClassA.getUsers(...)

ProxyClass
  .authenticate(Token)
  .getUsers(...);                     => calls ClassC.getUsers(..., Token)

T obj = ProxyClass
  .authenticate(Username, Password);  => calls ClassD.login(Username, Password)

obj.getUsers(...)                     => calls ClassD.getUsers(...)
obj.logout()                          => calls ClassD.logout();

Is this even possible? If it possible, can someone guide me as to how the ProxyClass will look like?
Is it possible to ensure that, for instance, if ClassC did not have getUsers(), then ProxyClass.authentication(Token). would not show getUsers at all?
Is it possible to do something like if a method in the proxied classes is declared as void, we return an instance of the proxied class again, so the caller of proxy can chain calls together?
A full solution, if possible, would definitely be nice. But I'll settle for a partial one as well. If I have a good starting point, I can probably work out the remainder. But right now I don't know how to even begin implementing it in the first place. :(
Thanks, AweSIM

EDIT I think I should've mentioned that by ProxyClass, I meant DynamicProxy classes. Which involves reflection in method invoking. If that's not possible, or not insanely complicated, I guess I'll have to settle with static proxy classes.

A:

Sure.
package utils;

public class ProxyClasses {

    public static class ClassA {
        public void function1(Object arg1, Object arg2, Object arg3) {}
    }
    public static class ClassB {
        public void function1(Object arg1, Object arg2, Object arg3, String username, String password) {}
    }
    public static class ClassC {
        public void function1(Object arg1, Object arg2, Object arg3, String token) {}
    }

    public static interface ClassCommon {
        ProxyClasses function1(Object arg1, Object arg2, Object arg3); // or whatever
    }
    public static class ProxyClass implements ClassCommon {
        @Override
        public void function1(Object arg1, Object arg2, Object arg3) {
            new ClassA().function1(arg1, arg2, arg3);
        }

        public ClassCommon authenticate() {
            return new ClassCommon() {
                @Override
                public void function1(Object arg1, Object arg2, Object arg3) {
                    new ClassA().function1(arg1, arg2, arg3);
                    return this;
                }
            };
        }
        public ClassCommon authenticate(final String username, final String password) {
            ClassB classB = new ClassB();
            classB.login(username, password);
            return new ClassCommon() {
                @Override
                public void function1(Object arg1, Object arg2, Object arg3) {
                    new ClassB().function1(arg1, arg2, arg3, username, password);
                    return this;
                }
            };
        }
        public ClassCommon authenticate(final String token) {
            return new ClassCommon() {
                @Override
                public void function1(Object arg1, Object arg2, Object arg3) {
                    new ClassC().function1(arg1, arg2, arg3, token);
                    return this;
                }
            };
        }
    }
}

