1
14
15 package com.liferay.portal.xmlrpc;
16
17 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
18 import com.liferay.portal.kernel.util.CharPool;
19 import com.liferay.portal.kernel.util.GetterUtil;
20 import com.liferay.portal.kernel.util.StringBundler;
21 import com.liferay.portal.kernel.util.StringPool;
22 import com.liferay.portal.kernel.util.Tuple;
23 import com.liferay.portal.kernel.xmlrpc.Response;
24 import com.liferay.portal.kernel.xmlrpc.XmlRpcException;
25 import com.liferay.portal.kernel.xmlrpc.XmlRpcUtil;
26 import com.liferay.portal.xml.StAXReaderUtil;
27
28 import java.io.IOException;
29
30 import java.util.ArrayList;
31 import java.util.List;
32
33 import javax.xml.stream.XMLInputFactory;
34 import javax.xml.stream.XMLStreamConstants;
35 import javax.xml.stream.XMLStreamReader;
36
37
43 public class XmlRpcParser {
44
45 public static String buildMethod(String methodName, Object[] arguments)
46 throws XmlRpcException {
47
48 StringBundler sb = new StringBundler(arguments.length * 3 + 8);
49
50 sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
51
52 sb.append("<methodCall>");
53 sb.append("<methodName>");
54 sb.append(methodName);
55 sb.append("</methodName>");
56 sb.append("<params>");
57
58 for (Object argument : arguments) {
59 sb.append("<param>");
60 sb.append(wrapValue(argument));
61 sb.append("</param>");
62 }
63
64 sb.append("</params>");
65 sb.append("</methodCall>");
66
67 return sb.toString();
68 }
69
70 public static Tuple parseMethod(String xml) throws IOException {
71 XMLStreamReader xmlStreamReader = null;
72
73 try {
74 XMLInputFactory xmlInputFactory =
75 StAXReaderUtil.getXMLInputFactory();
76
77 xmlStreamReader = xmlInputFactory.createXMLStreamReader(
78 new UnsyncStringReader(xml));
79
80 xmlStreamReader.nextTag();
81 xmlStreamReader.nextTag();
82 xmlStreamReader.next();
83
84 String methodName = xmlStreamReader.getText();
85 List<Object> arguments = new ArrayList<Object>();
86
87 xmlStreamReader.nextTag();
88
89 String name = xmlStreamReader.getLocalName();
90
91 while (!name.equals("methodCall")) {
92 xmlStreamReader.nextTag();
93
94 name = xmlStreamReader.getLocalName();
95
96 if (name.equals("param")) {
97 xmlStreamReader.nextTag();
98
99 name = xmlStreamReader.getLocalName();
100
101 int event = xmlStreamReader.next();
102
103 if (event == XMLStreamConstants.START_ELEMENT) {
104 name = xmlStreamReader.getLocalName();
105
106 xmlStreamReader.next();
107
108 String text = xmlStreamReader.getText();
109
110 if (name.equals("string")) {
111 arguments.add(text);
112 }
113 else if (name.equals("int") || name.equals("i4")) {
114 arguments.add(GetterUtil.getInteger(text));
115 }
116 else if (name.equals("double")) {
117 arguments.add(GetterUtil.getDouble(text));
118 }
119 else if (name.equals("boolean")) {
120 arguments.add(GetterUtil.getBoolean(text));
121 }
122 else {
123 throw new IOException(
124 "XML-RPC not implemented for " + name);
125 }
126
127 xmlStreamReader.nextTag();
128 xmlStreamReader.nextTag();
129 xmlStreamReader.nextTag();
130 }
131 else {
132 String text = xmlStreamReader.getText();
133
134 arguments.add(text);
135
136 xmlStreamReader.nextTag();
137 xmlStreamReader.nextTag();
138 }
139
140 name = xmlStreamReader.getLocalName();
141 }
142 }
143
144 return new Tuple(methodName, arguments.toArray());
145 }
146 catch (Exception e) {
147 throw new IOException(e.getMessage());
148 }
149 finally {
150 if (xmlStreamReader != null) {
151 try {
152 xmlStreamReader.close();
153 }
154 catch (Exception e) {
155 }
156 }
157 }
158 }
159
160 public static Response parseResponse(String xml) throws XmlRpcException {
161 XMLStreamReader xmlStreamReader = null;
162
163 try {
164 XMLInputFactory xmlInputFactory =
165 StAXReaderUtil.getXMLInputFactory();
166
167 xmlStreamReader = xmlInputFactory.createXMLStreamReader(
168 new UnsyncStringReader(xml));
169
170 xmlStreamReader.nextTag();
171 xmlStreamReader.nextTag();
172
173 String name = xmlStreamReader.getLocalName();
174
175 if (name.equals("params")) {
176 String description = null;
177
178 xmlStreamReader.nextTag();
179 xmlStreamReader.nextTag();
180
181 int event = xmlStreamReader.next();
182
183 if (event == XMLStreamConstants.START_ELEMENT) {
184 xmlStreamReader.next();
185
186 description = xmlStreamReader.getText();
187 }
188 else {
189 description = xmlStreamReader.getText();
190 }
191
192 return XmlRpcUtil.createSuccess(description);
193 }
194 else if (name.equals("fault")) {
195 int code = 0;
196 String description = null;
197
198 xmlStreamReader.nextTag();
199 xmlStreamReader.nextTag();
200
201 for (int i = 0; i < 2; i++) {
202 xmlStreamReader.nextTag();
203 xmlStreamReader.nextTag();
204
205 xmlStreamReader.next();
206
207 String valueName = xmlStreamReader.getText();
208
209 if (valueName.equals("faultCode")) {
210 xmlStreamReader.nextTag();
211 xmlStreamReader.nextTag();
212 xmlStreamReader.nextTag();
213
214 name = xmlStreamReader.getLocalName();
215
216 if (name.equals("int") || name.equals("i4")) {
217 xmlStreamReader.next();
218
219 code = GetterUtil.getInteger(
220 xmlStreamReader.getText());
221 }
222
223 xmlStreamReader.nextTag();
224 xmlStreamReader.nextTag();
225 xmlStreamReader.nextTag();
226 }
227 else if (valueName.equals("faultString")) {
228 xmlStreamReader.nextTag();
229 xmlStreamReader.nextTag();
230
231 int event = xmlStreamReader.next();
232
233 if (event == XMLStreamConstants.START_ELEMENT) {
234 xmlStreamReader.next();
235
236 description = xmlStreamReader.getText();
237
238 xmlStreamReader.nextTag();
239 }
240 else {
241 description = xmlStreamReader.getText();
242 }
243
244 xmlStreamReader.nextTag();
245 xmlStreamReader.nextTag();
246 }
247 }
248
249 return XmlRpcUtil.createFault(code, description);
250 }
251
252 return null;
253 }
254 catch (Exception e) {
255 throw new XmlRpcException(xml, e);
256 }
257 finally {
258 if (xmlStreamReader != null) {
259 try {
260 xmlStreamReader.close();
261 }
262 catch (Exception e) {
263 }
264 }
265 }
266 }
267
268 public static String wrapValue(Object value) throws XmlRpcException {
269 if (value == null) {
270 return StringPool.BLANK;
271 }
272
273 StringBundler sb = new StringBundler(5);
274
275 sb.append("<value>");
276
277 if (value instanceof String) {
278 sb.append("<string>");
279 sb.append(value.toString());
280 sb.append("</string>");
281 }
282 else if ((value instanceof Integer) || (value instanceof Short)) {
283 sb.append("<i4>");
284 sb.append(value.toString());
285 sb.append("</i4>");
286 }
287 else if ((value instanceof Double) || (value instanceof Float)) {
288 sb.append("<double>");
289 sb.append(value.toString());
290 sb.append("</double>");
291 }
292 else if (value instanceof Boolean) {
293 sb.append("<boolean>");
294
295 if ((Boolean)value) {
296 sb.append(CharPool.NUMBER_1);
297 }
298 else {
299 sb.append(CharPool.NUMBER_0);
300 }
301
302 sb.append("</boolean>");
303 }
304 else {
305 throw new XmlRpcException("Unsupported type " + value.getClass());
306 }
307
308 sb.append("</value>");
309
310 return sb.toString();
311 }
312
313 }