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
111 JNIEXPORT void JNICALL
112 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
130 JNIEXPORT void JNICALL
131 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_all_keys
161 * Signature: (Ljava/lang/String;)Ljava/util/List;
163 JNIEXPORT jobject JNICALL
164 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_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;
170 const char *_val = NULL;
171 const char *_val_unescaped = NULL;
174 GSList *entries = NULL;
177 /* java.util.ArrayList */
178 jobject jlist = NULL;
180 dir = JCL_jstring_to_cstring (env, node);
186 gdk_threads_enter ();
187 entries = gconf_client_all_entries (client, dir, &err);
188 gdk_threads_leave ();
191 throw_exception_by_name (env, "java/util/prefs/BackingStoreException",
196 JCL_free_cstring (env, node, dir);
200 jlist = get_jlist_reference (env, jlist_class);
203 throw_exception_by_name (env, "java/util/prefs/BackingStoreException",
204 "Unable to get java.util.List reference in native code\n");
205 JCL_free_cstring (env, node, dir);
206 g_slist_foreach (entries, (GFunc) gconf_entry_free, NULL);
207 g_slist_free (entries);
214 _val = gconf_entry_get_key (tmp->data);
215 _val = strrchr (_val, '/');
218 _val_unescaped = gconf_unescape_key (_val, strlen (_val));
220 (*env)->CallBooleanMethod (env, jlist, jlist_add_id,
221 (*env)->NewStringUTF (env, _val_unescaped));
223 tmp = g_slist_next (tmp);
225 g_free ((gpointer) _val_unescaped);
228 /* clean up things */
229 JCL_free_cstring (env, node, dir);
230 g_slist_foreach (entries, (GFunc) gconf_entry_free, NULL);
231 g_slist_free (entries);
237 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
238 * Method: gconf_client_all_nodes
239 * Signature: (Ljava/lang/String;)Ljava/util/List;
241 JNIEXPORT jobject JNICALL
242 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1all_1nodes
243 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring node)
245 const char *dir = NULL;
246 const char *_val = NULL;
247 const char *_val_unescaped = NULL;
250 GSList *entries = NULL;
253 /* java.util.ArrayList */
254 jobject jlist = NULL;
256 dir = JCL_jstring_to_cstring (env, node);
262 gdk_threads_enter ();
263 entries = gconf_client_all_dirs (client, dir, &err);
264 gdk_threads_leave ();
267 throw_exception_by_name (env, "java/util/prefs/BackingStoreException",
271 JCL_free_cstring (env, node, dir);
275 jlist = get_jlist_reference (env, jlist_class);
278 throw_exception_by_name (env, "java/util/prefs/BackingStoreException",
279 "Unable to get java.util.List reference in native code\n");
280 JCL_free_cstring (env, node, dir);
281 g_slist_foreach (entries, (GFunc) gconf_entry_free, NULL);
282 g_slist_free (entries);
291 _val = strrchr (_val, '/');
294 _val_unescaped = gconf_unescape_key (_val, strlen (_val));
296 (*env)->CallBooleanMethod (env, jlist, jlist_add_id,
297 (*env)->NewStringUTF (env, _val_unescaped));
299 tmp = g_slist_next (tmp);
301 g_free ((gpointer) _val_unescaped);
304 /* clean up things */
305 JCL_free_cstring (env, node, dir);
306 g_slist_foreach (entries, (GFunc) gconf_entry_free, NULL);
307 g_slist_free (entries);
313 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
314 * Method: gconf_client_suggest_sync
317 JNIEXPORT void JNICALL
318 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1suggest_1sync
319 (JNIEnv *env, jclass clazz __attribute__ ((unused)))
323 gdk_threads_enter ();
324 gconf_client_suggest_sync (client, &err);
325 gdk_threads_leave ();
328 throw_exception_by_name (env, "java/util/prefs/BackingStoreException",
336 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
337 * Method: gconf_client_unset
338 * Signature: (Ljava/lang/String;)Z
340 JNIEXPORT jboolean JNICALL
341 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1unset
342 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring key)
344 const char *_key = NULL;
345 gboolean result = JNI_FALSE;
348 _key = JCL_jstring_to_cstring (env, key);
354 gdk_threads_enter ();
355 result = gconf_client_unset (client, _key, &err);
356 gdk_threads_leave ();
364 JCL_free_cstring (env, key, _key);
370 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
371 * Method: gconf_client_get_string
372 * Signature: (Ljava/lang/String;)Ljava/lang/String;
374 JNIEXPORT jstring JNICALL
375 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1get_1string
376 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring key)
378 const char *_key = NULL;
379 const char *_value = NULL;
381 jstring result = NULL;
383 _key = JCL_jstring_to_cstring (env, key);
389 gdk_threads_enter ();
390 _value = gconf_client_get_string (client, _key, &err);
391 gdk_threads_leave ();
392 JCL_free_cstring (env, key, _key);
396 if (_value != NULL) g_free ((gpointer) _value);
403 /* Even if Gconf reported no error it is possible that NULL was returned */
404 /* and it should be prevented to create a Java string from that value. */
407 result = (*env)->NewStringUTF (env, _value);
408 g_free ((gpointer) _value);
415 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
416 * Method: gconf_client_set_string
417 * Signature: (Ljava/lang/String;Ljava/lang/String;)Z
419 JNIEXPORT jboolean JNICALL
420 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1set_1string
421 (JNIEnv *env, jclass clazz __attribute__ ((unused)),
422 jstring key, jstring value)
424 const char *_key = NULL;
425 const char *_value = NULL;
428 gboolean result = JNI_FALSE;
430 /* load an UTF string from the virtual machine. */
431 _key = JCL_jstring_to_cstring (env, key);
432 _value = JCL_jstring_to_cstring (env, value);
433 if (_key == NULL || _value == NULL)
438 gdk_threads_enter ();
439 result = gconf_client_set_string (client, _key, _value, &err);
440 gdk_threads_leave ();
448 JCL_free_cstring (env, key, _key);
449 JCL_free_cstring (env, value, _value);
451 return (jboolean) result;
455 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
456 * Method: gconf_client_remove_dir
457 * Signature: (Ljava/lang/String;)V
459 JNIEXPORT void JNICALL
460 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1remove_1dir
461 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring node)
463 const char *dir = NULL;
465 dir = JCL_jstring_to_cstring (env, node);
469 gdk_threads_enter ();
470 gconf_client_remove_dir (client, dir, NULL);
471 gdk_threads_leave ();
473 JCL_free_cstring (env, node, dir);
477 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
478 * Method: gconf_client_add_dir
479 * Signature: (Ljava/lang/String;)V
481 JNIEXPORT void JNICALL
482 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1add_1dir
483 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring node)
485 const char *dir = NULL;
487 dir = JCL_jstring_to_cstring (env, node);
492 gdk_threads_enter ();
493 gconf_client_add_dir (client, dir, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
494 gdk_threads_leave ();
496 JCL_free_cstring (env, node, dir);
500 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
501 * Method: gconf_client_dir_exists
502 * Signature: (Ljava/lang/String;)Z
504 JNIEXPORT jboolean JNICALL
505 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1dir_1exists
506 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring node)
508 const char *dir = NULL;
510 jboolean value = JNI_FALSE;
512 dir = JCL_jstring_to_cstring (env, node);
516 /* on error return false */
517 gdk_threads_enter ();
518 value = gconf_client_dir_exists (client, dir, &err);
519 gdk_threads_leave ();
523 JCL_free_cstring (env, node, dir);
529 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
530 * Method: finalize_class
533 JNIEXPORT void JNICALL
534 Java_gnu_java_util_prefs_gconf_GConfNativePeer_finalize_1class
535 (JNIEnv *env, jclass clazz __attribute__ ((unused)))
537 if (reference_count == 0)
539 /* last reference, free all resources and return */
540 gdk_threads_enter ();
541 g_object_unref (G_OBJECT (client));
542 gdk_threads_leave ();
544 (*env)->DeleteGlobalRef (env, jlist_class);
547 jlist_init_id = NULL;
557 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
558 * Method: Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1escape_1key
559 * Signature: (Ljava/lang/String;)Z
561 JNIEXPORT jstring JNICALL
562 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1escape_1key
563 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring plain)
565 const char *escaped = NULL;
566 const char *_plain = NULL;
567 jstring result = NULL;
569 _plain = JCL_jstring_to_cstring (env, plain);
575 gdk_threads_enter ();
576 escaped = gconf_escape_key (_plain, strlen (_plain));
577 gdk_threads_leave ();
579 JCL_free_cstring (env, plain, _plain);
580 /* check for NULL, if so prevent string creation */
583 result = (*env)->NewStringUTF (env, escaped);
584 g_free ((gpointer) escaped);
591 * Class: gnu_java_util_prefs_gconf_GConfNativePeer
592 * Method: Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1unescape_1key
593 * Signature: (Ljava/lang/String;)Z
595 JNIEXPORT jstring JNICALL
596 Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1unescape_1key
597 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring escaped)
599 const char *plain = NULL;
600 const char *_escaped = NULL;
601 jstring result = NULL;
603 _escaped = JCL_jstring_to_cstring (env, escaped);
604 if (_escaped == NULL)
609 gdk_threads_enter ();
610 plain = gconf_unescape_key (_escaped, strlen (_escaped));
611 gdk_threads_leave ();
613 JCL_free_cstring (env, escaped, _escaped);
614 /* check for NULL, if so prevent string creation */
617 result = (*env)->NewStringUTF (env, plain);
618 g_free ((gpointer) plain);
624 /* ***** END: NATIVE FUNCTIONS ***** */
626 /* ***** PRIVATE FUNCTIONS IMPLEMENTATION ***** */
628 static void throw_exception (JNIEnv *env, const char *msg)
630 throw_exception_by_name (env, "java/lang/RuntimeException", msg);
634 throw_exception_by_name (JNIEnv *env, const char *name, const char *msg)
636 JCL_ThrowException (env, name, msg);
639 static void init_gconf_client (void)
642 client = gconf_client_get_default ();
645 static gboolean set_jlist_class (JNIEnv *env)
647 jclass local_jlist_class = NULL;
649 /* gets a reference to the ArrayList class */
650 local_jlist_class = JCL_FindClass (env, "java/util/ArrayList");
651 if (local_jlist_class == NULL)
656 jlist_class = (*env)->NewGlobalRef (env, local_jlist_class);
657 (*env)->DeleteLocalRef (env, local_jlist_class);
658 if (jlist_class == NULL)
663 /* and initialize it */
664 jlist_init_id = (*env)->GetMethodID (env, jlist_class, "<init>", "()V");
665 if (jlist_init_id == NULL)
670 jlist_add_id = (*env)->GetMethodID (env, jlist_class, "add",
671 "(Ljava/lang/Object;)Z");
672 if (jlist_add_id == NULL)
680 static jobject get_jlist_reference (JNIEnv *env, jclass jlist_class)
682 return (*env)->NewObject (env, jlist_class, jlist_init_id);
685 /* ***** END: PRIVATE FUNCTIONS IMPLEMENTATION ***** */