diff options
11 files changed, 696 insertions, 1000 deletions
diff --git a/src/com/isode/stroke/elements/Form.java b/src/com/isode/stroke/elements/Form.java index 362408a..8068f28 100644 --- a/src/com/isode/stroke/elements/Form.java +++ b/src/com/isode/stroke/elements/Form.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Isode Limited, London, England. + * Copyright (c) 2012-2014 Isode Limited, London, England. * All rights reserved. */ /* @@ -12,7 +12,6 @@ package com.isode.stroke.elements; import java.util.ArrayList; import java.util.List; -import com.isode.stroke.elements.FormField.HiddenFormField; /** * XEP-0004 Data form. For the relevant Fields, the parsers and serialisers @@ -34,6 +33,16 @@ public class Form extends Payload { * Element "instructions" */ public static final String FORM_ELEMENT_INSTRUCTIONS = "instructions"; + + /** + * Element "reported" + */ + public static final String FORM_ELEMENT_REPORTED = "reported"; + + /** + * Element "item" + */ + public static final String FORM_ELEMENT_ITEM = "item"; /** * Element "field" @@ -97,13 +106,15 @@ public class Form extends Payload { public String getStringForm() { return stringForm_; } - }; + } private List<FormField> fields_ = new ArrayList<FormField>(); - private String title_ = ""; + private List<FormField> reportedFields_ = new ArrayList<FormField>(); + private List<FormItem> items_ = new ArrayList<FormItem>(); private String instructions_ = ""; + private String title_ = ""; private Type type_; - + /** * Create a form of the given type. * @@ -130,7 +141,6 @@ public class Form extends Payload { if (field == null) { throw new NullPointerException("'field' must not be null"); } - fields_.add(field); } @@ -143,6 +153,52 @@ public class Form extends Payload { public List<FormField> getFields() { return new ArrayList<FormField>(fields_); } + + /** + * Add a reported element to this Form. + * @param reportedField should not be null + */ + public void addReportedField(FormField reportedField) { + if (reportedField == null) { + throw new NullPointerException("'reportedField' should not be null"); + } + reportedFields_.add(reportedField); + } + + /** + * Return the list of reported fields for this Form. + * @return reportedFields_, never null + */ + public List<FormField> getReportedFields() { + return reportedFields_; + } + + /** + * Add a list of item elements to the Form. + * @param item List<FormField>, should not be null + */ + public void addItem(FormItem item) { + if (item == null) { + throw new NullPointerException("'item' should not be null"); + } + items_.add(item); + } + + /** + * Get the list of FormItem elements for the form. + * @return itemsCopy ArrayList<List<FormItem>>, list of items for the Form, + * a copy is made + */ + public List<FormItem> getItems() { + return new ArrayList<FormItem>(items_); + } + + /** + * Remove all reported fields from this Form. + */ + public void clearReportedFields() { + reportedFields_.clear(); + } /** * Set title of the form. @@ -209,19 +265,11 @@ public class Form extends Payload { * the form, an empty string otherwise, will never be null */ public String getFormType() { - String value = null; - FormField field = getField("FORM_TYPE"); - try { - HiddenFormField f = (HiddenFormField) field; - if (f != null) { - value = f.getValue(); - } - } catch (ClassCastException e) { - // value remains null + if (field != null && field.getType() == FormField.Type.HIDDEN_TYPE) { + return field.getValues().isEmpty() ? "" : field.getValues().get(0); } - - return ((value != null) ? value : ""); + return ""; } /** diff --git a/src/com/isode/stroke/elements/FormField.java b/src/com/isode/stroke/elements/FormField.java index aedc8fe..2ec0e4b 100644 --- a/src/com/isode/stroke/elements/FormField.java +++ b/src/com/isode/stroke/elements/FormField.java @@ -1,18 +1,16 @@ /* - * Copyright (c) 2012 Isode Limited, London, England. + * Copyright (c) 2012-2014 Isode Limited, London, England. * All rights reserved. */ /* * Copyright (c) 2010 Remko Tronçon * All rights reserved. */ - package com.isode.stroke.elements; import java.util.ArrayList; import java.util.List; -import com.isode.stroke.elements.Form.Type; import com.isode.stroke.jid.JID; /** @@ -28,120 +26,88 @@ import com.isode.stroke.jid.JID; * optionally providing a textual explanation. */ public class FormField { - /** - * Attribute "var" - */ + public static final String FORM_FIELD_ATTRIBUTE_VAR = "var"; - - /** - * Attribute "label" - */ public static final String FORM_FIELD_ATTRIBUTE_LABEL = "label"; - - /** - * Element "required" - */ public static final String FORM_FIELD_ELEMENT_REQUIRED = "required"; - - /** - * Element "desc" - */ public static final String FORM_FIELD_ELEMENT_DESC = "desc"; - - /** - * Element "value" - */ public static final String FORM_FIELD_ELEMENT_VALUE = "value"; - - /** - * Attribute "type" - */ public static final String FORM_FIELD_ATTRIBUTE_TYPE = "type"; - - /** - * Element "option" - */ public static final String FORM_FIELD_ELEMENT_OPTION = "option"; - - /** - * Attribute option "label" - */ public static final String FORM_FIELD_ATTRIBUTE_OPTION_LABEL = "label"; - - /** - * Element option "value" - */ public static final String FORM_FIELD_ELEMENT_OPTION_VALUE = "value"; - - /** - * Type "boolean" - */ - public static final String FORM_FIELD_TYPE_BOOLEAN = "boolean"; - - /** - * Type "fixed" - */ - public static final String FORM_FIELD_TYPE_FIXED = "fixed"; - - /** - * Type "hidden" - */ - public static final String FORM_FIELD_TYPE_HIDDEN = "hidden"; - - /** - * Type "list-single" - */ - public static final String FORM_FIELD_TYPE_LIST_SINGLE = "list-single"; - - /** - * Type "text-private" - */ - public static final String FORM_FIELD_TYPE_TEXT_PRIVATE = "text-private"; - - /** - * Type "text-single" - */ - public static final String FORM_FIELD_TYPE_TEXT_SINGLE = "text-single"; - - /** - * Type "jid-multi" - */ - public static final String FORM_FIELD_TYPE_JID_MULTI = "jid-multi"; - - /** - * Type "jid-single" - */ - public static final String FORM_FIELD_TYPE_JID_SINGLE = "jid-single"; - - /** - * Type "list-multi" - */ - public static final String FORM_FIELD_TYPE_LIST_MULTI = "list-multi"; - - /** - * Type "text-multi" - */ - public static final String FORM_FIELD_TYPE_TEXT_MULTI = "text-multi"; - + private static final String ILLEGAL_ARG_EX_STR = "This API is not valid for getting a value of type "; + + private boolean required_; + private List<Option> options_ = new ArrayList<Option>(); + private List<String> values_ = new ArrayList<String>(); + private String description_ = ""; + private String label_ = ""; + private String name_ = ""; + private Type type_; + + public enum Type { + UNKNOWN_TYPE("unknown"), + BOOLEAN_TYPE("boolean"), + FIXED_TYPE("fixed"), + HIDDEN_TYPE("hidden"), + LIST_SINGLE_TYPE("list-single"), + LIST_MULTI_TYPE("list-multi"), + TEXT_PRIVATE_TYPE("text-private"), + TEXT_MULTI_TYPE("text-multi"), + TEXT_SINGLE_TYPE("text-single"), + JID_MULTI_TYPE("jid-multi"), + JID_SINGLE_TYPE("jid-single"); + private String description_; + private Type(String description) { + description_ = description; + } + public String getDescription() { + return description_; + } + + public static Type getTypeFromString(String string) { + for (Type type : Type.values()) { + if (type.getDescription().equals(string)) { + return type; + } + } + return Type.UNKNOWN_TYPE; + } + } + + public FormField(Type type) { + type_ = type; + required_ = false; + if (type == Type.BOOLEAN_TYPE) { + setBoolValue(false); + } + } + + public FormField(Type type, String value) { + addValue(value); + type_ = type; + required_ = false; + } + /** * This class defines the option element that can be used in - * {@link ListSingleFormField} and {@link ListMultiFormField}. This class is + * ListSingleFormField and ListMultiFormField. This class is * immutable. */ public static class Option { /** * Human-readable name for the option, will not be null */ - public final String label; + public final String label_; /** * Option value, will not be null */ - public final String value; + public final String value_; /** * Create an option element. - * * @param label Human-readable name for the option, must not be null * @param value Option value, must not be null */ @@ -152,46 +118,31 @@ public class FormField { if (value == null) { throw new NullPointerException("'value' must not be null"); } - - this.label = label; - this.value = value; + label_ = label; + value_ = value; } } - private String name = ""; - private String label = ""; - private String description = ""; - private boolean required; - private List<Option> options = new ArrayList<Option>(); - private List<String> rawValues = new ArrayList<String>(); - - protected FormField() { - required = false; - } - /** * Set the unique identifier for the field in the form. - * * @param name unique identifier for the field in the form, must not be null */ public void setName(String name) { if (name == null) { throw new NullPointerException("'name' must not be null"); } - - this.name = name; + name_ = name; } /** * @return unique identifier for the field, will never be null */ public String getName() { - return name; + return name_; } /** * Set the human-readable name for the field. - * * @param label human-readable name for the field, must not be null */ public void setLabel(String label) { @@ -199,19 +150,18 @@ public class FormField { throw new NullPointerException("'label' must not be null"); } - this.label = label; + label_ = label; } /** * @return human-readable name for the field, will never be null */ public String getLabel() { - return label; + return label_; } /** * Set the natural-language description for the field. - * * @param description natural-language description for the field, must not * be null */ @@ -220,464 +170,248 @@ public class FormField { throw new NullPointerException("'description' must not be null"); } - this.description = description; + description_ = description; } /** * @return natural-language description for the field, will never be null */ public String getDescription() { - return description; + return description_; } /** * Set if the field is required for the form to be considered valid. - * * @param required true if the field is required for the form to be * considered valid */ public void setRequired(boolean required) { - this.required = required; + required_ = required; } /** * @return true if the field is required for the form to be considered valid */ public boolean getRequired() { - return required; + return required_; } /** - * Add to the list of options for this form field. - * + * Add to the list of options_ for this FormField. * @param option Option to add, must not be null */ public void addOption(Option option) { if (option == null) { throw new NullPointerException("'option' must not be null"); } - - options.add(option); + options_.add(option); } /** - * @return List of options for this form, will never be null. The instance + * @return List of options_ for this FormField, will never be null. The instance * of the list stored in the object is not returned, a copy is made. */ public List<Option> getOptions() { - return new ArrayList<Option>(options); + return new ArrayList<Option>(options_); + } + + /** + * Clears the list of options_ for the FormField. + */ + public void clearOptions() { + options_.clear(); } /** - * Add to values for this field. The values can be the defaults suggested in - * a form of {@link Type#FORM_TYPE} or results provided in a form of - * {@link Type#RESULT_TYPE} or values submitted in a form of + * Add to values_ for this field. The values_ can be the defaults suggested in + * a form of {@link Form.Type#FORM_TYPE} or results provided in a form of + * {@link Type#RESULT_TYPE} or values_ submitted in a form of * {@link Type#SUBMIT_TYPE}. - * * @param value Value to add, must not be null */ - public void addRawValue(String value) { + public void addValue(String value) { if (value == null) { throw new NullPointerException("'value' must not be null"); } - - rawValues.add(value); + values_.add(value); } - + + /** + * Creates a single value for the FormField. This resets the values_ for this + * field to a single argument. + * @param value String, should not be null + */ + public void setValue(String value) { + if (value == null ) { + throw new NullPointerException("'value' should not be null"); + } + values_.clear(); + values_.add(value); + } + /** - * @return List of values for this field, will never be null. The instance - * of the list stored in the object is not returned, a copy is made. + * Resets the list of values for this field to the specified argument. The + * instance of the list stored in the object is not returned, a copy is made. + * @param values List<String> of values */ - public List<String> getRawValues() { - return new ArrayList<String>(rawValues); + public void setValues(List<String> values) { + if (values == null) { + throw new NullPointerException("'values' must not be null"); + } + values_ = new ArrayList<String>(values); } /** - * Template for creating a form field. - * - * @param <T> Type of form field. + * @return List of values_ for this field, will never be null. The instance + * of the list stored in the object is not returned, a copy is made. */ - public static class GenericFormField<T> extends FormField { - private T value; - - /** - * @return Values for this field. The values can be the defaults - * suggested in a form of {@link Type#FORM_TYPE} or results - * provided in a form of {@link Type#RESULT_TYPE} or values - * submitted in a form of {@link Type#SUBMIT_TYPE}. Will never - * be null. - */ - public final T getValue() { - return value; - } - - /** - * Set values for this field. The values can be the defaults suggested - * in a form of {@link Type#FORM_TYPE} or results provided in a form of - * {@link Type#RESULT_TYPE} or values submitted in a form of - * {@link Type#SUBMIT_TYPE}. - * - * @param value Value to set, must not be null - */ - public void setValue(final T value) { - if (value == null) { - throw new NullPointerException("'value' must not be null"); - } - - this.value = value; - } - - protected GenericFormField(final T value) { - setValue(value); - } + public List<String> getValues() { + if (values_ == null) { + values_ = new ArrayList<String>(); + } + return new ArrayList<String>(values_); } /** - * This field enables an entity to gather or provide an either-or choice - * between two options. The default value is "false". + * Returns the type of the FormField. + * @return type_ Type, never null */ - public static class BooleanFormField extends GenericFormField<Boolean> { - private BooleanFormField(Boolean value) { - super(value); - } - - /** - * Create an object with given value. - * - * @param value Value for this field, must not be null - * - * @return new object, will never be null - */ - public static BooleanFormField create(final Boolean value) { - if (value == null) { - throw new NullPointerException("'value' must not be null"); - } - - return new BooleanFormField(value); - } - - /** - * Create an object with value FALSE. - * - * @return new object, will never be null - */ - public static BooleanFormField create() { - return new BooleanFormField(Boolean.FALSE); - } + public Type getType() { + return type_; } - + /** - * This field is intended for data description (e.g., human-readable text - * such as "section" headers) rather than data gathering or provision. + * Sets the type of the FormField. + * @param type Type, never null */ - public static class FixedFormField extends GenericFormField<String> { - private FixedFormField(String value) { - super(value); - } - - /** - * Create an object with given value. - * - * @param value Value for this field, must not be null - * - * @return new object, will never be null - */ - public static FixedFormField create(final String value) { - if (value == null) { - throw new NullPointerException("'value' must not be null"); - } - - return new FixedFormField(value); - } - - /** - * Create an object with value as an empty string. - * - * @return new object, will never be null - */ - public static FixedFormField create() { - return new FixedFormField(""); - } + public void setType(Type type) { + type_ = type; } - + /** - * This field is not shown to the form-submitting entity, but instead is - * returned with the form. + * Returns the value of a FormField with the type boolean. + * @return value boolean, will return false if FormField has no values */ - public static class HiddenFormField extends GenericFormField<String> { - private HiddenFormField(String value) { - super(value); - } - - /** - * Create an object with given value. - * - * @param value Value for this field, must not be null - * - * @return new object, will never be null - */ - public static HiddenFormField create(final String value) { - if (value == null) { - throw new NullPointerException("'value' must not be null"); - } - - return new HiddenFormField(value); - } - - /** - * Create an object with value as an empty string. - * - * @return new object, will never be null - */ - public static HiddenFormField create() { - return new HiddenFormField(""); - } + public boolean getBoolValue() { + if (type_ != Type.BOOLEAN_TYPE) { + throw new IllegalArgumentException(ILLEGAL_ARG_EX_STR + type_); + } + return values_.isEmpty() ? false : values_.get(0).equals("true") || values_.get(0).equals("1"); } - + /** - * This field enables an entity to gather or provide one option from among - * many. + * Sets the value of a FormField with type boolean to a boolean value. + * @param bool boolean */ - public static class ListSingleFormField extends GenericFormField<String> { - private ListSingleFormField(String value) { - super(value); - } - - /** - * Create an object with given value. - * - * @param value Value for this field, must not be null - * - * @return new object, will never be null - */ - public static ListSingleFormField create(final String value) { - if (value == null) { - throw new NullPointerException("'value' must not be null"); - } - - return new ListSingleFormField(value); - } - - /** - * Create an object with value as an empty string. - * - * @return new object, will never be null - */ - public static ListSingleFormField create() { - return new ListSingleFormField(""); - } + public void setBoolValue(boolean bool) { + values_.clear(); + values_.add(bool ? "1" : "0"); } - + /** - * This field enables an entity to gather or provide multiple lines of text - * (i.e. containing newlines). + * Returns a JID single value. + * @return JID value, or empty JID is FormField has no values */ - public static class TextMultiFormField extends GenericFormField<String> { - private TextMultiFormField(String value) { - super(value); - } - - /** - * Create an object with given value. - * - * @param value Value for this field, must not be null - * - * @return new object, will never be null - */ - public static TextMultiFormField create(final String value) { - if (value == null) { - throw new NullPointerException("'value' must not be null"); - } - - return new TextMultiFormField(value); - } - - /** - * Create an object with value as an empty string. - * - * @return new object, will never be null - */ - public static TextMultiFormField create() { - return new TextMultiFormField(""); - } + public JID getJIDSingleValue() { + if (type_ != Type.JID_SINGLE_TYPE) { + throw new IllegalArgumentException(ILLEGAL_ARG_EX_STR + type_); + } + return values_.isEmpty() ? new JID() : JID.fromString(values_.get(0)); } /** - * This field enables an entity to gather or provide a single line or word - * of text, which shall be obscured in an interface (e.g., with multiple - * instances of the asterisk character). + * Gets the value at a specified index of a JID-multi FormField. + * @param index index of the JID value + * @return JID value, or empty JID is FormField has no values */ - public static class TextPrivateFormField extends GenericFormField<String> { - private TextPrivateFormField(String value) { - super(value); - } - - /** - * Create an object with given value. - * - * @param value Value for this field, must not be null - * - * @return new object, will never be null - */ - public static TextPrivateFormField create(final String value) { - if (value == null) { - throw new NullPointerException("'value' must not be null"); - } - - return new TextPrivateFormField(value); - } - - /** - * Create an object with value as an empty string. - * - * @return new object, will never be null - */ - public static TextPrivateFormField create() { - return new TextPrivateFormField(""); - } + public JID getJIDMultiValue(int index) { + if (type_ != Type.JID_MULTI_TYPE) { + throw new IllegalArgumentException(ILLEGAL_ARG_EX_STR + type_); + } + return values_.isEmpty() ? new JID() : JID.fromString(values_.get(index)); } /** - * This field enables an entity to gather or provide a single line or word - * of text, which may be shown in an interface. + * Gets the value of a FormField with the type text-private. + * @return value String, empty String if FormField has no values */ - public static class TextSingleFormField extends GenericFormField<String> { - private TextSingleFormField(String value) { - super(value); - } - - /** - * Create an object with given value. - * - * @param value Value for this field, must not be null - * - * @return new object, will never be null - */ - public static TextSingleFormField create(final String value) { - if (value == null) { - throw new NullPointerException("'value' must not be null"); - } - - return new TextSingleFormField(value); - } - - /** - * Create an object with value as an empty string. - * - * @return new object, will never be null - */ - public static TextSingleFormField create() { - return new TextSingleFormField(""); - } + public String getTextPrivateValue() { + if (type_ != Type.TEXT_PRIVATE_TYPE) { + throw new IllegalArgumentException(ILLEGAL_ARG_EX_STR + type_); + } + return values_.isEmpty() ? "" : values_.get(0); } /** - * This field enables an entity to gather or provide a single Jabber ID. + * Gets the value of a FormField with the type fixed. + * @return value String, or empty String if invalid FormField type */ - public static class JIDSingleFormField extends GenericFormField<JID> { - private JIDSingleFormField(JID value) { - super(value); - } - - /** - * Create an object with given value. - * - * @param value Value for this field, must not be null - * - * @return new object, will never be null - */ - public static JIDSingleFormField create(final JID value) { - if (value == null) { - throw new NullPointerException("'value' must not be null"); - } - - return new JIDSingleFormField(value); - } - - /** - * Create an object with value as an invalid JID. - * - * @return new object, will never be null - */ - public static JIDSingleFormField create() { - return new JIDSingleFormField(new JID()); - } + public String getFixedValue() { + if (type_ != Type.FIXED_TYPE) { + throw new IllegalArgumentException(ILLEGAL_ARG_EX_STR + type_); + } + return values_.isEmpty() ? "" : values_.get(0); } - + /** - * This field enables an entity to gather or provide multiple Jabber IDs. + * Gets the value of a FormField with the type text-single. + * If unknown type, extract a string value. + * @return value String, or empty String if invalid FormField type */ - public static class JIDMultiFormField extends GenericFormField<List<JID>> { - private JIDMultiFormField(List<JID> value) { - super(value); - } - - /** - * Create an object with given value. - * - * @param value Value for this field, must not be null. A copy of the - * given list will be kept by this object. - * - * @return new object, will never be null - */ - public static JIDMultiFormField create(final List<JID> value) { - if (value == null) { - throw new NullPointerException("'value' must not be null"); - } - - return new JIDMultiFormField(new ArrayList<JID>(value)); - } - - /** - * Create an object with an empty list. - * - * @return new object, will never be null - */ - public static JIDMultiFormField create() { - return new JIDMultiFormField(new ArrayList<JID>()); - } + public String getTextSingleValue() { + if (type_ != Type.TEXT_SINGLE_TYPE && type_ != Type.UNKNOWN_TYPE) { + throw new IllegalArgumentException(ILLEGAL_ARG_EX_STR + type_); + } + return values_.isEmpty() ? "" : values_.get(0); + } + + /** + * Gets the value of a FormField with the type text-multi. + * @return value String + */ + public String getTextMultiValue() { + if (type_ != Type.TEXT_MULTI_TYPE) { + throw new IllegalArgumentException(ILLEGAL_ARG_EX_STR + type_); + } + StringBuilder val = new StringBuilder(); + for (int i=0; i<values_.size(); i++) { + String s = values_.get(i); + if (i != 0) { + val.append("\n"); + } + val.append(s); + } + return val.toString(); } /** - * This field enables an entity to gather or provide one or more options - * from among many. The order of items MAY be significant. - */ - public static class ListMultiFormField extends - GenericFormField<List<String>> { - private ListMultiFormField(List<String> value) { - super(value); - } - - /** - * Create an object with given value. - * - * @param value Value for this field, must not be null. A copy of the - * given list will be kept by this object. - * - * @return new object, will never be null - */ - public static ListMultiFormField create(final List<String> value) { - if (value == null) { - throw new NullPointerException("'value' must not be null"); - } - - return new ListMultiFormField(new ArrayList<String>(value)); - } - - /** - * Create an object with an empty list. - * - * @return new object, will never be null - */ - public static ListMultiFormField create() { - return new ListMultiFormField(new ArrayList<String>()); - } + * Sets the value of a FormField with the type text-multi. + * @param val String value to set, must not be null + */ + public void setTextMultiValue(String val) { + if (type_ != Type.TEXT_MULTI_TYPE) { + throw new IllegalArgumentException(ILLEGAL_ARG_EX_STR + type_); + } + values_.clear(); + if (val.contains("\r\n")){ + for (String s : val.split("\r\n")) { + values_.add(s); + } + } + else if (val.contains("\n")){ + for (String s : val.split("\n")) { + values_.add(s); + } + } + else { + values_.add(val); + } } @Override public String toString() { - return FormField.class.getSimpleName() + "\nname: " + name - + "\nlabel: " + label + "\ndescription: " + description - + "\nrequired: " + required; + return FormField.class.getSimpleName() + "\nname: " + name_ + + "\nlabel: " + label_ + "\ndescription: " + description_ + + "\nrequired: " + required_; } } diff --git a/src/com/isode/stroke/elements/FormItem.java b/src/com/isode/stroke/elements/FormItem.java new file mode 100644 index 0000000..3081c87 --- /dev/null +++ b/src/com/isode/stroke/elements/FormItem.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014 Isode Limited, London, England. + * All rights reserved. + */ +package com.isode.stroke.elements; + +import java.util.ArrayList; +import java.util.List; + +/** + * Class representing a XEP-0004 data form <item/> element. + * @author tr + * + */ +public class FormItem { + + private List<FormField> itemFields_ = new ArrayList<FormField>(); + + public FormItem() {} + + /** + * Add a single FormField to this FormItem. + * @param itemField FormField, should not be null + */ + public void addItemField(FormField itemField) { + if (itemField == null) { + throw new NullPointerException("'itemField' must not be null"); + } + itemFields_.add(itemField); + } + + /** + * Add a list of FormFields to this FormItem. + * @param itemFields List<ForMField>, should not be null + */ + public void addItemFields(List<FormField> itemFields) { + if (itemFields == null) { + throw new NullPointerException("'itemFields' must not be null"); + } + itemFields_.addAll(itemFields); + } + + /** + * Returns a list of FormFields for this FormItem. + * @return List<FormField> list of item, never null + */ + public List<FormField> getItemFields() { + return new ArrayList<FormField>(itemFields_); + } +} diff --git a/src/com/isode/stroke/parser/payloadparsers/FormParser.java b/src/com/isode/stroke/parser/payloadparsers/FormParser.java index 86852e6..2aa398c 100644 --- a/src/com/isode/stroke/parser/payloadparsers/FormParser.java +++ b/src/com/isode/stroke/parser/payloadparsers/FormParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Isode Limited, London, England. + * Copyright (c) 2012-2014 Isode Limited, London, England. * All rights reserved. */ /* @@ -9,223 +9,46 @@ package com.isode.stroke.parser.payloadparsers; +import java.util.ArrayList; import java.util.List; import com.isode.stroke.elements.Form; -import com.isode.stroke.elements.FormField; import com.isode.stroke.elements.Form.Type; -import com.isode.stroke.elements.FormField.BooleanFormField; -import com.isode.stroke.elements.FormField.FixedFormField; -import com.isode.stroke.elements.FormField.GenericFormField; -import com.isode.stroke.elements.FormField.HiddenFormField; -import com.isode.stroke.elements.FormField.JIDMultiFormField; -import com.isode.stroke.elements.FormField.JIDSingleFormField; -import com.isode.stroke.elements.FormField.ListMultiFormField; -import com.isode.stroke.elements.FormField.ListSingleFormField; +import com.isode.stroke.elements.FormField; import com.isode.stroke.elements.FormField.Option; -import com.isode.stroke.elements.FormField.TextMultiFormField; -import com.isode.stroke.elements.FormField.TextPrivateFormField; -import com.isode.stroke.elements.FormField.TextSingleFormField; -import com.isode.stroke.jid.JID; +import com.isode.stroke.elements.FormItem; import com.isode.stroke.parser.AttributeMap; import com.isode.stroke.parser.GenericPayloadParser; -import java.util.ArrayList; /** * Parser for {@link Form} element. */ public class FormParser extends GenericPayloadParser<Form> { - private static abstract class FieldParseHelper<T> { - protected GenericFormField<T> field; - - public void addValue(String s) { - if (s == null) { - throw new NullPointerException("'s' must not be null"); - } - - field.addRawValue(s); - } - - public GenericFormField<T> getField() { - return field; - } - } - - private static class BoolFieldParseHelper extends FieldParseHelper<Boolean> { - public void addValue(String s) { - super.addValue(s); - field.setValue(((s.equals("1")) || (s.equals("true")))); - } - } - - private static class StringFieldParseHelper extends - FieldParseHelper<String> { - public void addValue(String s) { - super.addValue(s); - if (field.getValue().isEmpty()) { - field.setValue(s); - } else { - field.setValue(field.getValue() + "\n" + s); - } - } - }; - - private static class JIDFieldParseHelper extends FieldParseHelper<JID> { - public void addValue(String s) { - super.addValue(s); - field.setValue(new JID(s)); - } - }; - - private static class StringListFieldParseHelper extends - FieldParseHelper<List<String>> { - public void addValue(String s) { - super.addValue(s); - List<String> l = field.getValue(); - l.add(s); - field.setValue(l); - } - }; - - private static class JIDListFieldParseHelper extends - FieldParseHelper<List<JID>> { - public void addValue(String s) { - super.addValue(s); - List<JID> l = field.getValue(); - l.add(new JID(s)); - field.setValue(l); - } - }; - - private static class BooleanFormFieldParseHelper extends - BoolFieldParseHelper { - public BooleanFormFieldParseHelper() { - field = BooleanFormField.create(); - } - - public static BooleanFormFieldParseHelper create() { - return new BooleanFormFieldParseHelper(); - } - } - - private static class FixedFormFieldParseHelper extends - StringFieldParseHelper { - public FixedFormFieldParseHelper() { - field = FixedFormField.create(); - } - - public static FixedFormFieldParseHelper create() { - return new FixedFormFieldParseHelper(); - } - } - - private static class HiddenFormFieldParseHelper extends - StringFieldParseHelper { - public HiddenFormFieldParseHelper() { - field = HiddenFormField.create(); - } - - public static HiddenFormFieldParseHelper create() { - return new HiddenFormFieldParseHelper(); - } - } - - private static class ListSingleFormFieldParseHelper extends - StringFieldParseHelper { - public ListSingleFormFieldParseHelper() { - field = ListSingleFormField.create(); - } - - public static ListSingleFormFieldParseHelper create() { - return new ListSingleFormFieldParseHelper(); - } - } - - private static class TextMultiFormFieldParseHelper extends - StringFieldParseHelper { - public TextMultiFormFieldParseHelper() { - field = TextMultiFormField.create(); - } - - public static TextMultiFormFieldParseHelper create() { - return new TextMultiFormFieldParseHelper(); - } - } - - private static class TextPrivateFormFieldParseHelper extends - StringFieldParseHelper { - public TextPrivateFormFieldParseHelper() { - field = TextPrivateFormField.create(); - } - - public static TextPrivateFormFieldParseHelper create() { - return new TextPrivateFormFieldParseHelper(); - } - } - - private static class TextSingleFormFieldParseHelper extends - StringFieldParseHelper { - public TextSingleFormFieldParseHelper() { - field = TextSingleFormField.create(); - } - - public static TextSingleFormFieldParseHelper create() { - return new TextSingleFormFieldParseHelper(); - } - } - - private static class JIDSingleFormFieldParseHelper extends - JIDFieldParseHelper { - public JIDSingleFormFieldParseHelper() { - field = JIDSingleFormField.create(); - } - - public static JIDSingleFormFieldParseHelper create() { - return new JIDSingleFormFieldParseHelper(); - } - } - - private static class JIDMultiFormFieldParseHelper extends - JIDListFieldParseHelper { - public JIDMultiFormFieldParseHelper() { - field = JIDMultiFormField.create(); - } - - public static JIDMultiFormFieldParseHelper create() { - return new JIDMultiFormFieldParseHelper(); - } - } - - private static class ListMultiFormFieldParseHelper extends - StringListFieldParseHelper { - public ListMultiFormFieldParseHelper() { - field = ListMultiFormField.create(); - } - - public static ListMultiFormFieldParseHelper create() { - return new ListMultiFormFieldParseHelper(); - } - } - - private static final int TopLevel = 0; + + private List<FormField> currentFields_ = new ArrayList<FormField>(); + private FormField currentField_ = null; + private FormItem currentItem_ = null; + private boolean parsingReported_ = false; + private boolean parsingOption_ = false; + private String currentOptionValue_ = ""; + private String currentText_ = ""; + + private static final int TopLevel = 0; private static final int PayloadLevel = 1; private static final int FieldLevel = 2; private int level_; - //private String currentText_ = ""; - private ArrayList<String> texts_ = new ArrayList<String>(); private String currentOptionLabel_ = ""; - private FieldParseHelper<?> currentFieldParseHelper_ = null; /** * Constructor */ public FormParser() { super(new Form()); - level_ = TopLevel; } + @Override public void handleStartElement(String element, String ns, final AttributeMap attributes) { if (element == null) { @@ -237,80 +60,66 @@ public class FormParser extends GenericPayloadParser<Form> { if (attributes == null) { throw new NullPointerException("'attributes' must not be null"); } - Form form = getPayloadInternal(); if (level_ == TopLevel) { String type = attributes.getAttribute(Form.FORM_ATTRIBUTE_TYPE); form.setType(Type.getType(type)); - } else if (level_ == PayloadLevel) { + } + + else if (level_ == PayloadLevel) { if (element.equals(Form.FORM_ELEMENT_TITLE)) { - texts_ = new ArrayList(); - } else if (element.equals(Form.FORM_ELEMENT_INSTRUCTIONS)) { - texts_ = new ArrayList(); - } else if (element.equals(Form.FORM_ELEMENT_FIELD)) { - String type = attributes - .getAttribute(FormField.FORM_FIELD_ATTRIBUTE_TYPE); - if (type == null) { - type = ""; - } - if (type.equals(FormField.FORM_FIELD_TYPE_BOOLEAN)) { - currentFieldParseHelper_ = BooleanFormFieldParseHelper - .create(); - } else if (type.equals(FormField.FORM_FIELD_TYPE_FIXED)) { - currentFieldParseHelper_ = FixedFormFieldParseHelper - .create(); - } else if (type.equals(FormField.FORM_FIELD_TYPE_HIDDEN)) { - currentFieldParseHelper_ = HiddenFormFieldParseHelper - .create(); - } else if (type.equals(FormField.FORM_FIELD_TYPE_JID_MULTI)) { - currentFieldParseHelper_ = JIDMultiFormFieldParseHelper - .create(); - } else if (type.equals(FormField.FORM_FIELD_TYPE_JID_SINGLE)) { - currentFieldParseHelper_ = JIDSingleFormFieldParseHelper - .create(); - } else if (type.equals(FormField.FORM_FIELD_TYPE_LIST_MULTI)) { - currentFieldParseHelper_ = ListMultiFormFieldParseHelper - .create(); - } else if (type.equals(FormField.FORM_FIELD_TYPE_LIST_SINGLE)) { - currentFieldParseHelper_ = ListSingleFormFieldParseHelper - .create(); - } else if (type.equals(FormField.FORM_FIELD_TYPE_TEXT_MULTI)) { - currentFieldParseHelper_ = TextMultiFormFieldParseHelper - .create(); - } else if (type.equals(FormField.FORM_FIELD_TYPE_TEXT_PRIVATE)) { - currentFieldParseHelper_ = TextPrivateFormFieldParseHelper - .create(); - } else { - /* - * if (type == FormField.FORM_FIELD_TYPE_TEXT_SINGLE) || - * undefined - */ - currentFieldParseHelper_ = TextSingleFormFieldParseHelper - .create(); - } - - if (currentFieldParseHelper_ != null) { - String name = attributes - .getAttribute(FormField.FORM_FIELD_ATTRIBUTE_VAR); - currentFieldParseHelper_.getField().setName(name); - - String label = attributes - .getAttribute(FormField.FORM_FIELD_ATTRIBUTE_LABEL); - currentFieldParseHelper_.getField().setLabel(label); - } + currentText_ = ""; + } + + else if (element.equals(Form.FORM_ELEMENT_INSTRUCTIONS)) { + currentText_ = ""; + } + + else if (element.equals(Form.FORM_ELEMENT_REPORTED)) { + parsingReported_ = true; } - } else if ((level_ == FieldLevel) && (currentFieldParseHelper_ != null)) { - texts_ = new ArrayList(); + + else if (element.equals(Form.FORM_ELEMENT_ITEM)) { + currentItem_ = new FormItem(); + } + + } + + if (level_ == FieldLevel && currentField_ != null) { + currentText_ = ""; if (element.equals(FormField.FORM_FIELD_ELEMENT_OPTION)) { currentOptionLabel_ = attributes .getAttribute(FormField.FORM_FIELD_ATTRIBUTE_OPTION_LABEL); + currentOptionValue_ = ""; + parsingOption_ = true; } } - + + if (level_ >= PayloadLevel) { + if (element.equals(Form.FORM_ELEMENT_FIELD)) { + currentField_ = new FormField(FormField.Type.UNKNOWN_TYPE); + String type = attributes.getAttribute(FormField.FORM_FIELD_ATTRIBUTE_TYPE); + if (type == null) { + type = ""; + } + FormField.Type fieldType = FormField.Type.getTypeFromString(type); + String name = attributes.getAttribute(FormField.FORM_FIELD_ATTRIBUTE_VAR); + String label = attributes.getAttribute(FormField.FORM_FIELD_ATTRIBUTE_LABEL); + currentField_.setType(fieldType); + currentField_.setName(name); + currentField_.setLabel(label); + } + + else if (element.equals(FormField.FORM_FIELD_ELEMENT_VALUE)) { + currentText_ = ""; + } + } + ++level_; } - + + @Override public void handleEndElement(String element, String ns) { if (element == null) { throw new NullPointerException("'element' must not be null"); @@ -326,63 +135,80 @@ public class FormParser extends GenericPayloadParser<Form> { if (element.equals(Form.FORM_ELEMENT_TITLE)) { String currentTitle = form.getTitle(); if (currentTitle.isEmpty()) { - form.setTitle(getCurrentText()); + form.setTitle(currentText_); } else { - form.setTitle(currentTitle + "\n" + getCurrentText()); + form.setTitle(currentTitle + "\n" + currentText_); } - } else if (element.equals(Form.FORM_ELEMENT_INSTRUCTIONS)) { + } + + else if (element.equals(Form.FORM_ELEMENT_INSTRUCTIONS)) { String currentInstructions = form.getInstructions(); if (currentInstructions.isEmpty()) { - form.setInstructions(getCurrentText()); + form.setInstructions(currentText_); } else { form.setInstructions(currentInstructions + "\n" - + getCurrentText()); - } - } else if (element.equals(Form.FORM_ELEMENT_FIELD)) { - if (currentFieldParseHelper_ != null) { - form.addField(currentFieldParseHelper_.getField()); - currentFieldParseHelper_ = null; + + currentText_); } + } + + else if (element.equals(Form.FORM_ELEMENT_REPORTED)) { + parsingReported_ = false; } - } else if ((level_ == FieldLevel) && (currentFieldParseHelper_ != null)) { - if (element.equals(FormField.FORM_FIELD_ELEMENT_REQUIRED)) { - currentFieldParseHelper_.getField().setRequired(true); - } else if (element.equals(FormField.FORM_FIELD_ELEMENT_DESC)) { - currentFieldParseHelper_.getField() - .setDescription(getCurrentText()); - } else if (element.equals(FormField.FORM_FIELD_ELEMENT_OPTION)) { - currentFieldParseHelper_.getField().addOption( - new Option(currentOptionLabel_, getCurrentText())); - } else if (element.equals(FormField.FORM_FIELD_ELEMENT_VALUE)) { - currentFieldParseHelper_.addValue(getCurrentText()); + + else if (element.equals(Form.FORM_ELEMENT_ITEM)) { + currentItem_.addItemFields(currentFields_); + form.addItem(currentItem_); + currentFields_.clear(); + currentItem_ = null; } } - } - - private String getCurrentText() { - int size = 0; - for (String text : texts_) { - size += text.length(); - } - StringBuilder builder = new StringBuilder(size); - for (String text : texts_) { - builder.append(text); + + if (element.equals(FormField.FORM_FIELD_ELEMENT_REQUIRED)) { + currentField_.setRequired(true); + } + else if (element.equals(FormField.FORM_FIELD_ELEMENT_DESC)) { + currentField_.setDescription(currentText_); + } + else if (element.equals(FormField.FORM_FIELD_ELEMENT_OPTION)) { + currentField_.addOption( + new Option(currentOptionLabel_, currentOptionValue_)); + parsingOption_ = false; + } + else if (element.equals(FormField.FORM_FIELD_ELEMENT_VALUE)) { + if (parsingOption_) { + currentOptionValue_ = currentText_; + } + else { + currentField_.addValue(currentText_); + } + } + + if (level_ >= PayloadLevel && currentField_ != null) { + if (element.equals("field")) { + if (parsingReported_) { + form.addReportedField(currentField_); + } else if (currentItem_ != null) { + currentFields_.add(currentField_); + } else { + form.addField(currentField_); + } + currentField_ = null; + } } - return builder.toString(); } - + + @Override public void handleCharacterData(String text) { if (text == null) { throw new NullPointerException("'text' must not be null"); } - - texts_.add(text); + currentText_ += text; } @Override public String toString() { return FormParser.class.getSimpleName() + "\nlevel: " + level_ - + "\ncurrent text: " + getCurrentText() + + "\ncurrent text: " + currentText_ + "\ncurrent option label: " + currentOptionLabel_; } } diff --git a/src/com/isode/stroke/serializer/payloadserializers/FormSerializer.java b/src/com/isode/stroke/serializer/payloadserializers/FormSerializer.java index 9ab5e37..23160c6 100644 --- a/src/com/isode/stroke/serializer/payloadserializers/FormSerializer.java +++ b/src/com/isode/stroke/serializer/payloadserializers/FormSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Isode Limited, London, England. + * Copyright (c) 2012-2014 Isode Limited, London, England. * All rights reserved. */ /* @@ -9,23 +9,9 @@ package com.isode.stroke.serializer.payloadserializers; -import java.util.List; - import com.isode.stroke.elements.Form; import com.isode.stroke.elements.FormField; -import com.isode.stroke.elements.FormField.BooleanFormField; -import com.isode.stroke.elements.FormField.FixedFormField; -import com.isode.stroke.elements.FormField.GenericFormField; -import com.isode.stroke.elements.FormField.HiddenFormField; -import com.isode.stroke.elements.FormField.JIDMultiFormField; -import com.isode.stroke.elements.FormField.JIDSingleFormField; -import com.isode.stroke.elements.FormField.ListMultiFormField; -import com.isode.stroke.elements.FormField.ListSingleFormField; -import com.isode.stroke.elements.FormField.Option; -import com.isode.stroke.elements.FormField.TextMultiFormField; -import com.isode.stroke.elements.FormField.TextPrivateFormField; -import com.isode.stroke.elements.FormField.TextSingleFormField; -import com.isode.stroke.jid.JID; +import com.isode.stroke.elements.FormItem; import com.isode.stroke.serializer.GenericPayloadSerializer; import com.isode.stroke.serializer.xml.XMLElement; import com.isode.stroke.serializer.xml.XMLTextNode; @@ -34,9 +20,7 @@ import com.isode.stroke.serializer.xml.XMLTextNode; * Serializer for {@link Form} element. */ public class FormSerializer extends GenericPayloadSerializer<Form> { - /** - * Constructor - */ + public FormSerializer() { super(Form.class); } @@ -45,7 +29,7 @@ public class FormSerializer extends GenericPayloadSerializer<Form> { if (form == null) { throw new NullPointerException("'form' must not be null"); } - + XMLElement formElement = new XMLElement("x", "jabber:x:data"); String type = form.getType().getStringForm(); formElement.setAttribute(Form.FORM_ATTRIBUTE_TYPE, type); @@ -56,13 +40,35 @@ public class FormSerializer extends GenericPayloadSerializer<Form> { multiLineify(form.getInstructions(), Form.FORM_ELEMENT_INSTRUCTIONS, formElement); } + + // Add reported element + + if (!form.getReportedFields().isEmpty()) { + XMLElement reportedElement = new XMLElement("reported"); + for (FormField field : form.getReportedFields()) { + reportedElement.addNode(fieldToXML(field, true)); + } + formElement.addNode(reportedElement); + } + + // Add item elements + for (FormItem item : form.getItems()) { + XMLElement itemElement = new XMLElement("item"); + for (FormField ff : item.getItemFields()) { + itemElement.addNode(fieldToXML(ff, false)); + } + formElement.addNode(itemElement); + } + + // Add fields for (FormField field : form.getFields()) { - formElement.addNode(fieldToXML(field)); + formElement.addNode(fieldToXML(field, true)); } + return formElement.serialize(); } - - private XMLElement fieldToXML(FormField field) { + + private XMLElement fieldToXML(FormField field, boolean withTypeAttribute) { if (field == null) { throw new NullPointerException("'field' must not be null"); } @@ -86,87 +92,87 @@ public class FormSerializer extends GenericPayloadSerializer<Form> { descriptionElement.addNode(new XMLTextNode(field.getDescription())); fieldElement.addNode(descriptionElement); } - - // Set the value and type - String fieldType = ""; - if (field instanceof BooleanFormField) { - fieldType = FormField.FORM_FIELD_TYPE_BOOLEAN; - XMLElement valueElement = new XMLElement( - FormField.FORM_FIELD_ELEMENT_VALUE); - valueElement.addNode(XMLTextNode.create(((BooleanFormField) field) - .getValue() ? "1" : "0")); - fieldElement.addNode(valueElement); - } else if (field instanceof FixedFormField) { - fieldType = FormField.FORM_FIELD_TYPE_FIXED; - serializeValueAsString((FixedFormField) field, fieldElement); - } else if (field instanceof HiddenFormField) { - fieldType = FormField.FORM_FIELD_TYPE_HIDDEN; - serializeValueAsString((HiddenFormField) field, fieldElement); - } else if (field instanceof ListSingleFormField) { - fieldType = FormField.FORM_FIELD_TYPE_LIST_SINGLE; - serializeValueAsString((ListSingleFormField) field, fieldElement); - } else if (field instanceof TextPrivateFormField) { - fieldType = FormField.FORM_FIELD_TYPE_TEXT_PRIVATE; - serializeValueAsString((TextPrivateFormField) field, fieldElement); - } else if (field instanceof TextSingleFormField) { - fieldType = FormField.FORM_FIELD_TYPE_TEXT_SINGLE; - serializeValueAsString((TextSingleFormField) field, fieldElement); - } else if (field instanceof JIDMultiFormField) { - fieldType = FormField.FORM_FIELD_TYPE_JID_MULTI; - List<JID> jids = ((JIDMultiFormField) (field)).getValue(); - for (JID jid : jids) { - XMLElement valueElement = new XMLElement( - FormField.FORM_FIELD_ELEMENT_VALUE); - valueElement.addNode(XMLTextNode.create(jid.toString())); - fieldElement.addNode(valueElement); - } - } else if (field instanceof JIDSingleFormField) { - fieldType = FormField.FORM_FIELD_TYPE_JID_SINGLE; - XMLElement valueElement = new XMLElement( - FormField.FORM_FIELD_ELEMENT_VALUE); - JIDSingleFormField jidSingleFormField = (JIDSingleFormField) field; - valueElement.addNode(XMLTextNode.create(jidSingleFormField - .getValue().toString())); - fieldElement.addNode(valueElement); - } else if (field instanceof ListMultiFormField) { - fieldType = FormField.FORM_FIELD_TYPE_LIST_MULTI; - List<String> lines = ((ListMultiFormField) (field)).getValue(); - for (String line : lines) { - XMLElement valueElement = new XMLElement( - FormField.FORM_FIELD_ELEMENT_VALUE); - valueElement.addNode(XMLTextNode.create(line)); - fieldElement.addNode(valueElement); - } - } else if (field instanceof TextMultiFormField) { - fieldType = FormField.FORM_FIELD_TYPE_TEXT_MULTI; - multiLineify(((TextMultiFormField) field).getValue(), + + String fieldType = field.getType().getDescription(); + + if (!fieldType.isEmpty() && withTypeAttribute) { + fieldElement.setAttribute("type", fieldType); + } + + if (fieldType.equals("boolean")) { + XMLElement valueElement = new XMLElement("value"); + if (field.getBoolValue() == true) { + valueElement.addNode(XMLTextNode.create("1")); + } else { + valueElement.addNode(XMLTextNode.create("0")); + } + fieldElement.addNode(valueElement); + } + + else if (fieldType.equals("jid-single")) { + XMLElement valueElement = new XMLElement("value"); + valueElement.addNode(XMLTextNode.create(field.getJIDSingleValue().toString())); + fieldElement.addNode(valueElement); + } + + else if (fieldType.equals("jid-multi")) { + for (String jid : field.getValues()){ + XMLElement valueElement = new XMLElement("value"); + valueElement.addNode(XMLTextNode.create(jid)); + fieldElement.addNode(valueElement); + } + } + + else if (fieldType.equals("text-private")) { + XMLElement valueElement = new XMLElement("value"); + valueElement.addNode(XMLTextNode.create(field.getTextPrivateValue())); + fieldElement.addNode(valueElement); + } + + else if (fieldType.equals("fixed")) { + XMLElement valueElement = new XMLElement("value"); + valueElement.addNode(XMLTextNode.create(field.getFixedValue())); + fieldElement.addNode(valueElement); + } + + else if (fieldType.equals("text-single") || + fieldType.equals("unknown")) { + XMLElement valueElement = new XMLElement("value"); + valueElement.addNode(XMLTextNode.create(field.getTextSingleValue())); + fieldElement.addNode(valueElement); + } + + else if (fieldType.equals("text-multi")) { + multiLineify(field.getTextMultiValue(), FormField.FORM_FIELD_ELEMENT_VALUE, fieldElement); - } else { - assert (false); + } + + else if (fieldType.equals("list-multi") || + fieldType.equals("list-single")) { + for (String s : field.getValues()) { + XMLElement valueElement = new XMLElement("value"); + valueElement.addNode(XMLTextNode.create(s)); + fieldElement.addNode(valueElement); + } } - - if (!fieldType.isEmpty()) { - fieldElement.setAttribute(FormField.FORM_FIELD_ATTRIBUTE_TYPE, - fieldType); + + else { // Unknown type + XMLElement valueElement = new XMLElement("value"); + valueElement.addNode(XMLTextNode.create(field.getValues().get(0))); + fieldElement.addNode(valueElement); } - - for (Option option : field.getOptions()) { - XMLElement optionElement = new XMLElement( - FormField.FORM_FIELD_ELEMENT_OPTION); - if (!option.label.isEmpty()) { - optionElement.setAttribute( - FormField.FORM_FIELD_ATTRIBUTE_OPTION_LABEL, - option.label); - } - - XMLElement valueElement = new XMLElement( - FormField.FORM_FIELD_ELEMENT_OPTION_VALUE); - valueElement.addNode(XMLTextNode.create(option.value)); - optionElement.addNode(valueElement); - - fieldElement.addNode(optionElement); + + for (FormField.Option option : field.getOptions()) { + XMLElement optionElement = new XMLElement("option"); + if (!option.label_.isEmpty()) { + optionElement.setAttribute("label", option.label_); + } + XMLElement valueElement = new XMLElement("value"); + valueElement.addNode(XMLTextNode.create(option.value_)); + optionElement.addNode(valueElement); + fieldElement.addNode(optionElement); } - + return fieldElement; } @@ -188,17 +194,6 @@ public class FormSerializer extends GenericPayloadSerializer<Form> { } } - private static void serializeValueAsString(GenericFormField<String> field, - XMLElement parent) { - String value = field.getValue(); - // FIXME with the proper fix after Swiften is fixed: if (!value.isEmpty()) { - XMLElement valueElement = new XMLElement( - FormField.FORM_FIELD_ELEMENT_VALUE); - valueElement.addNode(XMLTextNode.create(value)); - parent.addNode(valueElement); - // } - } - @Override public String toString() { return FormSerializer.class.getSimpleName(); diff --git a/test/com/isode/stroke/elements/FormTest.java b/test/com/isode/stroke/elements/FormTest.java index 1d37c86..f270976 100644 --- a/test/com/isode/stroke/elements/FormTest.java +++ b/test/com/isode/stroke/elements/FormTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Isode Limited, London, England. + * Copyright (c) 2012-2014 Isode Limited, London, England. * All rights reserved. */ /* @@ -14,8 +14,7 @@ import static org.junit.Assert.assertEquals; import org.junit.BeforeClass; import org.junit.Test; -import com.isode.stroke.elements.FormField.FixedFormField; -import com.isode.stroke.elements.FormField.HiddenFormField; +import com.isode.stroke.elements.FormField.Type; public class FormTest { @BeforeClass @@ -26,13 +25,13 @@ public class FormTest { public void testGetFormType() { Form form = new Form(); - form.addField(FixedFormField.create("Foo")); + form.addField(new FormField(Type.FIXED_TYPE, "Foo")); - FormField field = HiddenFormField.create("jabber:bot"); + FormField field = new FormField(Type.HIDDEN_TYPE, "jabber:bot"); field.setName("FORM_TYPE"); form.addField(field); - form.addField(FixedFormField.create("Bar")); + form.addField(new FormField(Type.FIXED_TYPE, "Bar")); assertEquals("jabber:bot", form.getFormType()); } @@ -41,7 +40,7 @@ public class FormTest { public void testGetFormType_InvalidFormType() { Form form = new Form(); - FormField field = FixedFormField.create("jabber:bot"); + FormField field = new FormField(Type.FIXED_TYPE, "jabber:bot"); field.setName("FORM_TYPE"); form.addField(field); @@ -52,7 +51,7 @@ public class FormTest { public void testGetFormType_NoFormType() { Form form = new Form(); - form.addField(FixedFormField.create("Foo")); + form.addField(new FormField(Type.FIXED_TYPE, "Foo")); assertEquals("", form.getFormType()); } diff --git a/test/com/isode/stroke/parser/payloadparsers/FormParserTest.java b/test/com/isode/stroke/parser/payloadparsers/FormParserTest.java index 5dace99..4ab8190 100644 --- a/test/com/isode/stroke/parser/payloadparsers/FormParserTest.java +++ b/test/com/isode/stroke/parser/payloadparsers/FormParserTest.java @@ -1,12 +1,11 @@ /* - * Copyright (c) 2012 Isode Limited, London, England. + * Copyright (c) 2012-2014 Isode Limited, London, England. * All rights reserved. */ /* * Copyright (c) 2010 Remko Tronçon * All rights reserved. */ - package com.isode.stroke.parser.payloadparsers; import static org.junit.Assert.assertEquals; @@ -16,16 +15,8 @@ import org.junit.BeforeClass; import org.junit.Test; import com.isode.stroke.elements.Form; -import com.isode.stroke.elements.Payload; import com.isode.stroke.elements.Form.Type; -import com.isode.stroke.elements.FormField.BooleanFormField; -import com.isode.stroke.elements.FormField.FixedFormField; -import com.isode.stroke.elements.FormField.HiddenFormField; -import com.isode.stroke.elements.FormField.JIDMultiFormField; -import com.isode.stroke.elements.FormField.ListMultiFormField; -import com.isode.stroke.elements.FormField.ListSingleFormField; -import com.isode.stroke.elements.FormField.TextMultiFormField; -import com.isode.stroke.elements.FormField.TextSingleFormField; +import com.isode.stroke.elements.Payload; import com.isode.stroke.eventloop.DummyEventLoop; import com.isode.stroke.jid.JID; @@ -73,6 +64,16 @@ public class FormParserTest { + "<field type=\"hidden\" var=\"FORM_TYPE\">" + "<value>jabber:bot</value>" + "</field>" + + "<reported>" + + "<field var=\"field name\" label=\"description\" type=\"unknown\">" + + "<value>someText</value>" + + "</field>" + + "</reported>" + + "<item>" + + "<field label=\"itemField\">" + + "<value>itemValue</value>" + + "</field>" + + "</item>" + "<field type=\"fixed\"><value>Section 1: Bot Info</value></field>" + "<field label=\"The name of your bot\" type=\"text-single\" var=\"botname\"/>" + "<field label=\"Helpful description of your bot\" type=\"text-multi\" var=\"description\"><value>This is a bot.</value><value>A quite good one actually</value></field>" @@ -103,57 +104,57 @@ public class FormParserTest { + "<desc>Tell all your friends about your new bot!</desc>" + "<value>foo@bar.com</value>" + "<value>baz@fum.org</value>" + "</field>" + "<field var=\"untyped\">" + "<value>foo</value>" - + "</field>" + "</x>"); + + "</field>" + + "</x>"); + + assertEquals(10, payload.getFields().size()); - assertEquals("jabber:bot", ((HiddenFormField) (payload.getFields() - .get(0))).getValue()); + + assertEquals("jabber:bot", payload.getFields().get(0).getValues().get(0)); + assertEquals("FORM_TYPE", payload.getFields().get(0).getName()); assertTrue(!payload.getFields().get(0).getRequired()); + + assertEquals("description", payload.getReportedFields().get(0).getLabel()); + assertEquals("someText", payload.getReportedFields().get(0).getValues().get(0)); + assertEquals("itemField", payload.getItems().get(0).getItemFields().get(0).getLabel()); + assertEquals("itemValue", payload.getItems().get(0).getItemFields().get(0).getValues().get(0)); - assertEquals("Section 1: Bot Info", ((FixedFormField) (payload - .getFields().get(1))).getValue()); + assertEquals("Section 1: Bot Info", payload.getFields().get(1).getValues().get(0)); assertEquals("The name of your bot", payload.getFields().get(2) .getLabel()); assertEquals("This is a bot.\nA quite good one actually", - ((TextMultiFormField) (payload.getFields().get(3))).getValue()); + payload.getFields().get(3).getTextMultiValue()); - assertEquals(Boolean.TRUE, ((BooleanFormField) (payload.getFields() - .get(4))).getValue()); + assertEquals(Boolean.TRUE, payload.getFields() + .get(4).getBoolValue()); assertTrue(payload.getFields().get(4).getRequired()); - assertEquals("1", ((BooleanFormField) (payload.getFields().get(4))) - .getRawValues().get(0)); + assertEquals("1", payload.getFields().get(4).getValues().get(0)); - assertEquals("news", - ((ListMultiFormField) (payload.getFields().get(6))).getValue() - .get(0)); - assertEquals("news", payload.getFields().get(6).getRawValues().get(0)); - assertEquals("search", ((ListMultiFormField) (payload.getFields() - .get(6))).getValue().get(1)); - assertEquals("search", payload.getFields().get(6).getRawValues().get(1)); + assertEquals("news", payload.getFields().get(6).getValues().get(0)); + assertEquals("search", payload.getFields().get(6).getValues().get(1)); assertEquals(5, payload.getFields().get(6).getOptions().size()); assertEquals("Contests", - payload.getFields().get(6).getOptions().get(0).label); + payload.getFields().get(6).getOptions().get(0).label_); assertEquals("contests", - payload.getFields().get(6).getOptions().get(0).value); + payload.getFields().get(6).getOptions().get(0).value_); assertEquals("News", - payload.getFields().get(6).getOptions().get(1).label); + payload.getFields().get(6).getOptions().get(1).label_); assertEquals("news", - payload.getFields().get(6).getOptions().get(1).value); + payload.getFields().get(6).getOptions().get(1).value_); - assertEquals("20", ((ListSingleFormField) (payload.getFields().get(7))) - .getValue()); + assertEquals("20", payload.getFields().get(7).getValues().get(0)); - assertEquals(new JID("foo@bar.com"), ((JIDMultiFormField) (payload - .getFields().get(8))).getValue().get(0)); - assertEquals(new JID("baz@fum.org"), ((JIDMultiFormField) (payload - .getFields().get(8))).getValue().get(1)); + assertEquals(new JID("foo@bar.com"), payload + .getFields().get(8).getJIDMultiValue(0)); + assertEquals(new JID("baz@fum.org"), payload + .getFields().get(8).getJIDMultiValue(1)); assertEquals("Tell all your friends about your new bot!", payload .getFields().get(8).getDescription()); - assertEquals("foo", - ((TextSingleFormField) (payload.getFields().get(9))).getValue()); + assertEquals("foo", payload.getFields().get(9).getValues().get(0)); } }
\ No newline at end of file diff --git a/test/com/isode/stroke/parser/payloadparsers/MAMQueryParserTest.java b/test/com/isode/stroke/parser/payloadparsers/MAMQueryParserTest.java index c98562f..1cd09d1 100644 --- a/test/com/isode/stroke/parser/payloadparsers/MAMQueryParserTest.java +++ b/test/com/isode/stroke/parser/payloadparsers/MAMQueryParserTest.java @@ -45,12 +45,13 @@ public class MAMQueryParserTest { assertEquals("id0", payload.getQueryID()); assertTrue(payload.getForm() != null); - FormField.TextSingleFormField fieldType = (FormField.TextSingleFormField)payload.getForm().getField("FORM_TYPE"); + + FormField fieldType = payload.getForm().getField("FORM_TYPE"); assertTrue(fieldType != null); - assertEquals("urn:xmpp:mam:0", fieldType.getValue()); - FormField.TextSingleFormField fieldStart = (FormField.TextSingleFormField)payload.getForm().getField("start"); + assertEquals("urn:xmpp:mam:0", fieldType.getTextSingleValue()); + FormField fieldStart = payload.getForm().getField("start"); assertTrue(fieldStart != null); - assertEquals("2010-08-07T00:00:00Z", fieldStart.getValue()); + assertEquals("2010-08-07T00:00:00Z", fieldStart.getTextSingleValue()); assertTrue(payload.getResultSet() != null); ResultSet resultSet = payload.getResultSet(); diff --git a/test/com/isode/stroke/pubsub/PubSubTools.java b/test/com/isode/stroke/pubsub/PubSubTools.java index 17d0896..2af92bf 100644 --- a/test/com/isode/stroke/pubsub/PubSubTools.java +++ b/test/com/isode/stroke/pubsub/PubSubTools.java @@ -14,8 +14,7 @@ import com.isode.stroke.elements.DiscoItems; import com.isode.stroke.elements.ErrorPayload; import com.isode.stroke.elements.Form; import com.isode.stroke.elements.FormField; -import com.isode.stroke.elements.FormField.BooleanFormField; -import com.isode.stroke.elements.FormField.ListSingleFormField; +import com.isode.stroke.elements.FormField.Type; import com.isode.stroke.elements.IQ; import com.isode.stroke.elements.Payload; import com.isode.stroke.elements.PubSub; @@ -35,7 +34,6 @@ import com.isode.stroke.elements.PubSubPublish; import com.isode.stroke.elements.PubSubRetract; import com.isode.stroke.elements.PubSubSubscribe; import com.isode.stroke.elements.PubSubSubscriptions; -import com.isode.stroke.elements.FormField.TextSingleFormField; import com.isode.stroke.elements.PubSubUnsubscribe; import com.isode.stroke.jid.JID; import com.isode.stroke.queries.GenericRequest; @@ -189,15 +187,15 @@ public class PubSubTools { Form form = config.getData(); for (FormField field : form.getFields()) { if (field.getName().equals(parameter)) { - if (field instanceof TextSingleFormField) { /* find and update the specified parameter */ - TextSingleFormField fieldText = (TextSingleFormField)field; - fieldText.setValue(newValue); - } else if (field instanceof ListSingleFormField) { - ListSingleFormField fieldList = (ListSingleFormField)field; - fieldList.setValue(newValue); - } else if (field instanceof BooleanFormField) { - BooleanFormField fieldBoolean = (BooleanFormField)field; - fieldBoolean.setValue(newValue.equals("1")); + if (field.getType() == Type.TEXT_SINGLE_TYPE) { /* find and update the specified parameter */ + FormField fieldText = field; + fieldText.addValue(newValue); + } else if (field.getType() == Type.LIST_SINGLE_TYPE) { + FormField fieldList = field; + fieldList.addValue(newValue); + } else if (field.getType() == Type.BOOLEAN_TYPE) { + FormField fieldBoolean = field; + fieldBoolean.setBoolValue(newValue.equals("1")); } } } diff --git a/test/com/isode/stroke/serializer/payloadserializers/FormSerializerTest.java b/test/com/isode/stroke/serializer/payloadserializers/FormSerializerTest.java index 7636eb4..7b16aa4 100644 --- a/test/com/isode/stroke/serializer/payloadserializers/FormSerializerTest.java +++ b/test/com/isode/stroke/serializer/payloadserializers/FormSerializerTest.java @@ -1,36 +1,23 @@ /* - * Copyright (c) 2012 Isode Limited, London, England. + * Copyright (c) 2012-2014 Isode Limited, London, England. * All rights reserved. */ /* * Copyright (c) 2010 Remko Tronçon * All rights reserved. */ - package com.isode.stroke.serializer.payloadserializers; import static org.junit.Assert.assertEquals; -import java.util.ArrayList; -import java.util.List; - import org.junit.BeforeClass; import org.junit.Test; import com.isode.stroke.elements.Form; -import com.isode.stroke.elements.FormField; import com.isode.stroke.elements.Form.Type; -import com.isode.stroke.elements.FormField.BooleanFormField; -import com.isode.stroke.elements.FormField.FixedFormField; -import com.isode.stroke.elements.FormField.HiddenFormField; -import com.isode.stroke.elements.FormField.JIDMultiFormField; -import com.isode.stroke.elements.FormField.ListMultiFormField; -import com.isode.stroke.elements.FormField.ListSingleFormField; +import com.isode.stroke.elements.FormField; import com.isode.stroke.elements.FormField.Option; -import com.isode.stroke.elements.FormField.TextMultiFormField; -import com.isode.stroke.elements.FormField.TextPrivateFormField; -import com.isode.stroke.elements.FormField.TextSingleFormField; -import com.isode.stroke.jid.JID; +import com.isode.stroke.elements.FormItem; public class FormSerializerTest { @BeforeClass @@ -58,38 +45,51 @@ public class FormSerializerTest { FormSerializer testling = new FormSerializer(); Form form = new Form(Type.FORM_TYPE); - FormField field = HiddenFormField.create("jabber:bot"); + FormField field = new FormField(FormField.Type.UNKNOWN_TYPE); + field.setName("field name"); + field.setLabel("description"); + field.addValue("someText"); + form.addReportedField(field); + + FormItem item = new FormItem(); + field = new FormField(FormField.Type.UNKNOWN_TYPE); + field.setName("itemField"); + field.addValue("itemValue"); + item.addItemField(field); + form.addItem(item); + + field = new FormField(FormField.Type.HIDDEN_TYPE, "jabber:bot"); field.setName("FORM_TYPE"); form.addField(field); + + form.addField(new FormField(FormField.Type.FIXED_TYPE, "Section 1: Bot Info")); - form.addField(FixedFormField.create("Section 1: Bot Info")); - - field = TextSingleFormField.create(); + field = new FormField(FormField.Type.TEXT_SINGLE_TYPE); field.setName("botname"); field.setLabel("The name of your bot"); form.addField(field); - field = TextMultiFormField - .create("This is a bot.\nA quite good one actually"); + field = new FormField(FormField.Type.TEXT_MULTI_TYPE, + "This is a bot.\nA quite good one actually"); field.setName("description"); field.setLabel("Helpful description of your bot"); form.addField(field); - field = BooleanFormField.create(true); + field = new FormField(FormField.Type.BOOLEAN_TYPE); + field.setBoolValue(true); field.setName("public"); field.setLabel("Public bot?"); field.setRequired(true); form.addField(field); - field = TextPrivateFormField.create(); + field = new FormField(FormField.Type.TEXT_PRIVATE_TYPE); field.setName("password"); field.setLabel("Password for special access"); form.addField(field); - List<String> values = new ArrayList<String>(); - values.add("news"); - values.add("search"); - field = ListMultiFormField.create(values); + field = new FormField(FormField.Type.LIST_MULTI_TYPE); + field.addValue("news"); + field.addValue("search"); field.setName("features"); field.setLabel("What features will the bot support?"); field.addOption(new Option("Contests", "contests")); @@ -99,7 +99,7 @@ public class FormSerializerTest { field.addOption(new Option("Search", "search")); form.addField(field); - field = ListSingleFormField.create("20"); + field = new FormField(FormField.Type.LIST_SINGLE_TYPE, "20"); field.setName("maxsubs"); field.setLabel("Maximum number of subscribers"); field.addOption(new Option("10", "10")); @@ -109,11 +109,18 @@ public class FormSerializerTest { field.addOption(new Option("100", "100")); field.addOption(new Option("", "none")); form.addField(field); + + String jid = "user@example.com"; + field = new FormField(FormField.Type.JID_SINGLE_TYPE); + field.addValue(jid); + field.setName("jidSingle"); + field.setLabel("jidSingleLabel"); + field.setDescription("jidSingleDescription"); + form.addField(field); - List<JID> jids = new ArrayList<JID>(); - jids.add(new JID("foo@bar.com")); - jids.add(new JID("baz@fum.org")); - field = JIDMultiFormField.create(jids); + field = new FormField(FormField.Type.JID_MULTI_TYPE); + field.addValue("foo@bar.com"); + field.addValue("baz@fum.org"); field.setName("invitelist"); field.setLabel("People to invite"); field.setDescription("Tell all your friends about your new bot!"); @@ -121,6 +128,16 @@ public class FormSerializerTest { assertEquals( "<x type=\"form\" xmlns=\"jabber:x:data\">" + + "<reported>" + + "<field label=\"description\" type=\"unknown\" var=\"field name\">" + + "<value>someText</value>" + + "</field>" + + "</reported>" + + "<item>" + + "<field var=\"itemField\">" + + "<value>itemValue</value>" + + "</field>" + + "</item>" + "<field type=\"hidden\" var=\"FORM_TYPE\">" + "<value>jabber:bot</value>" + "</field>" @@ -150,10 +167,36 @@ public class FormSerializerTest { + "<option label=\"100\"><value>100</value></option>" + "<option><value>none</value></option>" + "</field>" + + "<field label=\"jidSingleLabel\" type=\"jid-single\" var=\"jidSingle\">" + + "<desc>jidSingleDescription</desc>" + + "<value>user@example.com</value>" + + "</field>" + "<field label=\"People to invite\" type=\"jid-multi\" var=\"invitelist\">" + "<desc>Tell all your friends about your new bot!</desc>" + "<value>foo@bar.com</value>" + "<value>baz@fum.org</value>" + "</field>" + "</x>", + + /* + + "<field label=\"booleanField\" type=\"boolean\"><value>0</value></field>" + + "<field label=\"fixedField\" type=\"fixed\"><value>Fixed></value></field>" + + "<field label=\"hiddenField\" type=\"hidden\"/>" + + "<field label=\"listSingleField\" type=\"list-single\">" + + "<option label=\"option1\"><value>listVal</value></option>" + + "<option label=\"option2\"><value>listVal</value></option>" + + "<option label=\"option3\"><value>listVal</value></option>" + + "</field>" + + "<field label=\"listMultiField\" type=\"list-multi\">" + + "<option label=\"option1\"><value>listVal</value></option>" + + "<option label=\"option1\"><value>listVal</value></option>" + + "<option label=\"option1\"><value>listVal</value></option>" + + "</field>" + + "<field label=\"textPrivateField\" type=\"text-private\"><value>textPrivateVal</value></field>" + + "<field label=\"textMultiField\" type=\"text-multi\">" + + "" + + "" + + "" + + "</field>" + */ testling.serialize(form)); } } diff --git a/test/com/isode/stroke/serializer/payloadserializers/MAMQuerySerializerTest.java b/test/com/isode/stroke/serializer/payloadserializers/MAMQuerySerializerTest.java index ab4a3fa..519b981 100644 --- a/test/com/isode/stroke/serializer/payloadserializers/MAMQuerySerializerTest.java +++ b/test/com/isode/stroke/serializer/payloadserializers/MAMQuerySerializerTest.java @@ -13,6 +13,7 @@ package com.isode.stroke.serializer.payloadserializers; import org.junit.Test; import com.isode.stroke.elements.Form; import com.isode.stroke.elements.FormField; +import com.isode.stroke.elements.FormField.Type; import com.isode.stroke.elements.MAMQuery; import com.isode.stroke.elements.ResultSet; import static org.junit.Assert.assertEquals; @@ -25,11 +26,11 @@ public class MAMQuerySerializerTest { Form parameters = new Form(); - FormField.TextSingleFormField fieldType = FormField.TextSingleFormField.create("urn:xmpp:mam:0"); + FormField fieldType = new FormField(Type.TEXT_SINGLE_TYPE, "urn:xmpp:mam:0"); fieldType.setName("FORM_TYPE"); parameters.addField(fieldType); - FormField.TextSingleFormField fieldStart = FormField.TextSingleFormField.create("2010-08-07T00:00:00Z"); + FormField fieldStart = new FormField(Type.TEXT_SINGLE_TYPE, "2010-08-07T00:00:00Z"); fieldStart.setName("start"); parameters.addField(fieldStart); |