[jboss-svn-commits] JBossWS SVN: r661 - in trunk/src/main/java/org/jboss/ws: common jaxws jaxws/handler server

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Aug 1 12:32:41 EDT 2006


Author: thomas.diesler at jboss.com
Date: 2006-08-01 12:32:34 -0400 (Tue, 01 Aug 2006)
New Revision: 661

Added:
   trunk/src/main/java/org/jboss/ws/common/SOAPMessageContextBase.java
   trunk/src/main/java/org/jboss/ws/jaxws/InvokerDelegateJAXWS.java
   trunk/src/main/java/org/jboss/ws/jaxws/handler/HandlerChainBaseImpl.java
   trunk/src/main/java/org/jboss/ws/jaxws/handler/HandlerInfo.java
   trunk/src/main/java/org/jboss/ws/jaxws/handler/HandlerWrapper.java
   trunk/src/main/java/org/jboss/ws/jaxws/handler/ServerHandlerChain.java
   trunk/src/main/java/org/jboss/ws/server/InvokerDelegate.java
   trunk/src/main/java/org/jboss/ws/server/ServiceEndpointInvokerBase.java
Log:
Refactor SOAPMessageContext in two flavors

Added: trunk/src/main/java/org/jboss/ws/common/SOAPMessageContextBase.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/common/SOAPMessageContextBase.java	2006-08-01 16:29:43 UTC (rev 660)
+++ trunk/src/main/java/org/jboss/ws/common/SOAPMessageContextBase.java	2006-08-01 16:32:34 UTC (rev 661)
@@ -0,0 +1,70 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.common;
+
+// $Id$
+
+import java.util.Iterator;
+
+import javax.xml.soap.SOAPMessage;
+
+import org.jboss.ws.binding.SerializationContext;
+import org.jboss.ws.metadata.EndpointMetaData;
+import org.jboss.ws.metadata.OperationMetaData;
+import org.jboss.xb.binding.NamespaceRegistry;
+
+/**
+ * Provides access to the SOAP message and WS meta data.
+ * 
+ * Both the JAXRPC and the JAXWS SOAPMessageContext im plement this interface.
+ *
+ * @author Thomas.Diesler at jboss.org
+ * @since 1-Aug-2006
+ */
+public interface SOAPMessageContextBase 
+{
+   public SOAPMessage getMessage();
+
+   public void setMessage(SOAPMessage message);
+
+   public EndpointMetaData getEndpointMetaData();
+
+   public void setEndpointMetaData(EndpointMetaData epMetaData);
+
+   public OperationMetaData getOperationMetaData();
+
+   public void setOperationMetaData(OperationMetaData opMetaData);
+
+   public SerializationContext getSerializationContext();
+   
+   public NamespaceRegistry getNamespaceRegistry();
+   
+   public boolean containsProperty(String name);
+
+   public Object getProperty(String name);
+
+   public Iterator getPropertyNames();
+
+   public void removeProperty(String name);
+
+   public void setProperty(String name, Object value);
+}


