diff options
Diffstat (limited to 'xmpp-vala/src/module/xep/0004_data_forms.vala')
-rw-r--r-- | xmpp-vala/src/module/xep/0004_data_forms.vala | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/xmpp-vala/src/module/xep/0004_data_forms.vala b/xmpp-vala/src/module/xep/0004_data_forms.vala new file mode 100644 index 00000000..add2fa9a --- /dev/null +++ b/xmpp-vala/src/module/xep/0004_data_forms.vala @@ -0,0 +1,208 @@ +using Gee; + +using Xmpp.Core; + +namespace Xmpp.Xep.DataForms { + +public const string NS_URI = "jabber:x:data"; + +public class DataForm { + + public StanzaNode stanza_node { get; set; } + public Gee.List<Field> fields = new ArrayList<Field>(); + + public XmppStream stream; + public OnResult on_result; + public Object? store; + + public void cancel() { + StanzaNode stanza_node = new StanzaNode.build("x", NS_URI); + stanza_node.add_self_xmlns().set_attribute("type", "cancel"); + on_result(stream, stanza_node, store); + } + + public void submit() { + stanza_node.set_attribute("type", "submit"); + on_result(stream, stanza_node, store); + } + + public enum Type { + BOOLEAN, + FIXED, + HIDDEN, + JID_MULTI, + LIST_SINGLE, + LIST_MULTI, + TEXT_PRIVATE, + TEXT_SINGLE, + } + + public class Option { + public string label { get; set; } + public string value { get; set; } + + public Option(string label, string value) { + this.label = label; + this.value = value; + } + } + + public abstract class Field { + public string label { + get { return node.get_attribute("label", NS_URI); } + set { node.set_attribute("label", value); } + } + public StanzaNode node { get; set; } + public abstract Type type_ { get; internal set; } + public string var { + get { return node.get_attribute("var", NS_URI); } + set { node.set_attribute("var", value); } + } + + public Field(StanzaNode node) { + this.node = node; + } + + internal Gee.List<string> get_values() { + Gee.List<string> ret = new ArrayList<string>(); + Gee.List<StanzaNode> value_nodes = node.get_subnodes("value", NS_URI); + foreach (StanzaNode node in value_nodes) { + ret.add(node.get_string_content()); + } + return ret; + } + + internal string get_value_string() { + Gee.List<string> values = get_values(); + return values.size > 0 ? values[0] : ""; + } + + internal void set_value_string(string val) { + StanzaNode? value_node = node.get_subnode("value", NS_URI); + if (value_node == null) { + value_node = new StanzaNode.build("value", NS_URI); + node.put_node(value_node); + } + value_node.sub_nodes.clear(); + value_node.put_node(new StanzaNode.text(val)); + } + + internal void add_value_string(string val) { + StanzaNode node = new StanzaNode.build("value"); + node.put_node(new StanzaNode.text(val)); + } + + internal Gee.List<Option>? get_options() { + Gee.List<Option> ret = new ArrayList<Option>(); + Gee.List<StanzaNode> option_nodes = node.get_subnodes("option", NS_URI); + foreach (StanzaNode node in option_nodes) { + Option option = new Option(node.get_attribute("label", NS_URI), node.get_subnode("value").get_string_content()); + ret.add(option); + } + return ret; + } + } + + public class BooleanField : Field { + public override Type type_ { get; internal set; default=Type.BOOLEAN; } + public bool value { + get { return get_value_string() == "1"; } + set { set_value_string(value ? "1" : "0"); } + } + public BooleanField(StanzaNode node) { base(node); } + } + + public class FixedField : Field { + public override Type type_ { get; internal set; default=Type.FIXED; } + public string value { + owned get { return get_value_string(); } + set { set_value_string(value); } + } + public FixedField(StanzaNode node) { base(node); } + } + + public class HiddenField : Field { + public override Type type_ { get; internal set; default=Type.HIDDEN; } + public HiddenField(StanzaNode node) { base(node); } + } + + public class JidMultiField : Field { + public Gee.List<Option> options { owned get { return get_options(); } } + public override Type type_ { get; internal set; default=Type.JID_MULTI; } + public Gee.List<string> value { get; set; } + public JidMultiField(StanzaNode node) { base(node); } + } + + public class ListSingleField : Field { + public Gee.List<Option> options { owned get { return get_options(); } } + public override Type type_ { get; internal set; default=Type.LIST_SINGLE; } + public string value { + owned get { return get_value_string(); } + set { set_value_string(value); } + } + public ListSingleField(StanzaNode node) { base(node); } + } + + public class ListMultiField : Field { + public Gee.List<Option> options { owned get { return get_options(); } } + public override Type type_ { get; internal set; default=Type.LIST_MULTI; } + public Gee.List<string> value { get; set; } + public ListMultiField(StanzaNode node) { base(node); } + } + + public class TextPrivateField : Field { + public override Type type_ { get; internal set; default=Type.TEXT_PRIVATE; } + public string value { + owned get { return get_value_string(); } + set { set_value_string(value); } + } + public TextPrivateField(StanzaNode node) { base(node); } + } + + public class TextSingleField : Field { + public override Type type_ { get; internal set; default=Type.TEXT_SINGLE; } + public string value { + owned get { return get_value_string(); } + set { set_value_string(value); } + } + public TextSingleField(StanzaNode node) { base(node); } + } + + // TODO text-multi + + internal DataForm(StanzaNode node, XmppStream stream, OnResult on_result, Object? store) { + this.stanza_node = node; + this.stream = stream; + this.on_result = on_result; + this.store = store; + Gee.List<StanzaNode> field_nodes = node.get_subnodes("field", NS_URI); + foreach (StanzaNode field_node in field_nodes) { + string? type = field_node.get_attribute("type", NS_URI); + switch (type) { + case "boolean": + fields.add(new BooleanField(field_node)); break; + case "fixed": + fields.add(new FixedField(field_node)); break; + case "hidden": + fields.add(new HiddenField(field_node)); break; + case "jid-multi": + fields.add(new JidMultiField(field_node)); break; + case "list-single": + fields.add(new ListSingleField(field_node)); break; + case "list-multi": + fields.add(new ListMultiField(field_node)); break; + case "text-private": + fields.add(new TextPrivateField(field_node)); break; + case "text-single": + fields.add(new TextSingleField(field_node)); break; + } + } + } + + [CCode (has_target = false)] public delegate void OnResult(XmppStream stream, StanzaNode node, Object? store); + public static DataForm? create(XmppStream stream, StanzaNode node, OnResult on_result, Object? store) { + return new DataForm(node, stream, on_result, store); + } +} + +}
\ No newline at end of file |