1 /*
2  * e-source-backend.c
3  *
4  * This library is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation.
7  *
8  * This library is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this library. If not, see <http://www.gnu.org/licenses/>.
15  *
16  */
17 
18 /**
19  * SECTION: e-source-backend
20  * @include: libedataserver/libedataserver.h
21  * @short_description: Base class for backend-based data sources
22  *
23  * #ESourceBackend is an abstract base class for data sources requiring
24  * an associated backend to function.  The extension merely records the
25  * name of the backend the data source should be paired with.
26  **/
27 
28 #include "e-source-backend.h"
29 
30 #include <libedataserver/e-data-server-util.h>
31 
32 struct _ESourceBackendPrivate {
33 	gchar *backend_name;
34 };
35 
36 enum {
37 	PROP_0,
38 	PROP_BACKEND_NAME
39 };
40 
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(ESourceBackend,e_source_backend,E_TYPE_SOURCE_EXTENSION)41 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (
42 	ESourceBackend,
43 	e_source_backend,
44 	E_TYPE_SOURCE_EXTENSION)
45 
46 static void
47 source_backend_set_property (GObject *object,
48                              guint property_id,
49                              const GValue *value,
50                              GParamSpec *pspec)
51 {
52 	switch (property_id) {
53 		case PROP_BACKEND_NAME:
54 			e_source_backend_set_backend_name (
55 				E_SOURCE_BACKEND (object),
56 				g_value_get_string (value));
57 			return;
58 	}
59 
60 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
61 }
62 
63 static void
source_backend_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)64 source_backend_get_property (GObject *object,
65                              guint property_id,
66                              GValue *value,
67                              GParamSpec *pspec)
68 {
69 	switch (property_id) {
70 		case PROP_BACKEND_NAME:
71 			g_value_take_string (
72 				value,
73 				e_source_backend_dup_backend_name (
74 				E_SOURCE_BACKEND (object)));
75 			return;
76 	}
77 
78 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
79 }
80 
81 static void
source_backend_finalize(GObject * object)82 source_backend_finalize (GObject *object)
83 {
84 	ESourceBackendPrivate *priv;
85 
86 	priv = E_SOURCE_BACKEND (object)->priv;
87 
88 	g_free (priv->backend_name);
89 
90 	/* Chain up to parent's finalize() method. */
91 	G_OBJECT_CLASS (e_source_backend_parent_class)->finalize (object);
92 }
93 
94 static void
e_source_backend_class_init(ESourceBackendClass * class)95 e_source_backend_class_init (ESourceBackendClass *class)
96 {
97 	GObjectClass *object_class;
98 
99 	object_class = G_OBJECT_CLASS (class);
100 	object_class->set_property = source_backend_set_property;
101 	object_class->get_property = source_backend_get_property;
102 	object_class->finalize = source_backend_finalize;
103 
104 	/* We do not provide an extension name,
105 	 * which is why the class is abstract. */
106 
107 	g_object_class_install_property (
108 		object_class,
109 		PROP_BACKEND_NAME,
110 		g_param_spec_string (
111 			"backend-name",
112 			"Backend Name",
113 			"The name of the backend handling the data source",
114 			NULL,
115 			G_PARAM_READWRITE |
116 			G_PARAM_CONSTRUCT |
117 			G_PARAM_EXPLICIT_NOTIFY |
118 			G_PARAM_STATIC_STRINGS |
119 			E_SOURCE_PARAM_SETTING));
120 }
121 
122 static void
e_source_backend_init(ESourceBackend * extension)123 e_source_backend_init (ESourceBackend *extension)
124 {
125 	extension->priv = e_source_backend_get_instance_private (extension);
126 }
127 
128 /**
129  * e_source_backend_get_backend_name:
130  * @extension: an #ESourceBackend
131  *
132  * Returns the backend name for @extension.
133  *
134  * Returns: (nullable): the backend name for @extension
135  *
136  * Since: 3.6
137  **/
138 const gchar *
e_source_backend_get_backend_name(ESourceBackend * extension)139 e_source_backend_get_backend_name (ESourceBackend *extension)
140 {
141 	g_return_val_if_fail (E_IS_SOURCE_BACKEND (extension), NULL);
142 
143 	return extension->priv->backend_name;
144 }
145 
146 /**
147  * e_source_backend_dup_backend_name:
148  * @extension: an #ESourceBackend
149  *
150  * Thread-safe variation of e_source_backend_get_backend_name().
151  * Use this function when accessing @extension from multiple threads.
152  *
153  * The returned string should be freed with g_free() when no longer needed.
154  *
155  * Returns: (nullable): a newly-allocated copy of #ESourceBackend:backend-name
156  *
157  * Since: 3.6
158  **/
159 gchar *
e_source_backend_dup_backend_name(ESourceBackend * extension)160 e_source_backend_dup_backend_name (ESourceBackend *extension)
161 {
162 	const gchar *protected;
163 	gchar *duplicate;
164 
165 	g_return_val_if_fail (E_IS_SOURCE_BACKEND (extension), NULL);
166 
167 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
168 
169 	protected = e_source_backend_get_backend_name (extension);
170 	duplicate = g_strdup (protected);
171 
172 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
173 
174 	return duplicate;
175 }
176 
177 /**
178  * e_source_backend_set_backend_name:
179  * @extension: an #ESourceBackend
180  * @backend_name: (nullable): a backend name, or %NULL
181  *
182  * Sets the backend name for @extension.
183  *
184  * The internal copy of @backend_name is automatically stripped of leading
185  * and trailing whitespace.  If the resulting string is empty, %NULL is set
186  * instead.
187  *
188  * Since: 3.6
189  **/
190 void
e_source_backend_set_backend_name(ESourceBackend * extension,const gchar * backend_name)191 e_source_backend_set_backend_name (ESourceBackend *extension,
192                                    const gchar *backend_name)
193 {
194 	g_return_if_fail (E_IS_SOURCE_BACKEND (extension));
195 
196 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
197 
198 	if (e_util_strcmp0 (extension->priv->backend_name, backend_name) == 0) {
199 		e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
200 		return;
201 	}
202 
203 	g_free (extension->priv->backend_name);
204 	extension->priv->backend_name = e_util_strdup_strip (backend_name);
205 
206 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
207 
208 	g_object_notify (G_OBJECT (extension), "backend-name");
209 }
210 
211