Property changes on: trunk/src/main/java/org/jboss/ws/common/SOAPMessageContextBase.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Added: trunk/src/main/java/org/jboss/ws/jaxws/InvokerDelegateJAXWS.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/jaxws/InvokerDelegateJAXWS.java	2006-08-01 16:29:43 UTC (rev 660)
+++ trunk/src/main/java/org/jboss/ws/jaxws/InvokerDelegateJAXWS.java	2006-08-01 16:32:34 UTC (rev 661)
@@ -0,0 +1,252 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.jaxws;
+
+// $Id$
+
+import java.lang.reflect.InvocationTargetException;
+
+import javax.management.MBeanException;
+import javax.xml.namespace.QName;
+import javax.xml.rpc.soap.SOAPFaultException;
+import javax.xml.soap.Name;
+import javax.xml.soap.SOAPBody;
+import javax.xml.soap.SOAPBodyElement;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPHeader;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.ws.Service.Mode;
+
+import org.jboss.logging.Logger;
+import org.jboss.util.NotImplementedException;
+import org.jboss.ws.Constants;
+import org.jboss.ws.binding.BindingProvider;
+import org.jboss.ws.binding.BindingProviderRegistry;
+import org.jboss.ws.binding.EndpointInvocation;
+import org.jboss.ws.common.SOAPMessageContextBase;
+import org.jboss.ws.jaxrpc.SOAPFaultExceptionHelper;
+import org.jboss.ws.metadata.EndpointMetaData;
+import org.jboss.ws.metadata.OperationMetaData;
+import org.jboss.ws.metadata.j2ee.UnifiedHandlerMetaData.HandlerType;
+import org.jboss.ws.server.InvokerDelegate;
+import org.jboss.ws.server.ServiceEndpointInfo;
+import org.jboss.ws.server.ServiceEndpointInvoker;
+import org.jboss.ws.soap.MessageContextAssociation;
+import org.jboss.ws.soap.SOAPMessageImpl;
+
+/** An implementation of handles invocations on the endpoint
+ *
+ * @author Thomas.Diesler at jboss.org
+ * @since 19-Jan-2005
+ */
+public class InvokerDelegateJAXWS implements InvokerDelegate
+{
+   // provide logging
+   private static Logger log = Logger.getLogger(InvokerDelegateJAXWS.class);
+
+   private ServiceEndpointInvoker sepInvoker;
+
+   public InvokerDelegateJAXWS(ServiceEndpointInvoker sepInvoker)
+   {
+      this.sepInvoker = sepInvoker;
+   }
+
+   /** Invoke the the service endpoint */
+   public SOAPMessage invoke(ServiceEndpointInfo seInfo, Object endpointContext) throws Exception
+   {
+      SOAPMessageContextBase msgContext = MessageContextAssociation.peekMessageContext();
+      EndpointMetaData epMetaData = msgContext.getEndpointMetaData();
+      SOAPMessageImpl reqMessage = (SOAPMessageImpl)msgContext.getMessage();
+
+      // Load the endpoint implementation bean
+      Class seImpl = sepInvoker.loadServiceEndpoint(seInfo);
+
+      // Create an instance of the endpoint implementation bean
+      Object seInstance = sepInvoker.createServiceEndpoint(seInfo, endpointContext, seImpl);
+
+      try
+      {
+         boolean oneway = false;
+
+         // call the handler chain
+         boolean handlersPass = callRequestHandlerChain(seInfo, HandlerType.PRE);
+         handlersPass = handlersPass && callRequestHandlerChain(seInfo, HandlerType.JAXWS);
+         handlersPass = handlersPass && callRequestHandlerChain(seInfo, HandlerType.POST);
+         
+         if (handlersPass)
+         {
+            // Get the binding provider for the given bindingURI
+            BindingProvider bindingProvider;
+            if (epMetaData.getServiceMode() == Mode.MESSAGE)
+            {
+               bindingProvider = BindingProviderRegistry.getProvider(BindingProvider.JAXWS_MESSAGE_BINDING);
+            }
+            else if (epMetaData.getServiceMode() == Mode.PAYLOAD)
+            {
+               bindingProvider = BindingProviderRegistry.getProvider(BindingProvider.JAXWS_PAYLOAD_BINDING);
+            }
+            else
+            {
+               bindingProvider = BindingProviderRegistry.getDefaultProvider();
+            }
+
+            // Get the operation meta data from the SOAP message
+            OperationMetaData opMetaData = getDispatchDestination(epMetaData, reqMessage);
+            msgContext.setOperationMetaData(opMetaData);
+            oneway = opMetaData.isOneWayOperation();
+
+            // Unbind the request message
+            EndpointInvocation epInv = bindingProvider.unbindRequestMessage(opMetaData, reqMessage);
+
+            // Invoke the service endpoint
+            sepInvoker.invokeServiceEndpoint(seInfo, seInstance, epInv);
+
+            // Bind the response message
+            SOAPMessage resMessage = bindingProvider.bindResponseMessage(opMetaData, epInv);
+            msgContext.setMessage(resMessage);
+         }
+
+         // call the handler chain
+         if (oneway == false)
+         {
+            handlersPass = callResponseHandlerChain(seInfo, HandlerType.POST);
+            handlersPass = handlersPass && callResponseHandlerChain(seInfo, HandlerType.JAXWS);
+            handlersPass = handlersPass && callResponseHandlerChain(seInfo, HandlerType.PRE);
+         }
+
+         SOAPMessage resMessage = msgContext.getMessage();
+         return resMessage;
+      }
+      catch (Exception ex)
+      {
+         try
+         {
+            SOAPMessage faultMessage = SOAPFaultExceptionHelper.exceptionToFaultMessage(ex);
+            msgContext.setMessage(faultMessage);
+            
+            // call the handler chain
+            boolean handlersPass = callFaultHandlerChain(seInfo, HandlerType.POST, ex);
+            handlersPass = handlersPass && callFaultHandlerChain(seInfo, HandlerType.JAXWS, ex);
+            handlersPass = handlersPass && callFaultHandlerChain(seInfo, HandlerType.PRE, ex);
+         }
+         catch (Exception subEx)
+         {
+            log.warn("Cannot process handlerChain.handleFault, ignoring: ", subEx);
+         }
+         throw ex;
+      }
+      finally
+      {
+         sepInvoker.destroyServiceEndpoint(seInfo, seInstance);
+      }
+   }
+
+   private OperationMetaData getDispatchDestination(EndpointMetaData epMetaData, SOAPMessageImpl reqMessage) throws SOAPException
+   {
+      OperationMetaData opMetaData = reqMessage.getOperationMetaData(epMetaData);
+      SOAPHeader soapHeader = reqMessage.getSOAPHeader();
+
+      // Report a MustUnderstand fault
+      if (opMetaData == null)
+      {
+         SOAPBody soapBody = reqMessage.getSOAPBody();
+         SOAPBodyElement soapBodyElement = (SOAPBodyElement)soapBody.getChildElements().next();
+         Name soapName = soapBodyElement.getElementName();
+
+         // R2724 If an INSTANCE receives a message that is inconsistent with its WSDL description, it SHOULD generate a soap:Fault
+         // with a faultcode of "Client", unless a "MustUnderstand" or "VersionMismatch" fault is generated.
+         if (soapHeader != null && soapHeader.examineMustUnderstandHeaderElements(Constants.URI_SOAP11_NEXT_ACTOR).hasNext())
+         {
+            QName faultCode = Constants.SOAP11_FAULT_CODE_MUST_UNDERSTAND;
+            String faultString = "Endpoint " + epMetaData.getQName() + " does not contain operation meta data for: " + soapName;
+            throw new SOAPFaultException(faultCode, faultString, null, null);
+         }
+         else
+         {
+            QName faultCode = Constants.SOAP11_FAULT_CODE_CLIENT;
+            String faultString = "Endpoint " + epMetaData.getQName() + " does not contain operation meta data for: " + soapName;
+            throw new SOAPFaultException(faultCode, faultString, null, null);
+         }
+      }
+      return opMetaData;
+   }
+
+   /** handle invokation exceptions */
+   public void handleInvocationException(Throwable th) throws SOAPFaultException
+   {
+      if (th instanceof RuntimeException)
+         throw (RuntimeException)th;
+
+      if (th instanceof InvocationTargetException)
+      {
+         InvocationTargetException targetException = (InvocationTargetException)th;
+         Throwable targetEx = targetException.getTargetException();
+         if (targetEx instanceof SOAPFaultException)
+         {
+            throw (SOAPFaultException)targetEx;
+         }
+         else
+         {
+            String faultString = targetEx.toString();
+            SOAPFaultException soapFaultEx = new SOAPFaultException(Constants.SOAP11_FAULT_CODE_CLIENT, faultString, null, null);
+            soapFaultEx.initCause(targetEx);
+            throw soapFaultEx;
+         }
+      }
+
+      if (th instanceof MBeanException)
+      {
+         Exception targetEx = ((MBeanException)th).getTargetException();
+         if (targetEx instanceof SOAPFaultException)
+         {
+            throw (SOAPFaultException)targetEx;
+         }
+         else
+         {
+            String faultString = targetEx.toString();
+            SOAPFaultException soapFaultEx = new SOAPFaultException(Constants.SOAP11_FAULT_CODE_CLIENT, faultString, null, null);
+            soapFaultEx.initCause(targetEx);
+            throw soapFaultEx;
+         }
+      }
+
+      String faultString = th.toString();
+      SOAPFaultException soapFaultEx = new SOAPFaultException(Constants.SOAP11_FAULT_CODE_CLIENT, faultString, null, null);
+      soapFaultEx.initCause(th);
+      throw soapFaultEx;
+   }
+
+   public boolean callFaultHandlerChain(ServiceEndpointInfo seInfo, HandlerType type, Exception ex)
+   {
+      return true;
+   }
+
+   public boolean callRequestHandlerChain(ServiceEndpointInfo seInfo, HandlerType type)
+   {
+      return true;
+   }
+
+   public boolean callResponseHandlerChain(ServiceEndpointInfo seInfo, HandlerType type)
+   {
+      return true;
+   }
+}


