KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xmpp > forms > DataForm


1 /**
2  * $RCSfile: DataForm.java,v $
3  * $Revision: 1.3 $
4  * $Date: 2005/05/11 19:56:11 $
5  *
6  * Copyright 2004 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
21 package org.xmpp.forms;
22
23 import org.dom4j.Element;
24 import org.dom4j.QName;
25 import org.xmpp.packet.PacketExtension;
26
27 import java.util.*;
28 import java.text.SimpleDateFormat JavaDoc;
29 import java.text.ParseException JavaDoc;
30
31 /**
32  * Represents a form that could be use for gathering data as well as for reporting data
33  * returned from a search.
34  * <p/>
35  * The form could be of the following types:
36  * <ul>
37  * <li>form -> Indicates a form to fill out.</li>
38  * <li>submit -> The form is filled out, and this is the data that is being returned from
39  * the form.</li>
40  * <li>cancel -> The form was cancelled. Tell the asker that piece of information.</li>
41  * <li>result -> Data results being returned from a search, or some other query.</li>
42  * </ul>
43  * <p/>
44  * In case the form represents a search, the report will be structured in columns and rows. Use
45  * {@link #addReportedField(String,String,FormField.Type)} to set the columns of the report whilst
46  * the report's rows can be configured using {@link #addItemFields(Map)}.
47  *
48  * @author Gaston Dombiak
49  */

