Update entry xml node before using it
[cascardo/atompub.git] / src / 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   return backend;
41 }
42
43 void
44 atom_backend_delete (AtomBackend *backend)
45 {
46   g_slice_free (AtomBackend, backend);
47 }
48
49 void
50 atom_backend_retrieve_entry_set (AtomBackend *backend,
51                                  AtomEntry *retrieve_entry (AtomCtx *,
52                                                             AtomID *))
53 {
54   backend->retrieve_entry = retrieve_entry;
55 }
56
57 void
58 atom_backend_enumerate_entries_set (AtomBackend *backend,
59                                     void enumerate_entries (AtomCtx *,
60                                                             char ***,
61                                                             AtomEntry ***,
62                                                             size_t *))
63 {
64   backend->enumerate_entries = enumerate_entries;
65 }
66
67 void
68 atom_backend_is_feed_set (AtomBackend *backend,
69                           int is_feed (AtomCtx *, AtomID *))
70 {
71   backend->is_feed = is_feed;
72 }
73
74 AtomEntry *
75 atom_retrieve_entry (AtomCtx *ctx, AtomID *id)
76 {
77   AtomBackend *backend;
78   backend = atom_backend (ctx);
79   if (backend && backend->retrieve_entry)
80     return backend->retrieve_entry (ctx, id);
81   return NULL;
82 }
83
84 void
85 atom_backend_enumerate_entries (AtomCtx *ctx, char *** reqs,
86                                 AtomEntry *** entries, size_t *len)
87 {
88   AtomBackend *backend;
89   char **rreqs = NULL;
90   AtomEntry **rentries = NULL;
91   size_t rlen = 0;
92   int i;
93   backend = atom_backend (ctx);
94   if (backend && backend->enumerate_entries)
95     {
96       backend->enumerate_entries (ctx, &rreqs, &rentries, &rlen);
97     }
98   if (reqs)
99     {
100       *reqs = rreqs;
101     }
102   else
103     {
104       for (i = 0; i < rlen; i++)
105         g_free (rreqs[i]);
106       g_free (rreqs);
107     }
108   if (entries)
109     {
110       *entries = rentries;
111     }
112   else
113     {
114       for (i = 0; i < rlen; i++)
115         atom_entry_delete (rentries[i]);
116       g_free (rentries);
117     }
118   if (len)
119     *len = rlen;
120 }
121
122 int
123 atom_is_feed (AtomCtx *ctx, AtomID *id)
124 {
125   AtomBackend *backend;
126   AtomError *aerr;
127   backend = atom_backend (ctx);
128   if (backend && backend->is_feed)
129     {
130       return backend->is_feed (ctx, id);
131     }
132   /* Frontend may make the decision of whether the requested resource is
133    * a feed or not. If it is not able to do so and backend isn't either,
134    * it is an error.
135    */
136   aerr = atom_error_new ();
137   atom_error_code_set (aerr, 404);
138   atom_error_message_set (aerr, "Not Found");
139   atom_error_set (ctx, aerr);
140   return 0;
141 }
142
143 AtomFeed *
144 atom_retrieve_feed (AtomCtx *ctx)
145 {
146   AtomFeed *feed;
147   AtomEntry **entries;
148   size_t len;
149   atom_backend_enumerate_entries (ctx, NULL, &entries, &len);
150   if (atom_error_get (ctx) != NULL)
151     return NULL;
152   feed = atom_feed_new ();
153   atom_feed_entry_append_array (feed, entries, len);
154   g_free (entries);
155   return feed;
156 }
157
158 AtomResource *
159 atom_retrieve_resource (AtomCtx *ctx, AtomID *id)
160 {
161   AtomResource *res;
162   res = NULL;
163   if (atom_is_feed (ctx, id))
164     {
165       AtomFeed *feed;
166       feed = atom_retrieve_feed (ctx);
167       if (feed == NULL)
168         return NULL;
169       res = atom_resource_new_from_feed (feed);
170       atom_feed_delete (feed);
171     }
172   else if (atom_error_get (ctx) == NULL)
173     {
174       AtomEntry *entry;
175       entry = atom_retrieve_entry (ctx, id);
176       if (entry == NULL)
177         return NULL;
178       res = atom_resource_new_from_entry (entry);
179       atom_entry_delete (entry);
180     }
181   return res;
182 }