/* * JBoss, Home of Professional Open Source * Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual * contributors by the @authors tag. See the copyright.txt in the * distribution for a full listing of individual 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.jboss.weld.bean.proxy; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.enterprise.inject.spi.Decorator; import javax.inject.Inject; import org.jboss.weld.annotated.runtime.InvokableAnnotatedMethod; import org.jboss.weld.bean.WeldDecorator; import org.jboss.weld.interceptor.util.proxy.TargetInstanceProxyMethodHandler; import org.jboss.weld.logging.BeanLogger; import org.jboss.weld.serialization.spi.helpers.SerializableContextualInstance; import org.jboss.weld.util.reflection.Reflections; /** * Method handler for decorated beans * * @author Pete Muir * @author Marius Bogoevici */ public class DecoratorProxyMethodHandler extends TargetInstanceProxyMethodHandler<Object> { private static final long serialVersionUID = 4577632640130385060L; private final SerializableContextualInstance<Decorator<Object>, Object> decoratorInstance; public DecoratorProxyMethodHandler(SerializableContextualInstance<Decorator<Object>, Object> decoratorInstance, Object delegateInstance) { super(delegateInstance, delegateInstance.getClass()); this.decoratorInstance = decoratorInstance; } /** * @param self the proxy instance. * @param method the overridden method declared in the super class or * interface. * @param proceed the forwarder method for invoking the overridden method. It * is null if the overridden method is abstract or declared in the * interface. * @param args an array of objects containing the values of the arguments * passed in the method invocation on the proxy instance. If a * parameter type is a primitive type, the type of the array * element is a wrapper class. * @return the resulting value of the method invocation. * @throws Throwable if the method invocation fails. */ @Override protected Object doInvoke(Object self, Method method, Method proceed, Object[] args) throws Throwable { Decorator<Object> decorator = decoratorInstance.getContextual().get(); if (decorator instanceof WeldDecorator<?>) { WeldDecorator<?> weldDecorator = (WeldDecorator<?>) decorator; return doInvoke(weldDecorator, decoratorInstance.getInstance(), method, args); } else { throw BeanLogger.LOG.unexpectedUnwrappedCustomDecorator(decorator); } } private Object doInvoke(WeldDecorator<?> weldDecorator, Object decoratorInstance, Method method, Object[] args) throws Throwable { if (!method.isAnnotationPresent(Inject.class)) { InvokableAnnotatedMethod<?> decoratorMethod = weldDecorator.getDecoratorMethod(method); if (decoratorMethod != null) { try { return decoratorMethod.invokeOnInstance(decoratorInstance, args); } catch (InvocationTargetException e) { throw e.getCause(); } } } SecurityActions.ensureAccessible(method); return Reflections.invokeAndUnwrap(getTargetInstance(), method, args); } }