1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /*
3  * GData Client
4  * Copyright (C) Philip Withnall 2009–2010 <philip@tecnocode.co.uk>
5  *
6  * GData Client is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * GData Client is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with GData Client.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 /**
21  * SECTION:gdata-gd-who
22  * @short_description: GData who element
23  * @stability: Stable
24  * @include: gdata/gd/gdata-gd-who.h
25  *
26  * #GDataGDWho represents an "who" element from the
27  * <ulink type="http" url="http://code.google.com/apis/gdata/docs/2.0/elements.html#gdWho">GData specification</ulink>.
28  *
29  * Since: 0.4.0
30  */
31 
32 #include <glib.h>
33 #include <libxml/parser.h>
34 
35 #include "gdata-gd-who.h"
36 #include "gdata-parsable.h"
37 #include "gdata-parser.h"
38 #include "gdata-comparable.h"
39 
40 static void gdata_gd_who_comparable_init (GDataComparableIface *iface);
41 static void gdata_gd_who_finalize (GObject *object);
42 static void gdata_gd_who_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
43 static void gdata_gd_who_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
44 static gboolean pre_parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *root_node, gpointer user_data, GError **error);
45 /*static gboolean parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *root_node, gpointer user_data, GError **error);*/
46 static void pre_get_xml (GDataParsable *parsable, GString *xml_string);
47 /*static void get_xml (GDataParsable *parsable, GString *xml_string);*/
48 static void get_namespaces (GDataParsable *parsable, GHashTable *namespaces);
49 
50 struct _GDataGDWhoPrivate {
51 	gchar *relation_type;
52 	gchar *value_string;
53 	gchar *email_address;
54 };
55 
56 enum {
57 	PROP_RELATION_TYPE = 1,
58 	PROP_VALUE_STRING,
59 	PROP_EMAIL_ADDRESS
60 };
61 
G_DEFINE_TYPE_WITH_CODE(GDataGDWho,gdata_gd_who,GDATA_TYPE_PARSABLE,G_IMPLEMENT_INTERFACE (GDATA_TYPE_COMPARABLE,gdata_gd_who_comparable_init))62 G_DEFINE_TYPE_WITH_CODE (GDataGDWho, gdata_gd_who, GDATA_TYPE_PARSABLE,
63                          G_IMPLEMENT_INTERFACE (GDATA_TYPE_COMPARABLE, gdata_gd_who_comparable_init))
64 
65 static void
66 gdata_gd_who_class_init (GDataGDWhoClass *klass)
67 {
68 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
69 	GDataParsableClass *parsable_class = GDATA_PARSABLE_CLASS (klass);
70 
71 	g_type_class_add_private (klass, sizeof (GDataGDWhoPrivate));
72 
73 	gobject_class->get_property = gdata_gd_who_get_property;
74 	gobject_class->set_property = gdata_gd_who_set_property;
75 	gobject_class->finalize = gdata_gd_who_finalize;
76 
77 	parsable_class->pre_parse_xml = pre_parse_xml;
78 	/*parsable_class->parse_xml = parse_xml;*/
79 	parsable_class->pre_get_xml = pre_get_xml;
80 	/*parsable_class->get_xml = get_xml;*/
81 	parsable_class->get_namespaces = get_namespaces;
82 	parsable_class->element_name = "who";
83 	parsable_class->element_namespace = "gd";
84 
85 	/**
86 	 * GDataGDWho:relation-type:
87 	 *
88 	 * Specifies the relationship between the containing entity and the contained person. For example: %GDATA_GD_WHO_EVENT_PERFORMER or
89 	 * %GDATA_GD_WHO_EVENT_ATTENDEE.
90 	 *
91 	 * For more information, see the
92 	 * <ulink type="http" url="http://code.google.com/apis/gdata/docs/2.0/elements.html#gdWho">GData specification</ulink>.
93 	 *
94 	 * Since: 0.4.0
95 	 */
96 	g_object_class_install_property (gobject_class, PROP_RELATION_TYPE,
97 	                                 g_param_spec_string ("relation-type",
98 	                                                      "Relation type", "Specifies the relationship between the container and the containee.",
99 	                                                      NULL,
100 	                                                      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
101 
102 	/**
103 	 * GDataGDWho:value-string:
104 	 *
105 	 * A simple string representation of this person.
106 	 *
107 	 * For more information, see the
108 	 * <ulink type="http" url="http://code.google.com/apis/gdata/docs/2.0/elements.html#gdWho">GData specification</ulink>.
109 	 *
110 	 * Since: 0.4.0
111 	 */
112 	g_object_class_install_property (gobject_class, PROP_VALUE_STRING,
113 	                                 g_param_spec_string ("value-string",
114 	                                                      "Value string", "A simple string representation of this person.",
115 	                                                      NULL,
116 	                                                      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
117 
118 	/**
119 	 * GDataGDWho:email-address:
120 	 *
121 	 * The e-mail address of the person represented by the #GDataGDWho.
122 	 *
123 	 * For more information, see the
124 	 * <ulink type="http" url="http://code.google.com/apis/gdata/docs/2.0/elements.html#gdWho">GData specification</ulink>.
125 	 *
126 	 * Since: 0.4.0
127 	 */
128 	g_object_class_install_property (gobject_class, PROP_EMAIL_ADDRESS,
129 	                                 g_param_spec_string ("email-address",
130 	                                                      "E-mail address", "The e-mail address of the person represented by the #GDataGDWho.",
131 	                                                      NULL,
132 	                                                      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
133 }
134 
135 static gint
compare_with(GDataComparable * self,GDataComparable * other)136 compare_with (GDataComparable *self, GDataComparable *other)
137 {
138 	GDataGDWhoPrivate *a = ((GDataGDWho*) self)->priv, *b = ((GDataGDWho*) other)->priv;
139 
140 	if (g_strcmp0 (a->value_string, b->value_string) == 0 && g_strcmp0 (a->email_address, b->email_address) == 0)
141 		return 0;
142 	return 1;
143 }
144 
145 static void
gdata_gd_who_comparable_init(GDataComparableIface * iface)146 gdata_gd_who_comparable_init (GDataComparableIface *iface)
147 {
148 	iface->compare_with = compare_with;
149 }
150 
151 static void
gdata_gd_who_init(GDataGDWho * self)152 gdata_gd_who_init (GDataGDWho *self)
153 {
154 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GDATA_TYPE_GD_WHO, GDataGDWhoPrivate);
155 }
156 
157 static void
gdata_gd_who_finalize(GObject * object)158 gdata_gd_who_finalize (GObject *object)
159 {
160 	GDataGDWhoPrivate *priv = GDATA_GD_WHO (object)->priv;
161 
162 	g_free (priv->relation_type);
163 	g_free (priv->value_string);
164 	g_free (priv->email_address);
165 
166 	/* Chain up to the parent class */
167 	G_OBJECT_CLASS (gdata_gd_who_parent_class)->finalize (object);
168 }
169 
170 static void
gdata_gd_who_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)171 gdata_gd_who_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
172 {
173 	GDataGDWhoPrivate *priv = GDATA_GD_WHO (object)->priv;
174 
175 	switch (property_id) {
176 		case PROP_RELATION_TYPE:
177 			g_value_set_string (value, priv->relation_type);
178 			break;
179 		case PROP_VALUE_STRING:
180 			g_value_set_string (value, priv->value_string);
181 			break;
182 		case PROP_EMAIL_ADDRESS:
183 			g_value_set_string (value, priv->email_address);
184 			break;
185 		default:
186 			/* We don't have any other property... */
187 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
188 			break;
189 	}
190 }
191 
192 static void
gdata_gd_who_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)193 gdata_gd_who_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
194 {
195 	GDataGDWho *self = GDATA_GD_WHO (object);
196 
197 	switch (property_id) {
198 		case PROP_RELATION_TYPE:
199 			gdata_gd_who_set_relation_type (self, g_value_get_string (value));
200 			break;
201 		case PROP_VALUE_STRING:
202 			gdata_gd_who_set_value_string (self, g_value_get_string (value));
203 			break;
204 		case PROP_EMAIL_ADDRESS:
205 			gdata_gd_who_set_email_address (self, g_value_get_string (value));
206 			break;
207 		default:
208 			/* We don't have any other property... */
209 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
210 			break;
211 	}
212 }
213 
214 static gboolean
pre_parse_xml(GDataParsable * parsable,xmlDoc * doc,xmlNode * root_node,gpointer user_data,GError ** error)215 pre_parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *root_node, gpointer user_data, GError **error)
216 {
217 	xmlChar *rel, *email;
218 	GDataGDWhoPrivate *priv = GDATA_GD_WHO (parsable)->priv;
219 
220 	rel = xmlGetProp (root_node, (xmlChar*) "rel");
221 	if (rel != NULL && *rel == '\0') {
222 		xmlFree (rel);
223 		return gdata_parser_error_required_property_missing (root_node, "rel", error);
224 	}
225 
226 	email = xmlGetProp (root_node, (xmlChar*) "email");
227 	if (email != NULL && *email == '\0') {
228 		xmlFree (rel);
229 		xmlFree (email);
230 		return gdata_parser_error_required_property_missing (root_node, "email", error);
231 	}
232 
233 	priv->relation_type = (gchar*) rel;
234 	priv->value_string = (gchar*) xmlGetProp (root_node, (xmlChar*) "valueString");
235 	priv->email_address = (gchar*) email;
236 
237 	return TRUE;
238 }
239 
240 /*static gboolean
241 parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
242 {
243 	GDataGDWhoPrivate *priv = GDATA_GD_WHO (parsable)->priv;
244 
245 	TODO: deal with the attendeeType, attendeeStatus and entryLink
246 
247 	return TRUE;
248 }*/
249 
250 static void
pre_get_xml(GDataParsable * parsable,GString * xml_string)251 pre_get_xml (GDataParsable *parsable, GString *xml_string)
252 {
253 	GDataGDWhoPrivate *priv = GDATA_GD_WHO (parsable)->priv;
254 
255 	if (priv->email_address != NULL)
256 		gdata_parser_string_append_escaped (xml_string, " email='", priv->email_address, "'");
257 	if (priv->relation_type != NULL)
258 		gdata_parser_string_append_escaped (xml_string, " rel='", priv->relation_type, "'");
259 	if (priv->value_string != NULL)
260 		gdata_parser_string_append_escaped (xml_string, " valueString='", priv->value_string, "'");
261 }
262 
263 /*static void
264 get_xml (GDataParsable *parsable, GString *xml_string)
265 {
266 	GDataGDWhoPrivate *priv = GDATA_GD_WHO (parsable)->priv;
267 
268 	TODO: deal with the attendeeType, attendeeStatus and entryLink
269 }*/
270 
271 static void
get_namespaces(GDataParsable * parsable,GHashTable * namespaces)272 get_namespaces (GDataParsable *parsable, GHashTable *namespaces)
273 {
274 	g_hash_table_insert (namespaces, (gchar*) "gd", (gchar*) "http://schemas.google.com/g/2005");
275 }
276 
277 /**
278  * gdata_gd_who_new:
279  * @relation_type: (allow-none): the relationship between the item and this person, or %NULL
280  * @value_string: (allow-none): a string to represent the person, or %NULL
281  * @email_address: (allow-none): the person's e-mail address, or %NULL
282  *
283  * Creates a new #GDataGDWho. More information is available in the <ulink type="http"
284  * url="http://code.google.com/apis/gdata/docs/2.0/elements.html#gdWho">GData specification</ulink>.
285  *
286  * Currently, entryLink functionality is not implemented in #GDataGDWho.
287  *
288  * Return value: a new #GDataGDWho; unref with g_object_unref()
289  *
290  * Since: 0.2.0
291  */
292 GDataGDWho *
gdata_gd_who_new(const gchar * relation_type,const gchar * value_string,const gchar * email_address)293 gdata_gd_who_new (const gchar *relation_type, const gchar *value_string, const gchar *email_address)
294 {
295 	g_return_val_if_fail (relation_type == NULL || *relation_type != '\0', NULL);
296 	g_return_val_if_fail (email_address == NULL || *email_address != '\0', NULL);
297 	return g_object_new (GDATA_TYPE_GD_WHO, "relation-type", relation_type, "value-string", value_string, "email-address", email_address, NULL);
298 }
299 
300 /**
301  * gdata_gd_who_get_relation_type:
302  * @self: a #GDataGDWho
303  *
304  * Gets the #GDataGDWho:relation-type property.
305  *
306  * Return value: the relation type, or %NULL
307  *
308  * Since: 0.4.0
309  */
310 const gchar *
gdata_gd_who_get_relation_type(GDataGDWho * self)311 gdata_gd_who_get_relation_type (GDataGDWho *self)
312 {
313 	g_return_val_if_fail (GDATA_IS_GD_WHO (self), NULL);
314 	return self->priv->relation_type;
315 }
316 
317 /**
318  * gdata_gd_who_set_relation_type:
319  * @self: a #GDataGDWho
320  * @relation_type: (allow-none): the new relation type, or %NULL
321  *
322  * Sets the #GDataGDWho:relation-type property to @relation_type.
323  *
324  * Set @relation_type to %NULL to unset the property.
325  *
326  * Since: 0.4.0
327  */
328 void
gdata_gd_who_set_relation_type(GDataGDWho * self,const gchar * relation_type)329 gdata_gd_who_set_relation_type (GDataGDWho *self, const gchar *relation_type)
330 {
331 	g_return_if_fail (GDATA_IS_GD_WHO (self));
332 	g_return_if_fail (relation_type == NULL || *relation_type != '\0');
333 
334 	g_free (self->priv->relation_type);
335 	self->priv->relation_type = g_strdup (relation_type);
336 	g_object_notify (G_OBJECT (self), "relation-type");
337 }
338 
339 /**
340  * gdata_gd_who_get_value_string:
341  * @self: a #GDataGDWho
342  *
343  * Gets the #GDataGDWho:value-string property.
344  *
345  * Return value: the value string, or %NULL
346  *
347  * Since: 0.4.0
348  */
349 const gchar *
gdata_gd_who_get_value_string(GDataGDWho * self)350 gdata_gd_who_get_value_string (GDataGDWho *self)
351 {
352 	g_return_val_if_fail (GDATA_IS_GD_WHO (self), NULL);
353 	return self->priv->value_string;
354 }
355 
356 /**
357  * gdata_gd_who_set_value_string:
358  * @self: a #GDataGDWho
359  * @value_string: (allow-none): the new value string, or %NULL
360  *
361  * Sets the #GDataGDWho:value-string property to @value_string.
362  *
363  * Set @value_string to %NULL to unset the property.
364  *
365  * Since: 0.4.0
366  */
367 void
gdata_gd_who_set_value_string(GDataGDWho * self,const gchar * value_string)368 gdata_gd_who_set_value_string (GDataGDWho *self, const gchar *value_string)
369 {
370 	g_return_if_fail (GDATA_IS_GD_WHO (self));
371 
372 	g_free (self->priv->value_string);
373 	self->priv->value_string = g_strdup (value_string);
374 	g_object_notify (G_OBJECT (self), "value-string");
375 }
376 
377 /**
378  * gdata_gd_who_get_email_address:
379  * @self: a #GDataGDWho
380  *
381  * Gets the #GDataGDWho:email-address property.
382  *
383  * Return value: the e-mail address, or %NULL
384  *
385  * Since: 0.4.0
386  */
387 const gchar *
gdata_gd_who_get_email_address(GDataGDWho * self)388 gdata_gd_who_get_email_address (GDataGDWho *self)
389 {
390 	g_return_val_if_fail (GDATA_IS_GD_WHO (self), NULL);
391 	return self->priv->email_address;
392 }
393 
394 /**
395  * gdata_gd_who_set_email_address:
396  * @self: a #GDataGDWho
397  * @email_address: (allow-none): the new e-mail address, or %NULL
398  *
399  * Sets the #GDataGDWho:email-address property to @email_address.
400  *
401  * Set @email_address to %NULL to unset the property.
402  *
403  * Since: 0.4.0
404  */
405 void
gdata_gd_who_set_email_address(GDataGDWho * self,const gchar * email_address)406 gdata_gd_who_set_email_address (GDataGDWho *self, const gchar *email_address)
407 {
408 	g_return_if_fail (GDATA_IS_GD_WHO (self));
409 	g_return_if_fail (email_address == NULL || *email_address != '\0');
410 
411 	g_free (self->priv->email_address);
412 	self->priv->email_address = g_strdup (email_address);
413 	g_object_notify (G_OBJECT (self), "email-address");
414 }
415