From 1e7c54dd456af2c6d44d21e91dcb0ec339ce35d3 Mon Sep 17 00:00:00 2001 From: Gergely Polonkai Date: Mon, 1 Feb 2016 17:16:51 +0100 Subject: [PATCH] Define MatrixEvent --- .gitignore | 1 + configure.ac | 4 + .../matrix-glib/matrix-glib-docs.xml | 1 + .../matrix-glib/matrix-glib-sections.txt | 31 ++ src/Makefile.am | 4 + src/Matrix-0.0.deps | 1 + src/matrix-event.vala | 278 ++++++++++++++++++ vala-globals.mk | 1 + 8 files changed, 321 insertions(+) create mode 100644 src/matrix-event.vala diff --git a/.gitignore b/.gitignore index 9cfa4bf..113eea2 100644 --- a/.gitignore +++ b/.gitignore @@ -66,3 +66,4 @@ Makefile.in /src/matrix-http-api.c /src/matrix-http-client.c /src/matrix-compacts.c +/src/matrix-event.c diff --git a/configure.ac b/configure.ac index c6803ec..8d7e350 100644 --- a/configure.ac +++ b/configure.ac @@ -90,6 +90,7 @@ AC_SUBST([MATRIX_GLIB_VERSION], matrix_glib_base_version) GLIB_REQUIRED=2.40.0 VALA_REQUIRED=0.30.0 LIBVALA_REQUIRED=0.30 +GEE_REQUIRED=0.10.5 GIO_REQUIRED=2.22 SOUP_REQUIRED=2.44.2 JSON_REQUIRED=0.16.2 @@ -102,6 +103,9 @@ PKG_CHECK_MODULES([GLIB], # Check for vala VALAC_CHECK +# Check for libgee +PKG_CHECK_MODULES([GEE], [gee-0.8 >= $GEE_REQUIRED]) + # Check for GIO PKG_CHECK_MODULES([GIO], [gio-2.0 >= $GIO_REQUIRED]) diff --git a/docs/reference/matrix-glib/matrix-glib-docs.xml b/docs/reference/matrix-glib/matrix-glib-docs.xml index b4884d1..fbb1ff6 100644 --- a/docs/reference/matrix-glib/matrix-glib-docs.xml +++ b/docs/reference/matrix-glib/matrix-glib-docs.xml @@ -19,6 +19,7 @@ Matrix Client + diff --git a/docs/reference/matrix-glib/matrix-glib-sections.txt b/docs/reference/matrix-glib/matrix-glib-sections.txt index ba61c43..ebc812c 100644 --- a/docs/reference/matrix-glib/matrix-glib-sections.txt +++ b/docs/reference/matrix-glib/matrix-glib-sections.txt @@ -1,3 +1,34 @@ +
+matrix-event +MatrixEvent +MatrixEventClass +matrix_event_register_type +matrix_event_unregister_type +matrix_event_new +matrix_event_get_event_type +matrix_event_set_room_id +matrix_event_get_room_id +matrix_event_set_origin_server_ts +matrix_event_get_origin_server_ts +matrix_event_set_sender +matrix_event_get_sender +matrix_event_set_unsigned_data +matrix_event_get_unsigned_data +matrix_event_set_custom_field +matrix_event_get_custom_field +matrix_event_delete_custom_field +matrix_event_to_json + +MatrixEvent +MATRIX_EVENT +MATRIX_EVENT_CLASS +MATRIX_IS_EVENT +MATRIX_IS_EVENT_CLASS +MATRIX_EVENT_GET_CLASS +MATRIX_TYPE_EVENT +matrix_event_get_type +
+
matrix-client MatrixClient diff --git a/src/Makefile.am b/src/Makefile.am index c2229c5..14f3f60 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,6 +22,7 @@ libmatrix_glib_0_0_la_VALA_SOURCES = \ matrix-http-api.vala \ matrix-http-client.vala \ matrix-compacts.vala \ + matrix-event.vala \ $(NULL) AM_CPPFLAGS += \ @@ -33,6 +34,7 @@ AM_CPPFLAGS += \ $(GOBJECT_CFLAGS) \ $(SOUP_CFLAGS) \ $(JSON_CFLAGS) \ + $(GEE_CFLAGS) \ $(VALA_CFLAGS) \ $(NULL) @@ -93,6 +95,7 @@ libmatrix_glib_0_0_la_CFLAGS = \ $(GOBJECT_CFLAGS) \ $(SOUP_CFLAGS) \ $(JSON_CFLAGS) \ + $(GEE_CFLAGS) \ $(NULL) libmatrix_glib_0_0_la_LIBADD = \ @@ -100,6 +103,7 @@ libmatrix_glib_0_0_la_LIBADD = \ $(GOBJECT_LIBS) \ $(SOUP_LIBS) \ $(JSON_LIBS) \ + $(GEE_LIBS) \ $(NULL) libmatrix_glib_0_0_la_LDFLAGS = \ diff --git a/src/Matrix-0.0.deps b/src/Matrix-0.0.deps index b39c797..784e0d5 100644 --- a/src/Matrix-0.0.deps +++ b/src/Matrix-0.0.deps @@ -1,3 +1,4 @@ gio-2.0 Json-1.0 +gee-0.8 libsoup-2.4 diff --git a/src/matrix-event.vala b/src/matrix-event.vala new file mode 100644 index 0000000..e7a7f7b --- /dev/null +++ b/src/matrix-event.vala @@ -0,0 +1,278 @@ +/* + * This file is part of matrix-glib-sdk + * + * matrix-glib-sdk is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * matrix-glib-sdk is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with matrix-glib-sdk. If not, see + * . + */ + +/** + * Base class for Matrix events. + */ +public class Matrix.Event : GLib.Object, GLib.Initable { + private Error? _construct_error = null; + private bool _inited = false; + private Json.Node? _json; + private Gee.HashMap _custom_fields = + new Gee.HashMap(); + + protected string? _sender = null; + protected string? _room_id = null; + + /** + * The Matrix ID of the events sender. + */ + public string? sender { + get { + return _sender; + } + + set { + _sender = value; + } + + default = null; + } + + /** + * The ID of the room this event is associated with. + */ + public string? room_id { + get { + return _room_id; + } + + set { + _room_id = value; + } + + default = null; + } + + /** + * The type of the event. + */ + public string? event_type { get; construct; default = null; } + + /** + * The timestamp of the event on the originating server. + */ + public ulong? origin_server_ts { get; set; default = null; } + + /** + * The unsigned part of the event. + */ + public Matrix.UnsignedEventData unsigned_data { + get; set; + default = null; + } + + /** + * The event as a JSON node. + */ + public Json.Node? json { + get { + if (_json == null) { + _json = new Json.Node(Json.NodeType.OBJECT); + _json.set_object(new Json.Object()); + + } + + try { + to_json(_json); + } + catch (Matrix.Error e) { + return null; + } + + return _json; + } + + construct { + if (value != null) { + try { + initialize_from_json(value); + } catch (Matrix.Error e) {} + } + } + } + + public bool + init(GLib.Cancellable? cancellable = null) + throws Error, Matrix.Error + { + if (cancellable != null) { + throw new Matrix.Error.UNSUPPORTED( + "Cancellable initialization not supported"); + } + + if (_construct_error != null) { + throw _construct_error; + } + + _inited = true; + + return true; + } + + private void + initialize_from_json(Json.Node json_data) + throws Matrix.Error + { + Json.Object root; + Json.Node node; + + if (json_data.get_node_type() != Json.NodeType.OBJECT) { + throw new Matrix.Error.INVALID_FORMAT( + "The event is not valid"); + } + + root = json_data.get_object(); + + if ((node = root.get_member("type")) == null) { + throw new Matrix.Error.INCOMPLETE( + "Event type is not specified"); + } + + if ((_event_type != null) + && (_event_type != node.get_string())) { + throw new Matrix.Error.INVALID_TYPE( + "Changing event type is not supported"); + } + + from_json(json_data); + + _event_type = node.get_string(); + + if ((node = root.get_member("origin_server_ts")) != null) { + _origin_server_ts = (ulong)node.get_int(); + } + + if ((node = root.get_member("sender")) != null) { + _sender = node.get_string(); + } + + if ((node = root.get_member("unsigned")) != null) { + _unsigned_data = new Matrix.UnsignedEventData.from_json(node); + } + } + + /** + * Subclasses should implement this function to initialize + * themselves from JSON data. + */ + public virtual void + from_json(Json.Node json_data) + throws Matrix.Error + {} + + /** + * Subclasses should implement this to export their data to JSON. + */ + public virtual void + to_json(Json.Node json_data) + throws Matrix.Error + { + Json.Object root = json_data.get_object(); + + foreach (var entry in _custom_fields.entries) { + root.set_member(entry.key, _json_node_deep_copy(entry.value)); + } + + if (event_type != null) { + root.set_string_member("type", event_type); + } + + if (origin_server_ts != null) { + root.set_int_member("origin_server_ts", origin_server_ts); + } + + if (sender != null) { + root.set_string_member("sender", sender); + } + + if (unsigned_data != null) { + root.set_member("unsigned", unsigned_data.get_json_node()); + } + } + + public static Event? + new_from_json(owned string? event_type = null, + string? room_id = null, + Json.Node? json_data = null) + throws Matrix.Error, GLib.Error + { + GLib.Type event_gtype; + Event? ret = null; + + if (event_type == null) { + if (json_data == null) { + throw new Matrix.Error.INCOMPLETE( + "Either event_type or json_data must be set!"); + } + + if (json_data.get_node_type() != Json.NodeType.OBJECT) { + throw new Matrix.Error.INVALID_FORMAT( + "Event is not a JSON object!"); + } + + Json.Node? node; + + if ((node = json_data.get_object().get_member("type")) == null) { + throw new Matrix.Error.INCOMPLETE( + "event_type is null and JSON object doesn't contain type!"); + } + + event_type = node.get_string(); + } + + // This is kind of a hack until type registration is done + event_gtype = typeof(Matrix.Event); + + ret = (Event)Object.new(event_gtype, + event_type : event_type, + room_id : room_id, + json : json_data); + + ret.init(); + + return ret; + } + + /** + * Set a value for a custom field. + */ + public void + set_custom_field(string field_name, Json.Node value) + { + _custom_fields.set(field_name, value); + } + + /** + * Get the value of a custom field. + */ + public Json.Node? + get_custom_field (string field_name) + { + return _custom_fields.get(field_name); + } + + /** + * Delete a custom field. + */ + public void + delete_custom_field (string field_name) + { + _custom_fields.unset(field_name); + } +} diff --git a/vala-globals.mk b/vala-globals.mk index c82b70d..fc6791d 100644 --- a/vala-globals.mk +++ b/vala-globals.mk @@ -2,4 +2,5 @@ VALA_PKG_LIST = \ --pkg=gio-2.0 \ --pkg=Json-1.0 \ --pkg=libsoup-2.4 \ + --pkg=gee-0.8 \ $(NULL)