[evolution-data-server] EBackend: Add a "connectable" property (GSocketConnectable).



commit 63d1350ed10d91a5915ef47fb0a92c43b70c7686
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sun Feb 17 19:30:29 2013 -0500

    EBackend: Add a "connectable" property (GSocketConnectable).
    
    This is the socket endpoint for the network service to which the
    EBackend is a client.  This can be NULL if the EBackend does not
    use network sockets.
    
    The initial value of the "connectable" property is derived from the
    ESourceAuthentication extension of the EBackend's "source" property,
    if the extension is present.

 .../reference/libebackend/libebackend-sections.txt |    2 +
 libebackend/e-backend.c                            |  148 ++++++++++++++++++++
 libebackend/e-backend.h                            |    4 +
 3 files changed, 154 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/libebackend/libebackend-sections.txt 
b/docs/reference/libebackend/libebackend-sections.txt
index 9854be2..81e59b2 100644
--- a/docs/reference/libebackend/libebackend-sections.txt
+++ b/docs/reference/libebackend/libebackend-sections.txt
@@ -77,6 +77,8 @@ EBackend
 e_backend_get_online
 e_backend_set_online
 e_backend_get_source
+e_backend_ref_connectable
+e_backend_set_connectable
 e_backend_authenticate_sync
 e_backend_authenticate
 e_backend_authenticate_finish
diff --git a/libebackend/e-backend.c b/libebackend/e-backend.c
index eb71e3e..8c36b0f 100644
--- a/libebackend/e-backend.c
+++ b/libebackend/e-backend.c
@@ -48,8 +48,10 @@
 typedef struct _AsyncContext AsyncContext;
 
 struct _EBackendPrivate {
+       GMutex property_lock;
        ESource *source;
        EUserPrompter *prompter;
+       GSocketConnectable *connectable;
        gboolean online;
 };
 
