1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $RCSfile$
3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Revision$
4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Date$
5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Copyright 2003-2007 Jive Software.
7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * you may not use this file except in compliance with the License.
10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * You may obtain a copy of the License at
11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *     http://www.apache.org/licenses/LICENSE-2.0
13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Unless required by applicable law or agreed to in writing, software
15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * distributed under the License is distributed on an "AS IS" BASIS,
16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * See the License for the specific language governing permissions and
18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * limitations under the License.
19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.jivesoftware.smackx;
22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.ArrayList;
24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Iterator;
25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.List;
26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.StringTokenizer;
27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.Packet;
29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.PacketExtension;
30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.packet.DataForm;
31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Represents a Form for gathering data. The form could be of the following types:
34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <ul>
35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *  <li>form -> Indicates a form to fill out.</li>
36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *  <li>submit -> The form is filled out, and this is the data that is being returned from
37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the form.</li>
38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *  <li>cancel -> The form was cancelled. Tell the asker that piece of information.</li>
39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *  <li>result -> Data results being returned from a search, or some other query.</li>
40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * </ul>
41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Depending of the form's type different operations are available. For example, it's only possible
43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * to set answers if the form is of type "submit".
44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see <a href="http://xmpp.org/extensions/xep-0004.html">XEP-0004 Data Forms</a>
46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Gaston Dombiak
48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic class Form {
50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public static final String TYPE_FORM = "form";
52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public static final String TYPE_SUBMIT = "submit";
53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public static final String TYPE_CANCEL = "cancel";
54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public static final String TYPE_RESULT = "result";
55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public static final String NAMESPACE = "jabber:x:data";
57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public static final String ELEMENT = "x";
58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private DataForm dataForm;
60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns a new ReportedData if the packet is used for gathering data and includes an
63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * extension that matches the elementName and namespace "x","jabber:x:data".
64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param packet the packet used for gathering data.
66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return the data form parsed from the packet or <tt>null</tt> if there was not
67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *      a form in the packet.
68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public static Form getFormFrom(Packet packet) {
70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Check if the packet includes the DataForm extension
71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        PacketExtension packetExtension = packet.getExtension("x","jabber:x:data");
72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (packetExtension != null) {
73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Check if the existing DataForm is not a result of a search
74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            DataForm dataForm = (DataForm) packetExtension;
75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (dataForm.getReportedData() == null)
76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                return new Form(dataForm);
77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Otherwise return null
79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return null;
80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Creates a new Form that will wrap an existing DataForm. The wrapped DataForm must be
84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * used for gathering data.
85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param dataForm the data form used for gathering data.
87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public Form(DataForm dataForm) {
89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        this.dataForm = dataForm;
90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Creates a new Form of a given type from scratch.<p>
94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Possible form types are:
96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <ul>
97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *  <li>form -> Indicates a form to fill out.</li>
98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *  <li>submit -> The form is filled out, and this is the data that is being returned from
99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the form.</li>
100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *  <li>cancel -> The form was cancelled. Tell the asker that piece of information.</li>
101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *  <li>result -> Data results being returned from a search, or some other query.</li>
102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * </ul>
103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param type the form's type (e.g. form, submit,cancel,result).
105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public Form(String type) {
107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        this.dataForm = new DataForm(type);
108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Adds a new field to complete as part of the form.
112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param field the field to complete.
114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void addField(FormField field) {
116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        dataForm.addField(field);
117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Sets a new String value to a given form's field. The field whose variable matches the
121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * requested variable will be completed with the specified value. If no field could be found
122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * for the specified variable then an exception will be raised.<p>
123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * If the value to set to the field is not a basic type (e.g. String, boolean, int, etc.) you
125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * can use this message where the String value is the String representation of the object.
126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param variable the variable name that was completed.
128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param value the String value that was answered.
129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalStateException if the form is not of type "submit".
130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalArgumentException if the form does not include the specified variable or
131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *      if the answer type does not correspond with the field type..
132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void setAnswer(String variable, String value) {
134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        FormField field = getField(variable);
135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (field == null) {
136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalArgumentException("Field not found for the specified variable name.");
137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (!FormField.TYPE_TEXT_MULTI.equals(field.getType())
139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            && !FormField.TYPE_TEXT_PRIVATE.equals(field.getType())
140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            && !FormField.TYPE_TEXT_SINGLE.equals(field.getType())
141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            && !FormField.TYPE_JID_SINGLE.equals(field.getType())
142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            && !FormField.TYPE_HIDDEN.equals(field.getType())) {
143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalArgumentException("This field is not of type String.");
144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        setAnswer(field, value);
146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Sets a new int value to a given form's field. The field whose variable matches the
150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * requested variable will be completed with the specified value. If no field could be found
151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * for the specified variable then an exception will be raised.
152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param variable the variable name that was completed.
154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param value the int value that was answered.
155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalStateException if the form is not of type "submit".
156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalArgumentException if the form does not include the specified variable or
157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *      if the answer type does not correspond with the field type.
158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void setAnswer(String variable, int value) {
160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        FormField field = getField(variable);
161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (field == null) {
162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalArgumentException("Field not found for the specified variable name.");
163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (!FormField.TYPE_TEXT_MULTI.equals(field.getType())
165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            && !FormField.TYPE_TEXT_PRIVATE.equals(field.getType())
166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            && !FormField.TYPE_TEXT_SINGLE.equals(field.getType())) {
167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalArgumentException("This field is not of type int.");
168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        setAnswer(field, value);
170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Sets a new long value to a given form's field. The field whose variable matches the
174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * requested variable will be completed with the specified value. If no field could be found
175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * for the specified variable then an exception will be raised.
176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param variable the variable name that was completed.
178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param value the long value that was answered.
179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalStateException if the form is not of type "submit".
180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalArgumentException if the form does not include the specified variable or
181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *      if the answer type does not correspond with the field type.
182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void setAnswer(String variable, long value) {
184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        FormField field = getField(variable);
185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (field == null) {
186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalArgumentException("Field not found for the specified variable name.");
187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (!FormField.TYPE_TEXT_MULTI.equals(field.getType())
189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            && !FormField.TYPE_TEXT_PRIVATE.equals(field.getType())
190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            && !FormField.TYPE_TEXT_SINGLE.equals(field.getType())) {
191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalArgumentException("This field is not of type long.");
192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        setAnswer(field, value);
194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Sets a new float value to a given form's field. The field whose variable matches the
198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * requested variable will be completed with the specified value. If no field could be found
199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * for the specified variable then an exception will be raised.
200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param variable the variable name that was completed.
202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param value the float value that was answered.
203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalStateException if the form is not of type "submit".
204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalArgumentException if the form does not include the specified variable or
205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *      if the answer type does not correspond with the field type.
206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void setAnswer(String variable, float value) {
208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        FormField field = getField(variable);
209d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (field == null) {
210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalArgumentException("Field not found for the specified variable name.");
211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (!FormField.TYPE_TEXT_MULTI.equals(field.getType())
213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            && !FormField.TYPE_TEXT_PRIVATE.equals(field.getType())
214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            && !FormField.TYPE_TEXT_SINGLE.equals(field.getType())) {
215d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalArgumentException("This field is not of type float.");
216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        setAnswer(field, value);
218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
219d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
221d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Sets a new double value to a given form's field. The field whose variable matches the
222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * requested variable will be completed with the specified value. If no field could be found
223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * for the specified variable then an exception will be raised.
224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param variable the variable name that was completed.
226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param value the double value that was answered.
227d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalStateException if the form is not of type "submit".
228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalArgumentException if the form does not include the specified variable or
229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *      if the answer type does not correspond with the field type.
230d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void setAnswer(String variable, double value) {
232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        FormField field = getField(variable);
233d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (field == null) {
234d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalArgumentException("Field not found for the specified variable name.");
235d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (!FormField.TYPE_TEXT_MULTI.equals(field.getType())
237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            && !FormField.TYPE_TEXT_PRIVATE.equals(field.getType())
238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            && !FormField.TYPE_TEXT_SINGLE.equals(field.getType())) {
239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalArgumentException("This field is not of type double.");
240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        setAnswer(field, value);
242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Sets a new boolean value to a given form's field. The field whose variable matches the
246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * requested variable will be completed with the specified value. If no field could be found
247d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * for the specified variable then an exception will be raised.
248d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param variable the variable name that was completed.
250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param value the boolean value that was answered.
251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalStateException if the form is not of type "submit".
252d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalArgumentException if the form does not include the specified variable or
253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *      if the answer type does not correspond with the field type.
254d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
255d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void setAnswer(String variable, boolean value) {
256d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        FormField field = getField(variable);
257d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (field == null) {
258d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalArgumentException("Field not found for the specified variable name.");
259d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
260d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (!FormField.TYPE_BOOLEAN.equals(field.getType())) {
261d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalArgumentException("This field is not of type boolean.");
262d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
263d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        setAnswer(field, (value ? "1" : "0"));
264d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
265d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
266d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
267d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Sets a new Object value to a given form's field. In fact, the object representation
268d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * (i.e. #toString) will be the actual value of the field.<p>
269d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
270d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * If the value to set to the field is not a basic type (e.g. String, boolean, int, etc.) you
271d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * will need to use {@link #setAnswer(String, String))} where the String value is the
272d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * String representation of the object.<p>
273d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
274d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Before setting the new value to the field we will check if the form is of type submit. If
275d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the form isn't of type submit means that it's not possible to complete the form and an
276d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * exception will be thrown.
277d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
278d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param field the form field that was completed.
279d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param value the Object value that was answered. The object representation will be the
280d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * actual value.
281d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalStateException if the form is not of type "submit".
282d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
283d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private void setAnswer(FormField field, Object value) {
284d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (!isSubmitType()) {
285d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalStateException("Cannot set an answer if the form is not of type " +
286d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            "\"submit\"");
287d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
288d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        field.resetValues();
289d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        field.addValue(value.toString());
290d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
291d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
292d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
293d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Sets a new values to a given form's field. The field whose variable matches the requested
294d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * variable will be completed with the specified values. If no field could be found for
295d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the specified variable then an exception will be raised.<p>
296d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
297d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * The Objects contained in the List could be of any type. The String representation of them
298d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * (i.e. #toString) will be actually used when sending the answer to the server.
299d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
300d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param variable the variable that was completed.
301d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param values the values that were answered.
302d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalStateException if the form is not of type "submit".
303d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalArgumentException if the form does not include the specified variable.
304d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
305d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void setAnswer(String variable, List<String> values) {
306d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (!isSubmitType()) {
307d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalStateException("Cannot set an answer if the form is not of type " +
308d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            "\"submit\"");
309d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
310d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        FormField field = getField(variable);
311d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (field != null) {
312d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Check that the field can accept a collection of values
313d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (!FormField.TYPE_JID_MULTI.equals(field.getType())
314d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                && !FormField.TYPE_LIST_MULTI.equals(field.getType())
315d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                && !FormField.TYPE_LIST_SINGLE.equals(field.getType())
316d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                && !FormField.TYPE_TEXT_MULTI.equals(field.getType())
317d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                && !FormField.TYPE_HIDDEN.equals(field.getType())) {
318d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw new IllegalArgumentException("This field only accept list of values.");
319d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
320d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Clear the old values
321d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            field.resetValues();
322d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Set the new values. The string representation of each value will be actually used.
323d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            field.addValues(values);
324d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
325d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        else {
326d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalArgumentException("Couldn't find a field for the specified variable.");
327d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
328d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
329d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
330d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
331d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Sets the default value as the value of a given form's field. The field whose variable matches
332d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the requested variable will be completed with its default value. If no field could be found
333d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * for the specified variable then an exception will be raised.
334d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
335d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param variable the variable to complete with its default value.
336d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalStateException if the form is not of type "submit".
337d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws IllegalArgumentException if the form does not include the specified variable.
338d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
339d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void setDefaultAnswer(String variable) {
340d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (!isSubmitType()) {
341d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalStateException("Cannot set an answer if the form is not of type " +
342d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            "\"submit\"");
343d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
344d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        FormField field = getField(variable);
345d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (field != null) {
346d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Clear the old values
347d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            field.resetValues();
348d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Set the default value
349d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            for (Iterator<String> it = field.getValues(); it.hasNext();) {
350d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                field.addValue(it.next());
351d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
352d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
353d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        else {
354d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalArgumentException("Couldn't find a field for the specified variable.");
355d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
356d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
357d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
358d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
359d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns an Iterator for the fields that are part of the form.
360d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
361d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return an Iterator for the fields that are part of the form.
362d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
363d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public Iterator<FormField> getFields() {
364d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return dataForm.getFields();
365d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
366d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
367d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
368d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns the field of the form whose variable matches the specified variable.
369d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * The fields of type FIXED will never be returned since they do not specify a
370d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * variable.
371d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
372d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param variable the variable to look for in the form fields.
373d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return the field of the form whose variable matches the specified variable.
374d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
375d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public FormField getField(String variable) {
376d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (variable == null || variable.equals("")) {
377d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalArgumentException("Variable must not be null or blank.");
378d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
379d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Look for the field whose variable matches the requested variable
380d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        FormField field;
381d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        for (Iterator<FormField> it=getFields();it.hasNext();) {
382d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            field = it.next();
383d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (variable.equals(field.getVariable())) {
384d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                return field;
385d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
386d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
387d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return null;
388d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
389d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
390d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
391d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns the instructions that explain how to fill out the form and what the form is about.
392d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
393d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return instructions that explain how to fill out the form.
394d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
395d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public String getInstructions() {
396d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        StringBuilder sb = new StringBuilder();
397d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Join the list of instructions together separated by newlines
398d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        for (Iterator<String> it = dataForm.getInstructions(); it.hasNext();) {
399d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            sb.append(it.next());
400d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // If this is not the last instruction then append a newline
401d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (it.hasNext()) {
402d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                sb.append("\n");
403d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
404d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
405d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return sb.toString();
406d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
407d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
408d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
409d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
410d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns the description of the data. It is similar to the title on a web page or an X
411d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * window.  You can put a <title/> on either a form to fill out, or a set of data results.
412d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
413d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return description of the data.
414d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
415d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public String getTitle() {
416d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return dataForm.getTitle();
417d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
418d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
419d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
420d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
421d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns the meaning of the data within the context. The data could be part of a form
422d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * to fill out, a form submission or data results.<p>
423d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
424d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Possible form types are:
425d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <ul>
426d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *  <li>form -> Indicates a form to fill out.</li>
427d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *  <li>submit -> The form is filled out, and this is the data that is being returned from
428d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the form.</li>
429d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *  <li>cancel -> The form was cancelled. Tell the asker that piece of information.</li>
430d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *  <li>result -> Data results being returned from a search, or some other query.</li>
431d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * </ul>
432d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
433d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return the form's type.
434d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
435d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public String getType() {
436d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return dataForm.getType();
437d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
438d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
439d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
440d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
441d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Sets instructions that explain how to fill out the form and what the form is about.
442d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
443d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param instructions instructions that explain how to fill out the form.
444d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
445d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void setInstructions(String instructions) {
446d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Split the instructions into multiple instructions for each existent newline
447d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        ArrayList<String> instructionsList = new ArrayList<String>();
448d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        StringTokenizer st = new StringTokenizer(instructions, "\n");
449d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        while (st.hasMoreTokens()) {
450d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            instructionsList.add(st.nextToken());
451d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
452d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Set the new list of instructions
453d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        dataForm.setInstructions(instructionsList);
454d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
455d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
456d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
457d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
458d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
459d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Sets the description of the data. It is similar to the title on a web page or an X window.
460d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * You can put a <title/> on either a form to fill out, or a set of data results.
461d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
462d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param title description of the data.
463d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
464d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void setTitle(String title) {
465d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        dataForm.setTitle(title);
466d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
467d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
468d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
469d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns a DataForm that serves to send this Form to the server. If the form is of type
470d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * submit, it may contain fields with no value. These fields will be removed since they only
471d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * exist to assist the user while editing/completing the form in a UI.
472d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
473d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return the wrapped DataForm.
474d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
475d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public DataForm getDataFormToSend() {
476d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (isSubmitType()) {
477d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Create a new DataForm that contains only the answered fields
478d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            DataForm dataFormToSend = new DataForm(getType());
479d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            for(Iterator<FormField> it=getFields();it.hasNext();) {
480d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                FormField field = it.next();
481d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                if (field.getValues().hasNext()) {
482d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    dataFormToSend.addField(field);
483d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                }
484d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
485d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return dataFormToSend;
486d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
487d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return dataForm;
488d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
489d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
490d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
491d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns true if the form is a form to fill out.
492d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
493d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return if the form is a form to fill out.
494d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
495d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private boolean isFormType() {
496d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return TYPE_FORM.equals(dataForm.getType());
497d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
498d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
499d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
500d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns true if the form is a form to submit.
501d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
502d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return if the form is a form to submit.
503d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
504d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private boolean isSubmitType() {
505d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return TYPE_SUBMIT.equals(dataForm.getType());
506d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
507d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
508d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
509d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns a new Form to submit the completed values. The new Form will include all the fields
510d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * of the original form except for the fields of type FIXED. Only the HIDDEN fields will
511d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * include the same value of the original form. The other fields of the new form MUST be
512d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * completed. If a field remains with no answer when sending the completed form, then it won't
513d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * be included as part of the completed form.<p>
514d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
515d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * The reason why the fields with variables are included in the new form is to provide a model
516d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * for binding with any UI. This means that the UIs will use the original form (of type
517d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * "form") to learn how to render the form, but the UIs will bind the fields to the form of
518d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * type submit.
519d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
520d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return a Form to submit the completed values.
521d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
522d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public Form createAnswerForm() {
523d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (!isFormType()) {
524d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalStateException("Only forms of type \"form\" could be answered");
525d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
526d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Create a new Form
527d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        Form form = new Form(TYPE_SUBMIT);
528d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        for (Iterator<FormField> fields=getFields(); fields.hasNext();) {
529d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            FormField field = fields.next();
530d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Add to the new form any type of field that includes a variable.
531d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Note: The fields of type FIXED are the only ones that don't specify a variable
532d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (field.getVariable() != null) {
533d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                FormField newField = new FormField(field.getVariable());
534d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                newField.setType(field.getType());
535d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                form.addField(newField);
536d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                // Set the answer ONLY to the hidden fields
537d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                if (FormField.TYPE_HIDDEN.equals(field.getType())) {
538d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    // Since a hidden field could have many values we need to collect them
539d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    // in a list
540d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    List<String> values = new ArrayList<String>();
541d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    for (Iterator<String> it=field.getValues();it.hasNext();) {
542d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        values.add(it.next());
543d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    }
544d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    form.setAnswer(field.getVariable(), values);
545d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                }
546d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
547d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
548d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return form;
549d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
550d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
551d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
552