1 /* GConfNativePeer.c -- Implements native methods for class GConfNativePeer
2 Copyright (C) 2003, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
45 #include <gconf/gconf-client.h>
49 #include "gnu_java_util_prefs_gconf_GConfNativePeer.h"
52 * Cached id, methods and objects
55 /** Reference count */
56 static int reference_count = 0;
58 /** GConfClient backend */
59 static GConfClient *client = NULL;
61 /** java.util.ArrayList class */
62 static jclass jlist_class = NULL;
64 /** java.util.ArrayList constructor id */
65 static jmethodID jlist_init_id = NULL;
67 /** ava.util.ArrayList add id */
68 static jmethodID jlist_add_id = NULL;
70 /* ***** PRIVATE FUNCTIONS DELCARATION ***** */
73 * Gets the reference of the default GConfClient and initialize the
75 * The client reference should be released with g_object_unref after use.
76 * This functions must be called with gdk lock held.
78 static void init_gconf_client (void);
81 * Throws a new runtime exception after a failure, with the given message.
83 static void throw_exception (JNIEnv * env, const char *msg);
86 * Throws the given exception after a failure, with the given message.
89 throw_exception_by_name (JNIEnv * env, const char *name, const char *msg);
92 * Return a reference to a java.util.ArrayList class.
94 static gboolean set_jlist_class (JNIEnv * env);
97 * Builds a new reference to a new java.util.ArrayList instace.
98 * The instance should be freed by the caller after use.
100 static jclass get_jlist_reference (JNIEnv * env, jclass jlist_class);
102 /* ***** END: PRIVATE FUNCTIONS DELCARATION ***** */
104 /* ***** NATIVE FUNCTIONS ***** */
107 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
112 JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_init_1class
113 (JNIEnv *env, jclass clazz)
115 if (reference_count == 0)
117 Java_gnu_java_util_prefs_gconf_GConfNativePeer_init_1id_1cache
126 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
127 * Method: init_id_chache
131 JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_init_1id_1cache
132 (JNIEnv *env, jclass clazz __attribute__ ((unused)))
136 gdk_threads_enter ();
137 init_gconf_client ();
138 gdk_threads_leave ();
140 /* if client is null, there is probably an out of memory */
143 /* release the string and throw a runtime exception */
144 throw_exception (env,
145 "Unable to initialize GConfClient in native code\n");
149 /* ***** java.util.ArrayList ***** */
150 if (set_jlist_class (env) == FALSE)
152 throw_exception (env,
153 "Unable to get valid reference to java.util.List in native code\n");
159 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
160 * Method: gconf_client_gconf_client_all_keys
161 * Signature: (Ljava/lang/String;)Ljava/util/List;
163 JNIEXPORT jobject JNICALL
164 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1gconf_1client_1all_1keys
165 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring node)
167 /* TODO: check all the calls to gdk_threads_enter/leave */
169 const char *dir = NULL;
171 GSList *entries = NULL;
174 /* java.util.ArrayList */
175 jobject jlist = NULL;
177 dir = JCL_jstring_to_cstring (env, node);
183 gdk_threads_enter ();
184 entries = gconf_client_all_entries (client, dir, &err);
185 gdk_threads_leave ();
188 throw_exception_by_name (env, "java/util/prefs/BackingStoreException",
193 JCL_free_cstring (env, node, dir);
197 jlist = get_jlist_reference (env, jlist_class);
200 throw_exception_by_name (env, "java/util/prefs/BackingStoreException",
201 "Unable to get java.util.List reference in native code\n");
202 JCL_free_cstring (env, node, dir);
203 g_slist_foreach (entries, (GFunc) gconf_entry_free, NULL);
204 g_slist_free (entries);
211 const char *_val = gconf_entry_get_key (tmp->data);
212 _val = strrchr (_val, '/');
214 (*env)->CallBooleanMethod (env, jlist, jlist_add_id,
215 (*env)->NewStringUTF (env, _val));
216 tmp = g_slist_next (tmp);
219 /* clean up things */
220 JCL_free_cstring (env, node, dir);
221 g_slist_foreach (entries, (GFunc) gconf_entry_free, NULL);
222 g_slist_free (entries);
228 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
229 * Method: gconf_client_gconf_client_all_nodes
230 * Signature: (Ljava/lang/String;)Ljava/util/List;
232 JNIEXPORT jobject JNICALL
233 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1gconf_1client_1all_1nodes
234 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring node)
236 const char *dir = NULL;
238 GSList *entries = NULL;
241 /* java.util.ArrayList */
242 jobject jlist = NULL;
244 dir = JCL_jstring_to_cstring (env, node);
250 gdk_threads_enter ();
251 entries = gconf_client_all_dirs (client, dir, &err);
252 gdk_threads_leave ();
255 throw_exception_by_name (env, "java/util/prefs/BackingStoreException",
259 JCL_free_cstring (env, node, dir);
263 jlist = get_jlist_reference (env, jlist_class);
266 throw_exception_by_name (env, "java/util/prefs/BackingStoreException",
267 "Unable to get java.util.List reference in native code\n");
268 JCL_free_cstring (env, node, dir);
269 g_slist_foreach (entries, (GFunc) gconf_entry_free, NULL);
270 g_slist_free (entries);
277 const char *_val = tmp->data;
278 _val = strrchr (_val, '/');
280 (*env)->CallBooleanMethod (env, jlist, jlist_add_id,
281 (*env)->NewStringUTF (env, _val));
282 tmp = g_slist_next (tmp);
285 /* clean up things */
286 JCL_free_cstring (env, node, dir);
287 g_slist_foreach (entries, (GFunc) gconf_entry_free, NULL);
288 g_slist_free (entries);
294 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
295 * Method: gconf_client_suggest_sync
298 JNIEXPORT void JNICALL
299 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1suggest_1sync
300 (JNIEnv *env, jclass clazz __attribute__ ((unused)))
304 gdk_threads_enter ();
305 gconf_client_suggest_sync (client, &err);
306 gdk_threads_leave ();
309 throw_exception_by_name (env, "java/util/prefs/BackingStoreException",
317 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
318 * Method: gconf_client_unset
319 * Signature: (Ljava/lang/String;)Z
321 JNIEXPORT jboolean JNICALL
322 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1unset
323 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring key)
325 const char *_key = NULL;
326 gboolean result = JNI_FALSE;
329 _key = JCL_jstring_to_cstring (env, key);
335 gdk_threads_enter ();
336 result = gconf_client_unset (client, _key, &err);
337 gdk_threads_leave ();
345 JCL_free_cstring (env, key, _key);
351 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
352 * Method: gconf_client_get_string
353 * Signature: (Ljava/lang/String;)Ljava/lang/String;
355 JNIEXPORT jstring JNICALL
356 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1get_1string
357 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring key)
359 const char *_key = NULL;
360 const char *_value = NULL;
362 jstring result = NULL;
364 _key = JCL_jstring_to_cstring (env, key);
370 gdk_threads_enter ();
371 _value = gconf_client_get_string (client, _key, &err);
372 gdk_threads_leave ();
373 JCL_free_cstring (env, key, _key);
377 if (_value != NULL) g_free ((gpointer) _value);
384 /* Even if Gconf reported no error it is possible that NULL was returned */
385 /* and it should be prevented to create a Java string from that value. */
388 result = (*env)->NewStringUTF (env, _value);
389 g_free ((gpointer) _value);
396 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
397 * Method: gconf_client_set_string
398 * Signature: (Ljava/lang/String;Ljava/lang/String;)Z
400 JNIEXPORT jboolean JNICALL
401 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1set_1string
402 (JNIEnv *env, jclass clazz __attribute__ ((unused)),
403 jstring key, jstring value)
405 const char *_key = NULL;
406 const char *_value = NULL;
409 gboolean result = JNI_FALSE;
411 /* load an UTF string from the virtual machine. */
412 _key = JCL_jstring_to_cstring (env, key);
413 _value = JCL_jstring_to_cstring (env, value);
414 if (_key == NULL || _value == NULL)
419 gdk_threads_enter ();
420 result = gconf_client_set_string (client, _key, _value, &err);
421 gdk_threads_leave ();
429 JCL_free_cstring (env, key, _key);
430 JCL_free_cstring (env, value, _value);
432 return (jboolean) result;
436 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
437 * Method: gconf_client_remove_dir
438 * Signature: (Ljava/lang/String;)V
440 JNIEXPORT void JNICALL
441 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1remove_1dir
442 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring node)
444 const char *dir = NULL;
446 dir = JCL_jstring_to_cstring (env, node);
450 gdk_threads_enter ();
451 gconf_client_remove_dir (client, dir, NULL);
452 gdk_threads_leave ();
454 JCL_free_cstring (env, node, dir);
458 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
459 * Method: gconf_client_add_dir
460 * Signature: (Ljava/lang/String;)V
462 JNIEXPORT void JNICALL
463 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1add_1dir
464 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring node)
466 const char *dir = NULL;
468 dir = JCL_jstring_to_cstring (env, node);
473 gdk_threads_enter ();
474 gconf_client_add_dir (client, dir, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
475 gdk_threads_leave ();
477 JCL_free_cstring (env, node, dir);
481 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
482 * Method: gconf_client_dir_exists
483 * Signature: (Ljava/lang/String;)Z
485 JNIEXPORT jboolean JNICALL
486 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1dir_1exists
487 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring node)
489 const char *dir = NULL;
491 jboolean value = JNI_FALSE;
493 dir = JCL_jstring_to_cstring (env, node);
497 /* on error return false */
498 gdk_threads_enter ();
499 value = gconf_client_dir_exists (client, dir, &err);
500 gdk_threads_leave ();
504 JCL_free_cstring (env, node, dir);
510 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
511 * Method: finalize_class
515 JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_finalize_1class
516 (JNIEnv *env, jclass clazz __attribute__ ((unused)))
518 if (reference_count == 0)
520 /* last reference, free all resources and return */
521 gdk_threads_enter ();
522 g_object_unref (G_OBJECT (client));
523 gdk_threads_leave ();
525 (*env)->DeleteGlobalRef (env, jlist_class);
528 jlist_init_id = NULL;
537 /* ***** END: NATIVE FUNCTIONS ***** */
539 /* ***** PRIVATE FUNCTIONS IMPLEMENTATION ***** */
541 static void throw_exception (JNIEnv *env, const char *msg)
543 throw_exception_by_name (env, "java/lang/RuntimeException", msg);
547 throw_exception_by_name (JNIEnv *env, const char *name, const char *msg)
549 JCL_ThrowException (env, name, msg);
552 static void init_gconf_client (void)
555 client = gconf_client_get_default ();
558 static gboolean set_jlist_class (JNIEnv *env)
560 jclass local_jlist_class = NULL;
562 /* gets a reference to the ArrayList class */
563 local_jlist_class = JCL_FindClass (env, "java/util/ArrayList");
564 if (local_jlist_class == NULL)
569 jlist_class = (*env)->NewGlobalRef (env, local_jlist_class);
570 (*env)->DeleteLocalRef (env, local_jlist_class);
571 if (jlist_class == NULL)
576 /* and initialize it */
577 jlist_init_id = (*env)->GetMethodID (env, jlist_class, "<init>", "()V");
578 if (jlist_init_id == NULL)
583 jlist_add_id = (*env)->GetMethodID (env, jlist_class, "add",
584 "(Ljava/lang/Object;)Z");
585 if (jlist_add_id == NULL)
593 static jobject get_jlist_reference (JNIEnv *env, jclass jlist_class)
595 return (*env)->NewObject (env, jlist_class, jlist_init_id);
598 /* ***** END: PRIVATE FUNCTIONS IMPLEMENTATION ***** */