View Javadoc

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 }