summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberto Mardegan <mardy@users.sourceforge.net>2008-04-10 14:31:42 +0000
committerAlberto Mardegan <mardy@users.sourceforge.net>2008-04-10 14:31:42 +0000
commit30767cf63dd92865febf3994050d5ee37d2d498e (patch)
tree77342acfa985a81669b3b028ddf4d5b318755cd9
parent10dd8c9c5ff92445ecdca9074990873304a323ee (diff)
Implement the account query API.
git-svn-id: https://mission-control.svn.sourceforge.net/svnroot/mission-control/trunk@356 d91c8aed-3f2b-0410-a83d-924a1c20a0ba
-rw-r--r--ChangeLog6
-rw-r--r--src/mcd-account-manager-query.c290
-rw-r--r--xml/Account_Manager_Interface_Query.xml2
3 files changed, 297 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 3fd6dded..0c2b21f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2008-04-10 Alberto Mardegan <alberto.mardegan@nokia.com>
+ * src/mcd-account-manager-query.[hc],
+ xml/Account_Manager_Interface_Query.xml:
+ Implement the account query API.
+
+2008-04-10 Alberto Mardegan <alberto.mardegan@nokia.com>
+
* tools/libglibcodegen.py:
Make the "ao" DBus type map to a C GPtrArray.
diff --git a/src/mcd-account-manager-query.c b/src/mcd-account-manager-query.c
index a5b80da2..d7094bfd 100644
--- a/src/mcd-account-manager-query.c
+++ b/src/mcd-account-manager-query.c
@@ -37,6 +37,34 @@
#include "mcd-account-manager-query.h"
#include "_gen/interfaces.h"
+typedef struct
+{
+ const gchar *name;
+ const GValue *value;
+} McdFindParam;
+
+typedef struct
+{
+ gchar *iface;
+ const gchar *name;
+ const GValue *value;
+} McdIfaceProperty;
+
+typedef struct
+{
+ const gchar *manager;
+ const gchar *protocol;
+ guint requested_presence;
+ const gchar *requested_status;
+ guint current_presence;
+ const gchar *current_status;
+ GArray *params;
+ GArray *properties;
+ gint n_accounts;
+ GPtrArray *accounts;
+ GError *error;
+} McdFindData;
+
static const gchar *supported_keywords[] = {
"Manager", "Protocol",
"RequestedPresence", "RequestedStatus",
@@ -64,9 +92,271 @@ _mcd_account_manager_query_get_properties (void)
return account_manager_query_properties;
}
+static gboolean
+match_account_parameter (McdAccount *account, const gchar *name,
+ const GValue *value)
+{
+ const gchar *unique_name;
+ GKeyFile *keyfile;
+ gboolean match = FALSE;
+
+ unique_name = mcd_account_get_unique_name (account);
+ keyfile = mcd_account_get_keyfile (account);
+ if (g_key_file_has_key (keyfile, unique_name, name, NULL))
+ {
+ const gchar *value_str;
+ gchar *conf_value_str;
+ gint conf_value_int, value_int;
+ gboolean conf_value_bool, value_bool;
+ switch (G_VALUE_TYPE (value))
+ {
+ case G_TYPE_STRING:
+ conf_value_str =
+ g_key_file_get_string (keyfile, unique_name, name,
+ NULL);
+ value_str = g_value_get_string (value);
+ if (strcmp (conf_value_str, value_str) == 0) match = TRUE;
+ g_free (conf_value_str);
+ break;
+ case G_TYPE_UINT:
+ conf_value_int =
+ g_key_file_get_integer (keyfile, unique_name, name,
+ NULL);
+ value_int = (gint)g_value_get_uint (value);
+ if (conf_value_int == value_int) match = TRUE;
+ break;
+ case G_TYPE_BOOLEAN:
+ conf_value_bool =
+ g_key_file_get_boolean (keyfile, unique_name, name,
+ NULL);
+ value_bool = g_value_get_boolean (value);
+ if (conf_value_bool == value_bool) match = TRUE;
+ break;
+ default:
+ g_warning ("Unexpected type %s", G_VALUE_TYPE_NAME (value));
+ }
+ }
+ return match;
+}
+
+static gboolean
+match_account_property (McdAccount *account, McdIfaceProperty *prop)
+{
+ const gchar *unique_name;
+ gboolean match = FALSE;
+ GValue value = { 0 };
+ GError *error = NULL;
+
+ g_debug ("prop %s, value type %s", prop->name, G_VALUE_TYPE_NAME (prop->value));
+ unique_name = mcd_account_get_unique_name (account);
+ mcd_dbusprop_get_property (TP_SVC_DBUS_PROPERTIES (account),
+ prop->iface, prop->name, &value,
+ &error);
+ if (error)
+ {
+ g_warning ("%s on %s: %s", G_STRFUNC, unique_name, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ if (G_VALUE_TYPE (&value) == G_VALUE_TYPE (prop->value))
+ {
+ switch (G_VALUE_TYPE (&value))
+ {
+ case G_TYPE_CHAR:
+ case G_TYPE_UCHAR:
+ case G_TYPE_BOOLEAN:
+ case G_TYPE_INT:
+ case G_TYPE_UINT:
+ case G_TYPE_LONG:
+ case G_TYPE_ULONG:
+ case G_TYPE_INT64:
+ case G_TYPE_UINT64:
+ case G_TYPE_FLOAT:
+ case G_TYPE_DOUBLE:
+ case G_TYPE_POINTER:
+ /* this assumes the GValue was previously initialized to 0, which
+ * should always be the case */
+ match = (value.data[0].v_uint64 == prop->value->data[0].v_uint64);
+ break;
+ case G_TYPE_STRING:
+ match = (strcmp (g_value_get_string (&value),
+ g_value_get_string (prop->value)) == 0);
+ break;
+ default:
+ g_warning ("%s: unsupported value type: %s",
+ G_STRFUNC, G_VALUE_TYPE_NAME (&value));
+ }
+ }
+ g_value_unset (&value);
+ return match;
+}
+
+static void
+find_accounts (gpointer key, gpointer value, gpointer userdata)
+{
+ McdAccount *account = MCD_ACCOUNT (value);
+ McdFindData *fd = userdata;
+ TpConnectionPresenceType presence;
+ const gchar *object_path, *string, *status, *message;
+ gint i;
+
+ g_debug ("%s: %s", G_STRFUNC, (gchar *)key);
+ if (fd->manager)
+ {
+ string = mcd_account_get_manager_name (account);
+ if (!string || strcmp (fd->manager, string) != 0) return;
+ }
+ if (fd->protocol)
+ {
+ string = mcd_account_get_protocol_name (account);
+ if (!string || strcmp (fd->protocol, string) != 0) return;
+ }
+ if (fd->requested_presence > 0)
+ {
+ mcd_account_get_requested_presence (account, &presence,
+ &status, &message);
+ if (fd->requested_presence != presence) return;
+ }
+ if (fd->requested_status)
+ {
+ mcd_account_get_requested_presence (account, &presence,
+ &status, &message);
+ if (!status || strcmp (fd->requested_status, status) != 0) return;
+ }
+ if (fd->current_presence > 0)
+ {
+ mcd_account_get_current_presence (account, &presence,
+ &status, &message);
+ if (fd->current_presence != presence) return;
+ }
+ if (fd->current_status)
+ {
+ mcd_account_get_current_presence (account, &presence,
+ &status, &message);
+ if (!status || strcmp (fd->current_status, status) != 0) return;
+ }
+
+ g_debug ("checking parameters");
+ for (i = 0; i < fd->params->len; i++)
+ {
+ McdFindParam *param;
+ param = &g_array_index (fd->params, McdFindParam, i);
+ if (!match_account_parameter (account, param->name, param->value))
+ return;
+ }
+
+ g_debug ("checking properties");
+ for (i = 0; i < fd->properties->len; i++)
+ {
+ McdIfaceProperty *prop;
+ prop = &g_array_index (fd->properties, McdIfaceProperty, i);
+ if (!match_account_property (account, prop))
+ return;
+ }
+ object_path = mcd_account_get_object_path (account);
+ g_debug ("%s", object_path);
+ g_ptr_array_add (fd->accounts, (gpointer)object_path);
+}
+
+static void
+parse_query (gpointer key, gpointer val, gpointer userdata)
+{
+ McdFindData *fd = userdata;
+ gchar *name = key, *dot;
+ GValue *value = val;
+
+ if (fd->error) return;
+
+ if (strcmp (name, "Manager") == 0)
+ fd->manager = g_value_get_string (value);
+ else if (strcmp (name, "Protocol") == 0)
+ fd->protocol = g_value_get_string (value);
+ else if (strcmp (name, "RequestedPresence") == 0)
+ fd->requested_presence = g_value_get_uint (value);
+ else if (strcmp (name, "RequestedStatus") == 0)
+ fd->requested_status = g_value_get_string (value);
+ else if (strcmp (name, "CurrentPresence") == 0)
+ fd->current_presence = g_value_get_uint (value);
+ else if (strcmp (name, "CurrentStatus") == 0)
+ fd->current_status = g_value_get_string (value);
+ else if (strncmp (name, "param-", 6) == 0)
+ {
+ McdFindParam param;
+
+ param.name = name;
+ param.value = value;
+ g_array_append_val (fd->params, param);
+ }
+ else if ((dot = strrchr (name, '.')) != NULL)
+ {
+ McdIfaceProperty prop;
+
+ prop.iface = g_strndup (name, dot - name);
+ prop.name = dot + 1;
+ prop.value = value;
+ g_array_append_val (fd->properties, prop);
+ }
+ else
+ {
+ g_set_error (&fd->error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+ "Unrecognized query parameter: %s", name);
+ }
+}
+
+static void
+account_manager_find_accounts (McSvcAccountManagerInterfaceQuery *self,
+ GHashTable *query,
+ DBusGMethodInvocation *context)
+{
+ McdAccountManager *account_manager = MCD_ACCOUNT_MANAGER (self);
+ McdFindData fd;
+ guint i;
+
+ g_debug ("%s called", G_STRFUNC);
+ memset (&fd, 0, sizeof (fd));
+ fd.params = g_array_new (FALSE, FALSE, sizeof (McdFindParam));
+ fd.properties = g_array_new (FALSE, FALSE, sizeof (McdIfaceProperty));
+
+ /* break the hash table into the McdFindData struct, to avoid having to
+ * iterate over it for every account */
+ g_hash_table_foreach (query, parse_query, &fd);
+ if (!fd.error)
+ {
+ GHashTable *accounts;
+ fd.accounts = g_ptr_array_sized_new (16);
+ accounts = mcd_account_manager_get_valid_accounts (account_manager);
+ g_hash_table_foreach (accounts, find_accounts, &fd);
+ }
+ g_array_free (fd.params, TRUE);
+ for (i = 0; i < fd.properties->len; i++)
+ {
+ McdIfaceProperty *prop;
+ prop = &g_array_index (fd.properties, McdIfaceProperty, i);
+ g_free (prop->iface);
+ }
+ g_array_free (fd.properties, TRUE);
+
+ if (fd.error)
+ {
+ dbus_g_method_return_error (context, fd.error);
+ g_error_free (fd.error);
+ return;
+ }
+
+ mc_svc_account_manager_interface_query_return_from_find_accounts (context,
+ fd.accounts);
+ g_ptr_array_free (fd.accounts, TRUE);
+}
+
+
void
_mcd_account_manager_query_iface_init (McSvcAccountManagerInterfaceQueryClass *iface,
gpointer iface_data)
{
+#define IMPLEMENT(x) mc_svc_account_manager_interface_query_implement_##x (\
+ iface, account_manager_##x)
+ IMPLEMENT(find_accounts);
+#undef IMPLEMENT
}
diff --git a/xml/Account_Manager_Interface_Query.xml b/xml/Account_Manager_Interface_Query.xml
index 4854c926..a207c112 100644
--- a/xml/Account_Manager_Interface_Query.xml
+++ b/xml/Account_Manager_Interface_Query.xml
@@ -16,7 +16,7 @@ Lesser General Public License for more details.</p>
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
</tp:license>
- <interface name="org.freedesktop.Telepathy.AccountManager.Interface.Query">
+ <interface name="com.nokia.AccountManager.Interface.Query">
<tp:requires interface="org.freedesktop.Telepathy.AccountManager"/>
<tp:docstring xmlns="http://www.w3.org/1999/xhtml">
<p>The Query interface provides a convienient way for clients to retrieve