+/*
+ * Copyright (C) 2007 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#include <atompub/atom.h>
+
+#include <glib.h>
+
+#include <string.h>
+
+struct _atom_backend
+{
+ AtomEntry * (*retrieve_entry) (AtomCtx *, AtomID *);
+ void (*enumerate_entries) (AtomCtx *, char ***, AtomEntry ***, size_t *);
+ int (*is_feed) (AtomCtx *, AtomID *);
+};
+
+AtomBackend *
+atom_backend_new ()
+{
+ AtomBackend *backend;
+ backend = g_slice_new (AtomBackend);
+ backend->retrieve_entry = NULL;
+ backend->enumerate_entries = NULL;
+ return backend;
+}
+
+void
+atom_backend_delete (AtomBackend *backend)
+{
+ g_slice_free (AtomBackend, backend);
+}
+
+void
+atom_backend_retrieve_entry_set (AtomBackend *backend,
+ AtomEntry *retrieve_entry (AtomCtx *,
+ AtomID *))
+{
+ backend->retrieve_entry = retrieve_entry;
+}
+
+void
+atom_backend_enumerate_entries_set (AtomBackend *backend,
+ void enumerate_entries (AtomCtx *,
+ char ***,
+ AtomEntry ***,
+ size_t *))
+{
+ backend->enumerate_entries = enumerate_entries;
+}
+
+void
+atom_backend_is_feed_set (AtomBackend *backend,
+ int is_feed (AtomCtx *, AtomID *))
+{
+ backend->is_feed = is_feed;
+}
+
+AtomEntry *
+atom_retrieve_entry (AtomCtx *ctx, AtomID *id)
+{
+ AtomBackend *backend;
+ backend = atom_backend (ctx);
+ if (backend && backend->retrieve_entry)
+ return backend->retrieve_entry (ctx, id);
+ return NULL;
+}
+
+void
+atom_backend_enumerate_entries (AtomCtx *ctx, char *** reqs,
+ AtomEntry *** entries, size_t *len)
+{
+ AtomBackend *backend;
+ char **rreqs = NULL;
+ AtomEntry **rentries = NULL;
+ size_t rlen = 0;
+ int i;
+ backend = atom_backend (ctx);
+ if (backend && backend->enumerate_entries)
+ {
+ backend->enumerate_entries (ctx, &rreqs, &rentries, &rlen);
+ }
+ if (reqs)
+ {
+ *reqs = rreqs;
+ }
+ else
+ {
+ for (i = 0; i < rlen; i++)
+ g_free (rreqs[i]);
+ g_free (rreqs);
+ }
+ if (entries)
+ {
+ *entries = rentries;
+ }
+ else
+ {
+ for (i = 0; i < rlen; i++)
+ atom_entry_delete (rentries[i]);
+ g_free (rentries);
+ }
+ if (len)
+ *len = rlen;
+}
+
+int
+atom_is_feed (AtomCtx *ctx, AtomID *id)
+{
+ AtomBackend *backend;
+ AtomError *aerr;
+ backend = atom_backend (ctx);
+ if (backend && backend->is_feed)
+ {
+ return backend->is_feed (ctx, id);
+ }
+ /* Frontend may make the decision of whether the requested resource is
+ * a feed or not. If it is not able to do so and backend isn't either,
+ * it is an error.
+ */
+ aerr = atom_error_new ();
+ atom_error_code_set (aerr, 404);
+ atom_error_message_set (aerr, "Not Found");
+ atom_error_set (ctx, aerr);
+ return 0;
+}
+
+AtomFeed *
+atom_retrieve_feed (AtomCtx *ctx)
+{
+ AtomFeed *feed;
+ AtomEntry **entries;
+ size_t len;
+ atom_backend_enumerate_entries (ctx, NULL, &entries, &len);
+ if (atom_error_get (ctx) != NULL)
+ return NULL;
+ feed = atom_feed_new ();
+ atom_feed_entry_append_array (feed, entries, len);
+ g_free (entries);
+ return feed;
+}
+
+AtomResource *
+atom_retrieve_resource (AtomCtx *ctx, AtomID *id)
+{
+ AtomResource *res;
+ res = NULL;
+ if (atom_is_feed (ctx, id))
+ {
+ AtomFeed *feed;
+ feed = atom_retrieve_feed (ctx);
+ if (feed == NULL)
+ return NULL;
+ res = atom_resource_new_from_feed (feed);
+ atom_feed_delete (feed);
+ }
+ else if (atom_error_get (ctx) == NULL)
+ {
+ AtomEntry *entry;
+ entry = atom_retrieve_entry (ctx, id);
+ if (entry == NULL)
+ return NULL;
+ res = atom_resource_new_from_entry (entry);
+ atom_entry_delete (entry);
+ }
+ return res;
+}