4e44c3c1a98e0f79a85a7fb1e0a819c97275768d
[cascardo/atompub.git] / atom / backend.c
1 /*
2  *  Copyright (C) 2007  Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
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
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along
15  *  with this program; if not, write to the Free Software Foundation, Inc.,
16  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19
20 #include <atompub/atom.h>
21
22 #include <glib.h>
23
24 #include <string.h>
25
26 struct _atom_backend
27 {
28   AtomEntry * (*retrieve_entry) (AtomCtx *, AtomID *);
29   void (*enumerate_entries) (AtomCtx *, char ***, AtomEntry ***, size_t *);
30   int  (*is_feed) (AtomCtx *, AtomID *);
31 };
32
33 AtomBackend *
34 atom_backend_new ()
35 {
36   AtomBackend *backend;
37   backend = g_slice_new (AtomBackend);
38   backend->retrieve_entry = NULL;
39   backend->enumerate_entries = NULL;
40   backend->is_feed = NULL;
41   return backend;
42 }
43
44 void
45 atom_backend_delete (AtomBackend *backend)
46 {
47   g_slice_free (AtomBackend, backend);
48 }
49
50 void
51 atom_backend_retrieve_entry_set (AtomBackend *backend,
52                                  AtomEntry *retrieve_entry (AtomCtx *,
53                                                             AtomID *))
54 {
55   backend->retrieve_entry = retrieve_entry;
56 }
57
58 void
59 atom_backend_enumerate_entries_set (AtomBackend *backend,
60                                     void enumerate_entries (AtomCtx *,
61                                                             char ***,
62                                                             AtomEntry ***,
63                                                             size_t *))
64 {
65   backend->enumerate_entries = enumerate_entries;
66 }
67
68 void
69 atom_backend_is_feed_set (AtomBackend *backend,
70                           int is_feed (AtomCtx *, AtomID *))
71 {
72   backend->is_feed = is_feed;
73 }
74
75 AtomEntry *
76 atom_retrieve_entry (AtomCtx *ctx, AtomID *id)
77 {
78   AtomBackend *backend;
79   backend = atom_backend (ctx);
80   if (backend && backend->retrieve_entry)
81     return backend->retrieve_entry (ctx, id);
82   return NULL;
83 }
84
85 void
86 atom_backend_enumerate_entries (AtomCtx *ctx, char *** reqs,
87                                 AtomEntry *** entries, size_t *len)
88 {
89   AtomBackend *backend;
90   char **rreqs = NULL;
91   AtomEntry **rentries = NULL;
92   size_t rlen = 0;
93   int i;
94   backend = atom_backend (ctx);
95   if (backend && backend->enumerate_entries)
96     {
97       backend->enumerate_entries (ctx, &rreqs, &rentries, &rlen);
98     }
99   if (reqs)
100     {
101       *reqs = rreqs;
102     }
103   else
104     {
105       for (i = 0; i < rlen; i++)
106         g_free (rreqs[i]);
107       g_free (rreqs);
108     }
109   if (entries)
110     {
111       *entries = rentries;
112     }
113   else
114     {
115       for (i = 0; i < rlen; i++)
116         atom_entry_delete (rentries[i]);
117       g_free (rentries);
118     }
119   if (len)
120     *len = rlen;
121 }
122
123 int
124 atom_is_feed (AtomCtx *ctx, AtomID *id)
125 {
126   AtomBackend *backend;
127   AtomError *aerr;
128   backend = atom_backend (ctx);
129   if (backend && backend->is_feed)
130     {
131       return backend->is_feed (ctx, id);
132     }
133   /* Frontend may make the decision of whether the requested resource is
134    * a feed or not. If it is not able to do so and backend isn't either,
135    * it is an error.
136    */
137   aerr = atom_error_new ();
138   atom_error_code_set (aerr, 404);
139   atom_error_message_set (aerr, "Not Found");
140   atom_error_set (ctx, aerr);
141   return 0;
142 }
143
144 AtomFeed *
145 atom_retrieve_feed (AtomCtx *ctx)
146 {
147   AtomFeed *feed;
148   AtomEntry **entries;
149   size_t len;
150   atom_backend_enumerate_entries (ctx, NULL, &entries, &len);
151   if (atom_error_get (ctx) != NULL)
152     return NULL;
153   feed = atom_feed_new ();
154   atom_feed_entry_append_array (feed, entries, len);
155   g_free (entries);
156   return feed;
157 }
158
159 AtomResource *
160 atom_retrieve_resource (AtomCtx *ctx, AtomID *id)
161 {
162   AtomResource *res;
163   res = NULL;
164   if (atom_is_feed (ctx, id))
165     {
166       AtomFeed *feed;
167       feed = atom_retrieve_feed (ctx);
168       if (feed == NULL)
169         return NULL;
170       res = atom_resource_new_from_feed (feed);
171       atom_feed_delete (feed);
172     }
173   else if (atom_error_get (ctx) == NULL)
174     {
175       AtomEntry *entry;
176       entry = atom_retrieve_entry (ctx, id);
177       if (entry == NULL)
178         return NULL;
179       res = atom_resource_new_from_entry (entry);
180       atom_entry_delete (entry);
181     }
182   return res;
183 }