Property changes on: trunk/src/main/java/org/jboss/ws/jaxws/InvokerDelegateJAXWS.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Added: trunk/src/main/java/org/jboss/ws/jaxws/handler/HandlerChainBaseImpl.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/jaxws/handler/HandlerChainBaseImpl.java	2006-08-01 16:29:43 UTC (rev 660)
+++ trunk/src/main/java/org/jboss/ws/jaxws/handler/HandlerChainBaseImpl.java	2006-08-01 16:32:34 UTC (rev 661)
@@ -0,0 +1,415 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.jaxws.handler;
+
+// $Id$
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+import javax.xml.rpc.soap.SOAPFaultException;
+import javax.xml.soap.Name;
+import javax.xml.soap.SOAPEnvelope;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPHeaderElement;
+import javax.xml.soap.SOAPPart;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.handler.Handler;
+import javax.xml.ws.handler.MessageContext;
+
+import org.jboss.logging.Logger;
+import org.jboss.util.xml.DOMWriter;
+import org.jboss.ws.Constants;
+import org.jboss.ws.metadata.EndpointMetaData;
+import org.jboss.ws.metadata.OperationMetaData;
+import org.jboss.ws.metadata.ParameterMetaData;
+import org.jboss.ws.soap.SOAPEnvelopeImpl;
+import org.jboss.ws.soap.SOAPMessageImpl;
+
+/**
+ * Represents a list of handlers. All elements in the
+ * HandlerChain are of the type javax.xml.rpc.handler.Handler.
+ * <p/>
+ * Abstracts the policy and mechanism for the invocation of the registered handlers.
+ *
+ * @author Thomas.Diesler at jboss.org
+ * @since 06-May-2004
+ */
+public abstract class HandlerChainBaseImpl
+{
+   private static Logger log = Logger.getLogger(HandlerChainBaseImpl.class);
+
+   public static final int STATE_DOES_NOT_EXIST = 0;
+   public static final int STATE_CREATED = 1;
+   public static final int STATE_READY = 2;
+   public static final int STATE_DESTROYED = 3;
+
+   // The List<Entry> objects
+   protected List<HandlerEntry> handlers = new ArrayList<HandlerEntry>();
+   // The roles associated with the handler chain
+   protected Set<String> roles = new HashSet<String>();
+   // The index of the first handler that returned false during processing
+   protected int falseIndex = -1;
+   // The state of this handler chain
+   protected int state;
+
+   /**
+    * Constructs a handler chain with the given handlers infos
+    */
+   public HandlerChainBaseImpl(List<HandlerInfo> infos, Set roles)
+   {
+      log.debug("Create a handler chain for roles: " + roles);
+      addHandlersToChain(infos, roles);
+   }
+
+   /**
+    * Initialize the a handler chain with the given handlers infos
+    *
+    * @throws javax.xml.rpc.JAXRPCException If any error during initialization
+    */
+   private void addHandlersToChain(List<HandlerInfo> infos, Set roleSet)
+   {
+      try
+      {
+         if (infos != null)
+         {
+            for (int i = 0; i < infos.size(); i++)
+            {
+               HandlerInfo info = (HandlerInfo)infos.get(i);
+               HandlerWrapper handler = new HandlerWrapper((Handler)info.getHandlerClass().newInstance());
+               handlers.add(new HandlerEntry(handler, info));
+            }
+         }
+         if (roleSet != null)
+         {
+            roles.addAll(roleSet);
+         }
+      }
+      catch (RuntimeException rte)
+      {
+         throw rte;
+      }
+      catch (Exception ex)
+      {
+         throw new WebServiceException("Cannot initialize handler chain", ex);
+      }
+
+      // set state to created
+      state = STATE_CREATED;
+   }
+
+   /**
+    * Get the state of this handler chain
+    */
+   public int getState()
+   {
+      return state;
+   }
+
+   /**
+    * Initializes the configuration for a HandlerChain.
+    *
+    * @param config Configuration for the initialization of this handler chain
+    * @throws javax.xml.rpc.JAXRPCException If any error during initialization
+    */
+   public void init(Map config)
+   {
+      log.debug("init: [config=" + config + "]");
+      // set state to ready
+      state = STATE_READY;
+   }
+
+   /**
+    * Indicates the end of lifecycle for a HandlerChain.
+    *
+    * @throws javax.xml.rpc.JAXRPCException If any error during destroy
+    */
+   public void close()
+   {
+      log.debug("destroy");
+      for (int i = 0; i < handlers.size(); i++)
+      {
+         HandlerEntry entry = (HandlerEntry)handlers.get(i);
+         entry.handler.close(null);
+      }
+      handlers.clear();
+
+      // set state to destroyed
+      state = STATE_DESTROYED;
+   }
+
+   /**
+    * Gets SOAP actor roles registered for this HandlerChain at this SOAP node. The returned array includes the
+    * special SOAP actor next.
+    *
+    * @return SOAP Actor roles as URIs
+    */
+   public String[] getRoles()
+   {
+      String[] arr = new String[roles.size()];
+      roles.toArray(arr);
+      return arr;
+   }
+
+   /**
+    * Sets SOAP Actor roles for this HandlerChain. This specifies the set of roles in which this HandlerChain is to act
+    * for the SOAP message processing at this SOAP node. These roles assumed by a HandlerChain must be invariant during
+    * the processing of an individual SOAP message through the HandlerChain.
+    * <p/>
+    * A HandlerChain always acts in the role of the special SOAP actor next. Refer to the SOAP specification for the
+    * URI name for this special SOAP actor. There is no need to set this special role using this method.
+    *
+    * @param soapActorNames URIs for SOAP actor name
+    */
+   public void setRoles(String[] soapActorNames)
+   {
+      List<String> newRoles = Arrays.asList(soapActorNames);
+      log.debug("setRoles: " + newRoles);
+
+      roles.clear();
+      roles.addAll(newRoles);
+   }
+
+   public boolean handleMessage(MessageContext msgContext)
+   {
+      boolean doNext = true;
+
+      if (handlers.size() > 0)
+      {
+         log.debug("Enter: handleMessage");
+
+         int handlerIndex = 0;
+         Handler currHandler = null;
+         try
+         {
+            for (; doNext && handlerIndex < handlers.size(); handlerIndex++)
+            {
+               String lastMessageTrace = null;
+               if (log.isTraceEnabled())
+               {
+                  SOAPMessageContextJAXWS msgCtx = (SOAPMessageContextJAXWS)msgContext;
+                  SOAPPart soapPart = msgCtx.getMessage().getSOAPPart();
+                  lastMessageTrace = traceSOAPPart(soapPart, lastMessageTrace);
+               }
+
+               currHandler = ((HandlerEntry)handlers.get(handlerIndex)).getHandler();
+               log.debug("Handle message: " + currHandler);
+               doNext = currHandler.handleMessage(msgContext);
+
+               if (log.isTraceEnabled())
+               {
+                  SOAPMessageContextJAXWS msgCtx = (SOAPMessageContextJAXWS)msgContext;
+                  SOAPPart soapPart = msgCtx.getMessage().getSOAPPart();
+                  lastMessageTrace = traceSOAPPart(soapPart, lastMessageTrace);
+               }
+            }
+         }
+         catch (RuntimeException e)
+         {
+            log.error("RuntimeException in request handler", e);
+            doNext = false;
+            throw e;
+         }
+         finally
+         {
+            // we start at this index in the response chain
+            if (doNext == false)
+               falseIndex = (handlerIndex - 1);
+
+            log.debug("Exit: handleMessage with status: " + doNext);
+         }
+      }
+
+      return doNext;
+   }
+
+   /**
+    * Initiates the SOAP fault processing for this handler chain.
+    * <p/>
+    * In this implementation, the fault handler chain starts processing from the same Handler
+    * instance (that returned false) and goes backward in the execution sequence.
+    *
+    * @return Returns true if all handlers in chain have been processed.
+    *         Returns false if a handler in the chain returned false from its handleFault method.
+    * @throws javax.xml.rpc.JAXRPCException if any processing error happens
+    */
+   public boolean handleFault(MessageContext msgContext)
+   {
+      boolean doNext = true;
+
+      if (handlers.size() > 0)
+      {
+         log.debug("Enter: handleFault");
+
+         try
+         {
+            int handlerIndex = handlers.size() - 1;
+            if (falseIndex != -1)
+               handlerIndex = falseIndex;
+
+            Handler currHandler = null;
+            for (; doNext && handlerIndex >= 0; handlerIndex--)
+            {
+               currHandler = ((HandlerEntry)handlers.get(handlerIndex)).getHandler();
+               log.debug("Handle fault: " + currHandler);
+               doNext = currHandler.handleFault(msgContext);
+            }
+         }
+         finally
+         {
+            log.debug("Exit: handleFault with status: " + doNext);
+         }
+      }
+
+      return doNext;
+   }
+
+   /**
+    * Trace the SOAPPart, do nothing if the String representation is equal to the last one.
+    */
+   protected String traceSOAPPart(SOAPPart soapPart, String lastMessageTrace)
+   {
+      try
+      {
+         SOAPEnvelopeImpl soapEnv = (SOAPEnvelopeImpl)soapPart.getEnvelope();
+         String envString = DOMWriter.printNode(soapEnv, true);
+         if (envString.equals(lastMessageTrace) == false)
+         {
+            log.debug(envString);
+            lastMessageTrace = envString;
+         }
+         return lastMessageTrace;
+      }
+      catch (SOAPException e)
+      {
+         log.error("Cannot get SOAPEnvelope", e);
+         return null;
+      }
+   }
+
+   /**
+    * Get the handler at the requested position
+    */
+   protected Handler getHandlerAt(int pos)
+   {
+      if (pos < 0 || handlers.size() <= pos)
+         throw new IllegalArgumentException("No handler at position: " + pos);
+
+      HandlerEntry entry = (HandlerEntry)handlers.get(pos);
+      return entry.handler;
+   }
+
+   /**
+    * R1027 A RECEIVER MUST generate a "soap:MustUnderstand" fault when a
+    * message contains a mandatory header block (i.e., one that has a
+    * soap:mustUnderstand attribute with the value "1") targeted at the
+    * receiver (via soap:actor) that the receiver does not understand.
+    */
+   public static void checkMustUnderstand(SOAPMessageContextJAXWS msgContext, String[] roles)
+   {
+      SOAPHeaderElement mustUnderstandHeaderElement = null;
+      List roleList = (roles != null ? Arrays.asList(roles) : new ArrayList());
+      try
+      {
+         SOAPMessageImpl soapMessage = (SOAPMessageImpl)msgContext.getMessage();
+
+         // A SOAPHeaderElement is possibly bound to the endpoint operation
+         // in order to check that we need a the opMetaData
+         OperationMetaData opMetaData = msgContext.getOperationMetaData();
+         if (opMetaData == null)
+         {
+            // The security handler must have decrypted the incomming message
+            // before the dispatch target operation can be known 
+            EndpointMetaData epMetaData = msgContext.getEndpointMetaData();
+            opMetaData = soapMessage.getOperationMetaData(epMetaData);
+         }
+
+         SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope();
+         if (soapEnvelope != null && soapEnvelope.getHeader() != null)
+         {
+            Iterator it = soapEnvelope.getHeader().examineAllHeaderElements();
+            while (it.hasNext() && mustUnderstandHeaderElement == null)
+            {
+               SOAPHeaderElement soapHeaderElement = (SOAPHeaderElement)it.next();
+               Name name = soapHeaderElement.getElementName();
+               QName xmlName = new QName(name.getURI(), name.getLocalName());
+
+               ParameterMetaData paramMetaData = (opMetaData != null ? opMetaData.getParameter(xmlName) : null);
+               boolean isBoundHeader = (paramMetaData != null && paramMetaData.isInHeader());
+
+               if (soapHeaderElement.getMustUnderstand() && isBoundHeader == false)
+               {
+                  String actor = soapHeaderElement.getActor();
+                  boolean noActor = (actor == null || actor.length() == 0);
+                  boolean nextActor = Constants.URI_SOAP11_NEXT_ACTOR.equals(actor);
+                  if (noActor || nextActor || roleList.contains(actor))
+                  {
+                     mustUnderstandHeaderElement = soapHeaderElement;
+                  }
+               }
+            }
+         }
+      }
+      catch (SOAPException ex)
+      {
+         log.error("Cannot check mustUnderstand for headers", ex);
+      }
+
+      if (mustUnderstandHeaderElement != null)
+      {
+         QName faultCode = Constants.SOAP11_FAULT_CODE_MUST_UNDERSTAND;
+         String faultString = "Unprocessed 'mustUnderstand' header element: " + mustUnderstandHeaderElement.getElementName();
+         throw new SOAPFaultException(faultCode, faultString, null, null);
+      }
+   }
+
+   /**
+    * An entry in the handler list
+    */
+   private class HandlerEntry
+   {
+      private HandlerWrapper handler;
+      private HandlerInfo info;
+
+      public HandlerEntry(HandlerWrapper handler, HandlerInfo info)
+      {
+         this.handler = handler;
+         this.info = info;
+      }
+
+      public Handler getHandler()
+      {
+         return handler;
+      }
+
+      public HandlerInfo getInfo()
+      {
+         return info;
+      }
+   }
+}


