[libgdata] [core] Add GDataAccessRule:edited



commit 3dad7fe3e3b48fd7090b21dc92ed770c338732da
Author: Philip Withnall <philip tecnocode co uk>
Date:   Thu Mar 25 14:33:04 2010 +0000

    [core] Add GDataAccessRule:edited
    
    Allow retrieval of the last edit time for access rules using the

 docs/reference/gdata-sections.txt |    1 +
 gdata/gdata-access-rule.c         |   53 +++++++++++++++++++++++++++++++++++-
 gdata/gdata-access-rule.h         |    1 +
 gdata/gdata.symbols               |    1 +
 gdata/tests/calendar.c            |    6 ++++
 gdata/tests/general.c             |   16 ++++++++++-
 6 files changed, 75 insertions(+), 3 deletions(-)
---
diff --git a/docs/reference/gdata-sections.txt b/docs/reference/gdata-sections.txt
index 16d44ee..28dbcb3 100644
--- a/docs/reference/gdata-sections.txt
+++ b/docs/reference/gdata-sections.txt
@@ -592,6 +592,7 @@ gdata_access_rule_get_role
 gdata_access_rule_set_role
 gdata_access_rule_get_scope
 gdata_access_rule_set_scope
+gdata_access_rule_get_edited
 <SUBSECTION Standard>
 gdata_access_rule_get_type
 GDATA_ACCESS_RULE
diff --git a/gdata/gdata-access-rule.c b/gdata/gdata-access-rule.c
index 06445fb..ea77bd8 100644
--- a/gdata/gdata-access-rule.c
+++ b/gdata/gdata-access-rule.c
@@ -52,12 +52,14 @@ struct _GDataAccessRulePrivate {
 	gchar *role;
 	gchar *scope_type; 
 	gchar *scope_value;
+	GTimeVal edited;
 };
 
 enum {
 	PROP_ROLE = 1,
 	PROP_SCOPE_TYPE,
 	PROP_SCOPE_VALUE,
+	PROP_EDITED
 };
 
 G_DEFINE_TYPE (GDataAccessRule, gdata_access_rule, GDATA_TYPE_ENTRY)
@@ -117,6 +119,22 @@ gdata_access_rule_class_init (GDataAccessRuleClass *klass)
 					"Scope value", "The scope value for this access rule.",
 					NULL,
 					G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+	/**
+	 * GDataAccessRule:edited:
+	 *
+	 * The last time the access rule was edited. If the rule has not been edited yet, the content indicates the time it was created.
+	 *
+	 * For more information, see the <ulink type="http" url="http://www.atomenabled.org/developers/protocol/#appEdited";>
+	 * Atom Publishing Protocol specification</ulink>.
+	 *
+	 * Since: 0.7.0
+	 **/
+	g_object_class_install_property (gobject_class, PROP_EDITED,
+				g_param_spec_boxed ("edited",
+					"Edited", "The last time the access rule was edited.",
+					GDATA_TYPE_G_TIME_VAL,
+					G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 }
 
 /**
@@ -132,7 +150,13 @@ gdata_access_rule_class_init (GDataAccessRuleClass *klass)
 GDataAccessRule *
 gdata_access_rule_new (const gchar *id)
 {
-	return g_object_new (GDATA_TYPE_ACCESS_RULE, "id", id, NULL);
+	GDataAccessRule *rule = GDATA_ACCESS_RULE (g_object_new (GDATA_TYPE_ACCESS_RULE, "id", id, NULL));
+
+	/* Set the edited property to the current time (creation time). We don't do this in *_init() since that would cause
+	 * setting it from parse_xml() to fail (duplicate element). */
+	g_get_current_time (&(rule->priv->edited));
+
+	return rule;
 }
 
 static void
