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 }