Property changes on: trunk/src/main/java/org/jboss/ws/jaxws/handler/HandlerChainBaseImpl.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Added: trunk/src/main/java/org/jboss/ws/jaxws/handler/HandlerInfo.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/jaxws/handler/HandlerInfo.java	2006-08-01 16:29:43 UTC (rev 660)
+++ trunk/src/main/java/org/jboss/ws/jaxws/handler/HandlerInfo.java	2006-08-01 16:32:34 UTC (rev 661)
@@ -0,0 +1,73 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.jaxws.handler;
+
+// $Id: $
+
+
+/** This represents information about a handler in the HandlerChain. A
+ * HandlerInfo instance is passed in the Handler.init method to initialize a
+ * Handler instance.
+ * 
+ * @author Thomas.Diesler at jboss.org
+ */
+public class HandlerInfo
+{
+   private Class handlerClass;
+
+   /** Constructor for HandlerInfo
+    *
+    * @param handlerClass Java Class for the Handler
+    * @param config Handler Configuration as a java.util.Map
+    * @param headers QNames for the header blocks processed by this Handler.
+    * QName is the qualified name of the outermost element of a header block
+    */
+   public HandlerInfo(Class handlerClass)
+   {
+      this.handlerClass = handlerClass;
+   }
+
+   /** Gets the Handler class
+    *
+    * @return Returns null if no Handler class has been set; otherwise the set handler class
+    */
+   public Class getHandlerClass()
+   {
+      return handlerClass;
+   }
+
+   /** Sets the Handler class
+    *
+    * @param handlerClass Class for the Handler
+    */
+   public void setHandlerClass(Class handlerClass)
+   {
+      this.handlerClass = handlerClass;
+   }
+
+   /** Returns a string representation of the object.
+    */
+   public String toString()
+   {
+      return "[class=" + handlerClass.getName() + "]";
+   }
+}


