CMIS Binding with Generated Class

Leave a comment

October 28, 2012 by huionn

I prefer strongly typed object to CmisObject. So I would like to convert CmisObject to model object in my client application but it requires to code a lot of getter/setter.

As I am a lazy programmer, I try exploring code generation with cglib. The result is satisfactory. By modifying my XSD parser to generate more metadata, now I can “build” my cmis adaptor with very little code. The magic is performed by cglib Enhancer. The abstract setters and getters are intercepted and implemented through my BindingProperty.

public class CmisBeanBuilder {

 private static GetterSetterInterceptor interceptor = new GetterSetterInterceptor();
 private Enhancer enhancer;

 public CmisBeanBuilder() {
  enhancer = new Enhancer();
 }

 public CmisBeanBuilder withClass(Class clazzOrInterface) {
  enhancer.setSuperclass(clazzOrInterface);
  return this;
 }

 public T build() {
  enhancer.setCallback(interceptor);
  return (T) enhancer.create();
 }

 public T build(Class argumentType, Object argument) {
  return build(new Class[]{argumentType}, new Object[]{argument});
 }

 public T build(Class[] argumentTypes, Object[] arguments) {
  enhancer.setCallback(interceptor);
  return (T) enhancer.create(argumentTypes, arguments);
 }

 private static class GetterSetterInterceptor implements MethodInterceptor {

  public final static Map, Class> primitiveTypeMap = new HashMap<>();

  static {
   primitiveTypeMap.put(boolean.class, Boolean.class);
   primitiveTypeMap.put(byte.class, Byte.class);
   primitiveTypeMap.put(short.class, Short.class);
   primitiveTypeMap.put(char.class, Character.class);
   primitiveTypeMap.put(int.class, Integer.class);
   primitiveTypeMap.put(long.class, Long.class);
   primitiveTypeMap.put(float.class, Float.class);
   primitiveTypeMap.put(double.class, Double.class);
  }

  public GetterSetterInterceptor() {
  }

  @Override
  public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
   if (!Modifier.isAbstract(method.getModifiers())) {
    Object retValFromSuper = proxy.invokeSuper(obj, args);
    return retValFromSuper;
   } else {
    String name = method.getName();
    if (name.startsWith("set")
      && args.length == 1
      && method.getReturnType() == Void.TYPE) {

     String propName = name.substring("set".length());
     propName = Character.toLowerCase(propName.charAt(0)) + propName.substring(1);
     CmisBean cb = (CmisBean) obj;
     cb.getProperty(cb.toPropertyId(propName)).setValue(args[0]);
     return null;
    } else if (name.startsWith("get") && args.length == 0) {

     String propName = name.substring("get".length());
     propName = Character.toLowerCase(propName.charAt(0)) + propName.substring(1);
     CmisBean cb = (CmisBean) obj;
     BindingProperty bp = cb.getProperty(cb.toPropertyId(propName));
     if (bp == null) {
      throw new UnsupportedOperationException(propName + " is not included in query.");
     }
     Object retVal = bp.getValue();
     return convertValue(retVal, method);
    } else if (name.startsWith("is") && args.length == 0
      && (method.getReturnType() == Boolean.TYPE || method.getReturnType() == Boolean.class)) {

     String propName = name.substring("is".length());
     propName = Character.toLowerCase(propName.charAt(0)) + propName.substring(1);
     CmisBean cb = (CmisBean) obj;
     BindingProperty bp = cb.getProperty(cb.toPropertyId(propName));
     if (bp == null) {
      throw new UnsupportedOperationException(propName + " is not included in query.");
     }
     Object retVal = bp.getValue();
     return convertValue(retVal, method);
    } else {
     throw new UnsupportedOperationException(method + " is not implemented");
    }
   }
  }

  private Object convertValue(Object val, Method method) {
   ...
 }
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: