[evolution-data-server] ESourceWebdav: Add "resource-query" property.



commit 44d5f2152663d0854dec4b2ee1e73ddd99e93a41
Author: Matthew Barnes <mbarnes redhat com>
Date:   Mon Aug 27 11:44:46 2012 -0400

    ESourceWebdav: Add "resource-query" property.
    
    Retain the query portion of a WebDAV URI, and update migration to
    preserve it from the old XML-based ESource URIs.
    
    Also reimplement the "soup-uri" property.  Using bi-directional property
    bindings from one property to many properties results in feedback loops.
    Instead, listen for "notify" signals from URI component properties and
    emit a "notify::soup-uri" signal, but don't actually update the internal
    SoupURI until a copy is requested.
    
    This makes Facebook birthday calendars work again, which has the form:
    webcal://www.facebook.com/ical/b.php?uid=<<UID>>&key=<<KEY>>

 .../libedataserver/libedataserver-sections.txt     |    3 +
 libedataserver/e-source-webdav.c                   |  497 +++++++++++---------
 libedataserver/e-source-webdav.h                   |    9 +-
 .../evolution-source-registry-migrate-sources.c    |   18 +
 4 files changed, 298 insertions(+), 229 deletions(-)
---
diff --git a/docs/reference/libedataserver/libedataserver-sections.txt b/docs/reference/libedataserver/libedataserver-sections.txt
index a7af852..54f9b28 100644
--- a/docs/reference/libedataserver/libedataserver-sections.txt
+++ b/docs/reference/libedataserver/libedataserver-sections.txt
@@ -991,6 +991,9 @@ e_source_webdav_set_ignore_invalid_cert
 e_source_webdav_get_resource_path
 e_source_webdav_dup_resource_path
 e_source_webdav_set_resource_path
+e_source_webdav_get_resource_query
+e_source_webdav_dup_resource_query
+e_source_webdav_set_resource_query
 e_source_webdav_dup_soup_uri
 e_source_webdav_set_soup_uri
 e_source_webdav_get_avoid_ifmatch