Property changes on: trunk/src/main/java/org/jboss/ws/jaxws/handler/HandlerInfo.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Added: trunk/src/main/java/org/jboss/ws/jaxws/handler/HandlerWrapper.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/jaxws/handler/HandlerWrapper.java	2006-08-01 16:29:43 UTC (rev 660)
+++ trunk/src/main/java/org/jboss/ws/jaxws/handler/HandlerWrapper.java	2006-08-01 16:32:34 UTC (rev 661)
@@ -0,0 +1,158 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ws.jaxws.handler;
+
+// $Id$
+
+import javax.xml.ws.handler.Handler;
+import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.soap.SOAPFaultException;
+
+import org.jboss.logging.Logger;
+
+/**
+ * A wrapper arround a {@link javax.xml.rpc.handler.Handler} that takes care of its lifecycle.
+ *
+ * @author thomas.diesler at jboss.org
+ */
+public class HandlerWrapper implements Handler
+{
+   private static Logger log = Logger.getLogger(HandlerWrapper.class);
+
+   public final static int DOES_NOT_EXIST = 0;
+   public final static int METHOD_READY = 1;
+
+   // The states as string
+   private static String[] stateNames = new String[]{"DOES_NOT_EXIST", "METHOD_READY"};
+
+   // The handler to delegate to
+   private Handler delegate;
+   // The handler state
+   private int state;
+
+   /**
+    * Delegate to the given handler
+    */
+   public HandlerWrapper(Handler handler)
+   {
+      delegate = handler;
+      state = DOES_NOT_EXIST; // this is somewhat a lie ;-)
+   }
+
+   /**
+    * Get the current state
+    */
+   public int getState()
+   {
+      return state;
+   }
+
+   /**
+    * Get the current state as string
+    */
+   public String getStateAsString()
+   {
+      return stateNames[state];
+   }
+
+   /**
+    * The destroy method indicates the end of lifecycle for a Handler instance.
+    */
+   public void close(MessageContext context)
+   {
+      log.debug("close: " + delegate);
+      state = DOES_NOT_EXIST;
+      delegate.close(context);
+   }
+
+   /**
+    * The handleRequest method processes the request message.
+    */
+   public boolean handleMessage(MessageContext context)
+   {
+      if (state == DOES_NOT_EXIST)
+      {
+         log.warn("Handler is in state DOES_NOT_EXIST, skipping Handler.handleRequest for: " + delegate);
+         return true;
+      }
+
+      try
+      {
+         return delegate.handleMessage(context);
+      }
+      catch (RuntimeException e)
+      {
+         return handleRuntimeException(context, e);
+      }
+   }
+
+   /**
+    * The handleFault method processes the SOAP faults based on the SOAP message processing model.
+    */
+   public boolean handleFault(MessageContext context)
+   {
+      if (state == DOES_NOT_EXIST)
+      {
+         log.warn("Handler is in state DOES_NOT_EXIST, skipping Handler.handleFault for: " + delegate);
+         return true;
+      }
+
+      try
+      {
+         return delegate.handleFault(context);
+      }
+      catch (RuntimeException e)
+      {
+         return handleRuntimeException(context, e);
+      }
+   }
+
+   /**
+    * As defined by JAX-RPC, a RuntimeException(other than SOAPFaultException) thrown from any method of
+    * the Handler results in the destroymethod being invoked and transition to the �Does Not Exist� state.
+    */
+   private boolean handleRuntimeException(MessageContext context, RuntimeException e)
+   {
+      if ((e instanceof SOAPFaultException) == false)
+      {
+         log.warn("RuntimeException in handler method, transition to DOES_NOT_EXIST");
+         close(context);
+      }
+      throw e;
+   }
+
+   /**
+    * Returns a hash code value for the object.
+    */
+   public int hashCode()
+   {
+      return delegate.hashCode();
+   }
+
+   /**
+    * Returns a string representation of the object.
+    */
+   public String toString()
+   {
+      return "[state=" + getStateAsString() + ",handler=" + delegate + "]";
+   }
+}


