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
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
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 }