Home » openejb-3.1.2-src » org.apache » openejb » server » cxf » ejb » [javadoc | source]

    1   /**
    2    *
    3    * Licensed to the Apache Software Foundation (ASF) under one or more
    4    * contributor license agreements.  See the NOTICE file distributed with
    5    * this work for additional information regarding copyright ownership.
    6    * The ASF licenses this file to You under the Apache License, Version 2.0
    7    * (the "License"); you may not use this file except in compliance with
    8    * the License.  You may obtain a copy of the License at
    9    *
   10    *     http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    *  Unless required by applicable law or agreed to in writing, software
   13    *  distributed under the License is distributed on an "AS IS" BASIS,
   14    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15    *  See the License for the specific language governing permissions and
   16    *  limitations under the License.
   17    */
   18   package org.apache.openejb.server.cxf.ejb;
   19   
   20   import org.apache.cxf.Bus;
   21   import org.apache.cxf.binding.soap.SoapMessage;
   22   import org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor;
   23   import org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor;
   24   import org.apache.cxf.binding.soap.interceptor.SoapActionInInterceptor;
   25   import org.apache.cxf.binding.soap.interceptor.SoapHeaderInterceptor;
   26   import org.apache.cxf.endpoint.Endpoint;
   27   import org.apache.cxf.interceptor.AbstractInDatabindingInterceptor;
   28   import org.apache.cxf.interceptor.AttachmentInInterceptor;
   29   import org.apache.cxf.interceptor.Interceptor;
   30   import org.apache.cxf.interceptor.InterceptorChain;
   31   import org.apache.cxf.interceptor.OutgoingChainInterceptor;
   32   import org.apache.cxf.interceptor.ServiceInvokerInterceptor;
   33   import org.apache.cxf.interceptor.StaxInInterceptor;
   34   import org.apache.cxf.jaxws.handler.logical.LogicalHandlerInInterceptor;
   35   import org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor;
   36   import org.apache.cxf.jaxws.interceptors.HolderInInterceptor;
   37   import org.apache.cxf.jaxws.interceptors.HolderOutInterceptor;
   38   import org.apache.cxf.jaxws.interceptors.WrapperClassInInterceptor;
   39   import org.apache.cxf.jaxws.support.JaxWsEndpointImpl;
   40   import org.apache.cxf.message.Exchange;
   41   import org.apache.cxf.message.Message;
   42   import org.apache.cxf.phase.PhaseInterceptorChain;
   43   import org.apache.cxf.phase.PhaseManager;
   44   import org.apache.cxf.service.Service;
   45   import org.apache.cxf.staxutils.StaxUtils;
   46   import org.apache.openejb.util.LogCategory;
   47   import org.apache.openejb.util.Logger;
   48   
   49   import javax.interceptor.AroundInvoke;
   50   import javax.interceptor.InvocationContext;
   51   import javax.xml.soap.SOAPMessage;
   52   import javax.xml.stream.XMLStreamReader;
   53   import javax.xml.transform.dom.DOMSource;
   54   import javax.xml.ws.Binding;
   55   
   56   import java.io.InputStream;
   57   import java.lang.reflect.Method;
   58   import java.util.List;
   59   
   60   public class EjbInterceptor {
   61       private static final Logger log = Logger.getInstance(LogCategory.CXF, EjbInterceptor.class);
   62   
   63       private Exchange exchange;
   64       private Bus bus;
   65       private List<Object> params;
   66       private Method method;
   67   
   68       public EjbInterceptor(List<Object> params, Method method, Bus bus, Exchange exchange) {
   69           this.params = params;
   70           this.method = method;
   71           this.bus = bus;
   72           this.exchange = exchange;
   73       }
   74   
   75       private static void copyDataBindingInterceptors(PhaseInterceptorChain newChain, InterceptorChain oldChain) {
   76           for (Interceptor interceptor : oldChain) {
   77               if (interceptor instanceof AbstractInDatabindingInterceptor) {
   78                   log.debug("Added data binding interceptor: " + interceptor);
   79                   newChain.add(interceptor);
   80               }
   81           }
   82       }
   83   
   84       @AroundInvoke
   85       public Object intercept(InvocationContext context) throws Exception {
   86           Endpoint endpoint = this.exchange.get(Endpoint.class);
   87           Service service = endpoint.getService();
   88           Binding binding = ((JaxWsEndpointImpl) endpoint).getJaxwsBinding();
   89   
   90           this.exchange.put(InvocationContext.class, context);
   91   
   92           if (binding.getHandlerChain() == null || binding.getHandlerChain().isEmpty()) {
   93               // no handlers so let's just directly invoke the bean
   94               log.debug("No handlers found.");
   95   
   96               EjbMethodInvoker invoker = (EjbMethodInvoker) service.getInvoker();
   97               return invoker.directEjbInvoke(this.exchange, this.method, this.params);
   98   
   99           } else {
  100               // have handlers so have to run handlers now and redo data binding
  101               // as handlers can change the soap message
  102               log.debug("Handlers found.");
  103   
  104               Message inMessage = exchange.getInMessage();
  105               PhaseInterceptorChain chain = new PhaseInterceptorChain(bus.getExtension(PhaseManager.class).getInPhases());
  106   
  107               chain.setFaultObserver(endpoint.getOutFaultObserver());
  108   
  109               /*
  110                * Since we have to re-do data binding and the XMLStreamReader
  111                * contents are already consumed by prior data binding step
  112                * we have to reinitialize the XMLStreamReader from the SOAPMessage
  113                * created by SAAJInInterceptor.
  114                */
  115               if (inMessage instanceof SoapMessage) {
  116                   try {
  117                       reserialize((SoapMessage) inMessage);
  118                   } catch (Exception e) {
  119                       throw new RuntimeException("Failed to reserialize soap message", e);
  120                   }
  121               } else {
  122                   // TODO: how to handle XML/HTTP binding?
  123               }
  124   
  125               this.exchange.setOutMessage(null);
  126   
  127               // install default interceptors
  128               chain.add(new ServiceInvokerInterceptor());
  129               chain.add(new OutgoingChainInterceptor());
  130               
  131               // add JAX-WS interceptors
  132               // See http://cwiki.apache.org/CXF20DOC/interceptors.html
  133               chain.add(new AttachmentInInterceptor());
  134               chain.add(new StaxInInterceptor());
  135               chain.add(new ReadHeadersInterceptor(bus));
  136               chain.add(new SoapActionInInterceptor());
  137               chain.add(new SoapHeaderInterceptor());
  138               chain.add(new WrapperClassInInterceptor());
  139               chain.add(new HolderInInterceptor());
  140   
  141               // install interceptors for handler processing
  142               chain.add(new MustUnderstandInterceptor());
  143               chain.add(new LogicalHandlerInInterceptor(binding));
  144               chain.add(new SOAPHandlerInterceptor(binding));
  145   
  146               // install data binding interceptors
  147               copyDataBindingInterceptors(chain, inMessage.getInterceptorChain());
  148   
  149               InterceptorChain oldChain = inMessage.getInterceptorChain();
  150               inMessage.setInterceptorChain(chain);
  151               try {
  152                   chain.doIntercept(inMessage);
  153               } finally {
  154                   inMessage.setInterceptorChain(oldChain);
  155               }
  156   
  157               // TODO: the result should be deserialized from SOAPMessage
  158               Object result = getResult();
  159   
  160               return result;
  161           }
  162       }
  163   
  164       private Object getResult() {
  165           Message outMessage = this.exchange.getOutMessage();
  166           if (outMessage == null) {
  167               return null;
  168           } else {
  169               List<?> result = outMessage.getContent(List.class);
  170               if (result == null) {
  171                   return outMessage.get(Object.class);
  172               } else if (result.isEmpty()) {
  173                   return null;
  174               } else {
  175                   return result.get(0);
  176               }
  177           }
  178       }
  179   
  180       private void reserialize(SoapMessage message) throws Exception {
  181   	// If we just remove XMLStreamReader from the message content, we
  182   	// only need to add the StaxInInterceptor to re serialize the message
  183   	// Then we must reset the InputStream to allow re serialization by the StaxInInterceptor
  184   	message.removeContent(XMLStreamReader.class);
  185   	InputStream is = message.getContent(InputStream.class);
  186   	is.reset();
  187   	
  188   //	SOAPMessage soapMessage = message.getContent(SOAPMessage.class);
  189   //	if (soapMessage == null) {
  190   //	    return;
  191   //	}
  192   //
  193   //        XMLStreamReader xmlReader = message.getContent(XMLStreamReader.class);
  194   //        StaxUtils.readDocElements(soapMessage.getSOAPPart().getEnvelope(), xmlReader, true);
  195   //        DOMSource bodySource = new DOMSource(soapMessage.getSOAPPart().getEnvelope());
  196   //        xmlReader = StaxUtils.createXMLStreamReader(bodySource);
  197   //        message.setContent(XMLStreamReader.class, xmlReader);
  198       }
  199   }

Home » openejb-3.1.2-src » org.apache » openejb » server » cxf » ejb » [javadoc | source]