001
014
015 package com.liferay.portal.xmlrpc;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
018 import com.liferay.portal.kernel.util.CharPool;
019 import com.liferay.portal.kernel.util.GetterUtil;
020 import com.liferay.portal.kernel.util.StringBundler;
021 import com.liferay.portal.kernel.util.StringPool;
022 import com.liferay.portal.kernel.util.Tuple;
023 import com.liferay.portal.kernel.xmlrpc.Response;
024 import com.liferay.portal.kernel.xmlrpc.XmlRpcException;
025 import com.liferay.portal.kernel.xmlrpc.XmlRpcUtil;
026 import com.liferay.portal.xml.StAXReaderUtil;
027
028 import java.io.IOException;
029
030 import java.util.ArrayList;
031 import java.util.List;
032
033 import javax.xml.stream.XMLInputFactory;
034 import javax.xml.stream.XMLStreamConstants;
035 import javax.xml.stream.XMLStreamReader;
036
037
041 public class XmlRpcParser {
042
043 public static String buildMethod(String methodName, Object[] arguments)
044 throws XmlRpcException {
045
046 StringBundler sb = new StringBundler(arguments.length * 3 + 8);
047
048 sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
049
050 sb.append("<methodCall>");
051 sb.append("<methodName>");
052 sb.append(methodName);
053 sb.append("</methodName>");
054 sb.append("<params>");
055
056 for (Object argument : arguments) {
057 sb.append("<param>");
058 sb.append(wrapValue(argument));
059 sb.append("</param>");
060 }
061
062 sb.append("</params>");
063 sb.append("</methodCall>");
064
065 return sb.toString();
066 }
067
068 public static Tuple parseMethod(String xml) throws IOException {
069 XMLStreamReader xmlStreamReader = null;
070
071 try {
072 XMLInputFactory xmlInputFactory =
073 StAXReaderUtil.getXMLInputFactory();
074
075 xmlStreamReader = xmlInputFactory.createXMLStreamReader(
076 new UnsyncStringReader(xml));
077
078 xmlStreamReader.nextTag();
079 xmlStreamReader.nextTag();
080 xmlStreamReader.next();
081
082 String methodName = xmlStreamReader.getText();
083 List<Object> arguments = new ArrayList<Object>();
084
085 xmlStreamReader.nextTag();
086
087 String name = xmlStreamReader.getLocalName();
088
089 while (!name.equals("methodCall")) {
090 xmlStreamReader.nextTag();
091
092 name = xmlStreamReader.getLocalName();
093
094 if (name.equals("param")) {
095 xmlStreamReader.nextTag();
096
097 name = xmlStreamReader.getLocalName();
098
099 int event = xmlStreamReader.next();
100
101 if (event == XMLStreamConstants.START_ELEMENT) {
102 name = xmlStreamReader.getLocalName();
103
104 xmlStreamReader.next();
105
106 String text = xmlStreamReader.getText();
107
108 if (name.equals("string")) {
109 arguments.add(text);
110 }
111 else if (name.equals("int") || name.equals("i4")) {
112 arguments.add(GetterUtil.getInteger(text));
113 }
114 else if (name.equals("double")) {
115 arguments.add(GetterUtil.getDouble(text));
116 }
117 else if (name.equals("boolean")) {
118 arguments.add(GetterUtil.getBoolean(text));
119 }
120 else {
121 throw new IOException(
122 "XML-RPC not implemented for " + name);
123 }
124
125 xmlStreamReader.nextTag();
126 xmlStreamReader.nextTag();
127 xmlStreamReader.nextTag();
128 }
129 else {
130 String text = xmlStreamReader.getText();
131
132 arguments.add(text);
133
134 xmlStreamReader.nextTag();
135 xmlStreamReader.nextTag();
136 }
137
138 name = xmlStreamReader.getLocalName();
139 }
140 }
141
142 return new Tuple(methodName, arguments.toArray());
143 }
144 catch (Exception e) {
145 throw new IOException(e.getMessage());
146 }
147 finally {
148 if (xmlStreamReader != null) {
149 try {
150 xmlStreamReader.close();
151 }
152 catch (Exception e) {
153 }
154 }
155 }
156 }
157
158 public static Response parseResponse(String xml) throws XmlRpcException {
159 XMLStreamReader xmlStreamReader = null;
160
161 try {
162 XMLInputFactory xmlInputFactory =
163 StAXReaderUtil.getXMLInputFactory();
164
165 xmlStreamReader = xmlInputFactory.createXMLStreamReader(
166 new UnsyncStringReader(xml));
167
168 xmlStreamReader.nextTag();
169 xmlStreamReader.nextTag();
170
171 String name = xmlStreamReader.getLocalName();
172
173 if (name.equals("params")) {
174 String description = null;
175
176 xmlStreamReader.nextTag();
177 xmlStreamReader.nextTag();
178
179 int event = xmlStreamReader.next();
180
181 if (event == XMLStreamConstants.START_ELEMENT) {
182 xmlStreamReader.next();
183
184 description = xmlStreamReader.getText();
185 }
186 else {
187 description = xmlStreamReader.getText();
188 }
189
190 return XmlRpcUtil.createSuccess(description);
191 }
192 else if (name.equals("fault")) {
193 int code = 0;
194 String description = null;
195
196 xmlStreamReader.nextTag();
197 xmlStreamReader.nextTag();
198
199 for (int i = 0; i < 2; i++) {
200 xmlStreamReader.nextTag();
201 xmlStreamReader.nextTag();
202
203 xmlStreamReader.next();
204
205 String valueName = xmlStreamReader.getText();
206
207 if (valueName.equals("faultCode")) {
208 xmlStreamReader.nextTag();
209 xmlStreamReader.nextTag();
210 xmlStreamReader.nextTag();
211
212 name = xmlStreamReader.getLocalName();
213
214 if (name.equals("int") || name.equals("i4")) {
215 xmlStreamReader.next();
216
217 code = GetterUtil.getInteger(
218 xmlStreamReader.getText());
219 }
220
221 xmlStreamReader.nextTag();
222 xmlStreamReader.nextTag();
223 xmlStreamReader.nextTag();
224 }
225 else if (valueName.equals("faultString")) {
226 xmlStreamReader.nextTag();
227 xmlStreamReader.nextTag();
228
229 int event = xmlStreamReader.next();
230
231 if (event == XMLStreamConstants.START_ELEMENT) {
232 xmlStreamReader.next();
233
234 description = xmlStreamReader.getText();
235
236 xmlStreamReader.nextTag();
237 }
238 else {
239 description = xmlStreamReader.getText();
240 }
241
242 xmlStreamReader.nextTag();
243 xmlStreamReader.nextTag();
244 }
245 }
246
247 return XmlRpcUtil.createFault(code, description);
248 }
249
250 return null;
251 }
252 catch (Exception e) {
253 throw new XmlRpcException(xml, e);
254 }
255 finally {
256 if (xmlStreamReader != null) {
257 try {
258 xmlStreamReader.close();
259 }
260 catch (Exception e) {
261 }
262 }
263 }
264 }
265
266 public static String wrapValue(Object value) throws XmlRpcException {
267 if (value == null) {
268 return StringPool.BLANK;
269 }
270
271 StringBundler sb = new StringBundler(5);
272
273 sb.append("<value>");
274
275 if (value instanceof String) {
276 sb.append("<string>");
277 sb.append(value.toString());
278 sb.append("</string>");
279 }
280 else if ((value instanceof Integer) || (value instanceof Short)) {
281 sb.append("<i4>");
282 sb.append(value.toString());
283 sb.append("</i4>");
284 }
285 else if ((value instanceof Double) || (value instanceof Float)) {
286 sb.append("<double>");
287 sb.append(value.toString());
288 sb.append("</double>");
289 }
290 else if (value instanceof Boolean) {
291 sb.append("<boolean>");
292
293 if ((Boolean)value) {
294 sb.append(CharPool.NUMBER_1);
295 }
296 else {
297 sb.append(CharPool.NUMBER_0);
298 }
299
300 sb.append("</boolean>");
301 }
302 else {
303 throw new XmlRpcException("Unsupported type " + value.getClass());
304 }
305
306 sb.append("</value>");
307
308 return sb.toString();
309 }
310
311 }