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-email-address
22 * @short_description: GData e-mail address element
23 * @stability: Stable
24 * @include: gdata/gd/gdata-gd-email-address.h
25 *
26 * #GDataGDEmailAddress represents an "email" element from the
27 * <ulink type="http" url="http://code.google.com/apis/gdata/docs/2.0/elements.html#gdEmail">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-email-address.h"
36 #include "gdata-parsable.h"
37 #include "gdata-parser.h"
38 #include "gdata-comparable.h"
39
40 static void gdata_gd_email_address_comparable_init (GDataComparableIface *iface);
41 static void gdata_gd_email_address_finalize (GObject *object);
42 static void gdata_gd_email_address_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
43 static void gdata_gd_email_address_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 void pre_get_xml (GDataParsable *parsable, GString *xml_string);
46 static void get_namespaces (GDataParsable *parsable, GHashTable *namespaces);
47
48 struct _GDataGDEmailAddressPrivate {
49 gchar *address;
50 gchar *relation_type;
51 gchar *label;
52 gboolean is_primary;
53 gchar *display_name;
54 };
55
56 enum {
57 PROP_ADDRESS = 1,
58 PROP_RELATION_TYPE,
59 PROP_LABEL,
60 PROP_IS_PRIMARY,
61 PROP_DISPLAY_NAME
62 };
63
G_DEFINE_TYPE_WITH_CODE(GDataGDEmailAddress,gdata_gd_email_address,GDATA_TYPE_PARSABLE,G_IMPLEMENT_INTERFACE (GDATA_TYPE_COMPARABLE,gdata_gd_email_address_comparable_init))64 G_DEFINE_TYPE_WITH_CODE (GDataGDEmailAddress, gdata_gd_email_address, GDATA_TYPE_PARSABLE,
65 G_IMPLEMENT_INTERFACE (GDATA_TYPE_COMPARABLE, gdata_gd_email_address_comparable_init))
66
67 static void
68 gdata_gd_email_address_class_init (GDataGDEmailAddressClass *klass)
69 {
70 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
71 GDataParsableClass *parsable_class = GDATA_PARSABLE_CLASS (klass);
72
73 g_type_class_add_private (klass, sizeof (GDataGDEmailAddressPrivate));
74
75 gobject_class->get_property = gdata_gd_email_address_get_property;
76 gobject_class->set_property = gdata_gd_email_address_set_property;
77 gobject_class->finalize = gdata_gd_email_address_finalize;
78
79 parsable_class->pre_parse_xml = pre_parse_xml;
80 parsable_class->pre_get_xml = pre_get_xml;
81 parsable_class->get_namespaces = get_namespaces;
82 parsable_class->element_name = "email";
83 parsable_class->element_namespace = "gd";
84
85 /**
86 * GDataGDEmailAddress:address:
87 *
88 * The e-mail address itself.
89 *
90 * For more information, see the
91 * <ulink type="http" url="http://code.google.com/apis/gdata/docs/2.0/elements.html#gdEmail">GData specification</ulink>.
92 *
93 * Since: 0.4.0
94 */
95 g_object_class_install_property (gobject_class, PROP_ADDRESS,
96 g_param_spec_string ("address",
97 "Address", "The e-mail address itself.",
98 NULL,
99 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
100
101 /**
102 * GDataGDEmailAddress:relation-type:
103 *
104 * A programmatic value that identifies the type of e-mail address. For example: %GDATA_GD_EMAIL_ADDRESS_HOME or %GDATA_GD_EMAIL_ADDRESS_WORK.
105 *
106 * For more information, see the
107 * <ulink type="http" url="http://code.google.com/apis/gdata/docs/2.0/elements.html#gdEmail">GData specification</ulink>.
108 *
109 * Since: 0.4.0
110 */
111 g_object_class_install_property (gobject_class, PROP_RELATION_TYPE,
112 g_param_spec_string ("relation-type",
113 "Relation type", "A programmatic value that identifies the type of e-mail address.",
114 NULL,
115 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
116
117 /**
118 * GDataGDEmailAddress:label:
119 *
120 * A simple string value used to name this e-mail address. It allows UIs to display a label such as "Work", "Personal", "Preferred", etc.
121 *
122 * For more information, see the
123 * <ulink type="http" url="http://code.google.com/apis/gdata/docs/2.0/elements.html#gdEmail">GData specification</ulink>.
124 *
125 * Since: 0.4.0
126 */
127 g_object_class_install_property (gobject_class, PROP_LABEL,
128 g_param_spec_string ("label",
129 "Label", "A simple string value used to name this e-mail address.",
130 NULL,
131 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
132
133 /**
134 * GDataGDEmailAddress:is-primary:
135 *
136 * Indicates which e-mail address out of a group is primary.
137 *
138 * For more information, see the
139 * <ulink type="http" url="http://code.google.com/apis/gdata/docs/2.0/elements.html#gdEmail">GData specification</ulink>.
140 *
141 * Since: 0.4.0
142 */
143 g_object_class_install_property (gobject_class, PROP_IS_PRIMARY,
144 g_param_spec_boolean ("is-primary",
145 "Primary?", "Indicates which e-mail address out of a group is primary.",
146 FALSE,
147 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
148
149 /**
150 * GDataGDEmailAddress:display-name:
151 *
152 * A display name of the entity (e.g. a person) the e-mail address belongs to.
153 *
154 * For more information, see the
155 * <ulink type="http" url="http://code.google.com/apis/gdata/docs/2.0/elements.html#gdEmail">GData specification</ulink>.
156 *
157 * Since: 0.6.0
158 */
159 g_object_class_install_property (gobject_class, PROP_DISPLAY_NAME,
160 g_param_spec_string ("display-name",
161 "Display name", "A display name of the entity the e-mail address belongs to.",
162 NULL,
163 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
164 }
165
166 static gint
compare_with(GDataComparable * self,GDataComparable * other)167 compare_with (GDataComparable *self, GDataComparable *other)
168 {
169 return g_strcmp0 (((GDataGDEmailAddress*) self)->priv->address, ((GDataGDEmailAddress*) other)->priv->address);
170 }
171
172 static void
gdata_gd_email_address_comparable_init(GDataComparableIface * iface)173 gdata_gd_email_address_comparable_init (GDataComparableIface *iface)
174 {
175 iface->compare_with = compare_with;
176 }
177
178 static void
gdata_gd_email_address_init(GDataGDEmailAddress * self)179 gdata_gd_email_address_init (GDataGDEmailAddress *self)
180 {
181 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GDATA_TYPE_GD_EMAIL_ADDRESS, GDataGDEmailAddressPrivate);
182 }
183
184 static void
gdata_gd_email_address_finalize(GObject * object)185 gdata_gd_email_address_finalize (GObject *object)
186 {
187 GDataGDEmailAddressPrivate *priv = GDATA_GD_EMAIL_ADDRESS (object)->priv;
188
189 g_free (priv->address);
190 g_free (priv->relation_type);
191 g_free (priv->label);
192 g_free (priv->display_name);
193
194 /* Chain up to the parent class */
195 G_OBJECT_CLASS (gdata_gd_email_address_parent_class)->finalize (object);
196 }
197
198 static void
gdata_gd_email_address_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)199 gdata_gd_email_address_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
200 {
201 GDataGDEmailAddressPrivate *priv = GDATA_GD_EMAIL_ADDRESS (object)->priv;
202
203 switch (property_id) {
204 case PROP_ADDRESS:
205 g_value_set_string (value, priv->address);
206 break;
207 case PROP_RELATION_TYPE:
208 g_value_set_string (value, priv->relation_type);
209 break;
210 case PROP_LABEL:
211 g_value_set_string (value, priv->label);
212 break;
213 case PROP_IS_PRIMARY:
214 g_value_set_boolean (value, priv->is_primary);
215 break;
216 case PROP_DISPLAY_NAME:
217 g_value_set_string (value, priv->display_name);
218 break;
219 default:
220 /* We don't have any other property... */
221 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
222 break;
223 }
224 }
225
226 static void
gdata_gd_email_address_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)227 gdata_gd_email_address_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
228 {
229 GDataGDEmailAddress *self = GDATA_GD_EMAIL_ADDRESS (object);
230
231 switch (property_id) {
232 case PROP_ADDRESS:
233 gdata_gd_email_address_set_address (self, g_value_get_string (value));
234 break;
235 case PROP_RELATION_TYPE:
236 gdata_gd_email_address_set_relation_type (self, g_value_get_string (value));
237 break;
238 case PROP_LABEL:
239 gdata_gd_email_address_set_label (self, g_value_get_string (value));
240 break;
241 case PROP_IS_PRIMARY:
242 gdata_gd_email_address_set_is_primary (self, g_value_get_boolean (value));
243 break;
244 case PROP_DISPLAY_NAME:
245 gdata_gd_email_address_set_display_name (self, g_value_get_string (value));
246 break;
247 default:
248 /* We don't have any other property... */
249 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
250 break;
251 }
252 }
253
254 static gboolean
pre_parse_xml(GDataParsable * parsable,xmlDoc * doc,xmlNode * root_node,gpointer user_data,GError ** error)255 pre_parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *root_node, gpointer user_data, GError **error)
256 {
257 xmlChar *address, *rel;
258 gboolean primary_bool;
259 GDataGDEmailAddressPrivate *priv = GDATA_GD_EMAIL_ADDRESS (parsable)->priv;
260
261 /* Is it the primary e-mail address? */
262 if (gdata_parser_boolean_from_property (root_node, "primary", &primary_bool, 0, error) == FALSE)
263 return FALSE;
264
265 address = xmlGetProp (root_node, (xmlChar*) "address");
266 if (address == NULL || *address == '\0') {
267 xmlFree (address);
268 return gdata_parser_error_required_property_missing (root_node, "address", error);
269 }
270
271 rel = xmlGetProp (root_node, (xmlChar*) "rel");
272 if (rel != NULL && *rel == '\0') {
273 xmlFree (address);
274 xmlFree (rel);
275 return gdata_parser_error_required_property_missing (root_node, "rel", error);
276 }
277
278 priv->address = (gchar*) address;
279 priv->relation_type = (gchar*) rel;
280 priv->label = (gchar*) xmlGetProp (root_node, (xmlChar*) "label");
281 priv->is_primary = primary_bool;
282 priv->display_name = (gchar*) xmlGetProp (root_node, (xmlChar*) "displayName");
283
284 return TRUE;
285 }
286
287 static void
pre_get_xml(GDataParsable * parsable,GString * xml_string)288 pre_get_xml (GDataParsable *parsable, GString *xml_string)
289 {
290 GDataGDEmailAddressPrivate *priv = GDATA_GD_EMAIL_ADDRESS (parsable)->priv;
291
292 gdata_parser_string_append_escaped (xml_string, " address='", priv->address, "'");
293 if (priv->relation_type != NULL)
294 gdata_parser_string_append_escaped (xml_string, " rel='", priv->relation_type, "'");
295 if (priv->label != NULL)
296 gdata_parser_string_append_escaped (xml_string, " label='", priv->label, "'");
297 if (priv->display_name != NULL)
298 gdata_parser_string_append_escaped (xml_string, " displayName='", priv->display_name, "'");
299
300 if (priv->is_primary == TRUE)
301 g_string_append (xml_string, " primary='true'");
302 else
303 g_string_append (xml_string, " primary='false'");
304 }
305
306 static void
get_namespaces(GDataParsable * parsable,GHashTable * namespaces)307 get_namespaces (GDataParsable *parsable, GHashTable *namespaces)
308 {
309 g_hash_table_insert (namespaces, (gchar*) "gd", (gchar*) "http://schemas.google.com/g/2005");
310 }
311
312 /**
313 * gdata_gd_email_address_new:
314 * @address: the e-mail address
315 * @relation_type: (allow-none): the relationship between the e-mail address and its owner, or %NULL
316 * @label: (allow-none): a human-readable label for the e-mail address, or %NULL
317 * @is_primary: %TRUE if this e-mail address is its owner's primary address, %FALSE otherwise
318 *
319 * Creates a new #GDataGDEmailAddress. More information is available in the <ulink type="http"
320 * url="http://code.google.com/apis/gdata/docs/2.0/elements.html#gdEmail">GData specification</ulink>.
321 *
322 * Return value: a new #GDataGDEmailAddress, or %NULL; unref with g_object_unref()
323 *
324 * Since: 0.2.0
325 */
326 GDataGDEmailAddress *
gdata_gd_email_address_new(const gchar * address,const gchar * relation_type,const gchar * label,gboolean is_primary)327 gdata_gd_email_address_new (const gchar *address, const gchar *relation_type, const gchar *label, gboolean is_primary)
328 {
329 g_return_val_if_fail (address != NULL && *address != '\0', NULL);
330 g_return_val_if_fail (relation_type == NULL || *relation_type != '\0', NULL);
331 return g_object_new (GDATA_TYPE_GD_EMAIL_ADDRESS, "address", address, "relation-type", relation_type,
332 "label", label, "is-primary", is_primary, NULL);
333 }
334
335 /**
336 * gdata_gd_email_address_get_address:
337 * @self: a #GDataGDEmailAddress
338 *
339 * Gets the #GDataGDEmailAddress:address property.
340 *
341 * Return value: the e-mail address itself, or %NULL
342 *
343 * Since: 0.4.0
344 */
345 const gchar *
gdata_gd_email_address_get_address(GDataGDEmailAddress * self)346 gdata_gd_email_address_get_address (GDataGDEmailAddress *self)
347 {
348 g_return_val_if_fail (GDATA_IS_GD_EMAIL_ADDRESS (self), NULL);
349 return self->priv->address;
350 }
351
352 /**
353 * gdata_gd_email_address_set_address:
354 * @self: a #GDataGDEmailAddress
355 * @address: the new e-mail address
356 *
357 * Sets the #GDataGDEmailAddress:address property to @address.
358 *
359 * Since: 0.4.0
360 */
361 void
gdata_gd_email_address_set_address(GDataGDEmailAddress * self,const gchar * address)362 gdata_gd_email_address_set_address (GDataGDEmailAddress *self, const gchar *address)
363 {
364 g_return_if_fail (GDATA_IS_GD_EMAIL_ADDRESS (self));
365 g_return_if_fail (address != NULL && *address != '\0');
366
367 g_free (self->priv->address);
368 self->priv->address = g_strdup (address);
369 g_object_notify (G_OBJECT (self), "address");
370 }
371
372 /**
373 * gdata_gd_email_address_get_relation_type:
374 * @self: a #GDataGDEmailAddress
375 *
376 * Gets the #GDataGDEmailAddress:relation-type property.
377 *
378 * Return value: the e-mail address' relation type, or %NULL
379 *
380 * Since: 0.4.0
381 */
382 const gchar *
gdata_gd_email_address_get_relation_type(GDataGDEmailAddress * self)383 gdata_gd_email_address_get_relation_type (GDataGDEmailAddress *self)
384 {
385 g_return_val_if_fail (GDATA_IS_GD_EMAIL_ADDRESS (self), NULL);
386 return self->priv->relation_type;
387 }
388
389 /**
390 * gdata_gd_email_address_set_relation_type:
391 * @self: a #GDataGDEmailAddress
392 * @relation_type: (allow-none): the new relation type for the email_address, or %NULL
393 *
394 * Sets the #GDataGDEmailAddress:relation-type property to @relation_type.
395 *
396 * Set @relation_type to %NULL to unset the property in the e-mail address.
397 *
398 * Since: 0.4.0
399 */
400 void
gdata_gd_email_address_set_relation_type(GDataGDEmailAddress * self,const gchar * relation_type)401 gdata_gd_email_address_set_relation_type (GDataGDEmailAddress *self, const gchar *relation_type)
402 {
403 g_return_if_fail (GDATA_IS_GD_EMAIL_ADDRESS (self));
404 g_return_if_fail (relation_type == NULL || *relation_type != '\0');
405
406 g_free (self->priv->relation_type);
407 self->priv->relation_type = g_strdup (relation_type);
408 g_object_notify (G_OBJECT (self), "relation-type");
409 }
410
411 /**
412 * gdata_gd_email_address_get_label:
413 * @self: a #GDataGDEmailAddress
414 *
415 * Gets the #GDataGDEmailAddress:label property.
416 *
417 * Return value: the e-mail address' label, or %NULL
418 *
419 * Since: 0.4.0
420 */
421 const gchar *
gdata_gd_email_address_get_label(GDataGDEmailAddress * self)422 gdata_gd_email_address_get_label (GDataGDEmailAddress *self)
423 {
424 g_return_val_if_fail (GDATA_IS_GD_EMAIL_ADDRESS (self), NULL);
425 return self->priv->label;
426 }
427
428 /**
429 * gdata_gd_email_address_set_label:
430 * @self: a #GDataGDEmailAddress
431 * @label: (allow-none): the new label for the e-mail address, or %NULL
432 *
433 * Sets the #GDataGDEmailAddress:label property to @label.
434 *
435 * Set @label to %NULL to unset the property in the e-mail address.
436 *
437 * Since: 0.4.0
438 */
439 void
gdata_gd_email_address_set_label(GDataGDEmailAddress * self,const gchar * label)440 gdata_gd_email_address_set_label (GDataGDEmailAddress *self, const gchar *label)
441 {
442 g_return_if_fail (GDATA_IS_GD_EMAIL_ADDRESS (self));
443
444 g_free (self->priv->label);
445 self->priv->label = g_strdup (label);
446 g_object_notify (G_OBJECT (self), "label");
447 }
448
449 /**
450 * gdata_gd_email_address_is_primary:
451 * @self: a #GDataGDEmailAddress
452 *
453 * Gets the #GDataGDEmailAddress:is-primary property.
454 *
455 * Return value: %TRUE if this is the primary e-mail address, %FALSE otherwise
456 *
457 * Since: 0.4.0
458 */
459 gboolean
gdata_gd_email_address_is_primary(GDataGDEmailAddress * self)460 gdata_gd_email_address_is_primary (GDataGDEmailAddress *self)
461 {
462 g_return_val_if_fail (GDATA_IS_GD_EMAIL_ADDRESS (self), FALSE);
463 return self->priv->is_primary;
464 }
465
466 /**
467 * gdata_gd_email_address_set_is_primary:
468 * @self: a #GDataGDEmailAddress
469 * @is_primary: %TRUE if this is the primary e-mail address, %FALSE otherwise
470 *
471 * Sets the #GDataGDEmailAddress:is-primary property to @is_primary.
472 *
473 * Since: 0.4.0
474 */
475 void
gdata_gd_email_address_set_is_primary(GDataGDEmailAddress * self,gboolean is_primary)476 gdata_gd_email_address_set_is_primary (GDataGDEmailAddress *self, gboolean is_primary)
477 {
478 g_return_if_fail (GDATA_IS_GD_EMAIL_ADDRESS (self));
479
480 self->priv->is_primary = is_primary;
481 g_object_notify (G_OBJECT (self), "is-primary");
482 }
483
484 /**
485 * gdata_gd_email_address_get_display_name:
486 * @self: a #GDataGDEmailAddress
487 *
488 * Gets the #GDataGDEmailAddress:display-name property.
489 *
490 * Return value: a display name for the e-mail address, or %NULL
491 *
492 * Since: 0.6.0
493 */
494 const gchar *
gdata_gd_email_address_get_display_name(GDataGDEmailAddress * self)495 gdata_gd_email_address_get_display_name (GDataGDEmailAddress *self)
496 {
497 g_return_val_if_fail (GDATA_IS_GD_EMAIL_ADDRESS (self), NULL);
498 return self->priv->display_name;
499 }
500
501 /**
502 * gdata_gd_email_address_set_display_name:
503 * @self: a #GDataGDEmailAddress
504 * @display_name: (allow-none): the new display name, or %NULL
505 *
506 * Sets the #GDataGDEmailAddress:display-name property to @display_name.
507 *
508 * Set @display_name to %NULL to unset the property in the e-mail address.
509 *
510 * Since: 0.6.0
511 */
512 void
gdata_gd_email_address_set_display_name(GDataGDEmailAddress * self,const gchar * display_name)513 gdata_gd_email_address_set_display_name (GDataGDEmailAddress *self, const gchar *display_name)
514 {
515 g_return_if_fail (GDATA_IS_GD_EMAIL_ADDRESS (self));
516
517 g_free (self->priv->display_name);
518 self->priv->display_name = g_strdup (display_name);
519 g_object_notify (G_OBJECT (self), "display-name");
520 }
521