1/**
2 * $RCSfile$
3 * $Revision$
4 * $Date$
5 *
6 * Copyright 2003-2007 Jive Software.
7 *
8 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 *     http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21package org.jivesoftware.smackx.provider;
22
23import org.jivesoftware.smack.packet.PacketExtension;
24import org.jivesoftware.smack.provider.PacketExtensionProvider;
25import org.jivesoftware.smackx.FormField;
26import org.jivesoftware.smackx.packet.DataForm;
27import org.xmlpull.v1.XmlPullParser;
28
29import java.util.ArrayList;
30import java.util.List;
31
32/**
33 * The DataFormProvider parses DataForm packets.
34 *
35 * @author Gaston Dombiak
36 */
37public class DataFormProvider implements PacketExtensionProvider {
38
39    /**
40     * Creates a new DataFormProvider.
41     * ProviderManager requires that every PacketExtensionProvider has a public, no-argument constructor
42     */
43    public DataFormProvider() {
44    }
45
46    public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
47        boolean done = false;
48        StringBuilder buffer = null;
49        DataForm dataForm = new DataForm(parser.getAttributeValue("", "type"));
50        while (!done) {
51            int eventType = parser.next();
52            if (eventType == XmlPullParser.START_TAG) {
53                if (parser.getName().equals("instructions")) {
54                    dataForm.addInstruction(parser.nextText());
55                }
56                else if (parser.getName().equals("title")) {
57                    dataForm.setTitle(parser.nextText());
58                }
59                else if (parser.getName().equals("field")) {
60                    dataForm.addField(parseField(parser));
61                }
62                else if (parser.getName().equals("item")) {
63                    dataForm.addItem(parseItem(parser));
64                }
65                else if (parser.getName().equals("reported")) {
66                    dataForm.setReportedData(parseReported(parser));
67                }
68            } else if (eventType == XmlPullParser.END_TAG) {
69                if (parser.getName().equals(dataForm.getElementName())) {
70                    done = true;
71                }
72            }
73        }
74        return dataForm;
75    }
76
77    private FormField parseField(XmlPullParser parser) throws Exception {
78        boolean done = false;
79        FormField formField = new FormField(parser.getAttributeValue("", "var"));
80        formField.setLabel(parser.getAttributeValue("", "label"));
81        formField.setType(parser.getAttributeValue("", "type"));
82        while (!done) {
83            int eventType = parser.next();
84            if (eventType == XmlPullParser.START_TAG) {
85                if (parser.getName().equals("desc")) {
86                    formField.setDescription(parser.nextText());
87                }
88                else if (parser.getName().equals("value")) {
89                    formField.addValue(parser.nextText());
90                }
91                else if (parser.getName().equals("required")) {
92                    formField.setRequired(true);
93                }
94                else if (parser.getName().equals("option")) {
95                    formField.addOption(parseOption(parser));
96                }
97            } else if (eventType == XmlPullParser.END_TAG) {
98                if (parser.getName().equals("field")) {
99                    done = true;
100                }
101            }
102        }
103        return formField;
104    }
105
106    private DataForm.Item parseItem(XmlPullParser parser) throws Exception {
107        boolean done = false;
108        List<FormField> fields = new ArrayList<FormField>();
109        while (!done) {
110            int eventType = parser.next();
111            if (eventType == XmlPullParser.START_TAG) {
112                if (parser.getName().equals("field")) {
113                    fields.add(parseField(parser));
114                }
115            } else if (eventType == XmlPullParser.END_TAG) {
116                if (parser.getName().equals("item")) {
117                    done = true;
118                }
119            }
120        }
121        return new DataForm.Item(fields);
122    }
123
124    private DataForm.ReportedData parseReported(XmlPullParser parser) throws Exception {
125        boolean done = false;
126        List<FormField> fields = new ArrayList<FormField>();
127        while (!done) {
128            int eventType = parser.next();
129            if (eventType == XmlPullParser.START_TAG) {
130                if (parser.getName().equals("field")) {
131                    fields.add(parseField(parser));
132                }
133            } else if (eventType == XmlPullParser.END_TAG) {
134                if (parser.getName().equals("reported")) {
135                    done = true;
136                }
137            }
138        }
139        return new DataForm.ReportedData(fields);
140    }
141
142    private FormField.Option parseOption(XmlPullParser parser) throws Exception {
143        boolean done = false;
144        FormField.Option option = null;
145        String label = parser.getAttributeValue("", "label");
146        while (!done) {
147            int eventType = parser.next();
148            if (eventType == XmlPullParser.START_TAG) {
149                if (parser.getName().equals("value")) {
150                    option = new FormField.Option(label, parser.nextText());
151                }
152            } else if (eventType == XmlPullParser.END_TAG) {
153                if (parser.getName().equals("option")) {
154                    done = true;
155                }
156            }
157        }
158        return option;
159    }
160}
161