View Javadoc

    1   package org.codehaus.xfire.handler;
    2
    3   import java.util.ArrayList;
    4   import java.util.Collections;
    5   import java.util.HashMap;
    6   import java.util.Iterator;
    7   import java.util.List;
    8   import java.util.Map;
    9   import java.util.Stack;
    10
    11  import javax.xml.namespace.QName;
    12
    13  import org.apache.commons.logging.Log;
    14  import org.apache.commons.logging.LogFactory;
    15  import org.codehaus.xfire.MessageContext;
    16  import org.codehaus.xfire.XFireRuntimeException;
    17  import org.codehaus.xfire.fault.XFireFault;
    18
    19  /***
    20   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
    21   */
    22  public class HandlerPipeline
    23      extends AbstractHandler
    24      implements Handler
    25  {
    26      private static final Log log = LogFactory.getLog(HandlerPipeline.class);
    27
    28      private List phases;
    29      private Map handlers;
    30
    31      public HandlerPipeline(List phases)
    32      {
    33          handlers = new HashMap();
    34
    35          // Order the phases correctly based on priority
    36          Collections.sort(phases);
    37          this.phases = phases;
    38
    39          for (Iterator itr = phases.iterator(); itr.hasNext();)
    40          {
    41              Phase phase = (Phase) itr.next();
    42
    43              handlers.put(phase.getName(), new ArrayList());
    44          }
    45      }
    46
    47      public void addHandlers(List handlers)
    48      {
    49          if (handlers == null) return;
    50
    51          for (Iterator itr = handlers.iterator(); itr.hasNext();)
    52          {
    53              Handler handler = (Handler) itr.next();
    54
    55              addHandler(handler);
    56          }
    57      }
    58
    59      public void addHandler(Handler handler)
    60      {
    61          List phaseHandlers = (List) handlers.get(handler.getPhase());
    62
    63          if (phaseHandlers == null)
    64              throw new XFireRuntimeException("Invalid phase: " + handler.getPhase());
    65
    66          phaseHandlers.add(handler);
    67      }
    68
    69      /***
    70       * Invokes each phase's handler in turn.
    71       *
    72       * @param context
    73       * @throws Exception
    74       */
    75      public void invoke(MessageContext context)
    76      	throws Exception
    77      {
    78          Stack invoked = new Stack();
    79          context.setProperty(this, invoked);
    80
    81          for (Iterator itr = phases.iterator(); itr.hasNext();)
    82          {
    83              Phase phase = (Phase) itr.next();
    84
    85              List phaseHandlers = (List) handlers.get(phase.getName());
    86              for (int i = 0; i < phaseHandlers.size(); i++ )
    87              {
    88                  Handler h = (Handler) phaseHandlers.get(i);
    89                  try
    90                  {
    91                      log.debug("Invoking handler " + h.getClass().getName() + " in phase " + phase.getName());
    92
    93                      h.invoke(context);
    94                  }
    95                  finally
    96                  {
    97                      // Add the invoked handler to the stack so we can come
    98                      // back to it later if a fault occurs.
    99                      invoked.push(h);
    100                 }
    101             }
    102         }
    103     }
    104
    105     /***
    106      * Takes a fault, creates a fault message and sends it via the fault channel.
    107      *
    108      * @param fault
    109      * @param context
    110      */
    111     public void handleFault(XFireFault fault, MessageContext context)
    112     {
    113         Stack invoked = (Stack) context.getProperty(this);
    114
    115         while (invoked.size() > 0)
    116         {
    117             Handler h = (Handler) invoked.pop();
    118             h.handleFault(fault, context);
    119         }
    120     }
    121
    122     /***
    123      * Determines whether or not this Pipeline "understands" a particular header.
    124      * @param pipeline
    125      * @param name
    126      * @return
    127      */
    128     public boolean understands(QName name)
    129     {
    130         for (Iterator itr = phases.iterator(); itr.hasNext();)
    131         {
    132             Phase phase = (Phase) itr.next();
    133
    134             List phaseHandlers = (List) handlers.get(phase.getName());
    135             for (int i = 0; i < phaseHandlers.size(); i++ )
    136             {
    137                 Handler h = (Handler) phaseHandlers.get(i);
    138                 QName[] understoodQs = h.getUnderstoodHeaders();
    139
    140                 if (understoodQs != null)
    141                 {
    142                     for (int j = 0; j < understoodQs.length; j++)
    143                     {
    144                         if (understoodQs[j].equals(name))
    145                             return true;
    146                     }
    147                 }
    148             }
    149         }
    150
    151         return false;
    152     }
    153 }