1 package org.codehaus.xfire.soap.handler;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 import javax.xml.stream.XMLStreamException;
7 import javax.xml.stream.XMLStreamReader;
8
9 import org.codehaus.xfire.MessageContext;
10 import org.codehaus.xfire.exchange.InMessage;
11 import org.codehaus.xfire.exchange.MessageSerializer;
12 import org.codehaus.xfire.fault.XFireFault;
13 import org.codehaus.xfire.handler.AbstractHandler;
14 import org.codehaus.xfire.handler.Phase;
15 import org.codehaus.yom.Element;
16 import org.codehaus.yom.stax.StaxBuilder;
17
18 public class ReadHeadersHandler
19 extends AbstractHandler
20 {
21 public static final String DECLARED_NAMESPACES = "declared.namespaces";
22
23 public String getPhase()
24 {
25 return Phase.PARSE;
26 }
27
28 public void invoke(MessageContext context)
29 throws Exception
30 {
31 InMessage message = context.getInMessage();
32 if (message.hasHeader()) return;
33
34 XMLStreamReader reader = message.getXMLStreamReader();
35
36 Map namespaces = new HashMap();
37 context.setProperty(DECLARED_NAMESPACES, namespaces);
38
39 boolean end = !reader.hasNext();
40 while (!end && reader.hasNext())
41 {
42 int event = reader.next();
43 switch (event)
44 {
45 case XMLStreamReader.START_DOCUMENT:
46 String encoding = reader.getCharacterEncodingScheme();
47 message.setEncoding(encoding);
48 break;
49 case XMLStreamReader.END_DOCUMENT:
50 end = true;
51 return;
52 case XMLStreamReader.END_ELEMENT:
53 break;
54 case XMLStreamReader.START_ELEMENT:
55 if (reader.getLocalName().equals("Header"))
56 {
57 readHeaders(context);
58 }
59 else if (reader.getLocalName().equals("Body"))
60 {
61 readNamespaces(reader, namespaces);
62
63 seekToWhitespaceEnd(reader);
64
65 checkForFault(context, message, reader);
66
67 return;
68 }
69 else if (reader.getLocalName().equals("Envelope"))
70 {
71 readNamespaces(reader, namespaces);
72
73 message.setSoapVersion(reader.getNamespaceURI());
74 }
75 break;
76 default:
77 break;
78 }
79 }
80 }
81
82 private void readNamespaces(XMLStreamReader reader, Map namespaces)
83 {
84 for (int i = 0; i < reader.getNamespaceCount(); i++)
85 {
86 namespaces.put(reader.getNamespacePrefix(i),
87 reader.getNamespaceURI(i));
88 }
89 }
90
91 protected void checkForFault(MessageContext context, InMessage msg, XMLStreamReader reader)
92 throws XFireFault
93 {
94 if (reader.getEventType() == XMLStreamReader.START_ELEMENT)
95 {
96 if (reader.getName().equals(msg.getSoapVersion().getFault()))
97 {
98 MessageSerializer serializer = context.getService().getFaultSerializer();
99
100 serializer.readMessage(msg, context);
101
102 throw (XFireFault) msg.getBody();
103 }
104 }
105 }
106
107 private void seekToWhitespaceEnd(XMLStreamReader reader)
108 throws XMLStreamException
109 {
110 int event = reader.next();
111 if (event != XMLStreamReader.SPACE) return;
112
113 do
114 {
115 event = reader.next();
116 }
117 while (event == XMLStreamReader.SPACE);
118
119 return;
120 }
121
122 /***
123 * Read in the headers as a YOM Element and create a response Header.
124 *
125 * @param context
126 * @throws XMLStreamException
127 */
128 protected void readHeaders(MessageContext context)
129 throws XMLStreamException
130 {
131 StaxBuilder builder = new StaxBuilder();
132
133 Element header = builder.buildElement(null, context.getInMessage().getXMLStreamReader());
134
135 context.getInMessage().setHeader(header);
136 }
137 }