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
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
98
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 }