Property changes on: trunk/src/main/java/org/jboss/ws/jaxws/handler/HandlerWrapper.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Added: trunk/src/main/java/org/jboss/ws/jaxws/handler/ServerHandlerChain.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/jaxws/handler/ServerHandlerChain.java	2006-08-01 16:29:43 UTC (rev 660)
+++ trunk/src/main/java/org/jboss/ws/jaxws/handler/ServerHandlerChain.java	2006-08-01 16:32:34 UTC (rev 661)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.jaxws.handler;
+
+// $Id$
+
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.ws.handler.MessageContext;
+
+import org.jboss.ws.metadata.j2ee.UnifiedHandlerMetaData.HandlerType;
+
+/**
+ * Represents a list of handlers. All elements in the
+ * HandlerChain are of the type javax.xml.rpc.handler.Handler.
+ *
+ * @author Thomas.Diesler at jboss.org
+ * @since 06-May-2004
+ */
+public class ServerHandlerChain extends HandlerChainBaseImpl
+{
+   // The required type of the handler
+   private HandlerType type;
+
+   public ServerHandlerChain(List<HandlerInfo> infos, Set roles, HandlerType type)
+   {
+      super(infos, roles);
+      this.type = type;
+   }
+
+   public boolean handleMessage(MessageContext msgContext)
+   {
+      boolean doNext = super.handleMessage(msgContext);
+      return doNext;
+   }
+}


