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>
31 struct json_object *pubarr;
32 struct json_object *direct;
33 struct json_object *byapp;
40 struct afapps applications;
43 struct appfwk *appfwk_create()
45 struct appfwk *appfwk = malloc(sizeof * appfwk);
52 appfwk->applications.pubarr = NULL;
53 appfwk->applications.direct = NULL;
54 appfwk->applications.byapp = NULL;
59 void appfwk_addref(struct appfwk *appfwk)
65 void appfwk_unref(struct appfwk *appfwk)
68 if (!--appfwk->refcount) {
69 json_object_put(appfwk->applications.pubarr);
70 json_object_put(appfwk->applications.direct);
71 json_object_put(appfwk->applications.byapp);
72 while (appfwk->nrroots)
73 free(appfwk->roots[--appfwk->nrroots]);
79 int appfwk_add_root(struct appfwk *appfwk, const char *path)
86 /* don't depend on the cwd and unique name */
87 r = realpath(path, NULL);
91 /* avoiding duplications */
93 roots = appfwk->roots;
94 for (i = 0 ; i < n ; i++) {
95 if (!strcmp(r, roots[i])) {
102 roots = realloc(roots, (n + 1) * sizeof(roots[0]));
109 appfwk->roots = roots;
114 static int json_add(struct json_object *obj, const char *key, struct json_object *val)
116 json_object_object_add(obj, key, val);
120 static int json_add_str(struct json_object *obj, const char *key, const char *val)
122 struct json_object *str = json_object_new_string (val ? val : "");
123 return str ? json_add(obj, key, str) : -1;
126 static int json_add_int(struct json_object *obj, const char *key, int val)
128 struct json_object *v = json_object_new_int (val);
129 return v ? json_add(obj, key, v) : -1;
132 static int addapp(struct afapps *apps, const char *path)
134 struct wgt_info *info;
135 const struct wgt_desc *desc;
136 const struct wgt_desc_feature *feat;
137 struct json_object *priv = NULL, *pub, *bya, *plugs, *str;
140 /* connect to the widget */
141 info = wgt_info_createat(AT_FDCWD, path, 0, 1, 0);
144 desc = wgt_info_desc(info);
146 /* create the application id */
147 appid = alloca(2 + strlen(desc->id) + strlen(desc->version));
148 end = stpcpy(appid, desc->id);
150 strcpy(end, desc->version);
152 /* create the application structure */
153 priv = json_object_new_object();
157 pub = json_object_new_object();
161 if (json_add(priv, "public", pub)) {
162 json_object_put(pub);
166 plugs = json_object_new_array();
170 if (json_add(priv, "plugins", plugs)) {
171 json_object_put(plugs);
175 if(json_add_str(pub, "id", appid)
176 || json_add_str(priv, "id", desc->id)
177 || json_add_str(pub, "version", desc->version)
178 || json_add_str(priv, "path", path)
179 || json_add_int(pub, "width", desc->width)
180 || json_add_int(pub, "height", desc->height)
181 || json_add_str(pub, "name", desc->name)
182 || json_add_str(pub, "description", desc->description)
183 || json_add_str(pub, "shortname", desc->name_short)
184 || json_add_str(pub, "author", desc->author))
187 feat = desc->features;
189 static const char prefix[] = FWK_PREFIX_PLUGIN;
190 if (!memcmp(feat->name, prefix, sizeof prefix - 1)) {
191 str = json_object_new_string (feat->name + sizeof prefix - 1);
194 if (json_object_array_add(plugs, str)) {
195 json_object_put(str);
202 /* record the application structure */
203 if (!json_object_object_get_ex(apps->byapp, desc->id, &bya)) {
204 bya = json_object_new_object();
207 if (json_add(apps->byapp, desc->id, bya)) {
208 json_object_put(bya);
213 if (json_add(apps->direct, appid, priv))
215 json_object_get(priv);
217 if (json_add(bya, desc->version, priv)) {
218 json_object_put(priv);
222 if (json_object_array_add(apps->pubarr, pub))
225 wgt_info_unref(info);
229 json_object_put(priv);
230 wgt_info_unref(info);
241 static int enumentries(struct enumdata *data, int (*callto)(struct enumdata *))
246 struct dirent entry, *e;
248 /* opens the directory */
249 dir = opendir(data->path);
253 /* prepare appending entry names */
254 beg = data->path + data->length;
257 /* enumerate entries */
258 rc = readdir_r(dir, &entry, &e);
260 if (entry.d_name[0] != '.' || (entry.d_name[1] && (entry.d_name[1] != '.' || entry.d_name[2]))) {
262 end = stpcpy(beg, entry.d_name);
263 data->length = end - data->path;
264 /* call the function */
269 rc = readdir_r(dir, &entry, &e);
275 static int recordapp(struct enumdata *data)
277 return addapp(&data->apps, data->path);
280 /* enumerate the versions */
281 static int enumvers(struct enumdata *data)
283 int rc = enumentries(data, recordapp);
284 return !rc || errno != ENOTDIR ? 0 : rc;
287 /* regenerate the list of applications */
288 int appfwk_update_applications(struct appfwk *af)
291 struct enumdata edata;
292 struct afapps oldapps;
294 /* create the result */
295 edata.apps.pubarr = json_object_new_array();
296 edata.apps.direct = json_object_new_object();
297 edata.apps.byapp = json_object_new_object();
298 if (edata.apps.pubarr == NULL || edata.apps.direct == NULL || edata.apps.byapp == NULL) {
303 for (iroot = 0 ; iroot < af->nrroots ; iroot++) {
304 edata.length = stpcpy(edata.path, af->roots[iroot]) - edata.path;
305 assert(edata.length < sizeof edata.path);
306 /* enumerate the applications */
307 rc = enumentries(&edata, enumvers);
311 /* commit the result */
312 oldapps = af->applications;
313 af->applications = edata.apps;
314 json_object_put(oldapps.pubarr);
315 json_object_put(oldapps.direct);
316 json_object_put(oldapps.byapp);
320 json_object_put(edata.apps.pubarr);
321 json_object_put(edata.apps.direct);
322 json_object_put(edata.apps.byapp);
326 int appfwk_ensure_applications(struct appfwk *af)
328 return af->applications.pubarr ? 0 : appfwk_update_applications(af);
331 struct json_object *appfwk_application_list(struct appfwk *af)
333 return appfwk_ensure_applications(af) ? NULL : af->applications.pubarr;
336 struct json_object *appfwk_get_application(struct appfwk *af, const char *id)
338 struct json_object *result;
339 if (!appfwk_ensure_applications(af) && json_object_object_get_ex(af->applications.direct, id, &result))
344 struct json_object *appfwk_get_application_public(struct appfwk *af, const char *id)
346 struct json_object *result = appfwk_get_application(af, id);
347 return result && json_object_object_get_ex(result, "public", &result) ? result : NULL;
353 #if defined(TESTAPPFWK)
357 struct appfwk *af = appfwk_create();
358 appfwk_add_root(af,FWK_APP_DIR);
359 appfwk_update_applications(af);
360 printf("array = %s\n", json_object_to_json_string_ext(af->applications.pubarr, 3));
361 printf("direct = %s\n", json_object_to_json_string_ext(af->applications.direct, 3));
362 printf("byapp = %s\n", json_object_to_json_string_ext(af->applications.byapp, 3));