@@ -59,6 +61,7 @@ struct _AsyncContext {
 
 enum {
        PROP_0,
+       PROP_CONNECTABLE,
        PROP_ONLINE,
        PROP_SOURCE,
        PROP_USER_PROMPTER
@@ -92,6 +95,12 @@ backend_set_property (GObject *object,
                       GParamSpec *pspec)
 {
        switch (property_id) {
+               case PROP_CONNECTABLE:
+                       e_backend_set_connectable (
+                               E_BACKEND (object),
+                               g_value_get_object (value));
+                       return;
+
                case PROP_ONLINE:
                        e_backend_set_online (
                                E_BACKEND (object),
@@ -115,6 +124,12 @@ backend_get_property (GObject *object,
                       GParamSpec *pspec)
 {
        switch (property_id) {
+               case PROP_CONNECTABLE:
+                       g_value_take_object (
+                               value, e_backend_ref_connectable (
+                               E_BACKEND (object)));
+                       return;
+
                case PROP_ONLINE:
                        g_value_set_boolean (
                                value, e_backend_get_online (
@@ -146,19 +161,66 @@ backend_dispose (GObject *object)
 
        g_clear_object (&priv->source);
        g_clear_object (&priv->prompter);
+       g_clear_object (&priv->connectable);
 
        /* Chain up to parent's dispose() method. */
        G_OBJECT_CLASS (e_backend_parent_class)->dispose (object);
 }
 
 static void
+backend_finalize (GObject *object)
+{
+       EBackendPrivate *priv;
+
+       priv = E_BACKEND_GET_PRIVATE (object);
+
+       g_mutex_clear (&priv->property_lock);
+
+       /* Chain up to parent's finalize() method. */
+       G_OBJECT_CLASS (e_backend_parent_class)->finalize (object);
+}
+
+static void
 backend_constructed (GObject *object)
 {
+       EBackend *backend;
+       ESource *source;
        GNetworkMonitor *monitor;
+       const gchar *extension_name;
+
+       backend = E_BACKEND (object);
 
        /* Chain up to parent's constructed() method. */
        G_OBJECT_CLASS (e_backend_parent_class)->constructed (object);
 
+       /* Create an initial GSocketConnectable from the data
+        * source's [Authentication] extension, if present. */
+       source = e_backend_get_source (backend);
+       extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+       if (e_source_has_extension (source, extension_name)) {
+               ESourceAuthentication *extension;
+               gchar *host;
+               guint16 port;
+
+               extension = e_source_get_extension (source, extension_name);
+               host = e_source_authentication_dup_host (extension);
+               port = e_source_authentication_get_port (extension);
+
+               /* XXX We should realy check both host and port, but
+                *     too many backends neglect to set a port number.
+                *     Need to fix that first before we can insist on
+                *     a valid port number. */
+               if (host != NULL) {
+                       GSocketConnectable *connectable;
+
+                       connectable = g_network_address_new (host, port);
+                       e_backend_set_connectable (backend, connectable);
+                       g_object_unref (connectable);
+               }
+
+               g_free (host);
+       }
+
        /* Synchronize network monitoring. */
 
        monitor = g_network_monitor_get_default ();
@@ -270,6 +332,7 @@ e_backend_class_init (EBackendClass *class)
        object_class->set_property = backend_set_property;
        object_class->get_property = backend_get_property;
        object_class->dispose = backend_dispose;
+       object_class->finalize = backend_finalize;
        object_class->constructed = backend_constructed;
 
        class->authenticate_sync = backend_authenticate_sync;
@@ -279,6 +342,17 @@ e_backend_class_init (EBackendClass *class)
 
        g_object_class_install_property (
                object_class,
+               PROP_CONNECTABLE,
+               g_param_spec_object (
+                       "connectable",
+                       "Connectable",
+                       "Socket endpoint of a network service",
+                       G_TYPE_SOCKET_CONNECTABLE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       g_object_class_install_property (
+               object_class,
                PROP_ONLINE,
                g_param_spec_boolean (
                        "online",
@@ -318,6 +392,8 @@ e_backend_init (EBackend *backend)
 {
        backend->priv = E_BACKEND_GET_PRIVATE (backend);
        backend->priv->prompter = e_user_prompter_new ();
+
+       g_mutex_init (&backend->priv->property_lock);
 }
 
 /**
@@ -385,6 +461,78 @@ e_backend_get_source (EBackend *backend)
 }
 
 /**
+ * e_backend_ref_connectable:
+ * @backend: an #EBackend
+ *
+ * Returns the socket endpoint for the network service to which @backend
+ * is a client, or %NULL if @backend does not use network sockets.
+ *
+ * The initial value of the #EBackend:connectable property is derived from
+ * the #ESourceAuthentication extension of the @backend's #EBackend:source
+ * property, if the extension is present.
+ *
+ * The returned #GSocketConnectable is referenced for thread-safety and
+ * must be unreferenced with g_object_unref() when finished with it.
+ *
+ * Returns: a #GSocketConnectable, or %NULL
+ *
+ * Since: 3.8
+ **/
+GSocketConnectable *
+e_backend_ref_connectable (EBackend *backend)
+{
+       GSocketConnectable *connectable = NULL;
+
+       g_return_val_if_fail (E_IS_BACKEND (backend), NULL);
+
+       g_mutex_lock (&backend->priv->property_lock);
+
+       if (backend->priv->connectable != NULL)
+               connectable = g_object_ref (backend->priv->connectable);
+
+       g_mutex_unlock (&backend->priv->property_lock);
+
+       return connectable;
+}
+
+/**
+ * e_backend_set_connectable:
+ * @backend: an #EBackend
+ * @connectable: a #GSocketConnectable, or %NULL
+ *
+ * Sets the socket endpoint for the network service to which @backend is
+ * a client.  This can be %NULL if @backend does not use network sockets.
+ *
+ * The initial value of the #EBackend:connectable property is derived from
+ * the #ESourceAuthentication extension of the @backend's #EBackend:source
+ * property, if the extension is present.
+ *
+ * Since: 3.8
+ **/
+void
+e_backend_set_connectable (EBackend *backend,
+                           GSocketConnectable *connectable)
+{
+       g_return_if_fail (E_IS_BACKEND (backend));
+
+       if (connectable != NULL) {
+               g_return_if_fail (G_IS_SOCKET_CONNECTABLE (connectable));
+               g_object_ref (connectable);
+       }
+
+       g_mutex_lock (&backend->priv->property_lock);
+
+       if (backend->priv->connectable != NULL)
+               g_object_unref (backend->priv->connectable);
+
+       backend->priv->connectable = connectable;
+
+       g_mutex_unlock (&backend->priv->property_lock);
+
+       g_object_notify (G_OBJECT (backend), "connectable");
+}
+
+/**
  * e_backend_authenticate_sync:
  * @backend: an #EBackend
  * @auth: an #ESourceAuthenticator
diff --git a/libebackend/e-backend.h b/libebackend/e-backend.h
index c0af453..b99527a 100644
--- a/libebackend/e-backend.h
+++ b/libebackend/e-backend.h
@@ -96,6 +96,10 @@ gboolean     e_backend_get_online            (EBackend *backend);
 void           e_backend_set_online            (EBackend *backend,
                                                 gboolean online);
 ESource *      e_backend_get_source            (EBackend *backend);
+GSocketConnectable *
+               e_backend_ref_connectable       (EBackend *backend);
+void           e_backend_set_connectable       (EBackend *backend,
+                                                GSocketConnectable *connectable);
 gboolean       e_backend_authenticate_sync     (EBackend *backend,
                                                 ESourceAuthenticator *auth,
                                                 GCancellable *cancellable,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]