Property changes on: trunk/src/main/java/org/jboss/ws/jaxws/handler/ServerHandlerChain.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Added: trunk/src/main/java/org/jboss/ws/server/InvokerDelegate.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/server/InvokerDelegate.java	2006-08-01 16:29:43 UTC (rev 660)
+++ trunk/src/main/java/org/jboss/ws/server/InvokerDelegate.java	2006-08-01 16:32:34 UTC (rev 661)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.server;
+
+// $Id$
+
+import javax.xml.soap.SOAPMessage;
+
+import org.jboss.ws.metadata.j2ee.UnifiedHandlerMetaData.HandlerType;
+
+/** An implementation of handles invocations on the endpoint
+ *
+ * @author Thomas.Diesler at jboss.org
+ * @since 19-Jan-2005
+ */
+public interface InvokerDelegate 
+{
+   public SOAPMessage invoke(ServiceEndpointInfo seInfo, Object endpointContext) throws Exception;
+
+   public boolean callRequestHandlerChain(ServiceEndpointInfo seInfo, HandlerType type);
+
+   public boolean callResponseHandlerChain(ServiceEndpointInfo seInfo, HandlerType type);
+   
+   public boolean callFaultHandlerChain(ServiceEndpointInfo seInfo, HandlerType type, Exception ex);
+}


