4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
24 #include <sys/types.h>
32 struct json_object *pubarr;
33 struct json_object *direct;
34 struct json_object *byapp;
41 struct afapps applications;
44 struct af_db *af_db_create()
46 struct af_db *afdb = malloc(sizeof * afdb);
53 afdb->applications.pubarr = NULL;
54 afdb->applications.direct = NULL;
55 afdb->applications.byapp = NULL;
60 void af_db_addref(struct af_db *afdb)
66 void af_db_unref(struct af_db *afdb)
69 if (!--afdb->refcount) {
70 json_object_put(afdb->applications.pubarr);
71 json_object_put(afdb->applications.direct);
72 json_object_put(afdb->applications.byapp);
74 free(afdb->roots[--afdb->nrroots]);
80 int af_db_add_root(struct af_db *afdb, const char *path)
87 /* don't depend on the cwd and unique name */
88 r = realpath(path, NULL);
92 /* avoiding duplications */
95 for (i = 0 ; i < n ; i++) {
96 if (!strcmp(r, roots[i])) {
103 roots = realloc(roots, (n + 1) * sizeof(roots[0]));
115 static int json_add(struct json_object *obj, const char *key, struct json_object *val)
117 json_object_object_add(obj, key, val);
121 static int json_add_str(struct json_object *obj, const char *key, const char *val)
123 struct json_object *str = json_object_new_string (val ? val : "");
124 return str ? json_add(obj, key, str) : -1;
127 static int json_add_int(struct json_object *obj, const char *key, int val)
129 struct json_object *v = json_object_new_int (val);
130 return v ? json_add(obj, key, v) : -1;
133 static int addapp(struct afapps *apps, const char *path)
135 struct wgt_info *info;
136 const struct wgt_desc *desc;
137 const struct wgt_desc_feature *feat;
138 struct json_object *priv = NULL, *pub, *bya, *plugs, *str;
141 /* connect to the widget */
142 info = wgt_info_createat(AT_FDCWD, path, 0, 1, 0);
145 desc = wgt_info_desc(info);
147 /* create the application id */
148 appid = alloca(2 + strlen(desc->id) + strlen(desc->version));
149 end = stpcpy(appid, desc->id);
151 strcpy(end, desc->version);
153 /* create the application structure */
154 priv = json_object_new_object();
158 pub = json_object_new_object();
162 if (json_add(priv, "public", pub)) {
163 json_object_put(pub);
167 plugs = json_object_new_array();
171 if (json_add(priv, "plugins", plugs)) {
172 json_object_put(plugs);
176 if(json_add_str(priv, "id", desc->id)
177 || json_add_str(priv, "path", path)
178 || json_add_str(priv, "content", desc->content_src)
179 || json_add_str(priv, "type", desc->content_type)
180 || json_add_str(pub, "id", appid)
181 || json_add_str(pub, "version", desc->version)
182 || json_add_int(pub, "width", desc->width)
183 || json_add_int(pub, "height", desc->height)
184 || json_add_str(pub, "name", desc->name)
185 || json_add_str(pub, "description", desc->description)
186 || json_add_str(pub, "shortname", desc->name_short)
187 || json_add_str(pub, "author", desc->author))
190 feat = desc->features;
192 static const char prefix[] = FWK_PREFIX_PLUGIN;
193 if (!memcmp(feat->name, prefix, sizeof prefix - 1)) {
194 str = json_object_new_string (feat->name + sizeof prefix - 1);
197 if (json_object_array_add(plugs, str)) {
198 json_object_put(str);
205 /* record the application structure */
206 if (!json_object_object_get_ex(apps->byapp, desc->id, &bya)) {
207 bya = json_object_new_object();
210 if (json_add(apps->byapp, desc->id, bya)) {
211 json_object_put(bya);
216 if (json_add(apps->direct, appid, priv))
218 json_object_get(priv);
220 if (json_add(bya, desc->version, priv)) {
221 json_object_put(priv);
225 if (json_object_array_add(apps->pubarr, pub))
228 wgt_info_unref(info);
232 json_object_put(priv);
233 wgt_info_unref(info);
244 static int enumentries(struct enumdata *data, int (*callto)(struct enumdata *))
249 struct dirent entry, *e;
251 /* opens the directory */
252 dir = opendir(data->path);
256 /* prepare appending entry names */
257 beg = data->path + data->length;
260 /* enumerate entries */
261 rc = readdir_r(dir, &entry, &e);
263 if (entry.d_name[0] != '.' || (entry.d_name[1] && (entry.d_name[1] != '.' || entry.d_name[2]))) {
265 end = stpcpy(beg, entry.d_name);
266 data->length = end - data->path;
267 /* call the function */
272 rc = readdir_r(dir, &entry, &e);
278 static int recordapp(struct enumdata *data)
280 return addapp(&data->apps, data->path);
283 /* enumerate the versions */
284 static int enumvers(struct enumdata *data)
286 int rc = enumentries(data, recordapp);
287 return !rc || errno != ENOTDIR ? 0 : rc;
290 /* regenerate the list of applications */
291 int af_db_update_applications(struct af_db *afdb)
294 struct enumdata edata;
295 struct afapps oldapps;
297 /* create the result */
298 edata.apps.pubarr = json_object_new_array();
299 edata.apps.direct = json_object_new_object();
300 edata.apps.byapp = json_object_new_object();
301 if (edata.apps.pubarr == NULL || edata.apps.direct == NULL || edata.apps.byapp == NULL) {
306 for (iroot = 0 ; iroot < afdb->nrroots ; iroot++) {
307 edata.length = stpcpy(edata.path, afdb->roots[iroot]) - edata.path;
308 assert(edata.length < sizeof edata.path);
309 /* enumerate the applications */
310 rc = enumentries(&edata, enumvers);
314 /* commit the result */
315 oldapps = afdb->applications;
316 afdb->applications = edata.apps;
317 json_object_put(oldapps.pubarr);
318 json_object_put(oldapps.direct);
319 json_object_put(oldapps.byapp);
323 json_object_put(edata.apps.pubarr);
324 json_object_put(edata.apps.direct);
325 json_object_put(edata.apps.byapp);
329 int af_db_ensure_applications(struct af_db *afdb)
331 return afdb->applications.pubarr ? 0 : af_db_update_applications(afdb);
334 struct json_object *af_db_application_list(struct af_db *afdb)
336 return af_db_ensure_applications(afdb) ? NULL : afdb->applications.pubarr;
339 struct json_object *af_db_get_application(struct af_db *afdb, const char *id)
341 struct json_object *result;
342 if (!af_db_ensure_applications(afdb) && json_object_object_get_ex(afdb->applications.direct, id, &result))
347 struct json_object *af_db_get_application_public(struct af_db *afdb, const char *id)
349 struct json_object *result = af_db_get_application(afdb, id);
350 return result && json_object_object_get_ex(result, "public", &result) ? result : NULL;
356 #if defined(TESTAPPFWK)
360 struct af_db *afdb = af_db_create();
361 af_db_add_root(afdb,FWK_APP_DIR);
362 af_db_update_applications(afdb);
363 printf("array = %s\n", json_object_to_json_string_ext(afdb->applications.pubarr, 3));
364 printf("direct = %s\n", json_object_to_json_string_ext(afdb->applications.direct, 3));
365 printf("byapp = %s\n", json_object_to_json_string_ext(afdb->applications.byapp, 3));