| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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.apache.openejb.server.cxf.rs; |
| |
| import org.apache.cxf.jaxrs.JAXRSInvoker; |
| import org.apache.cxf.message.Exchange; |
| import org.apache.openejb.ApplicationException; |
| import org.apache.openejb.BeanContext; |
| import org.apache.openejb.InvalidateReferenceException; |
| import org.apache.openejb.core.interceptor.InterceptorData; |
| import org.apache.openejb.monitoring.StatsInterceptor; |
| import org.apache.openejb.util.proxy.BeanContextInvocationHandler; |
| import org.apache.openejb.util.proxy.LocalBeanProxyFactory; |
| import org.apache.openejb.util.proxy.ProxyManager; |
| |
| import java.lang.reflect.InvocationHandler; |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.rmi.RemoteException; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Map; |
| import javax.ejb.EJBException; |
| |
| public class OpenEJBEJBInvoker extends JAXRSInvoker { |
| private final Map<Class<?>, Collection<Class<?>>> contextTypes = new HashMap<Class<?>, Collection<Class<?>>>(); |
| |
| public OpenEJBEJBInvoker(final Collection<BeanContext> restEjbs) { |
| for (final BeanContext context : restEjbs) { |
| final Collection<Class<?>> classes = new HashSet<>(); |
| Contexts.findContextFields(context.getBeanClass(), classes); |
| for (final Collection<InterceptorData> list : |
| Arrays.asList( |
| context.getInterceptorData(), |
| context.getInstanceScopedInterceptors(), |
| context.getCallbackInterceptors())) { |
| for (final InterceptorData id : list) { |
| final Class<?> interceptorClass = id.getInterceptorClass(); |
| if (!StatsInterceptor.class.equals(interceptorClass)) { |
| Contexts.findContextFields(interceptorClass, classes); |
| } |
| } |
| } |
| contextTypes.put(context.getBeanClass(), classes); |
| } |
| } |
| |
| @Override |
| public Object invoke(final Exchange exchange, final Object request, final Object resourceObject) { |
| Contexts.bind(exchange, getContextTypes(resourceObject)); |
| return super.invoke(exchange, request, resourceObject); |
| } |
| |
| private Collection<Class<?>> getContextTypes(final Object resourceObject) { |
| if (!ProxyManager.isProxyClass(resourceObject.getClass()) |
| && !LocalBeanProxyFactory.isProxy(resourceObject.getClass())) { |
| return Collections.emptySet(); |
| } |
| |
| final InvocationHandler handler = ProxyManager.getInvocationHandler(resourceObject); |
| if (!(handler instanceof BeanContextInvocationHandler)) { |
| return Collections.emptySet(); |
| } |
| |
| final BeanContext beanContext = ((BeanContextInvocationHandler) handler).getBeanContext(); |
| |
| if (beanContext == null) { |
| return Collections.emptySet(); |
| } |
| return contextTypes.get(beanContext.getBeanClass()); |
| } |
| |
| @Override |
| protected Object performInvocation(final Exchange exchange, final Object serviceObject, |
| final Method m, final Object[] paramArray) throws Exception { |
| try { |
| final Object[] args = super.insertExchange(m, paramArray, exchange); |
| return m.invoke(serviceObject, args); |
| } catch (final InvocationTargetException ite) { |
| Throwable cause = ite.getTargetException(); |
| // unwrap to get ExceptionMapper working |
| if (cause instanceof InvalidateReferenceException) { |
| cause = cause.getCause(); |
| if (cause instanceof RemoteException) { |
| cause = cause.getCause(); |
| } |
| } |
| |
| if (EJBException.class.isInstance(cause)) { |
| cause = EJBException.class.cast(cause).getCause(); |
| } |
| |
| if (ApplicationException.class.isInstance(cause) && Exception.class.isInstance(cause.getCause())) { |
| throw Exception.class.cast(ApplicationException.class.cast(cause).getCause()); |
| } |
| |
| if (cause instanceof Exception) { |
| throw (Exception) cause; |
| } |
| throw ite; |
| } |
| } |
| } |