Property changes on: trunk/src/main/java/org/jboss/ws/server/InvokerDelegate.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Added: trunk/src/main/java/org/jboss/ws/server/ServiceEndpointInvokerBase.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/server/ServiceEndpointInvokerBase.java	2006-08-01 16:29:43 UTC (rev 660)
+++ trunk/src/main/java/org/jboss/ws/server/ServiceEndpointInvokerBase.java	2006-08-01 16:32:34 UTC (rev 661)
@@ -0,0 +1,131 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.server;
+
+// $Id$
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import javax.management.MBeanException;
+import javax.xml.rpc.soap.SOAPFaultException;
+import javax.xml.soap.SOAPMessage;
+
+import org.jboss.ws.Constants;
+import org.jboss.ws.jaxrpc.InvokerDelegateJAXRPC;
+import org.jboss.ws.jaxws.InvokerDelegateJAXWS;
+import org.jboss.ws.metadata.EndpointMetaData;
+import org.jboss.ws.metadata.EndpointMetaData.Type;
+import org.jboss.ws.utils.JavaUtils;
+
+/** An implementation of handles invocations on the endpoint
+ *
+ * @author Thomas.Diesler at jboss.org
+ * @since 19-Jan-2005
+ */
+public abstract class ServiceEndpointInvokerBase implements ServiceEndpointInvoker 
+{
+   protected InvokerDelegate delegate;
+   
+   /** Initialize the service endpoint */
+   public void initServiceEndpoint(ServiceEndpointInfo seInfo)
+   {
+      Type type = seInfo.getServerEndpointMetaData().getType();
+      if (type == EndpointMetaData.Type.JAXRPC)
+      {
+         delegate = new InvokerDelegateJAXRPC(this);
+      }
+      else
+      {
+         delegate = new InvokerDelegateJAXWS(this);
+      }
+   }
+
+   public SOAPMessage invoke(ServiceEndpointInfo seInfo, Object context) throws Exception
+   {
+      return delegate.invoke(seInfo, context);
+   }
+   
+   protected Method getImplMethod(Class implClass, Method seiMethod) throws ClassNotFoundException, NoSuchMethodException
+   {
+      String methodName = seiMethod.getName();
+      Class[] paramTypes = seiMethod.getParameterTypes();
+      for (int i = 0; i < paramTypes.length; i++)
+      {
+         Class paramType = paramTypes[i];
+         if (JavaUtils.isPrimitive(paramType) == false)
+         {
+            String paramTypeName = paramType.getName();
+            paramType = JavaUtils.loadJavaType(paramTypeName);
+            paramTypes[i] = paramType;
+         }
+      }
+
+      Method implMethod = implClass.getMethod(methodName, paramTypes);
+      return implMethod;
+   }
+   
+   /** handle invokation exceptions */
+   public void handleInvocationException(Throwable th) throws SOAPFaultException
+   {
+      if (th instanceof RuntimeException)
+         throw (RuntimeException)th;
+
+      if (th instanceof InvocationTargetException)
+      {
+         InvocationTargetException targetException = (InvocationTargetException)th;
+         Throwable targetEx = targetException.getTargetException();
+         if (targetEx instanceof SOAPFaultException)
+         {
+            throw (SOAPFaultException)targetEx;
+         }
+         else
+         {
+            String faultString = targetEx.toString();
+            SOAPFaultException soapFaultEx = new SOAPFaultException(Constants.SOAP11_FAULT_CODE_CLIENT, faultString, null, null);
+            soapFaultEx.initCause(targetEx);
+            throw soapFaultEx;
+         }
+      }
+
+      if (th instanceof MBeanException)
+      {
+         Exception targetEx = ((MBeanException)th).getTargetException();
+         if (targetEx instanceof SOAPFaultException)
+         {
+            throw (SOAPFaultException)targetEx;
+         }
+         else
+         {
+            String faultString = targetEx.toString();
+            SOAPFaultException soapFaultEx = new SOAPFaultException(Constants.SOAP11_FAULT_CODE_CLIENT, faultString, null, null);
+            soapFaultEx.initCause(targetEx);
+            throw soapFaultEx;
+         }
+      }
+
+      String faultString = th.toString();
+      SOAPFaultException soapFaultEx = new SOAPFaultException(Constants.SOAP11_FAULT_CODE_CLIENT, faultString, null, null);
+      soapFaultEx.initCause(th);
+      throw soapFaultEx;
+   }
+}


Property changes on: trunk/src/main/java/org/jboss/ws/server/ServiceEndpointInvokerBase.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF




More information about the jboss-svn-commits mailing list