@@ -176,6 +200,9 @@ gdata_access_rule_get_property (GObject *object, guint property_id, GValue *valu
 		case PROP_SCOPE_VALUE:
 			g_value_set_string (value, priv->scope_value);
 			break;
+		case PROP_EDITED:
+			g_value_set_boxed (value, &(priv->edited));
+			break;
 		default:
 			/* We don't have any other property... */
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -205,9 +232,13 @@ gdata_access_rule_finalize (GObject *object)
 static gboolean
 parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
 {
+	gboolean success;
 	GDataAccessRule *self = GDATA_ACCESS_RULE (parsable);
 
-	if (gdata_parser_is_namespace (node, "http://schemas.google.com/acl/2007";) == TRUE) {
+	if (gdata_parser_is_namespace (node, "http://www.w3.org/2007/app";) == TRUE &&
+	    gdata_parser_time_val_from_element (node, "edited", P_REQUIRED | P_NO_DUPES, &(self->priv->edited), &success, error) == TRUE) {
+		return success;
+	} else if (gdata_parser_is_namespace (node, "http://schemas.google.com/acl/2007";) == TRUE) {
 		if (xmlStrcmp (node->name, (xmlChar*) "role") == 0) {
 			/* gAcl:role */
 			xmlChar *role = xmlGetProp (node, (xmlChar*) "value");
@@ -374,3 +405,21 @@ gdata_access_rule_get_scope (GDataAccessRule *self, const gchar **type, const gc
 	if (value != NULL)
 		*value = self->priv->scope_value;
 }
+
+/**
+ * gdata_access_rule_get_edited:
+ * @self: a #GDataAccessRule
+ * @edited: return location for the edited time
+ *
+ * Gets the #GDataAccessRule:edited property and puts it in @edited. If the property is unset,
+ * both fields in the #GTimeVal will be set to %0.
+ *
+ * Since: 0.7.0
+ **/
+void
+gdata_access_rule_get_edited (GDataAccessRule *self, GTimeVal *edited)
+{
+	g_return_if_fail (GDATA_IS_ACCESS_RULE (self));
+	g_return_if_fail (edited != NULL);
+	*edited = self->priv->edited;
+}
diff --git a/gdata/gdata-access-rule.h b/gdata/gdata-access-rule.h
index 6c41d27..8a8510c 100644
--- a/gdata/gdata-access-rule.h
+++ b/gdata/gdata-access-rule.h
@@ -69,6 +69,7 @@ const gchar *gdata_access_rule_get_role (GDataAccessRule *self);
 void gdata_access_rule_set_role (GDataAccessRule *self, const gchar *role);
 void gdata_access_rule_get_scope (GDataAccessRule *self, const gchar **type, const gchar **value);
 void gdata_access_rule_set_scope (GDataAccessRule *self, const gchar *type, const gchar *value);
+void gdata_access_rule_get_edited (GDataAccessRule *self, GTimeVal *edited);
 
 G_END_DECLS
 
diff --git a/gdata/gdata.symbols b/gdata/gdata.symbols
index 96807e5..1e8d531 100644
--- a/gdata/gdata.symbols
+++ b/gdata/gdata.symbols
@@ -316,6 +316,7 @@ gdata_access_rule_get_role
 gdata_access_rule_set_role
 gdata_access_rule_get_scope
 gdata_access_rule_set_scope
+gdata_access_rule_get_edited
 gdata_parsable_get_type
 gdata_parsable_new_from_xml
 gdata_parsable_get_xml
diff --git a/gdata/tests/calendar.c b/gdata/tests/calendar.c
index 78a4695..ee18292 100644
--- a/gdata/tests/calendar.c
+++ b/gdata/tests/calendar.c
@@ -577,6 +577,7 @@ test_acls_insert_rule (gconstpointer service)
 	GDataCategory *category;
 	GList *categories;
 	gchar *xml;
+	GTimeVal edited;
 	GError *error = NULL;
 
 	calendar = get_calendar (service, &error);
@@ -615,6 +616,8 @@ test_acls_insert_rule (gconstpointer service)
 	gdata_access_rule_get_scope (new_rule, &scope_type, &scope_value);
 	g_assert_cmpstr (scope_type, ==, "user");
 	g_assert_cmpstr (scope_value, ==, "darcy gmail com");
+	gdata_access_rule_get_edited (new_rule, &edited);
+	g_assert_cmpuint (edited.tv_sec, >, 0);
 
 	/* Check it only has the one category and that it's correct */
 	categories = gdata_entry_get_categories (GDATA_ENTRY (new_rule));
@@ -639,6 +642,7 @@ test_acls_update_rule (gconstpointer service)
 	GDataAccessRule *rule = NULL, *new_rule;
 	const gchar *scope_type, *scope_value;
 	GList *rules;
+	GTimeVal edited;
 	GError *error = NULL;
 
 	calendar = get_calendar (service, &error);
@@ -678,6 +682,8 @@ test_acls_update_rule (gconstpointer service)
 	gdata_access_rule_get_scope (new_rule, &scope_type, &scope_value);
 	g_assert_cmpstr (scope_type, ==, "user");
 	g_assert_cmpstr (scope_value, ==, "darcy gmail com");
+	gdata_access_rule_get_edited (new_rule, &edited);
+	g_assert_cmpuint (edited.tv_sec, >, 0);
 
 	g_object_unref (new_rule);
 	g_object_unref (calendar);
diff --git a/gdata/tests/general.c b/gdata/tests/general.c
index 0a92ed1..c8b1621 100644
--- a/gdata/tests/general.c
+++ b/gdata/tests/general.c
@@ -651,6 +651,7 @@ test_access_rule_get_xml (void)
 {
 	GDataAccessRule *rule, *rule2;
 	gchar *xml, *role, *scope_type3, *scope_value3;
+	GTimeVal edited, *edited2;
 	const gchar *scope_type, *scope_value, *scope_type2, *scope_value2;
 	GError *error = NULL;
 
@@ -667,6 +668,8 @@ test_access_rule_get_xml (void)
 	gdata_access_rule_get_scope (rule, &scope_type, &scope_value);
 	g_assert_cmpstr (scope_type, ==, "A scope type");
 	g_assert_cmpstr (scope_value, ==, "A scope value");
+	gdata_access_rule_get_edited (rule, &edited);
+	g_assert_cmpuint (edited.tv_sec, >, 0); /* current time */
 
 	/* Set the properties more conventionally */
 	gdata_access_rule_set_role (rule, "writer");
@@ -697,18 +700,25 @@ test_access_rule_get_xml (void)
 	gdata_access_rule_get_scope (rule2, &scope_type2, &scope_value2);
 	g_assert_cmpstr (scope_type, ==, scope_type2);
 	g_assert_cmpstr (scope_value, ==, scope_value2);
+	gdata_access_rule_get_edited (rule2, &edited);
+	g_assert_cmpuint (edited.tv_sec, ==, 0); /* unspecified in XML */
+	g_assert_cmpuint (edited.tv_usec, ==, 0);
 
 	/* Check properties a different way */
 	g_object_get (G_OBJECT (rule2),
 	              "role", &role,
 	              "scope-type", &scope_type3,
 	              "scope-value", &scope_value3,
+	              "edited", &edited2,
 	              NULL);
 
 	g_assert_cmpstr (role, ==, gdata_access_rule_get_role (rule));
 	g_assert_cmpstr (scope_type, ==, scope_type3);
 	g_assert_cmpstr (scope_value, ==, scope_value3);
+	g_assert_cmpuint (edited2->tv_sec, ==, 0);
+	g_assert_cmpuint (edited2->tv_usec, ==, 0);
 
+	g_free (edited2);
 	g_free (role);
 	g_free (scope_type3);
 	g_free (scope_value3);
@@ -724,7 +734,7 @@ test_access_rule_error_handling (void)
 	GError *error = NULL;
 
 #define TEST_XML_ERROR_HANDLING(x) rule = GDATA_ACCESS_RULE (gdata_parsable_new_from_xml (GDATA_TYPE_ACCESS_RULE,\
-		"<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007'>"\
+		"<entry xmlns='http://www.w3.org/2005/Atom' xmlns:app='http://www.w3.org/2007/app' xmlns:gAcl='http://schemas.google.com/acl/2007'>"\
 			x\
 		"</entry>", -1, &error));\
 	g_assert_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR);\
@@ -737,6 +747,10 @@ test_access_rule_error_handling (void)
 	/* scope */
 	TEST_XML_ERROR_HANDLING ("<gAcl:scope/>"); /* missing type */
 
+	/* edited */
+	TEST_XML_ERROR_HANDLING ("<app:edited/>"); /* missing date */
+	TEST_XML_ERROR_HANDLING ("<app:edited>not a date</app:edited>"); /* bad date */
+
 #undef TEST_XML_ERROR_HANDLING
 }
 



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