goa: Add missing linker flag (for real).
[platform/upstream/evolution-data-server.git] / libedataserver / e-source-resource.c
1 /*
2  * e-source-resource.c
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) version 3.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with the program; if not, see <http://www.gnu.org/licenses/>
16  *
17  */
18
19 /**
20  * SECTION: e-source-resource
21  * @include: libedataserver/libedataserver.h
22  * @short_description: #ESource extension for a remote resource
23  *
24  * The #ESourceResource extension holds the server-assigned identity of a
25  * remote calendar, address book, or whatever else an #ESource can represent.
26  *
27  * This extension is typically used by an #ECollectionBackend to note a
28  * server-assigned resource identity in an #ESource.  Then in a later session,
29  * after querying the server for available resources, a resource identity can
30  * be paired with the same #ESource #ESource:uid from the previous session,
31  * allowing locally cached data from the previous session to be reused.
32  *
33  * Access the extension as follows:
34  *
35  * |[
36  *   #include <libedataserver/libedataserver.h>
37  *
38  *   ESourceResource *extension;
39  *
40  *   extension = e_source_get_extension (source, E_SOURCE_EXTENSION_RESOURCE);
41  * ]|
42  **/
43
44 #include "e-source-resource.h"
45
46 #include <libedataserver/e-data-server-util.h>
47
48 #define E_SOURCE_RESOURCE_GET_PRIVATE(obj) \
49         (G_TYPE_INSTANCE_GET_PRIVATE \
50         ((obj), E_TYPE_SOURCE_RESOURCE, ESourceResourcePrivate))
51
52 struct _ESourceResourcePrivate {
53         GMutex property_lock;
54         gchar *identity;
55 };
56
57 enum {
58         PROP_0,
59         PROP_IDENTITY
60 };
61
62 G_DEFINE_TYPE (
63         ESourceResource,
64         e_source_resource,
65         E_TYPE_SOURCE_EXTENSION)
66
67 static void
68 source_resource_set_property (GObject *object,
69                               guint property_id,
70                               const GValue *value,
71                               GParamSpec *pspec)
72 {
73         switch (property_id) {
74                 case PROP_IDENTITY:
75                         e_source_resource_set_identity (
76                                 E_SOURCE_RESOURCE (object),
77                                 g_value_get_string (value));
78                         return;
79         }
80
81         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
82 }
83
84 static void
85 source_resource_get_property (GObject *object,
86                               guint property_id,
87                               GValue *value,
88                               GParamSpec *pspec)
89 {
90         switch (property_id) {
91                 case PROP_IDENTITY:
92                         g_value_take_string (
93                                 value,
94                                 e_source_resource_dup_identity (
95                                 E_SOURCE_RESOURCE (object)));
96                         return;
97         }
98
99         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
100 }
101
102 static void
103 source_resource_finalize (GObject *object)
104 {
105         ESourceResourcePrivate *priv;
106
107         priv = E_SOURCE_RESOURCE_GET_PRIVATE (object);
108
109         g_mutex_clear (&priv->property_lock);
110
111         g_free (priv->identity);
112
113         /* Chain up to parent's finalize() method. */
114         G_OBJECT_CLASS (e_source_resource_parent_class)->finalize (object);
115 }
116
117 static void
118 e_source_resource_class_init (ESourceResourceClass *class)
119 {
120         GObjectClass *object_class;
121         ESourceExtensionClass *extension_class;
122
123         g_type_class_add_private (class, sizeof (ESourceResourcePrivate));
124
125         object_class = G_OBJECT_CLASS (class);
126         object_class->set_property = source_resource_set_property;
127         object_class->get_property = source_resource_get_property;
128         object_class->finalize = source_resource_finalize;
129
130         extension_class = E_SOURCE_EXTENSION_CLASS (class);
131         extension_class->name = E_SOURCE_EXTENSION_RESOURCE;
132
133         g_object_class_install_property (
134                 object_class,
135                 PROP_IDENTITY,
136                 g_param_spec_string (
137                         "identity",
138                         "Identity",
139                         "Resource identity",
140                         NULL,
141                         G_PARAM_READWRITE |
142                         G_PARAM_CONSTRUCT |
143                         G_PARAM_STATIC_STRINGS |
144                         E_SOURCE_PARAM_SETTING));
145 }
146
147 static void
148 e_source_resource_init (ESourceResource *extension)
149 {
150         extension->priv = E_SOURCE_RESOURCE_GET_PRIVATE (extension);
151         g_mutex_init (&extension->priv->property_lock);
152 }
153
154 /**
155  * e_source_resource_get_identity:
156  * @extension: an #ESourceResource
157  *
158  * Returns the server-assigned identity of the remote resource associated
159  * with the #ESource to which @extension belongs.
160  *
161  * Returns: the identity of a remote resource
162  *
163  * Since: 3.6
164  **/
165 const gchar *
166 e_source_resource_get_identity (ESourceResource *extension)
167 {
168         g_return_val_if_fail (E_IS_SOURCE_RESOURCE (extension), NULL);
169
170         return extension->priv->identity;
171 }
172
173 /**
174  * e_source_resource_dup_identity:
175  * @extension: an #ESourceResource
176  *
177  * Thread-safe variation of e_source_resource_get_identity().
178  * Use this function when accessing @extension from multiple threads.
179  *
180  * The returned string should be freed with g_free() when no longer needed.
181  *
182  * Returns: a newly-allocated copy of #ESourceResource:identity
183  *
184  * Since: 3.6
185  **/
186 gchar *
187 e_source_resource_dup_identity (ESourceResource *extension)
188 {
189         const gchar *protected;
190         gchar *duplicate;
191
192         g_return_val_if_fail (E_IS_SOURCE_RESOURCE (extension), NULL);
193
194         g_mutex_lock (&extension->priv->property_lock);
195
196         protected = e_source_resource_get_identity (extension);
197         duplicate = g_strdup (protected);
198
199         g_mutex_unlock (&extension->priv->property_lock);
200
201         return duplicate;
202 }
203
204 /**
205  * e_source_resource_set_identity:
206  * @extension: an #ESourceResource
207  * @identity: (allow-none): the identity of a remote resource
208  *
209  * Sets the server-assigned identity of the remote resource associated with
210  * the #ESource to which @extension belongs.
211  *
212  * The internal copy of @identity is automatically stripped of leading and
213  * trailing whitespace.  If the resulting string is empty, %NULL is set
214  * instead.
215  *
216  * Since: 3.6
217  **/
218 void
219 e_source_resource_set_identity (ESourceResource *extension,
220                                 const gchar *identity)
221 {
222         g_return_if_fail (E_IS_SOURCE_RESOURCE (extension));
223
224         g_mutex_lock (&extension->priv->property_lock);
225
226         if (g_strcmp0 (extension->priv->identity, identity) == 0) {
227                 g_mutex_unlock (&extension->priv->property_lock);
228                 return;
229         }
230
231         g_free (extension->priv->identity);
232         extension->priv->identity = e_util_strdup_strip (identity);
233
234         g_mutex_unlock (&extension->priv->property_lock);
235
236         g_object_notify (G_OBJECT (extension), "identity");
237 }
238