Package org.springsource.loaded.ri

Source Code of org.springsource.loaded.ri.ReloadedTypeInvoker

/*
* Copyright 2010-2012 VMware and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springsource.loaded.ri;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import org.objectweb.asm.Type;
import org.springsource.loaded.CurrentLiveVersion;
import org.springsource.loaded.GlobalConfiguration;
import org.springsource.loaded.MethodMember;
import org.springsource.loaded.ReloadableType;
import org.springsource.loaded.Utils;
import org.springsource.loaded.jvm.JVM;


/**
* Common super type for Invoker for a method on a reloaded type.
*
* @author Kris De Volder
* @since 0.5.0
*/
public abstract class ReloadedTypeInvoker extends Invoker {

  ReloadableType rtype;
  private MethodMember methodMember;

  private ReloadedTypeInvoker(ReloadableTypeMethodProvider declaringType, MethodMember methodMember) {
    this.methodMember = methodMember;
    rtype = declaringType.getRType();
    if (GlobalConfiguration.assertsMode) {
      Utils.assertTrue(rtype.hasBeenReloaded(),
          "This class is only equiped to provide invocation/method services for reloaded types");
    }
  }

  @Override
  public abstract Object invoke(Object target, Object... params) throws IllegalArgumentException, IllegalAccessException,
      InvocationTargetException;

  /**
   * Create a 'mock' Java Method which is dependent on ReflectiveInterceptor to catch calls to invoke.
   */
  @Override
  public Method createJavaMethod() {
    Class<?> clazz = rtype.getClazz();
    String name = methodMember.getName();
    String methodDescriptor = methodMember.getDescriptor();

    ClassLoader classLoader = rtype.getTypeRegistry().getClassLoader();
    try {
      Class<?>[] params = Utils.toParamClasses(methodDescriptor, classLoader);
      Class<?> returnType = Utils.toClass(Type.getReturnType(methodDescriptor), classLoader);
      Class<?>[] exceptions = Utils.slashedNamesToClasses(methodMember.getExceptions(), classLoader);
      return JVM.newMethod(clazz, name, params, returnType, exceptions, methodMember.getModifiers(),
          methodMember.getGenericSignature());
    } catch (ClassNotFoundException e) {
      throw new IllegalStateException("Couldn't create j.l.r.Method for " + clazz.getName() + "." + methodDescriptor, e);
    }
  }

  @Override
  public int getModifiers() {
    return methodMember.getModifiers();
  }

  @Override
  public String getName() {
    return methodMember.getName();
  }

  @Override
  public String getMethodDescriptor() {
    return methodMember.getDescriptor();
  }

  @Override
  public String getClassName() {
    return rtype.getName();
  }

  public static Invoker create(ReloadableTypeMethodProvider declaringType, final MethodMember methodMember) {
    if (Modifier.isStatic(methodMember.getModifiers())) {
      // Since static methods don't change parameter lists, they just invoke the executor
      return new ReloadedTypeInvoker(declaringType, methodMember) {
        @Override
        public Object invoke(Object target, Object... params) throws IllegalArgumentException, IllegalAccessException,
            InvocationTargetException {
          CurrentLiveVersion clv = rtype.getLiveVersion();
          Method executor = clv.getExecutorMethod(methodMember);
          return executor.invoke(target, params);
        }
      };
    } else {
      // Non static method invokers need to add target as a first param
      return new ReloadedTypeInvoker(declaringType, methodMember) {
        @Override
        public Object invoke(Object target, Object... params) throws IllegalArgumentException, IllegalAccessException,
            InvocationTargetException {
          CurrentLiveVersion clv = rtype.getLiveVersion();
          Method executor = clv.getExecutorMethod(methodMember);
          if (params == null) {
            return executor.invoke(null, target);
          } else {
            Object[] ps = new Object[params.length + 1];
            System.arraycopy(params, 0, ps, 1, params.length);
            ps[0] = target;
            return executor.invoke(null, ps);
          }
        }
      };
    }
  }
}
TOP

Related Classes of org.springsource.loaded.ri.ReloadedTypeInvoker

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.