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

    1   /**
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    */
   17   package org.apache.openejb.server.axis;
   18   
   19   import javax.xml.rpc.JAXRPCException;
   20   import javax.xml.rpc.handler.Handler;
   21   import javax.xml.rpc.handler.HandlerInfo;
   22   import javax.xml.rpc.handler.MessageContext;
   23   import javax.xml.rpc.handler.soap.SOAPMessageContext;
   24   import javax.xml.rpc.soap.SOAPFaultException;
   25   import javax.xml.soap.SOAPBody;
   26   import javax.xml.soap.SOAPElement;
   27   import javax.xml.soap.SOAPException;
   28   import javax.xml.soap.SOAPMessage;
   29   import java.util.ArrayList;
   30   import java.util.Iterator;
   31   import java.util.LinkedList;
   32   import java.util.List;
   33   import java.util.Map;
   34   
   35   /**
   36    * Implementation of HandlerChain
   37    */
   38   public class HandlerChainImpl extends ArrayList implements javax.xml.rpc.handler.HandlerChain {
   39       private String[] roles;
   40       private LinkedList<Handler> invokedHandlers = new LinkedList<Handler>();
   41   
   42       public HandlerChainImpl(List<HandlerInfo> handlerInfos) {
   43           this(handlerInfos, null);
   44       }
   45   
   46       @SuppressWarnings({"unchecked"})
   47       public HandlerChainImpl(List<HandlerInfo> handlerInfos, String[] roles) {
   48           this.roles = roles;
   49           for (int i = 0; i < handlerInfos.size(); i++) {
   50               HandlerInfo handlerInfo = handlerInfos.get(i);
   51               try {
   52                   Handler handler = (Handler) handlerInfo.getHandlerClass().newInstance();
   53                   handler.init(handlerInfo);
   54                   add(handler);
   55               } catch (Exception e) {
   56                   throw new JAXRPCException("Unable to initialize handler class: " + handlerInfo.getHandlerClass().getName(), e);
   57               }
   58           }
   59       }
   60   
   61       public String[] getRoles() {
   62           return roles;
   63       }
   64   
   65       public void setRoles(String[] roles) {
   66           if (roles == null) {
   67               this.roles = new String[0];
   68           } else {
   69               this.roles = roles;
   70           }
   71       }
   72   
   73       public void init(Map map) {
   74       }
   75   
   76       public void destroy() {
   77           for (Iterator iterator = invokedHandlers.iterator(); iterator.hasNext();) {
   78               Handler handler = (Handler) iterator.next();
   79               handler.destroy();
   80           }
   81           invokedHandlers.clear();
   82           clear();
   83       }
   84   
   85       public boolean handleRequest(MessageContext context) {
   86           MessageSnapshot snapshot = new MessageSnapshot(context);
   87           try {
   88               for (int i = 0; i < size(); i++) {
   89                   Handler currentHandler = (Handler) get(i);
   90                   invokedHandlers.addFirst(currentHandler);
   91                   try {
   92                       if (!currentHandler.handleRequest(context)) {
   93                           return false;
   94                       }
   95                   } catch (SOAPFaultException e) {
   96                       throw e;
   97                   }
   98               }
   99           } finally {
  100               saveChanges(context);
  101           }
  102   
  103           if (!snapshot.equals(context)) {
  104               throw new IllegalStateException("The soap message operation or arguments were illegally modified by the HandlerChain");
  105           }
  106           return true;
  107       }
  108   
  109       public boolean handleResponse(MessageContext context) {
  110           MessageSnapshot snapshot = new MessageSnapshot(context);
  111           try {
  112               for (Iterator iterator = invokedHandlers.iterator(); iterator.hasNext();) {
  113                   Handler handler = (Handler) iterator.next();
  114                   if (!handler.handleResponse(context)) {
  115                       return false;
  116                   }
  117               }
  118           } finally {
  119               saveChanges(context);
  120           }
  121           if (!snapshot.equals(context)) {
  122               throw new IllegalStateException("The soap message operation or arguments were illegally modified by the HandlerChain");
  123           }
  124           return true;
  125       }
  126   
  127       public boolean handleFault(MessageContext context) {
  128           MessageSnapshot snapshot = new MessageSnapshot(context);
  129           try {
  130               for (Iterator iterator = invokedHandlers.iterator(); iterator.hasNext();) {
  131                   Handler handler = (Handler) iterator.next();
  132                   if (!handler.handleFault(context)) {
  133                       return false;
  134                   }
  135               }
  136           } finally {
  137               saveChanges(context);
  138           }
  139           if (!snapshot.equals(context)) {
  140               throw new IllegalStateException("The soap message operation or arguments were illegally modified by the HandlerChain");
  141           }
  142           return true;
  143       }
  144   
  145       private void saveChanges(MessageContext context) {
  146           try {
  147               SOAPMessage message = ((SOAPMessageContext) context).getMessage();
  148               if (message != null) {
  149                   message.saveChanges();
  150               }
  151           } catch (SOAPException e) {
  152               throw new RuntimeException("Unable to save changes to SOAPMessage : " + e.toString());
  153           }
  154       }
  155   
  156   
  157       /**
  158        * Handlers cannot:
  159        * <p/>
  160        * - re-target a request to a different component.
  161        * - change the operation
  162        * - change the message part types
  163        * - change the number of message parts.
  164        */
  165       static class MessageSnapshot {
  166           private final String operationName;
  167           private final List<String> parameterNames;
  168   
  169           public MessageSnapshot(MessageContext soapMessage) {
  170               SOAPMessage message = ((SOAPMessageContext) soapMessage).getMessage();
  171               if (message == null || message.getSOAPPart() == null) {
  172                   operationName = null;
  173                   parameterNames = null;
  174               } else {
  175                   SOAPBody body = getBody(message);
  176   
  177                   SOAPElement operation = ((SOAPElement) body.getChildElements().next());
  178                   this.operationName = operation.getElementName().toString();
  179   
  180                   this.parameterNames = new ArrayList<String>();
  181                   for (Iterator i = operation.getChildElements(); i.hasNext();) {
  182                       SOAPElement parameter = (SOAPElement) i.next();
  183                       String element = parameter.getElementName().toString();
  184                       parameterNames.add(element);
  185                   }
  186               }
  187           }
  188   
  189           private SOAPBody getBody(SOAPMessage message) {
  190               try {
  191                   return message.getSOAPPart().getEnvelope().getBody();
  192               } catch (SOAPException e) {
  193                   throw new RuntimeException(e);
  194               }
  195           }
  196   
  197           public boolean equals(Object obj) {
  198               return (obj instanceof SOAPMessageContext) && equals((SOAPMessageContext) obj);
  199           }
  200   
  201           private boolean equals(SOAPMessageContext soapMessage) {
  202               SOAPMessage message = soapMessage.getMessage();
  203   
  204               if (operationName == null) {
  205                   return message == null || message.getSOAPPart() == null;
  206               }
  207   
  208               SOAPBody body = getBody(message);
  209   
  210               // Handlers can't change the operation
  211               SOAPElement operation = ((SOAPElement) body.getChildElements().next());
  212               if (!this.operationName.equals(operation.getElementName().toString())) {
  213                   return false;
  214               }
  215   
  216               Iterator parameters = operation.getChildElements();
  217               for (Iterator i = parameterNames.iterator(); i.hasNext();) {
  218                   // Handlers can't remove parameters
  219                   if (!parameters.hasNext()) {
  220                       return false;
  221                   }
  222   
  223                   String original = (String) i.next();
  224                   SOAPElement parameter = (SOAPElement) parameters.next();
  225                   // Handlers can't change parameter types
  226                   if (parameter == null || !original.equals(parameter.getElementName().toString())) {
  227                       return false;
  228                   }
  229               }
  230   
  231               // Handlers can't add parameters
  232               return !parameters.hasNext();
  233           }
  234       }
  235   }

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