Save This Page
Home » axis2-1.5-src » org.apache » axis2 » engine » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements. See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership. The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with 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,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied. See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.
   18    */
   19   
   20   
   21   package org.apache.axis2.engine;
   22   
   23   import org.apache.axis2.AxisFault;
   24   import org.apache.axis2.context.MessageContext;
   25   import org.apache.axis2.description.HandlerDescription;
   26   import org.apache.axis2.description.Parameter;
   27   import org.apache.axis2.description.PhaseRule;
   28   import org.apache.axis2.phaseresolver.PhaseException;
   29   import org.apache.axis2.util.LoggingControl;
   30   import org.apache.commons.logging.Log;
   31   import org.apache.commons.logging.LogFactory;
   32   
   33   import java.util.Iterator;
   34   import java.util.List;
   35   import java.util.concurrent.CopyOnWriteArrayList;
   36   
   37   /**
   38    * A Phase is an ordered collection of Handlers.
   39    */
   40   public class Phase implements Handler {
   41   
   42       public static final String ALL_PHASES = "*";
   43   
   44       /**
   45        * Field log
   46        */
   47       private static final Log log = LogFactory.getLog(Phase.class);
   48       private static boolean isDebugEnabled = LoggingControl.debugLoggingAllowed && log.isDebugEnabled();
   49   
   50       /**
   51        * Field handlers
   52        */
   53       private List<Handler> handlers;
   54   
   55       /**
   56        * A handler has been marked as present in both the first phase and the last phase
   57        */
   58       private boolean isOneHandler;
   59   
   60       /**
   61        * Field phaseName
   62        */
   63       private String phaseName;
   64   
   65       /**
   66        * Field phaseFirstSet
   67        */
   68       private boolean phaseFirstSet;
   69   
   70       /**
   71        * Field phaseLastSet
   72        */
   73       private boolean phaseLastSet;
   74   
   75       /**
   76        * Default constructor
   77        */
   78       public Phase() {
   79           this(null);
   80       }
   81   
   82       /**
   83        * Create a named Phase
   84        *
   85        * @param phaseName the name for this Phase
   86        */
   87       public Phase(String phaseName) {
   88           handlers = new CopyOnWriteArrayList<Handler>();
   89           this.phaseName = phaseName;
   90       }
   91   
   92       /**
   93        * Add a handler to the Phase.
   94        *
   95        * @param handler the Handler to add
   96        */
   97       public void addHandler(Handler handler) {
   98           log.debug("Handler " + handler.getName() + " added to Phase " + phaseName);
   99   
  100           if (phaseLastSet) {
  101               // handlers.size() can not be 0 , since when setting phase last it is always > 0
  102               if (handlers.size() == 1) {
  103                   handlers.add(0, handler);
  104               } else {
  105                   handlers.add(handlers.size() - 2, handler);
  106               }
  107           } else {
  108               handlers.add(handler);
  109           }
  110       }
  111   
  112       /**
  113        * Add a HandlerDescription to the Phase
  114        *
  115        * @param handlerDesc the HandlerDescription to add
  116        * @throws PhaseException if there is a problem
  117        */
  118       public void addHandler(HandlerDescription handlerDesc) throws PhaseException {
  119           Iterator<Handler> handlers_itr = getHandlers().iterator();
  120   
  121           while (handlers_itr.hasNext()) {
  122               Handler hand = (Handler) handlers_itr.next();
  123               HandlerDescription thisDesc = hand.getHandlerDesc();
  124               if (handlerDesc.getName().equals(thisDesc.getName())) {
  125                   return;
  126               }
  127           }
  128   
  129           if (isOneHandler) {
  130               throw new PhaseException("Phase '" + this.getPhaseName()
  131                       + "' can only have one handler, since there is a "
  132                       + "handler with both phaseFirst and phaseLast true ");
  133           }
  134   
  135           if (handlerDesc.getRules().isPhaseFirst() && handlerDesc.getRules().isPhaseLast()) {
  136               if (!handlers.isEmpty()) {
  137                   throw new PhaseException(this.getPhaseName()
  138                           + " already contains Handlers, and "
  139                           + handlerDesc.getName()
  140                           + " cannot therefore be both phaseFirst and phaseLast.");
  141               } else {
  142                   handlers.add(handlerDesc.getHandler());
  143                   isOneHandler = true;
  144               }
  145           } else if (handlerDesc.getRules().isPhaseFirst()) {
  146               setPhaseFirst(handlerDesc.getHandler());
  147           } else if (handlerDesc.getRules().isPhaseLast()) {
  148               setPhaseLast(handlerDesc.getHandler());
  149           } else {
  150               insertHandler(handlerDesc);
  151           }
  152       }
  153   
  154       /**
  155        * Add a Handler at a particular index within the Phase.
  156        *
  157        * If we have a Phase with (H1, H2), calling addHandler(H3, 1) will result in (H1, H3, H2)
  158        *
  159        * @param handler the Handler to add
  160        * @param index the position in the Phase at which to place the Handler
  161        */
  162       public void addHandler(Handler handler, int index) {
  163           if (log.isDebugEnabled()) {
  164               log.debug("Handler " + handler.getName() + " inserted at position " + index +
  165                       " of Phase " + phaseName);
  166           }
  167           handlers.add(index, handler);
  168       }
  169   
  170       /**
  171        * Confirm that all post-conditions of this Phase are met.  After all Handlers in a
  172        * Phase are invoke()d, this method will be called.  Subclasses should override it in order
  173        * to confirm that the purpose of the given Phase has been acheived.
  174        *
  175        * @param msgContext the active MessageContext
  176        * @throws AxisFault if a post-condition has not been met, or other problems occur
  177        */
  178       public void checkPostConditions(MessageContext msgContext) throws AxisFault {
  179           // Default version does nothing
  180       }
  181   
  182       /**
  183        * Check the preconditions for a Phase.  This method will be called when the Phase is
  184        * invoked, BEFORE any Handlers are invoked.  Subclasses should override it in order
  185        * to confirm that necessary preconditions are met before the Phase does its work.  They
  186        * should throw an appropriate AxisFault if not.
  187        *
  188        * @param msgContext the active MessageContext
  189        * @throws AxisFault if a precondition is not met, or in case of other problem
  190        */
  191       public void checkPreconditions(MessageContext msgContext) throws AxisFault {
  192           // Default version does nothing
  193       }
  194   
  195       public void cleanup() {
  196           // Default version does nothing
  197       }
  198   
  199       public void init(HandlerDescription handlerdesc) {
  200           // Default version does nothing
  201       }
  202   
  203       private void insertHandler(HandlerDescription handlerDesc) throws PhaseException {
  204           Handler handler = handlerDesc.getHandler();
  205           PhaseRule rules = handler.getHandlerDesc().getRules();
  206           String beforeName = rules.getBefore();
  207           String afterName = rules.getAfter();
  208   
  209           // If we don't care where it goes, tack it on at the end
  210           if (beforeName == null && afterName == null) {
  211               addHandler(handler);
  212               return;
  213           }
  214   
  215           // Otherwise walk the list and find the right place to put it
  216           int beforeIndex = -1, afterIndex = -1;
  217   
  218           for (int i = 0; i < handlers.size(); i++) {
  219               Handler tempHandler = (Handler) handlers.get(i);
  220   
  221               if ((beforeName != null) && (beforeIndex == -1)) {
  222                   if (tempHandler.getName().equals(beforeName)) {
  223                       // Found the "before" handler
  224                       beforeIndex = i;
  225                   }
  226               }
  227   
  228               if ((afterName != null) && (afterIndex == -1)) {
  229                   if (tempHandler.getName().equals(afterName)) {
  230                       // Found the "after" handler
  231                       afterIndex = i;
  232                   }
  233               }
  234           }
  235   
  236           if ((beforeIndex > -1) && (afterIndex >= beforeIndex)) {
  237               throw new PhaseException("Can't insert handler because " + beforeName + " is before " +
  238                       afterName + " in Phase '" + phaseName + "'");
  239           }
  240   
  241           if (phaseFirstSet && beforeIndex == 0) {
  242               throw new PhaseException("Can't insert handler before handler '"
  243                       + beforeName
  244                       + "', which is marked phaseFirst");
  245           }
  246   
  247           if (phaseLastSet && afterIndex == (handlers.size() - 1)) {
  248               throw new PhaseException("Can't insert handler after handler '"
  249                       + afterName
  250                       + "', which is marked phaseLast");
  251           }
  252   
  253           if (beforeIndex > -1) {
  254               handlers.add(beforeIndex, handler);
  255           } else if (afterIndex > -1){
  256               if (phaseLastSet){
  257                   if (handlers.size() ==1){
  258                       handlers.add(0,handler);
  259                   }  else {
  260                       handlers.add(handlers.size() -2,handler);
  261                   }
  262               }  else {
  263                   if (afterIndex == (handlers.size() -1)) {
  264                       handlers.add(handler);
  265                   } else {
  266                       handlers.add(afterIndex +1,handler);
  267                   }
  268               }
  269           }  else {
  270               if (phaseLastSet) {
  271                   if (handlers.size() ==1){
  272                       handlers.add(0,handler);
  273                   }  else {
  274                       handlers.add(handlers.size() -2,handler);
  275                   }
  276               }    else {
  277                   handlers.add(handler);
  278               }
  279           }
  280       }
  281   
  282       /**
  283        * Invoke all the handlers in this Phase
  284        *
  285        * @param msgctx the current MessageContext
  286        * @return An InvocationResponse that indicates what
  287        *         the next step in the message processing should be.
  288        * @throws org.apache.axis2.AxisFault
  289        */
  290       public final InvocationResponse invoke(MessageContext msgctx) throws AxisFault {
  291           
  292           if (isDebugEnabled) {
  293               log.debug(msgctx.getLogIDString() + " Checking pre-condition for Phase \"" + phaseName +
  294                       "\"");
  295           }
  296   
  297           InvocationResponse pi = InvocationResponse.CONTINUE;
  298   
  299           int currentIndex = msgctx.getCurrentPhaseIndex();
  300   
  301           if (currentIndex == 0) {
  302               checkPreconditions(msgctx);
  303           }
  304   
  305           if (isDebugEnabled) {
  306               log.debug(msgctx.getLogIDString() + " Invoking phase \"" + phaseName + "\"");
  307           }
  308   
  309           int handlersSize = handlers.size();
  310           
  311           while (currentIndex < handlersSize) {
  312               Handler handler = (Handler) handlers.get(currentIndex);
  313   
  314               if (isDebugEnabled) {
  315                   log.debug(msgctx.getLogIDString() + " Invoking Handler '" + handler.getName() +
  316                           "' in Phase '" + phaseName + "'");
  317               }
  318               pi = handler.invoke(msgctx);
  319   
  320               if (!pi.equals(InvocationResponse.CONTINUE)) {
  321                   return pi;
  322               }
  323   
  324               currentIndex++;
  325               msgctx.setCurrentPhaseIndex(currentIndex);
  326           }
  327   
  328           if (isDebugEnabled) {
  329               log.debug(msgctx.getLogIDString() + " Checking post-conditions for phase \"" +
  330                       phaseName + "\"");
  331           }
  332   
  333           msgctx.setCurrentPhaseIndex(0);
  334           checkPostConditions(msgctx);
  335           return pi;
  336       }
  337   
  338       public void flowComplete(MessageContext msgContext) {
  339           if (isDebugEnabled) {
  340               log.debug(msgContext.getLogIDString() + " Invoking flowComplete() in Phase \"" +
  341                       phaseName + "\"");
  342           }
  343   
  344           // This will be non-zero if we failed during execution of one of the
  345           // handlers in this phase
  346           int currentHandlerIndex = msgContext.getCurrentPhaseIndex();
  347           if (currentHandlerIndex == 0) {
  348               currentHandlerIndex = handlers.size();
  349           } else {
  350               /*We need to set it to 0 so that any previous phases will execute all
  351            * of their handlers.*/
  352               msgContext.setCurrentPhaseIndex(0);
  353           }
  354   
  355           for (; currentHandlerIndex > 0; currentHandlerIndex--) {
  356               Handler handler = (Handler) handlers.get(currentHandlerIndex - 1);
  357   
  358               if (isDebugEnabled) {
  359                   log.debug(msgContext.getLogIDString() + " Invoking flowComplete() for Handler '" +
  360                           handler.getName() + "' in Phase '" + phaseName + "'");
  361               }
  362   
  363               handler.flowComplete(msgContext);
  364           }
  365       }
  366   
  367       public String toString() {
  368           return this.getPhaseName();
  369       }
  370   
  371       public int getHandlerCount() {
  372           return handlers.size();
  373       }
  374   
  375       public HandlerDescription getHandlerDesc() {
  376           return null;
  377       }
  378   
  379       /**
  380        * Gets all the handlers in the phase.
  381        *
  382        * @return Returns an ArrayList of Handlers
  383        */
  384       public List<Handler> getHandlers() {
  385           return handlers;
  386       }
  387   
  388       public String getName() {
  389           return phaseName;
  390       }
  391   
  392       public Parameter getParameter(String name) {
  393           return null;
  394       }
  395   
  396       /**
  397        * @return Returns the name.
  398        */
  399       public String getPhaseName() {
  400           return phaseName;
  401       }
  402   
  403       public void setName(String phaseName) {
  404           this.phaseName = phaseName;
  405       }
  406   
  407       /**
  408        * Add a Handler to the Phase in the very first position, and ensure no other Handler
  409        * will come before it.
  410        *
  411        * @param handler the Handler to add
  412        * @throws PhaseException if another Handler is already set as phaseFirst
  413        */
  414       public void setPhaseFirst(Handler handler) throws PhaseException {
  415           if (phaseFirstSet) {
  416               throw new PhaseException("PhaseFirst has been set already, cannot have two"
  417                       + " phaseFirst Handlers for Phase '" + this.getPhaseName() + "'");
  418           }
  419           handlers.add(0, handler);
  420           phaseFirstSet = true;
  421       }
  422   
  423       /**
  424        * Add a Handler to the Phase in the very last position, and ensure no other Handler
  425        * will come after it.
  426        *
  427        * @param handler the Handler to add
  428        * @throws PhaseException if another Handler is already set as phaseLast
  429        */
  430       public void setPhaseLast(Handler handler) throws PhaseException {
  431           if (phaseLastSet) {
  432               throw new PhaseException("PhaseLast already has been set,"
  433                       + " cannot have two PhaseLast Handler for same phase "
  434                       + this.getPhaseName());
  435           }
  436   
  437           handlers.add(handler);
  438           phaseLastSet = true;
  439       }
  440   
  441       /**
  442        * Remove a given Handler from a phase using a HandlerDescription
  443        *
  444        * @param handlerDesc the HandlerDescription to remove
  445        */
  446       public void removeHandler(HandlerDescription handlerDesc) {
  447           if (handlers.remove(handlerDesc.getHandler())) {
  448               PhaseRule rule = handlerDesc.getRules();
  449               if (rule.isPhaseFirst()) {
  450                   phaseFirstSet = false;
  451               }
  452               if (rule.isPhaseLast()) {
  453                   phaseLastSet = false;
  454               }
  455               if (rule.isPhaseFirst() && rule.isPhaseLast()) {
  456                   isOneHandler = false;
  457               }
  458               log.debug("removed handler " + handlerDesc.getName()
  459                       + " from the phase " + phaseName);
  460           } else {
  461               log.debug("unable to remove handler " + handlerDesc.getName()
  462                       + " from the phase " + phaseName);
  463           }
  464       }
  465   
  466   }

Save This Page
Home » axis2-1.5-src » org.apache » axis2 » engine » [javadoc | source]