Package org.ajax4jsf.builder.generator

Source Code of org.ajax4jsf.builder.generator.AbstractClassStubBuilder

/**
* License Agreement.
*
* Rich Faces - Natural Ajax for Java Server Faces (JSF)
*
* Copyright (C) 2007 Exadel, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
*/

package org.ajax4jsf.builder.generator;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import net.sf.cglib.core.ClassEmitter;
import net.sf.cglib.core.CodeEmitter;
import net.sf.cglib.core.EmitUtils;
import net.sf.cglib.core.MethodInfo;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.NoOp;

import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Constants;
import org.objectweb.asm.Type;

/**
* @author Nick - mailto:nbelaevski@exadel.com
* created 20.04.2007
*
*/
public class AbstractClassStubBuilder {

  public static Object buildInterfaceStub(final Class<?> clazz, ClassLoader classLoader) throws InstantiationException, IllegalAccessException {
    Enhancer enhancer = new Enhancer() {
      public void generateClass(ClassVisitor v) throws Exception {
        ClassEmitter ce = new ClassEmitter(v);
        ce.begin_class(Constants.V1_5,
            Constants.ACC_PUBLIC,
            getClassName(),
            null,
            new Type[]{Type.getType(clazz)},
            null);
        EmitUtils.null_constructor(ce);
        List methods = new ArrayList();
        getMethods(Object.class, new Class[]{clazz}, methods);

        for (Iterator iterator = methods.iterator(); iterator
        .hasNext();) {
          Method method = (Method) iterator.next();

          if (Modifier.isAbstract(method.getModifiers())) {
            MethodInfo methodInfo = ReflectUtils.getMethodInfo(method);
            Signature signature = methodInfo.getSignature();
            Type returnType = signature.getReturnType();

            CodeEmitter e = ce.begin_method(method.getModifiers() & ~Modifier.ABSTRACT,
                signature, methodInfo.getExceptionTypes(),
                methodInfo.getAttribute());

            e.zero_or_null(returnType);
            e.return_value();

            Type[] argumentTypes = methodInfo.getSignature().getArgumentTypes();
            int size = 0;
            if (argumentTypes != null) {
              for (int i = 0; i < argumentTypes.length; i++) {
                size += argumentTypes[i].getSize();
              }
            }

            // 1 is for this
            e.visitMaxs(returnType.getSize(), size + 1);

            e.end_method();
          }
        }

        ce.end_class();
      }
    };

    enhancer.setCallbackType(NoOp.class);
    enhancer.setInterfaces(new Class[]{clazz});
    enhancer.setClassLoader(classLoader != null ?
        classLoader : clazz.getClassLoader());

    return enhancer.createClass().newInstance();
  }

  public static <T> T buildStub(final Class<T> clazz, MethodInterceptor interceptor,
      ClassLoader classLoader) {
    Class<T> instrumentedClass;

    if ((Modifier.ABSTRACT & clazz.getModifiers()) != 0) {
      Enhancer enhancer = new Enhancer() {
        @Override
        public void generateClass(ClassVisitor v) throws Exception {
          ClassEmitter ce = new ClassEmitter(v);
          ce.begin_class(Constants.V1_5,
              Constants.ACC_PUBLIC,
              getClassName(),
              Type.getType(clazz),
              null,
              null);
          EmitUtils.null_constructor(ce);
          List methods = new ArrayList();
          getMethods(clazz, null, methods);

          for (Iterator iterator = methods.iterator(); iterator
          .hasNext();) {
            Method method = (Method) iterator.next();

            if (Modifier.isAbstract(method.getModifiers())) {
              MethodInfo methodInfo = ReflectUtils.getMethodInfo(method);
              Signature signature = methodInfo.getSignature();
              Type returnType = signature.getReturnType();

              CodeEmitter e = ce.begin_method(method.getModifiers() & ~Modifier.ABSTRACT,
                  signature, methodInfo.getExceptionTypes(),
                  methodInfo.getAttribute());

              e.zero_or_null(returnType);
              e.return_value();

              Type[] argumentTypes = methodInfo.getSignature().getArgumentTypes();
              int size = 0;
              if (argumentTypes != null) {
                for (int i = 0; i < argumentTypes.length; i++) {
                  size += argumentTypes[i].getSize();
                }
              }

              // 1 is for this
              e.visitMaxs(returnType.getSize(), size + 1);

              e.end_method();
            }
          }

          ce.end_class();
        }
      };
      enhancer.setSuperclass(clazz);
      enhancer.setCallbackType(MethodInterceptor.class);
      enhancer.setClassLoader(classLoader != null ?
          classLoader : clazz.getClassLoader());
      instrumentedClass = enhancer.createClass();
    } else {
      instrumentedClass = clazz;
    }

    Enhancer enhancer2 = new Enhancer();
    enhancer2.setSuperclass(instrumentedClass);
    enhancer2.setCallback(interceptor);
    enhancer2.setClassLoader(instrumentedClass.getClassLoader());

    return (T) enhancer2.create();
  }
}


TOP

Related Classes of org.ajax4jsf.builder.generator.AbstractClassStubBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.