View Javadoc

1   package org.codehaus.xfire.xmpp;
2   
3   import java.io.IOException;
4   import java.util.Iterator;
5   
6   import org.codehaus.xfire.soap.SoapVersion;
7   import org.codehaus.xfire.soap.SoapVersionFactory;
8   import org.dom4j.Document;
9   import org.dom4j.DocumentException;
10  import org.dom4j.DocumentFactory;
11  import org.dom4j.Element;
12  import org.dom4j.QName;
13  import org.jivesoftware.smack.packet.IQ;
14  import org.jivesoftware.smack.provider.IQProvider;
15  import org.jivesoftware.smack.provider.ProviderManager;
16  import org.xmlpull.v1.XmlPullParser;
17  import org.xmlpull.v1.XmlPullParserException;
18  
19  /***
20   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse </a>
21   */
22  public class SoapIQProvider
23      implements IQProvider
24  {
25      static
26      {
27          /* Register an IQ Provider for each soap namespace */
28          SoapIQProvider provider = new SoapIQProvider();
29          
30          for (Iterator itr = SoapVersionFactory.getInstance().getVersions(); itr.hasNext();)
31          {
32              SoapVersion version = (SoapVersion) itr.next();
33              
34              ProviderManager.addIQProvider(version.getEnvelope().getLocalPart(), 
35                                            version.getEnvelope().getNamespaceURI(),
36                                            provider);
37          }
38      }
39  
40      /***
41       * @param parser
42       * @return
43       * @throws java.lang.Exception
44       */
45      public IQ parseIQ(XmlPullParser parser)
46          throws Exception
47      {
48          try
49          {
50              return new SoapEnvelopePacket(parseDocument(parser).asXML());
51          }
52          catch(Exception e)
53          {
54              // TODO: Add better debugging
55              e.printStackTrace();
56              throw e;
57          }
58      }
59  
60      protected Document parseDocument(XmlPullParser pp)
61          throws DocumentException, IOException, XmlPullParserException
62      {
63          DocumentFactory df = DocumentFactory.getInstance();
64          Document document = df.createDocument();
65          Element parent = null;
66  
67          int depth = pp.getDepth();
68          int type = pp.getEventType();
69          
70          while (true)
71          {
72              switch (type)
73              {
74              case XmlPullParser.PROCESSING_INSTRUCTION:
75              {
76                  String text = pp.getText();
77                  int loc = text.indexOf(" ");
78  
79                  if (loc >= 0)
80                  {
81                      String target = text.substring(0, loc);
82                      String txt = text.substring(loc + 1);
83                      document.addProcessingInstruction(target, txt);
84                  }
85                  else
86                  {
87                      document.addProcessingInstruction(text, "");
88                  }
89  
90                  break;
91              }
92  
93              case XmlPullParser.COMMENT:
94              {
95                  if (parent != null)
96                  {
97                      parent.addComment(pp.getText());
98                  }
99                  else
100                 {
101                     document.addComment(pp.getText());
102                 }
103 
104                 break;
105             }
106 
107             case XmlPullParser.CDSECT:
108             {
109                 if (parent != null)
110                 {
111                     parent.addCDATA(pp.getText());
112                 }
113                 else
114                 {
115                     String msg = "Cannot have text content outside of the " + "root document";
116                     throw new DocumentException(msg);
117                 }
118 
119                 break;
120             }
121 
122             case XmlPullParser.ENTITY_REF:
123                 break;
124 
125             case XmlPullParser.END_DOCUMENT:
126                 return document;
127 
128             case XmlPullParser.START_TAG:
129             {
130                 QName qname = (pp.getPrefix() == null) ? df.createQName(pp.getName(), pp
131                         .getNamespace()) : df.createQName(pp.getName(), pp.getPrefix(), pp
132                         .getNamespace());
133                 Element newElement = df.createElement(qname);
134                 int nsStart = pp.getNamespaceCount(pp.getDepth() - 1);
135                 int nsEnd = pp.getNamespaceCount(pp.getDepth());
136 
137                 for (int i = nsStart; i < nsEnd; i++)
138                 {
139                     if (pp.getNamespacePrefix(i) != null)
140                     {
141                         newElement.addNamespace(pp.getNamespacePrefix(i), pp.getNamespaceUri(i));
142                     }
143                 }
144 
145                 for (int i = 0; i < pp.getAttributeCount(); i++)
146                 {
147                     QName qa = (pp.getAttributePrefix(i) == null) ? df.createQName(pp
148                             .getAttributeName(i)) : df.createQName(pp.getAttributeName(i), pp
149                             .getAttributePrefix(i), pp.getAttributeNamespace(i));
150                     newElement.addAttribute(qa, pp.getAttributeValue(i));
151                 }
152 
153                 if (parent != null)
154                 {
155                     parent.add(newElement);
156                 }
157                 else
158                 {
159                     document.add(newElement);
160                 }
161 
162                 parent = newElement;
163 
164                 break;
165             }
166 
167             case XmlPullParser.END_TAG:
168             {
169                 if (parent != null)
170                 {
171                     parent = parent.getParent();
172                 }
173 
174                 if (pp.getDepth() <= depth 
175                     && parent == null)
176                 {
177                     return document;
178                 }
179                 break;
180             }
181 
182             case XmlPullParser.TEXT:
183             {
184                 String text = pp.getText();
185                 if (parent != null)
186                 {
187                     parent.addText(text);
188                 }
189                 else
190                 {
191                     String msg = "Cannot have text content outside of the " + "root document";
192                     throw new DocumentException(msg);
193                 }
194 
195                 break;
196             }
197 
198             default:
199                 break;
200             }
201             
202             type = pp.nextToken();
203         }
204     }
205 }