diff --git a/libedataserver/e-source-webdav.c b/libedataserver/e-source-webdav.c
index 2a2a017..c624e1b 100644
--- a/libedataserver/e-source-webdav.c
+++ b/libedataserver/e-source-webdav.c
@@ -59,10 +59,11 @@ struct _ESourceWebdavPrivate {
 	gchar *display_name;
 	gchar *email_address;
 	gchar *resource_path;
+	gchar *resource_query;
 	gboolean avoid_ifmatch;
 	gboolean calendar_auto_schedule;
 	gboolean ignore_invalid_cert;
-	SoupURI *uri;
+	SoupURI *soup_uri;
 };
 
 enum {
@@ -73,6 +74,7 @@ enum {
 	PROP_EMAIL_ADDRESS,
 	PROP_IGNORE_INVALID_CERT,
 	PROP_RESOURCE_PATH,
+	PROP_RESOURCE_QUERY,
 	PROP_SOUP_URI
 };
 
@@ -81,210 +83,142 @@ G_DEFINE_TYPE (
 	e_source_webdav,
 	E_TYPE_SOURCE_EXTENSION)
 
-static gboolean
-source_webdav_host_to_soup_uri (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
+static void
+source_webdav_notify_cb (GObject *object,
+                         GParamSpec *pspec,
+                         ESourceWebdav *extension)
 {
-	GObject *target;
-	SoupURI *soup_uri;
-	const gchar *host;
-
-	host = g_value_get_string (source_value);
-
-	target = g_binding_get_target (binding);
-	g_return_val_if_fail (E_IS_SOURCE_WEBDAV (target), FALSE);
-
-	soup_uri = e_source_webdav_dup_soup_uri (E_SOURCE_WEBDAV (target));
-	soup_uri_set_host (soup_uri, host);
-	g_value_take_boxed (target_value, soup_uri);
-
-	return TRUE;
+	g_object_notify (G_OBJECT (extension), "soup-uri");
 }
 
 static gboolean
-source_webdav_soup_uri_to_host (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
+source_webdav_user_to_method (GBinding *binding,
+                              const GValue *source_value,
+                              GValue *target_value,
+                              gpointer user_data)
 {
-	SoupURI *soup_uri;
+	const gchar *user;
 
-	soup_uri = g_value_get_boxed (source_value);
-	g_value_set_string (target_value, soup_uri->host);
+	user = g_value_get_string (source_value);
+	if (user == NULL || *user == '\0')
+		g_value_set_string (target_value, "none");
+	else
+		g_value_set_string (target_value, "plain/password");
 
 	return TRUE;
 }
 
-static gboolean
-source_webdav_path_to_soup_uri (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
+static void
+source_webdav_update_properties_from_soup_uri (ESourceWebdav *webdav_extension)
 {
-	GObject *target;
+	ESource *source;
+	ESourceExtension *extension;
 	SoupURI *soup_uri;
-	const gchar *path;
+	const gchar *extension_name;
 
-	path = g_value_get_string (source_value);
+	/* Do not use e_source_webdav_dup_soup_uri() here.  That
+	 * builds the URI from properties we haven't yet updated. */
+	g_mutex_lock (webdav_extension->priv->property_lock);
+	soup_uri = soup_uri_copy (webdav_extension->priv->soup_uri);
+	g_mutex_unlock (webdav_extension->priv->property_lock);
 
-	/* soup_uri_set_path() warns on NULL. */
-	if (path == NULL)
-		path = "";
+	extension = E_SOURCE_EXTENSION (webdav_extension);
+	source = e_source_extension_get_source (extension);
 
-	target = g_binding_get_target (binding);
-	g_return_val_if_fail (E_IS_SOURCE_WEBDAV (target), FALSE);
+	g_object_set (
+		extension,
+		"resource-path", soup_uri->path,
+		"resource-query", soup_uri->query,
+		NULL);
 
-	soup_uri = e_source_webdav_dup_soup_uri (E_SOURCE_WEBDAV (target));
-	soup_uri_set_path (soup_uri, path);
-	g_value_take_boxed (target_value, soup_uri);
+	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+	extension = e_source_get_extension (source, extension_name);
 
-	return TRUE;
-}
+	g_object_set (
+		extension,
+		"host", soup_uri->host,
+		"port", soup_uri->port,
+		"user", soup_uri->user,
+		NULL);
 
-static gboolean
-source_webdav_soup_uri_to_path (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
-{
-	SoupURI *soup_uri;
+	extension_name = E_SOURCE_EXTENSION_SECURITY;
+	extension = e_source_get_extension (source, extension_name);
 
-	soup_uri = g_value_get_boxed (source_value);
-	g_value_set_string (target_value, soup_uri->path);
+	g_object_set (
+		extension,
+		"secure", (soup_uri->scheme == SOUP_URI_SCHEME_HTTPS),
+		NULL);
 
-	return TRUE;
+	soup_uri_free (soup_uri);
 }
 
-static gboolean
-source_webdav_port_to_soup_uri (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
+static void
+source_webdav_update_soup_uri_from_properties (ESourceWebdav *webdav_extension)
 {
-	GObject *target;
+	ESource *source;
+	ESourceExtension *extension;
 	SoupURI *soup_uri;
+	const gchar *extension_name;
+	gchar *user;
+	gchar *host;
+	gchar *path;
+	gchar *query;
 	guint port;
+	gboolean secure;
 
-	port = g_value_get_uint (source_value);
-
-	target = g_binding_get_target (binding);
-	g_return_val_if_fail (E_IS_SOURCE_WEBDAV (target), FALSE);
-
-	soup_uri = e_source_webdav_dup_soup_uri (E_SOURCE_WEBDAV (target));
-	soup_uri_set_port (soup_uri, port);
-	g_value_take_boxed (target_value, soup_uri);
+	extension = E_SOURCE_EXTENSION (webdav_extension);
+	source = e_source_extension_get_source (extension);
 
-	return TRUE;
-}
+	g_object_get (
+		extension,
+		"resource-path", &path,
+		"resource-query", &query,
+		NULL);
 
-static gboolean
-source_webdav_soup_uri_to_port (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
-{
-	SoupURI *soup_uri;
+	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+	extension = e_source_get_extension (source, extension_name);
 
-	soup_uri = g_value_get_boxed (source_value);
-	g_value_set_uint (target_value, soup_uri->port);
+	g_object_get (
+		extension,
+		"user", &user,
+		"host", &host,
+		"port", &port,
+		NULL);
 
-	return TRUE;
-}
+	extension_name = E_SOURCE_EXTENSION_SECURITY;
+	extension = e_source_get_extension (source, extension_name);
 
-static gboolean
-source_webdav_secure_to_soup_uri (GBinding *binding,
-                                  const GValue *source_value,
-                                  GValue *target_value,
-                                  gpointer user_data)
-{
-	GObject *target;
-	SoupURI *soup_uri;
-	gboolean secure;
+	g_object_get (
+		extension,
+		"secure", &secure,
+		NULL);
 
-	secure = g_value_get_boolean (source_value);
+	g_mutex_lock (webdav_extension->priv->property_lock);
 
-	target = g_binding_get_target (binding);
-	g_return_val_if_fail (E_IS_SOURCE_WEBDAV (target), FALSE);
+	soup_uri = webdav_extension->priv->soup_uri;
 
-	soup_uri = e_source_webdav_dup_soup_uri (E_SOURCE_WEBDAV (target));
-	if (secure)
+	/* Try not to disturb the scheme, in case it's "webcal" or some
+	 * other non-standard value.  But if we have to change it, do it. */
+	if (secure && soup_uri->scheme != SOUP_URI_SCHEME_HTTPS)
 		soup_uri_set_scheme (soup_uri, SOUP_URI_SCHEME_HTTPS);
-	else
+	if (!secure && soup_uri->scheme == SOUP_URI_SCHEME_HTTPS)
 		soup_uri_set_scheme (soup_uri, SOUP_URI_SCHEME_HTTP);
-	g_value_take_boxed (target_value, soup_uri);
-
-	return TRUE;
-}
-
-static gboolean
-source_webdav_soup_uri_to_secure (GBinding *binding,
-                                  const GValue *source_value,
-                                  GValue *target_value,
-                                  gpointer user_data)
-{
-	SoupURI *soup_uri;
-	gboolean secure;
 
-	soup_uri = g_value_get_boxed (source_value);
-	secure = (soup_uri->scheme == SOUP_URI_SCHEME_HTTPS);
-	g_value_set_boolean (target_value, secure);
-
-	return TRUE;
-}
-
-static gboolean
-source_webdav_user_to_soup_uri (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
-{
-	GObject *target;
-	SoupURI *soup_uri;
-	const gchar *user;
-
-	user = g_value_get_string (source_value);
-
-	target = g_binding_get_target (binding);
-	g_return_val_if_fail (E_IS_SOURCE_WEBDAV (target), FALSE);
-
-	soup_uri = e_source_webdav_dup_soup_uri (E_SOURCE_WEBDAV (target));
 	soup_uri_set_user (soup_uri, user);
-	g_value_take_boxed (target_value, soup_uri);
-
-	return TRUE;
-}
+	soup_uri_set_host (soup_uri, host);
+	soup_uri_set_port (soup_uri, port);
 
-static gboolean
-source_webdav_soup_uri_to_user (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
-{
-	SoupURI *soup_uri;
+	/* SoupURI doesn't like NULL paths. */
+	soup_uri_set_path (soup_uri, (path != NULL) ? path : "");
 
-	soup_uri = g_value_get_boxed (source_value);
-	g_value_set_string (target_value, soup_uri->user);
+	soup_uri_set_query (soup_uri, query);
 
-	return TRUE;
-}
+	g_mutex_unlock (webdav_extension->priv->property_lock);
 
-static gboolean
-source_webdav_user_to_method (GBinding *binding,
-                              const GValue *source_value,
-                              GValue *target_value,
-                              gpointer user_data)
-{
-	const gchar *user;
-
-	user = g_value_get_string (source_value);
-	if (user == NULL || *user == '\0')
-		g_value_set_string (target_value, "none");
-	else
-		g_value_set_string (target_value, "plain/password");
-
-	return TRUE;
+	g_free (user);
+	g_free (host);
+	g_free (path);
+	g_free (query);
 }
 
 static void
@@ -330,6 +264,12 @@ source_webdav_set_property (GObject *object,
 				g_value_get_string (value));
 			return;
 
+		case PROP_RESOURCE_QUERY:
+			e_source_webdav_set_resource_query (
+				E_SOURCE_WEBDAV (object),
+				g_value_get_string (value));
+			return;
+
 		case PROP_SOUP_URI:
 			e_source_webdav_set_soup_uri (
 				E_SOURCE_WEBDAV (object),
@@ -389,6 +329,13 @@ source_webdav_get_property (GObject *object,
 				E_SOURCE_WEBDAV (object)));
 			return;
 
+		case PROP_RESOURCE_QUERY:
+			g_value_take_string (
+				value,
+				e_source_webdav_dup_resource_query (
+				E_SOURCE_WEBDAV (object)));
+			return;
+
 		case PROP_SOUP_URI:
 			g_value_take_boxed (
 				value,
@@ -412,8 +359,9 @@ source_webdav_finalize (GObject *object)
 	g_free (priv->display_name);
 	g_free (priv->email_address);
 	g_free (priv->resource_path);
+	g_free (priv->resource_query);
 
-	soup_uri_free (priv->uri);
+	soup_uri_free (priv->soup_uri);
 
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (e_source_webdav_parent_class)->finalize (object);
@@ -423,76 +371,59 @@ static void
 source_webdav_constructed (GObject *object)
 {
 	ESource *source;
-	ESourceExtension *this_extension;
-	ESourceExtension *other_extension;
+	ESourceExtension *extension;
 	const gchar *extension_name;
 
 	/* Chain up to parent's constructed() method. */
 	G_OBJECT_CLASS (e_source_webdav_parent_class)->constructed (object);
 
-	this_extension = E_SOURCE_EXTENSION (object);
-	source = e_source_extension_get_source (this_extension);
+	/* XXX I *think* we don't need to worry about disconnecting the
+	 *     signals.  ESourceExtensions are only added, never removed,
+	 *     and they all finalize with their ESource.  At least that's
+	 *     how it's supposed to work if everyone follows the rules. */
 
-	g_object_bind_property_full (
-		this_extension, "resource-path",
-		this_extension, "soup-uri",
-		G_BINDING_BIDIRECTIONAL |
-		G_BINDING_SYNC_CREATE,
-		source_webdav_path_to_soup_uri,
-		source_webdav_soup_uri_to_path,
-		NULL, (GDestroyNotify) NULL);
+	extension = E_SOURCE_EXTENSION (object);
+	source = e_source_extension_get_source (extension);
+
+	g_signal_connect (
+		extension, "notify::resource-path",
+		G_CALLBACK (source_webdav_notify_cb), object);
 
-	/* Bind to properties of other extensions for convenience. */
+	g_signal_connect (
+		extension, "notify::resource-query",
+		G_CALLBACK (source_webdav_notify_cb), object);
 
 	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
-	other_extension = e_source_get_extension (source, extension_name);
+	extension = e_source_get_extension (source, extension_name);
 
-	g_object_bind_property_full (
-		other_extension, "host",
-		this_extension, "soup-uri",
-		G_BINDING_BIDIRECTIONAL |
-		G_BINDING_SYNC_CREATE,
-		source_webdav_host_to_soup_uri,
-		source_webdav_soup_uri_to_host,
-		NULL, (GDestroyNotify) NULL);
+	g_signal_connect (
+		extension, "notify::host",
+		G_CALLBACK (source_webdav_notify_cb), object);
 
-	g_object_bind_property_full (
-		other_extension, "port",
-		this_extension, "soup-uri",
-		G_BINDING_BIDIRECTIONAL |
-		G_BINDING_SYNC_CREATE,
-		source_webdav_port_to_soup_uri,
-		source_webdav_soup_uri_to_port,
-		NULL, (GDestroyNotify) NULL);
+	g_signal_connect (
+		extension, "notify::port",
+		G_CALLBACK (source_webdav_notify_cb), object);
 
-	g_object_bind_property_full (
-		other_extension, "user",
-		this_extension, "soup-uri",
-		G_BINDING_BIDIRECTIONAL |
-		G_BINDING_SYNC_CREATE,
-		source_webdav_user_to_soup_uri,
-		source_webdav_soup_uri_to_user,
-		NULL, (GDestroyNotify) NULL);
+	g_signal_connect (
+		extension, "notify::user",
+		G_CALLBACK (source_webdav_notify_cb), object);
 
+	/* This updates the authentication method
+	 * based on whether a user name was given. */
 	g_object_bind_property_full (
-		other_extension, "user",
-		other_extension, "method",
+		extension, "user",
+		extension, "method",
 		G_BINDING_SYNC_CREATE,
 		source_webdav_user_to_method,
 		NULL,
 		NULL, (GDestroyNotify) NULL);
 
 	extension_name = E_SOURCE_EXTENSION_SECURITY;
-	other_extension = e_source_get_extension (source, extension_name);
+	extension = e_source_get_extension (source, extension_name);
 
-	g_object_bind_property_full (
-		other_extension, "secure",
-		this_extension, "soup-uri",
-		G_BINDING_BIDIRECTIONAL |
-		G_BINDING_SYNC_CREATE,
-		source_webdav_secure_to_soup_uri,
-		source_webdav_soup_uri_to_secure,
-		NULL, (GDestroyNotify) NULL);
+	g_signal_connect (
+		extension, "notify::secure",
+		G_CALLBACK (source_webdav_notify_cb), object);
 }
 
 static void
@@ -587,6 +518,18 @@ e_source_webdav_class_init (ESourceWebdavClass *class)
 
 	g_object_class_install_property (
 		object_class,
+		PROP_RESOURCE_QUERY,
+		g_param_spec_string (
+			"resource-query",
+			"Resource Query",
+			"Query to access a WebDAV resource",
+			NULL,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT |
+			E_SOURCE_PARAM_SETTING));
+
+	g_object_class_install_property (
+		object_class,
 		PROP_SOUP_URI,
 		g_param_spec_boxed (
 			"soup-uri",
@@ -603,9 +546,9 @@ e_source_webdav_init (ESourceWebdav *extension)
 	extension->priv->property_lock = g_mutex_new ();
 
 	/* Initialize this enough for SOUP_URI_IS_VALID() to pass. */
-	extension->priv->uri = soup_uri_new (NULL);
-	extension->priv->uri->scheme = SOUP_URI_SCHEME_HTTP;
-	extension->priv->uri->path = g_strdup ("");
+	extension->priv->soup_uri = soup_uri_new (NULL);
+	extension->priv->soup_uri->scheme = SOUP_URI_SCHEME_HTTP;
+	extension->priv->soup_uri->path = g_strdup ("");
 }
 
 /**
@@ -1014,6 +957,100 @@ e_source_webdav_set_resource_path (ESourceWebdav *extension,
 }
 
 /**
+ * e_source_webdav_get_resource_query:
+ * @extension: an #ESourceWebdav
+ *
+ * Returns the URI query required to access a resource on a WebDAV server.
+ *
+ * This is typically used when the #ESourceWebdav:resource-path points not
+ * to the resource itself but to a web program that generates the resource
+ * content on-the-fly.  The #ESourceWebdav:resource-query holds the input
+ * values for the program.
+ *
+ * Returns: the query to access a WebDAV resource
+ *
+ * Since: 3.6
+ **/
+const gchar *
+e_source_webdav_get_resource_query (ESourceWebdav *extension)
+{
+	g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), NULL);
+
+	return extension->priv->resource_query;
+}
+
+/**
+ * e_source_webdav_dup_resource_query:
+ * @extension: an #ESourceWebdav
+ *
+ * Thread-safe variation of e_source_webdav_get_resource_query().
+ * Use this function when accessing @extension from multiple threads.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: the newly-allocated copy of #ESourceWebdav:resource-query
+ *
+ * Since: 3.6
+ **/
+gchar *
+e_source_webdav_dup_resource_query (ESourceWebdav *extension)
+{
+	const gchar *protected;
+	gchar *duplicate;
+
+	g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), NULL);
+
+	g_mutex_lock (extension->priv->property_lock);
+
+	protected = e_source_webdav_get_resource_query (extension);
+	duplicate = g_strdup (protected);
+
+	g_mutex_unlock (extension->priv->property_lock);
+
+	return duplicate;
+}
+
+/**
+ * e_source_webdav_set_resource_query:
+ * @extension: an #ESourceWebdav
+ * @resource_query: (allow-none): the query to access a WebDAV resource,
+ *                  or %NULL
+ *
+ * Sets the URI query required to access a resource on a WebDAV server.
+ *
+ * This is typically used when the #ESourceWebdav:resource-path points not
+ * to the resource itself but to a web program that generates the resource
+ * content on-the-fly.  The #ESourceWebdav:resource-query holds the input
+ * values for the program.
+ *
+ * The internal copy of @resource_query is automatically stripped of leading
+ * and trailing whitespace.  If the resulting string is empty, %NULL is set
+ * instead.
+ *
+ * Since: 3.6
+ **/
+void
+e_source_webdav_set_resource_query (ESourceWebdav *extension,
+                                    const gchar *resource_query)
+{
+	g_return_if_fail (E_IS_SOURCE_WEBDAV (extension));
+
+	g_mutex_lock (extension->priv->property_lock);
+
+	if (g_strcmp0 (extension->priv->resource_query, resource_query) == 0) {
+		g_mutex_unlock (extension->priv->property_lock);
+		return;
+	}
+
+	g_free (extension->priv->resource_query);
+	extension->priv->resource_query = e_util_strdup_strip (resource_query);
+
+	g_mutex_unlock (extension->priv->property_lock);
+
+	g_object_notify (G_OBJECT (extension), "resource-query");
+}
+
+/**
  * e_source_webdav_dup_soup_uri:
  * @extension: an #ESourceWebdav
  *
@@ -1033,9 +1070,12 @@ e_source_webdav_dup_soup_uri (ESourceWebdav *extension)
 
 	g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), NULL);
 
+	/* Keep this outside of the property lock. */
+	source_webdav_update_soup_uri_from_properties (extension);
+
 	g_mutex_lock (extension->priv->property_lock);
 
-	duplicate = soup_uri_copy (extension->priv->uri);
+	duplicate = soup_uri_copy (extension->priv->soup_uri);
 
 	g_mutex_unlock (extension->priv->property_lock);
 
@@ -1045,34 +1085,35 @@ e_source_webdav_dup_soup_uri (ESourceWebdav *extension)
 /**
  * e_source_webdav_set_soup_uri:
  * @extension: an #ESourceWebdav
- * @uri: a #SoupURI
+ * @soup_uri: a #SoupURI
  *
  * This is a convenience function which propagates the components of
  * @uri to the #ESourceAuthentication extension, the #ESourceSecurity
- * extension, and @extension itself.  (The "query" and "fragment"
- * components of @uri are ignored.)
+ * extension, and @extension itself.  (The "fragment" component of
+ * @uri is ignored.)
  *
  * Since: 3.6
  **/
 void
 e_source_webdav_set_soup_uri (ESourceWebdav *extension,
-                              SoupURI *uri)
+                              SoupURI *soup_uri)
 {
 	g_return_if_fail (E_IS_SOURCE_WEBDAV (extension));
-	g_return_if_fail (SOUP_URI_IS_VALID (uri));
+	g_return_if_fail (SOUP_URI_IS_VALID (soup_uri));
 
 	g_mutex_lock (extension->priv->property_lock);
 
-	if (extension->priv->uri && soup_uri_equal (extension->priv->uri, uri)) {
-		g_mutex_unlock (extension->priv->property_lock);
-		return;
-	}
+	/* Do not test for URI equality because our
+	 * internal SoupURI might not be up-to-date. */
 
-	soup_uri_free (extension->priv->uri);
-	extension->priv->uri = soup_uri_copy (uri);
+	soup_uri_free (extension->priv->soup_uri);
+	extension->priv->soup_uri = soup_uri_copy (soup_uri);
 
 	g_mutex_unlock (extension->priv->property_lock);
 
+	g_object_freeze_notify (G_OBJECT (extension));
+	source_webdav_update_properties_from_soup_uri (extension);
 	g_object_notify (G_OBJECT (extension), "soup-uri");
+	g_object_thaw_notify (G_OBJECT (extension));
 }
 
diff --git a/libedataserver/e-source-webdav.h b/libedataserver/e-source-webdav.h
index 1e69471..797d238 100644
--- a/libedataserver/e-source-webdav.h
+++ b/libedataserver/e-source-webdav.h
@@ -115,9 +115,16 @@ gchar *		e_source_webdav_dup_resource_path
 void		e_source_webdav_set_resource_path
 						(ESourceWebdav *extension,
 						 const gchar *resource_path);
+const gchar *	e_source_webdav_get_resource_query
+						(ESourceWebdav *extension);
+gchar *		e_source_webdav_dup_resource_query
+						(ESourceWebdav *extension);
+void		e_source_webdav_set_resource_query
+						(ESourceWebdav *extension,
+						 const gchar *resource_query);
 SoupURI *	e_source_webdav_dup_soup_uri	(ESourceWebdav *extension);
 void		e_source_webdav_set_soup_uri	(ESourceWebdav *extension,
-						 SoupURI *uri);
+						 SoupURI *soup_uri);
 
 G_END_DECLS
 
diff --git a/services/evolution-source-registry/evolution-source-registry-migrate-sources.c b/services/evolution-source-registry/evolution-source-registry-migrate-sources.c
index cabc692..99f8025 100644
--- a/services/evolution-source-registry/evolution-source-registry-migrate-sources.c
+++ b/services/evolution-source-registry/evolution-source-registry-migrate-sources.c
@@ -2254,6 +2254,12 @@ migrate_parse_caldav_source (ParseData *parse_data)
 			E_SOURCE_EXTENSION_WEBDAV_BACKEND,
 			"ResourcePath", parse_data->soup_uri->path);
 
+	if (parse_data->soup_uri->query != NULL)
+		g_key_file_set_string (
+			parse_data->key_file,
+			E_SOURCE_EXTENSION_WEBDAV_BACKEND,
+			"ResourceQuery", parse_data->soup_uri->query);
+
 	parse_data->property_func = migrate_parse_caldav_property;
 }
 
@@ -2502,6 +2508,12 @@ migrate_parse_webcal_source (ParseData *parse_data)
 			E_SOURCE_EXTENSION_WEBDAV_BACKEND,
 			"ResourcePath", parse_data->soup_uri->path);
 
+	if (parse_data->soup_uri->query != NULL)
+		g_key_file_set_string (
+			parse_data->key_file,
+			E_SOURCE_EXTENSION_WEBDAV_BACKEND,
+			"ResourceQuery", parse_data->soup_uri->query);
+
 	/* Webcal Backend has no special properties to parse. */
 }
 
@@ -2546,6 +2558,12 @@ migrate_parse_webdav_source (ParseData *parse_data)
 			E_SOURCE_EXTENSION_WEBDAV_BACKEND,
 			"ResourcePath", parse_data->soup_uri->path);
 
+	if (parse_data->soup_uri->query != NULL)
+		g_key_file_set_string (
+			parse_data->key_file,
+			E_SOURCE_EXTENSION_WEBDAV_BACKEND,
+			"ResourceQuery", parse_data->soup_uri->query);
+
 	parse_data->property_func = migrate_parse_webdav_property;
 }
 



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