5db545e6c420c597e37358276e34c674033d0b8d
[pub/Android/ownCloud.git] / oc_framework / src / com / owncloud / android / oc_framework / utils / ShareXMLParser.java
1 /* ownCloud Android Library is available under MIT license
2 * Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
18 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 *
23 */
24
25 package com.owncloud.android.oc_framework.utils;
26
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.util.ArrayList;
30
31 import org.xmlpull.v1.XmlPullParser;
32 import org.xmlpull.v1.XmlPullParserException;
33 import org.xmlpull.v1.XmlPullParserFactory;
34
35 import android.util.Log;
36 import android.util.Xml;
37
38 import com.owncloud.android.oc_framework.operations.ShareRemoteFile;
39 import com.owncloud.android.oc_framework.operations.ShareType;
40
41 /**
42 * Parser for Share API Response
43 * @author masensio
44 *
45 */
46
47 public class ShareXMLParser {
48
49 private static final String TAG = ShareXMLParser.class.getSimpleName();
50
51 // No namespaces
52 private static final String ns = null;
53
54 // NODES for XML Parser
55 private static final String NODE_OCS = "ocs";
56
57 private static final String NODE_META = "meta";
58 private static final String NODE_STATUS = "status";
59 private static final String NODE_STATUS_CODE = "statuscode";
60 //private static final String NODE_MESSAGE = "message";
61
62 private static final String NODE_DATA = "data";
63 private static final String NODE_ELEMENT = "element";
64 //private static final String NODE_ID = "id";
65 private static final String NODE_ITEM_TYPE = "item_type";
66 private static final String NODE_ITEM_SOURCE = "item_source";
67 private static final String NODE_PARENT = "parent";
68 private static final String NODE_SHARE_TYPE = "share_type";
69 private static final String NODE_SHARE_WITH = "share_with";
70 private static final String NODE_FILE_SOURCE = "file_source";
71 private static final String NODE_PATH = "path";
72 private static final String NODE_PERMISSIONS = "permissions";
73 private static final String NODE_STIME = "stime";
74 private static final String NODE_EXPIRATION = "expiration";
75 private static final String NODE_TOKEN = "token";
76 private static final String NODE_STORAGE = "storage";
77 private static final String NODE_MAIL_SEND = "mail_send";
78 private static final String NODE_SHARE_WITH_DISPLAY_NAME = "share_with_display_name";
79
80 private static final String TYPE_FOLDER = "folder";
81
82 private String mStatus;
83 private int mStatusCode;
84
85 // Getters and Setters
86 public String getStatus() {
87 return mStatus;
88 }
89
90 public void setStatus(String status) {
91 this.mStatus = status;
92 }
93
94 public int getStatusCode() {
95 return mStatusCode;
96 }
97
98 public void setStatusCode(int statusCode) {
99 this.mStatusCode = statusCode;
100 }
101
102 // Constructor
103 public ShareXMLParser() {
104
105 }
106
107 /**
108 * Parse is as response of Share API
109 * @param is
110 * @return List of ShareRemoteFiles
111 * @throws XmlPullParserException
112 * @throws IOException
113 */
114 public ArrayList<ShareRemoteFile> parseXMLResponse(InputStream is) throws XmlPullParserException, IOException {
115
116 try {
117 // XMLPullParser
118 XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
119 factory.setNamespaceAware(true);
120
121 XmlPullParser parser = Xml.newPullParser();
122 parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
123 parser.setInput(is, null);
124 parser.nextTag();
125 return readOCS(parser);
126
127 } finally {
128 is.close();
129 }
130 }
131
132 /**
133 * Parse OCS node
134 * @param parser
135 * @return List of ShareRemoteFiles
136 * @throws XmlPullParserException
137 * @throws IOException
138 */
139 private ArrayList<ShareRemoteFile> readOCS (XmlPullParser parser) throws XmlPullParserException, IOException {
140 ArrayList<ShareRemoteFile> sharedFiles = new ArrayList<ShareRemoteFile>();
141 parser.require(XmlPullParser.START_TAG, ns , NODE_OCS);
142 while (parser.next() != XmlPullParser.END_TAG) {
143 if (parser.getEventType() != XmlPullParser.START_TAG) {
144 continue;
145 }
146 String name = parser.getName();
147 // read NODE_META and NODE_DATA
148 if (name.equalsIgnoreCase(NODE_META)) {
149 readMeta(parser);
150 } else if (name.equalsIgnoreCase(NODE_DATA)) {
151 sharedFiles = readData(parser);
152 } else {
153 skip(parser);
154 }
155
156 }
157 return sharedFiles;
158
159
160 }
161
162 /**
163 * Parse Meta node
164 * @param parser
165 * @throws XmlPullParserException
166 * @throws IOException
167 */
168 private void readMeta(XmlPullParser parser) throws XmlPullParserException, IOException {
169 parser.require(XmlPullParser.START_TAG, ns, NODE_META);
170 Log.d(TAG, "---- NODE META ---");
171 while (parser.next() != XmlPullParser.END_TAG) {
172 if (parser.getEventType() != XmlPullParser.START_TAG) {
173 continue;
174 }
175 String name = parser.getName();
176
177 if (name.equalsIgnoreCase(NODE_STATUS)) {
178 setStatus(readNode(parser, NODE_STATUS));
179
180 } else if (name.equalsIgnoreCase(NODE_STATUS_CODE)) {
181 setStatusCode(Integer.parseInt(readNode(parser, NODE_STATUS_CODE)));
182
183 } else {
184 skip(parser);
185 }
186
187 }
188 }
189
190 /**
191 * Parse Data node
192 * @param parser
193 * @return
194 * @throws XmlPullParserException
195 * @throws IOException
196 */
197 private ArrayList<ShareRemoteFile> readData(XmlPullParser parser) throws XmlPullParserException, IOException {
198 ArrayList<ShareRemoteFile> sharedFiles = new ArrayList<ShareRemoteFile>();
199
200 parser.require(XmlPullParser.START_TAG, ns, NODE_DATA);
201 Log.d(TAG, "---- NODE DATA ---");
202 while (parser.next() != XmlPullParser.END_TAG) {
203 if (parser.getEventType() != XmlPullParser.START_TAG) {
204 continue;
205 }
206 String name = parser.getName();
207 if (name.equalsIgnoreCase(NODE_ELEMENT)) {
208 sharedFiles.add(readElement(parser));
209 } else {
210 skip(parser);
211 }
212 }
213
214 return sharedFiles;
215
216 }
217
218 /**
219 * Parse Element node
220 * @param parser
221 * @return
222 * @throws XmlPullParserException
223 * @throws IOException
224 */
225 private ShareRemoteFile readElement(XmlPullParser parser) throws XmlPullParserException, IOException {
226 parser.require(XmlPullParser.START_TAG, ns, NODE_ELEMENT);
227
228 ShareRemoteFile sharedFile = new ShareRemoteFile();
229
230 Log.d(TAG, "---- NODE ELEMENT ---");
231 while (parser.next() != XmlPullParser.END_TAG) {
232 if (parser.getEventType() != XmlPullParser.START_TAG) {
233 continue;
234 }
235
236 String name = parser.getName();
237
238 if (name.equalsIgnoreCase(NODE_ITEM_TYPE)) {
239 sharedFile.setIsDirectory(readNode(parser, NODE_ITEM_TYPE).equalsIgnoreCase(TYPE_FOLDER));
240
241 } else if (name.equalsIgnoreCase(NODE_ITEM_SOURCE)) {
242 sharedFile.setItemSource(Long.parseLong(readNode(parser, NODE_ITEM_SOURCE)));
243
244 } else if (name.equalsIgnoreCase(NODE_PARENT)) {
245 readNode(parser, NODE_PARENT);
246
247 } else if (name.equalsIgnoreCase(NODE_SHARE_TYPE)) {
248 int value = Integer.parseInt(readNode(parser, NODE_SHARE_TYPE));
249 sharedFile.setShareType(ShareType.fromValue(value));
250
251 } else if (name.equalsIgnoreCase(NODE_SHARE_WITH)) {
252 sharedFile.setShareWith(readNode(parser, NODE_SHARE_WITH));
253
254 } else if (name.equalsIgnoreCase(NODE_FILE_SOURCE)) {
255 sharedFile.setFileSource(Long.parseLong(readNode(parser, NODE_FILE_SOURCE)));
256
257 } else if (name.equalsIgnoreCase(NODE_PATH)) {
258 sharedFile.setPath(readNode(parser, NODE_PATH));
259
260 } else if (name.equalsIgnoreCase(NODE_PERMISSIONS)) {
261 sharedFile.setPermissions(Integer.parseInt(readNode(parser, NODE_PERMISSIONS)));
262
263 } else if (name.equalsIgnoreCase(NODE_STIME)) {
264 sharedFile.setSharedDate(Long.parseLong(readNode(parser, NODE_STIME)));
265
266 } else if (name.equalsIgnoreCase(NODE_EXPIRATION)) {
267 String value = readNode(parser, NODE_EXPIRATION);
268 if (!value.isEmpty()) {
269 sharedFile.setExpirationDate(Long.parseLong(readNode(parser, NODE_EXPIRATION))); // check if expiration is in long format or date format
270 }
271
272 } else if (name.equalsIgnoreCase(NODE_TOKEN)) {
273 sharedFile.setToken(readNode(parser, NODE_TOKEN));
274
275 } else if (name.equalsIgnoreCase(NODE_STORAGE)) {
276 readNode(parser, NODE_STORAGE);
277 } else if (name.equalsIgnoreCase(NODE_MAIL_SEND)) {
278 readNode(parser, NODE_MAIL_SEND);
279
280 } else if (name.equalsIgnoreCase(NODE_SHARE_WITH_DISPLAY_NAME)) {
281 sharedFile.setSharedWithDisplayName(readNode(parser, NODE_SHARE_WITH_DISPLAY_NAME));
282
283 } else {
284 skip(parser);
285 }
286 }
287
288 return sharedFile;
289 }
290
291 /**
292 * Parse a node, to obtain its text. Needs readText method
293 * @param parser
294 * @param node
295 * @return Text of the node
296 * @throws XmlPullParserException
297 * @throws IOException
298 */
299 private String readNode (XmlPullParser parser, String node) throws XmlPullParserException, IOException{
300 parser.require(XmlPullParser.START_TAG, ns, node);
301 String value = readText(parser);
302 Log.d(TAG, "node= " + node + ", value= " + value);
303 parser.require(XmlPullParser.END_TAG, ns, node);
304 return value;
305 }
306
307 /**
308 * Read the text from a node
309 * @param parser
310 * @return Text of the node
311 * @throws IOException
312 * @throws XmlPullParserException
313 */
314 private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
315 String result = "";
316 if (parser.next() == XmlPullParser.TEXT) {
317 result = parser.getText();
318 parser.nextTag();
319 }
320 return result;
321 }
322
323 /**
324 * Skip tags in parser procedure
325 * @param parser
326 * @throws XmlPullParserException
327 * @throws IOException
328 */
329 private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
330 if (parser.getEventType() != XmlPullParser.START_TAG) {
331 throw new IllegalStateException();
332 }
333 int depth = 1;
334 while (depth != 0) {
335 switch (parser.next()) {
336 case XmlPullParser.END_TAG:
337 depth--;
338 break;
339 case XmlPullParser.START_TAG:
340 depth++;
341 break;
342 }
343 }
344 }
345 }