Package br.com.caelum.vraptor.proxy

Source Code of br.com.caelum.vraptor.proxy.JavassistProxifier

/***
* Copyright (c) 2009 Caelum - www.caelum.com.br/opensource All rights reserved.
*
* 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 br.com.caelum.vraptor.proxy;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

import javassist.util.proxy.MethodFilter;
import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;
import javassist.util.proxy.ProxyObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import br.com.caelum.vraptor.ioc.ApplicationScoped;

/**
* Javassist implementation for {@link Proxifier}.
*
* @author Otávio Scherer Garcia
* @since 3.3.1
*/
@ApplicationScoped
public class JavassistProxifier
  implements Proxifier {

  private static final Logger logger = LoggerFactory.getLogger(JavassistProxifier.class);

  /**
   * Methods like toString and finalize will be ignored.
   */
  private static final List<Method> OBJECT_METHODS = Arrays.asList(Object.class.getDeclaredMethods());

  /**
   * Do not proxy these methods.
   */
  private static final MethodFilter IGNORE_BRIDGE_AND_OBJECT_METHODS = new MethodFilter() {
  public boolean isHandled(Method method) {
    return !method.isBridge() && !OBJECT_METHODS.contains(method);
  }
  };

  private final InstanceCreator instanceCreator;

  public JavassistProxifier(InstanceCreator instanceCreator) {
  this.instanceCreator = instanceCreator;
  }

  public <T> T proxify(Class<T> type, MethodInvocation<? super T> handler) {
  final ProxyFactory factory = new ProxyFactory();
  factory.setFilter(IGNORE_BRIDGE_AND_OBJECT_METHODS);

  if (type.isInterface()) {
    factory.setInterfaces(new Class[] { type });
  } else {
    factory.setSuperclass(type);
  }

  Class<?> proxyClass = factory.createClass();

  Object proxyInstance = instanceCreator.instanceFor(proxyClass);
  setHandler(proxyInstance, handler);

  logger.debug("a proxy for {} is created as {}", type, proxyClass);

  return type.cast(proxyInstance);
  }

  public boolean isProxy(Object o) {
  return o != null && ProxyObject.class.isAssignableFrom(o.getClass());
  }
 
  private <T> void setHandler(Object proxyInstance, final MethodInvocation<? super T> handler) {
  ProxyObject proxyObject = (ProxyObject) proxyInstance;

  proxyObject.setHandler(new MethodHandler() {
    public Object invoke(final Object self, final Method thisMethod, final Method proceed, Object[] args)
    throws Throwable {

    return handler.intercept((T) self, thisMethod, args, new SuperMethod() {
      public Object invoke(Object proxy, Object[] args) {
      try {
        return proceed.invoke(proxy, args);
      } catch (Throwable throwable) {
        throw new ProxyInvocationException(throwable);
      }
      }
    });
    }
  });
  }
}
TOP

Related Classes of br.com.caelum.vraptor.proxy.JavassistProxifier

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.