001/**
002 *
003 * Copyright 2003-2007 Jive Software.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.jivesoftware.smackx.xdata.provider;
019
020import org.jivesoftware.smack.packet.PacketExtension;
021import org.jivesoftware.smack.provider.PacketExtensionProvider;
022import org.jivesoftware.smackx.xdata.FormField;
023import org.jivesoftware.smackx.xdata.packet.DataForm;
024import org.xmlpull.v1.XmlPullParser;
025
026import java.util.ArrayList;
027import java.util.List;
028
029/**
030 * The DataFormProvider parses DataForm packets.
031 * 
032 * @author Gaston Dombiak
033 */
034public class DataFormProvider implements PacketExtensionProvider {
035
036    /**
037     * Creates a new DataFormProvider.
038     * ProviderManager requires that every PacketExtensionProvider has a public, no-argument constructor
039     */
040    public DataFormProvider() {
041    }
042
043    public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
044        boolean done = false;
045        DataForm dataForm = new DataForm(parser.getAttributeValue("", "type"));
046        while (!done) {
047            int eventType = parser.next();
048            if (eventType == XmlPullParser.START_TAG) {
049                if (parser.getName().equals("instructions")) { 
050                    dataForm.addInstruction(parser.nextText());
051                }
052                else if (parser.getName().equals("title")) {                    
053                    dataForm.setTitle(parser.nextText());
054                }
055                else if (parser.getName().equals("field")) {                    
056                    dataForm.addField(parseField(parser));
057                }
058                else if (parser.getName().equals("item")) {                    
059                    dataForm.addItem(parseItem(parser));
060                }
061                else if (parser.getName().equals("reported")) {                    
062                    dataForm.setReportedData(parseReported(parser));
063                }
064            } else if (eventType == XmlPullParser.END_TAG) {
065                if (parser.getName().equals(dataForm.getElementName())) {
066                    done = true;
067                }
068            }
069        }
070        return dataForm;
071    }
072
073    private FormField parseField(XmlPullParser parser) throws Exception {
074        boolean done = false;
075        FormField formField = new FormField(parser.getAttributeValue("", "var"));
076        formField.setLabel(parser.getAttributeValue("", "label"));
077        formField.setType(parser.getAttributeValue("", "type"));
078        while (!done) {
079            int eventType = parser.next();
080            if (eventType == XmlPullParser.START_TAG) {
081                if (parser.getName().equals("desc")) { 
082                    formField.setDescription(parser.nextText());
083                }
084                else if (parser.getName().equals("value")) {                    
085                    formField.addValue(parser.nextText());
086                }
087                else if (parser.getName().equals("required")) {                    
088                    formField.setRequired(true);
089                }
090                else if (parser.getName().equals("option")) {                    
091                    formField.addOption(parseOption(parser));
092                }
093            } else if (eventType == XmlPullParser.END_TAG) {
094                if (parser.getName().equals("field")) {
095                    done = true;
096                }
097            }
098        }
099        return formField;
100    }
101
102    private DataForm.Item parseItem(XmlPullParser parser) throws Exception {
103        boolean done = false;
104        List<FormField> fields = new ArrayList<FormField>();
105        while (!done) {
106            int eventType = parser.next();
107            if (eventType == XmlPullParser.START_TAG) {
108                if (parser.getName().equals("field")) { 
109                    fields.add(parseField(parser));
110                }
111            } else if (eventType == XmlPullParser.END_TAG) {
112                if (parser.getName().equals("item")) {
113                    done = true;
114                }
115            }
116        }
117        return new DataForm.Item(fields);
118    }
119
120    private DataForm.ReportedData parseReported(XmlPullParser parser) throws Exception {
121        boolean done = false;
122        List<FormField> fields = new ArrayList<FormField>();
123        while (!done) {
124            int eventType = parser.next();
125            if (eventType == XmlPullParser.START_TAG) {
126                if (parser.getName().equals("field")) { 
127                    fields.add(parseField(parser));
128                }
129            } else if (eventType == XmlPullParser.END_TAG) {
130                if (parser.getName().equals("reported")) {
131                    done = true;
132                }
133            }
134        }
135        return new DataForm.ReportedData(fields);
136    }
137
138    private FormField.Option parseOption(XmlPullParser parser) throws Exception {
139        boolean done = false;
140        FormField.Option option = null;
141        String label = parser.getAttributeValue("", "label");
142        while (!done) {
143            int eventType = parser.next();
144            if (eventType == XmlPullParser.START_TAG) {
145                if (parser.getName().equals("value")) {
146                    option = new FormField.Option(label, parser.nextText());                     
147                }
148            } else if (eventType == XmlPullParser.END_TAG) {
149                if (parser.getName().equals("option")) {
150                    done = true;
151                }
152            }
153        }
154        return option;
155    }
156}