1 package org.codehaus.xfire.fault;
2
3 import java.util.Iterator;
4 import java.util.Map;
5
6 import javax.xml.stream.XMLStreamException;
7 import javax.xml.stream.XMLStreamReader;
8 import javax.xml.stream.XMLStreamWriter;
9
10 import org.codehaus.xfire.MessageContext;
11 import org.codehaus.xfire.XFireRuntimeException;
12 import org.codehaus.xfire.exchange.InMessage;
13 import org.codehaus.xfire.exchange.MessageSerializer;
14 import org.codehaus.xfire.exchange.OutMessage;
15 import org.codehaus.xfire.soap.Soap12;
16 import org.codehaus.xfire.util.DepthXMLStreamReader;
17 import org.codehaus.xfire.util.STAXUtils;
18 import org.codehaus.yom.Element;
19 import org.codehaus.yom.Elements;
20 import org.codehaus.yom.stax.StaxBuilder;
21 import org.codehaus.yom.stax.StaxSerializer;
22
23 public class Soap12FaultSerializer
24 implements MessageSerializer
25 {
26 private StaxBuilder builder = new StaxBuilder();
27
28 public void readMessage(InMessage message, MessageContext context)
29 throws XFireFault
30 {
31 XFireFault fault = new XFireFault();
32
33 DepthXMLStreamReader reader = new DepthXMLStreamReader(message.getXMLStreamReader());
34
35 try
36 {
37 boolean end = false;
38 while (!end && reader.hasNext())
39 {
40 int event = reader.next();
41 switch (event)
42 {
43 case XMLStreamReader.START_DOCUMENT:
44 String encoding = reader.getCharacterEncodingScheme();
45 message.setEncoding(encoding);
46 break;
47 case XMLStreamReader.END_DOCUMENT:
48 end = true;
49 break;
50 case XMLStreamReader.END_ELEMENT:
51 break;
52 case XMLStreamReader.START_ELEMENT:
53 if (reader.getLocalName().equals("Code"))
54 {
55 reader.next();
56 STAXUtils.toNextElement(reader);
57
58 if (reader.getLocalName().equals("Value"))
59 {
60 fault.setFaultCode(parseFaultCode(reader, reader.getElementText()));
61 }
62 }
63 else if (reader.getLocalName().equals("SubCode"))
64 {
65 reader.next();
66 STAXUtils.toNextElement(reader);
67
68 if (reader.getLocalName().equals("Value"))
69 {
70 fault.setSubCode(reader.getElementText());
71 }
72
73 }
74 else if (reader.getLocalName().equals("Reason"))
75 {
76 reader.next();
77 STAXUtils.toNextElement(reader);
78
79 if (reader.getLocalName().equals("Text"))
80 {
81 fault.setMessage(reader.getElementText());
82 }
83 }
84 else if (reader.getLocalName().equals("Actor"))
85 {
86 fault.setRole(reader.getElementText());
87 }
88 else if (reader.getLocalName().equals("Detail"))
89 {
90 fault.setDetail(builder.buildElement(null, reader));
91 }
92 break;
93 default:
94 break;
95 }
96 }
97 }
98 catch (XMLStreamException e)
99 {
100 throw new XFireFault("Could not parse message.", e, XFireFault.SENDER);
101 }
102 message.setBody(fault);
103 }
104
105 protected static String parseFaultCode(XMLStreamReader reader, String value)
106 {
107 int colon = value.indexOf(":");
108 if (colon > -1)
109 {
110 String prefix = value.substring(0, colon);
111 String local = value.substring(colon+1);
112 String uri = reader.getNamespaceURI(prefix);
113
114 if (uri.equals(Soap12.getInstance().getNamespace()))
115 {
116 return local;
117 }
118
119 return value;
120 }
121 else
122 {
123 return value;
124 }
125 }
126 public void writeMessage(OutMessage message, XMLStreamWriter writer, MessageContext context)
127 throws XFireFault
128 {
129 XFireFault fault = (XFireFault) message.getBody();
130 try
131 {
132 Map namespaces = fault.getNamespaces();
133 for (Iterator itr = namespaces.keySet().iterator(); itr.hasNext();)
134 {
135 String prefix = (String) itr.next();
136 writer.writeAttribute("xmlns:" + prefix, (String) namespaces.get(prefix));
137 }
138
139 writer.writeStartElement("soap:Fault");
140
141 writer.writeStartElement("soap:Code");
142
143 writer.writeStartElement("soap:Value");
144 writer.writeCharacters("soap:" + fault.getFaultCode());
145 writer.writeEndElement();
146
147 if (fault.getSubCode() != null)
148 {
149 writer.writeStartElement("soap:SubCode");
150 writer.writeStartElement("soap:Value");
151 writer.writeCharacters(fault.getSubCode());
152 writer.writeEndElement();
153 writer.writeEndElement();
154 }
155
156 writer.writeEndElement();
157
158 writer.writeStartElement("soap:Reason");
159 writer.writeStartElement("soap:Text");
160 writer.writeCharacters(fault.getReason());
161 writer.writeEndElement();
162 writer.writeEndElement();
163
164 if (fault.getRole() != null)
165 {
166 writer.writeStartElement("soap:Role");
167 writer.writeCharacters(fault.getRole());
168 writer.writeEndElement();
169 }
170
171 if (fault.hasDetails())
172 {
173 Element detail = fault.getDetail();
174
175 writer.writeStartElement("soap:Detail");
176
177 StaxSerializer serializer = new StaxSerializer();
178 Elements details = detail.getChildElements();
179 for (int i = 0; i < details.size(); i++)
180 {
181 serializer.writeElement(details.get(i), writer);
182 }
183
184 writer.writeEndElement();
185 }
186
187 writer.writeEndElement();
188 }
189 catch (XMLStreamException xe)
190 {
191 throw new XFireRuntimeException("Couldn't create fault.", xe);
192 }
193 }
194 }