50 public class DataForm extends PacketExtension {
51
52     private static final SimpleDateFormat JavaDoc UTC_FORMAT = new SimpleDateFormat JavaDoc("yyyyMMdd'T'HH:mm:ss");
53
54     /**
55      * Element name of the packet extension.
56      */

57     public static final String JavaDoc ELEMENT_NAME = "x";
58
59     /**
60      * Namespace of the packet extension.
61      */

62     public static final String JavaDoc NAMESPACE = "jabber:x:data";
63
64     static {
65         UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
66         // Register that DataForms uses the jabber:x:data namespace
67
registeredExtensions.put(QName.get(ELEMENT_NAME, NAMESPACE), DataForm.class);
68     }
69
70     /**
71      * Returns the Date obtained by parsing the specified date representation. The date
72      * representation is expected to be in the UTC GMT+0 format.
73      *
74      * @param date date representation in the UTC GMT+0 format.
75      * @return the Date obtained by parsing the specified date representation.
76      * @throws ParseException if an error occurs while parsing the date representation.
77      */

78     public static Date parseDate(String JavaDoc date) throws ParseException JavaDoc {
79         return UTC_FORMAT.parse(date);
80     }
81
82     /**
83      * Returns the String representation of an Object to be used as a field value.
84      *
85      * @param object the object to encode.
86      * @return the String representation of an Object to be used as a field value.
87      */

88     static String JavaDoc encode(Object JavaDoc object) {
89         if (object instanceof String JavaDoc) {
90             return object.toString();
91         }
92         else if (object instanceof Date) {
93             return UTC_FORMAT.format(object);
94         }
95         else if (object instanceof Boolean JavaDoc) {
96             return Boolean.TRUE.equals(object) ? "1" : "0";
97         }
98         return object.toString();
99     }
100
101     public DataForm(Type type) {
102         super(ELEMENT_NAME, NAMESPACE);
103         // Set the type of the data form
104
element.addAttribute("type", type.toString());
105     }
106
107     public DataForm(Element element) {
108         super(element);
109     }
110
111     /**
112      * Returns the type of this data form.
113      *
114      * @return the data form type.
115      * @see org.xmpp.forms.DataForm.Type
116      */

117     public DataForm.Type getType() {
118         String JavaDoc type = element.attributeValue("type");
119         if (type != null) {
120             return DataForm.Type.valueOf(type);
121         }
122         else {
123             return null;
124         }
125     }
126
127     /**
128      * Sets the description of the data. It is similar to the title on a web page or an X window.
129      * You can put a <title/> on either a form to fill out, or a set of data results.
130      *
131      * @param title description of the data.
132      */

133     public void setTitle(String JavaDoc title) {
134         // Remove an existing title element.
135
if (element.element("title") != null) {
136             element.remove(element.element("title"));
137         }
138         element.addElement("title").setText(title);
139     }
140
141     /**
142      * Returns the description of the data form. It is similar to the title on a web page or an X
143      * window. You can put a <title/> on either a form to fill out, or a set of data results.
144      *
145      * @return description of the data.
146      */

147     public String JavaDoc getTitle() {
148         return element.elementTextTrim("title");
149     }
150
151     /**
152      * Returns an unmodifiable list of instructions that explain how to fill out the form and
153      * what the form is about. The dataform could include multiple instructions since each
154      * instruction could not contain newlines characters.
155      *
156      * @return an unmodifiable list of instructions that explain how to fill out the form.
157      */

158     public List<String JavaDoc> getInstructions() {
159         List<String JavaDoc> answer = new ArrayList<String JavaDoc>();
160         for (Iterator it = element.elementIterator("instructions"); it.hasNext();) {
161             answer.add(((Element) it.next()).getTextTrim());
162         }
163         return Collections.unmodifiableList(answer);
164     }
165
166     /**
167      * Adds a new instruction to the list of instructions that explain how to fill out the form
168      * and what the form is about. The dataform could include multiple instructions since each
169      * instruction could not contain newlines characters.
170      *
171      * @param instruction the new instruction that explain how to fill out the form.
172      */

173     public void addInstruction(String JavaDoc instruction) {
174         element.addElement("instructions").setText(instruction);
175     }
176
177     /**
178      * Clears all the stored instructions in this packet extension.
179      */

180     public void clearInstructions() {
181         for (Iterator it = element.elementIterator("instructions"); it.hasNext();) {
182             it.next();
183             it.remove();
184         }
185     }
186
187     /**
188      * Adds a new field as part of the form.
189      *
190      * @return the newly created field.
191      */

192     public FormField addField() {
193         return new FormField(element.addElement("field"));
194     }
195
196     /**
197      * Returns an Iterator for the fields that are part of the form.
198      *
199      * @return an Iterator for the fields that are part of the form.
200      */

201     public List<FormField> getFields() {
202         List<FormField> answer = new ArrayList<FormField>();
203         for (Iterator it = element.elementIterator("field"); it.hasNext();) {
204             answer.add(new FormField((Element) it.next()));
205         }
206         return answer;
207     }
208
209     /**
210      * Adds a field to the list of fields that will be returned from a search. Each field represents
211      * a column in the report. The order of the columns in the report will honor the sequence in
212      * which they were added.
213      *
214      * @param variable variable name of the new column. This value will be used in
215      * {@link #addItemFields} when adding reported items.
216      * @param label label that corresponds to the new column. Optional parameter.
217      * @param type indicates the type of field of the new column. Optional parameter.
218      */

219     public void addReportedField(String JavaDoc variable, String JavaDoc label, FormField.Type type) {
220         Element reported = element.element("reported");
221         synchronized (element) {
222             if (reported == null) {
223                 reported = element.element("reported");
224                 if (reported == null) {
225                     reported = element.addElement("reported");
226                 }
227             }
228         }
229         FormField newField = new FormField(reported.addElement("field"));
230         newField.setVariable(variable);
231         newField.setType(type);
232         newField.setLabel(label);
233     }
234
235     /**
236      * Adds a new row of items of reported data. For each entry in the <tt>fields</tt> parameter
237      * a <tt>field</tt> element will be added to the <item> element. The variable of the new
238      * <tt>field</tt> will be the key of the entry. The new <tt>field</tt> will have several values
239      * if the entry's value is a {@link Collection}. Since the value is of type {@link Object} it
240      * is possible to include any type of object as a value. The actual value to include in the
241      * data form is the result of the {@link #encode(Object)} method.
242      *
243      * @param fields list of <variable,value> to be added as a new item.
244      */

245     public void addItemFields(Map<String JavaDoc,Object JavaDoc> fields) {
246         Element item = element.addElement("item");
247         // Add a field element to the item element for each row in fields
248
for (String JavaDoc var : fields.keySet()) {
249             Element field = item.addElement("field");
250             field.addAttribute("var", var);
251             Object JavaDoc value = fields.get(var);
252             if (value instanceof Collection) {
253                 // Add a value element for each entry in the collection
254
for (Iterator it = ((Collection) value).iterator(); it.hasNext();) {
255                     field.addElement("value").setText(encode(it.next()));
256                 }
257             }
258             else {
259                 field.addElement("value").setText(encode(value));
260             }
261         }
262     }
263
264     public DataForm createCopy() {
265         return new DataForm(this.getElement().createCopy());
266     }
267
268     /**
269      * Type-safe enumeration to represent the type of the Data forms.
270      */

271     public enum Type {
272         /**
273          * The forms-processing entity is asking the forms-submitting entity to complete a form.
274          */

275         form,
276
277         /**
278          * The forms-submitting entity is submitting data to the forms-processing entity.
279          */

280         submit,
281
282         /**
283          * The forms-submitting entity has cancelled submission of data to the forms-processing
284          * entity.
285          */

286         cancel,
287
288         /**
289          * The forms-processing entity is returning data (e.g., search results) to the
290          * forms-submitting entity, or the data is a generic data set.
291          */

292         result;
293     }
294 }
295
Popular Tags