fix the name of "Helix Code, Inc." in all the copyrights
[platform/upstream/evolution-data-server.git] / camel / camel-service.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /* camelService.c : Abstract class for an email service */
3
4 /* 
5  *
6  * Author : 
7  *  Bertrand Guiheneuf <bertrand@helixcode.com>
8  *
9  * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com)
10  *
11  * This program is free software; you can redistribute it and/or 
12  * modify it under the terms of the GNU General Public License as 
13  * published by the Free Software Foundation; either version 2 of the
14  * License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24  * USA
25  */
26 #include <config.h>
27 #include "camel-service.h"
28 #include "camel-log.h"
29 #include "camel-exception.h"
30
31 static GtkObjectClass *parent_class=NULL;
32
33 /* Returns the class for a CamelService */
34 #define CSERV_CLASS(so) CAMEL_SERVICE_CLASS (GTK_OBJECT(so)->klass)
35
36 static gboolean _connect(CamelService *service, CamelException *ex);
37 static gboolean _connect_with_url (CamelService *service, Gurl *url,
38                                    CamelException *ex);
39 static gboolean _disconnect(CamelService *service, CamelException *ex);
40 static gboolean _is_connected (CamelService *service);
41 static void _finalize (GtkObject *object);
42 static gboolean _set_url (CamelService *service, Gurl *url,
43                           CamelException *ex);
44
45 static void
46 camel_service_class_init (CamelServiceClass *camel_service_class)
47 {
48         GtkObjectClass *gtk_object_class =
49                 GTK_OBJECT_CLASS (camel_service_class);
50
51         parent_class = gtk_type_class (gtk_object_get_type ());
52         
53         /* virtual method definition */
54         camel_service_class->connect = _connect;
55         camel_service_class->connect_with_url = _connect_with_url;
56         camel_service_class->disconnect = _disconnect;
57         camel_service_class->is_connected = _is_connected;
58
59         /* virtual method overload */
60         gtk_object_class->finalize = _finalize;
61 }
62
63 GtkType
64 camel_service_get_type (void)
65 {
66         static GtkType camel_service_type = 0;
67         
68         if (!camel_service_type)        {
69                 GtkTypeInfo camel_service_info =        
70                 {
71                         "CamelService",
72                         sizeof (CamelService),
73                         sizeof (CamelServiceClass),
74                         (GtkClassInitFunc) camel_service_class_init,
75                         (GtkObjectInitFunc) NULL,
76                                 /* reserved_1 */ NULL,
77                                 /* reserved_2 */ NULL,
78                         (GtkClassInitFunc) NULL,
79                 };
80                 
81                 camel_service_type = gtk_type_unique (gtk_object_get_type (),
82                                                       &camel_service_info);
83         }
84         
85         return camel_service_type;
86 }
87
88
89 static void           
90 _finalize (GtkObject *object)
91 {
92         CamelService *camel_service = CAMEL_SERVICE (object);
93
94         CAMEL_LOG_FULL_DEBUG ("Entering CamelService::finalize\n");
95
96         if (camel_service->url)
97                 g_url_free (camel_service->url);
98         if (camel_service->session)
99                 gtk_object_unref (GTK_OBJECT (camel_service->session));
100
101         GTK_OBJECT_CLASS (parent_class)->finalize (object);
102         CAMEL_LOG_FULL_DEBUG ("Leaving CamelService::finalize\n");
103 }
104
105
106 /**
107  * camel_service_new: create a new CamelService or subtype
108  * @type: the GtkType of the class to create
109  * @session: the session for the service
110  * @url: the default URL for the service (may be NULL)
111  * @ex: a CamelException
112  *
113  * Creates a new CamelService (or one of its subtypes), initialized
114  * with the given parameters.
115  *
116  * Return value: the CamelService, or NULL.
117  **/
118 CamelService *
119 camel_service_new (GtkType type, CamelSession *session, Gurl *url,
120                    CamelException *ex)
121 {
122         CamelService *service;
123
124         g_assert(session);
125
126         service = CAMEL_SERVICE (gtk_object_new (type, NULL));
127         service->session = session;
128         gtk_object_ref (GTK_OBJECT (session));
129         if (url) {
130                 if (!_set_url (service, url, ex))
131                         return NULL;
132         }
133
134         return service;
135 }
136
137 /**
138  * _connect : connect to a service 
139  * @service: object to connect
140  * @ex: a CamelException
141  *
142  * connect to the service using the parameters 
143  * stored in the session it is initialized with
144  *
145  * Return value: whether or not the connection succeeded
146  **/
147 static gboolean
148 _connect (CamelService *service, CamelException *ex)
149 {
150         g_assert (service->session);
151         /* XXX it's possible that this should be an exception
152          * rather than an assertion... I'm not sure how the code
153          * is supposed to be used.
154          */
155         g_assert (service->url);
156
157         service->connected = TRUE;
158         return TRUE;
159 }
160
161
162
163 /**
164  * camel_service_connect:connect to a service 
165  * @service: CamelService object
166  * @ex: a CamelException
167  * 
168  * connect to the service using the parameters 
169  * stored in the session it is initialized with
170  *
171  * Return value: whether or not the connection succeeded
172  **/
173 gboolean
174 camel_service_connect (CamelService *service, CamelException *ex)
175 {
176         return CSERV_CLASS(service)->connect(service, ex);
177 }
178
179
180
181 /**
182  * _connect_with_url: connect to the specified address
183  * @service: object to connect
184  * @url: URL describing service to connect to
185  * @ex: a CamelException
186  *
187  * Connect to the service, but do not use the session
188  * default parameters to retrieve server's address
189  *
190  * Return value: whether or not the connection succeeded
191  **/
192 static gboolean
193 _connect_with_url (CamelService *service, Gurl *url, CamelException *ex)
194 {
195         g_assert (service->session);
196
197         if (!_set_url (service, url, ex))
198                 return FALSE;
199
200         return CSERV_CLASS(service)->connect (service, ex);
201 }
202
203 /**
204  * camel_service_connect_with_url: connect a service 
205  * @service:  the service to connect
206  * @url:  URL describing the service to connect to
207  * @ex: a CamelException
208  * 
209  * Connect to a service, but do not use the session
210  * default parameters to retrieve server's address
211  *
212  * Return value: whether or not the connection succeeded
213  **/
214 gboolean
215 camel_service_connect_with_url (CamelService *service, char *url,
216                                 CamelException *ex)
217 {
218         return CSERV_CLASS(service)->connect_with_url (service, g_url_new(url),
219                                                        ex);
220 }
221
222
223
224 /**
225  * _disconnect : disconnect from a service 
226  * @service: object to disconnect
227  * @ex: a CamelException
228  *
229  * disconnect from the service
230  *
231  * Return value: whether or not the disconnection succeeded without
232  * errors. (Consult @ex if FALSE.)
233  **/
234 static gboolean
235 _disconnect (CamelService *service, CamelException *ex)
236 {
237         service->connected = FALSE;
238
239         return TRUE;
240 }
241
242
243
244 /**
245  * camel_service_disconnect: disconnect from a service 
246  * @service: CamelService object
247  * @ex: a CamelException
248  *
249  * disconnect from the service
250  *
251  * Return value: whether or not the disconnection succeeded without
252  * errors. (Consult @ex if FALSE.)
253  **/
254 gboolean
255 camel_service_disconnect (CamelService *service, CamelException *ex)
256 {
257         return CSERV_CLASS(service)->disconnect(service, ex);
258 }
259
260
261
262 /**
263  * _is_connected: test if the service object is connected
264  * @service: object to test
265  * 
266  * Return value: whether or not the service is connected
267  **/
268 static gboolean
269 _is_connected (CamelService *service)
270 {
271         return service->connected;
272 }
273
274
275 /**
276  * camel_service_is_connected: test if the service object is connected
277  * @service: object to test
278  * 
279  * Return value: whether or not the service is connected
280  **/
281 gboolean
282 camel_service_is_connected (CamelService *service)
283 {
284         return CSERV_CLASS(service)->is_connected(service);
285 }
286
287
288 /**
289  * _set_url: Validate a URL and set it as the default for a service
290  * @service: the CamelService
291  * @url_string: the URL
292  * @ex: a CamelException
293  *
294  * This converts the URL to a Gurl, validates it for the service,
295  * and sets it as the default URL for the service.
296  *
297  * Return value: success or failure
298  **/
299 static gboolean
300 _set_url (CamelService *service, Gurl *url, CamelException *ex)
301 {
302         char *url_string;
303
304         if (service->url_flags & CAMEL_SERVICE_URL_NEED_USER &&
305             (url->user == NULL || url->user[0] == '\0')) {
306                 url_string = g_url_to_string (url, FALSE);
307                 camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID,
308                                       "URL '%s' needs a username component",
309                                       url_string);
310                 g_free (url_string);
311                 return FALSE;
312         } else if (service->url_flags & CAMEL_SERVICE_URL_NEED_HOST &&
313                    (url->host == NULL || url->host[0] == '\0')) {
314                 url_string = g_url_to_string (url, FALSE);
315                 camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID,
316                                       "URL '%s' needs a host component",
317                                       url_string);
318                 g_free (url_string);
319                 return FALSE;
320         } else if (service->url_flags & CAMEL_SERVICE_URL_NEED_PATH &&
321                    (url->path == NULL || url->path[0] == '\0')) {
322                 url_string = g_url_to_string (url, FALSE);
323                 camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID,
324                                       "URL '%s' needs a path component",
325                                       url_string);
326                 g_free (url_string);
327                 return FALSE;
328         }
329
330         if (service->url)
331                 g_url_free (service->url);
332         service->url = url;
333         return TRUE;
334 }
335
336 /**
337  * camel_service_get_url: get the url representing a service
338  * @service: the service
339  * 
340  * returns the URL representing a service. The returned URL must be
341  * freed when it is no longer needed. For security reasons, this
342  * routine does not return the password.
343  * 
344  * Return value: the url name
345  **/
346 char *
347 camel_service_get_url (CamelService *service)
348 {
349         return g_url_to_string(service->url, FALSE);
350 }
351
352
353 /**
354  * camel_service_get_session: return the session associated with a service
355  * @service: the service
356  *
357  * returns the CamelSession associated with the service.
358  *
359  * Return value: the session
360  **/
361 CamelSession *
362 camel_service_get_session (CamelService *service)
363 {
364         return service->session;
365 }