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 }