001: /**
002: * $RCSfile$
003: * $Revision: 904 $
004: * $Date: 2005-01-25 15:41:48 -0300 (Tue, 25 Jan 2005) $
005: *
006: * Copyright (C) 2004 Jive Software. All rights reserved.
007: *
008: * This software is published under the terms of the GNU Public License (GPL),
009: * a copy of which is included in this distribution.
010: */package org.jivesoftware.openfire.forms.spi;
011:
012: import org.jivesoftware.openfire.forms.FormField;
013:
014: import java.util.*;
015: import org.dom4j.DocumentHelper;
016: import org.dom4j.Element;
017: import org.dom4j.QName;
018:
019: /**
020: * A concrete DataForm capable of sending itself to a writer and recover its state from an XMPP
021: * stanza. XDataForms are packets of the form:
022: * <code><pre>
023: * <x xmlns='jabber:x:data' type='{form-type}'>
024: * <title/>
025: * <instructions/>
026: * <field var='field-name'
027: * type='{field-type}'
028: * label='description'>
029: * <desc/>
030: * <required/>
031: * <value>field-value</value>
032: * <option label='option-label'><value>option-value</value></option>
033: * <option label='option-label'><value>option-value</value></option>
034: * </field>
035: * </x>
036: * </pre></code>
037: * <p/>
038: * An XDataFormImpl can contain zero or more XFormFieldImpl 'field' fragments.<p>
039: * <p/>
040: * To learn more follow this link: <a href="http://www.jabber.org/jeps/jep-0004.html">JEP-04</a>.
041: *
042: * @author gdombiak
043: */
044: public class XDataFormImpl {
045:
046: private String type;
047: private String title;
048: private List instructions = new ArrayList();
049: private List fields = new ArrayList();
050: private List reportedFields = new ArrayList();
051: private List reportedItems = new ArrayList();
052:
053: public XDataFormImpl() {
054: super ();
055: }
056:
057: public XDataFormImpl(String type) {
058: this .type = type;
059: }
060:
061: public void setTitle(String title) {
062: this .title = title;
063: }
064:
065: public void setInstructions(List instructions) {
066: this .instructions = instructions;
067: }
068:
069: public String getType() {
070: return type;
071: }
072:
073: public String getTitle() {
074: return title;
075: }
076:
077: public Iterator getInstructions() {
078: synchronized (instructions) {
079: return Collections.unmodifiableList(
080: new ArrayList(instructions)).iterator();
081: }
082: }
083:
084: public FormField getField(String variable) {
085: if (variable == null || variable.equals("")) {
086: throw new IllegalArgumentException(
087: "Variable must not be null or blank.");
088: }
089: // Look for the field whose variable matches the requested variable
090: FormField field;
091: for (Iterator it = getFields(); it.hasNext();) {
092: field = (FormField) it.next();
093: if (variable.equals(field.getVariable())) {
094: return field;
095: }
096: }
097: return null;
098: }
099:
100: public Iterator getFields() {
101: synchronized (fields) {
102: return Collections.unmodifiableList(new ArrayList(fields))
103: .iterator();
104: }
105: }
106:
107: public int getFieldsSize() {
108: return fields.size();
109: }
110:
111: public void addInstruction(String instruction) {
112: synchronized (instructions) {
113: instructions.add(instruction);
114: }
115: }
116:
117: public void addField(FormField field) {
118: synchronized (fields) {
119: fields.add(field);
120: }
121: }
122:
123: public void addReportedField(FormField field) {
124: synchronized (reportedFields) {
125: reportedFields.add(field);
126: }
127: }
128:
129: public void addItemFields(ArrayList itemFields) {
130: synchronized (reportedItems) {
131: // We are nesting a List (of fields) inside of the List of items
132: reportedItems.add(itemFields);
133: }
134: }
135:
136: public String getNamespace() {
137: // Is someone sending this message?
138: return "jabber:x:data";
139: }
140:
141: public void setNamespace(String namespace) {
142: // Is someone sending this message?
143: // Do nothing
144: }
145:
146: public String getName() {
147: // Is someone sending this message?
148: return "x";
149: }
150:
151: public void setName(String name) {
152: // Is someone sending this message?
153: // Do nothing
154: }
155:
156: public Element asXMLElement() {
157: Element x = DocumentHelper.createElement(QName.get("x",
158: "jabber:x:data"));
159: if (getType() != null) {
160: x.addAttribute("type", getType());
161: }
162: if (getTitle() != null) {
163: x.addElement("title").addText(getTitle());
164: }
165: if (instructions.size() > 0) {
166: Iterator instrItr = getInstructions();
167: while (instrItr.hasNext()) {
168: x.addElement("instructions").addText(
169: (String) instrItr.next());
170: }
171: }
172: // Append the list of fields returned from a search
173: if (reportedFields.size() > 0) {
174: Element reportedElement = x.addElement("reported");
175: Iterator fieldsItr = reportedFields.iterator();
176: while (fieldsItr.hasNext()) {
177: XFormFieldImpl field = (XFormFieldImpl) fieldsItr
178: .next();
179: reportedElement.add(field.asXMLElement());
180: }
181: }
182:
183: // Append the list of items returned from a search
184: // Note: each item contains a List of XFormFieldImpls
185: if (reportedItems.size() > 0) {
186: Iterator itemsItr = reportedItems.iterator();
187: while (itemsItr.hasNext()) {
188: // Add a new item element for this list of fields
189: Element itemElement = x.addElement("item");
190: List fields = (List) itemsItr.next();
191: Iterator fieldsItr = fields.iterator();
192: // Iterate on the fields and add them to the new item
193: while (fieldsItr.hasNext()) {
194: XFormFieldImpl field = (XFormFieldImpl) fieldsItr
195: .next();
196: itemElement.add(field.asXMLElement());
197: }
198: }
199: }
200:
201: if (fields.size() > 0) {
202: Iterator fieldsItr = getFields();
203: while (fieldsItr.hasNext()) {
204: XFormFieldImpl field = (XFormFieldImpl) fieldsItr
205: .next();
206: x.add(field.asXMLElement());
207: }
208: }
209:
210: return x;
211: }
212:
213: public void parse(Element formElement) {
214: type = formElement.attributeValue("type");
215: Element titleElement = formElement.element("title");
216: if (titleElement != null) {
217: setTitle(titleElement.getTextTrim());
218: }
219: Iterator instructionElements = formElement
220: .elementIterator("instructions");
221: while (instructionElements.hasNext()) {
222: addInstruction(((Element) instructionElements.next())
223: .getTextTrim());
224: }
225: Iterator fieldElements = formElement.elementIterator("field");
226: while (fieldElements.hasNext()) {
227: XFormFieldImpl field = new XFormFieldImpl();
228: field.parse((Element) fieldElements.next());
229: addField(field);
230: }
231:
232: Element reportedElement = formElement.element("reported");
233: if (reportedElement != null) {
234: Iterator reportedFieldElements = reportedElement
235: .elementIterator("field");
236: while (reportedFieldElements.hasNext()) {
237: XFormFieldImpl field = new XFormFieldImpl();
238: field.parse((Element) reportedFieldElements.next());
239: addReportedField(field);
240: }
241: }
242:
243: Iterator itemElements = formElement.elementIterator("item");
244: while (itemElements.hasNext()) {
245: Element itemElement = (Element) itemElements.next();
246: Iterator itemFieldElements = itemElement
247: .elementIterator("field");
248: ArrayList itemFields = new ArrayList();
249: while (itemFieldElements.hasNext()) {
250: XFormFieldImpl field = new XFormFieldImpl();
251: field.parse((Element) itemFieldElements.next());
252: itemFields.add(field);
253: }
254: addItemFields(itemFields);
255: }
256: }
257: }
|