diff options
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | configure.ac | 27 | ||||
-rw-r--r-- | gnu/java/util/prefs/GConfBasedFactory.java | 78 | ||||
-rw-r--r-- | gnu/java/util/prefs/GConfBasedPreferences.java | 406 | ||||
-rw-r--r-- | gnu/java/util/prefs/gconf/GConfNativePeer.java | 262 | ||||
-rw-r--r-- | include/Makefile.am | 7 | ||||
-rw-r--r-- | include/gnu_java_util_prefs_gconf_GConfNativePeer.h | 30 | ||||
-rw-r--r-- | native/jni/Makefile.am | 9 | ||||
-rw-r--r-- | native/jni/gconf-peer/GConfNativePeer.c | 519 | ||||
-rw-r--r-- | native/jni/gconf-peer/Makefile.am | 14 | ||||
-rwxr-xr-x | scripts/check_jni_methods.sh | 3 |
11 files changed, 1371 insertions, 3 deletions
@@ -1,3 +1,20 @@ +2006-0-12 Mario torre <neugens at limasoftware.net> + + * gnu/java/util/prefs/GConfBasedPreferences.java: new class. + * gnu/java/util/prefs/GConfBasedFactory.java: new class. + * gnu/java/util/prefs/gconf/GConfNativePeer.java: new class. + * gnu_java_util_prefs_gconf_GConfNativePeer.h: generated + header file. + * classpath/native/jni/gconf-peer/GConfNativePeer.c: new C file. + * configure.ac: update to introduce new files. Added options + to build gconf native peer used by the GConf preference backend. + * include/Makefile.am: update to introduce new files. + * native/jni/Makefile.am update to introduce new files. + * scripts/check_jni_methods.sh: added three new ignored file + from check. + * native/jni/gconf-peer/Makefile.am: new Makefile needed to + build gconf-peer shared library. + 2006-06-17 Andrew John Hughes <gnu_andrew@member.fsf.org> * javax/management/DynamicMBean.java: @@ -25,7 +42,7 @@ * examples/gnu/classpath/examples/java2d/J2dBenchmark.java: New file. * examples/gnu/classpath/examples/java2d/JNIOverhead.java: Moved from old FillRect. - + 2006-06-16 Tom Tromey <tromey@redhat.com> * tools/.cvsignore: Added new tool names. diff --git a/configure.ac b/configure.ac index 378e8f349..284e6f9ca 100644 --- a/configure.ac +++ b/configure.ac @@ -82,6 +82,25 @@ AC_ARG_ENABLE([core-jni], [COMPILE_CORE_JNI=yes]) AM_CONDITIONAL(CREATE_CORE_JNI_LIBRARIES, test "x${COMPILE_CORE_JNI}" = xyes) +dnl ----------------------------------------------------------- +dnl GConf native peer (enabled by default) +dnl ----------------------------------------------------------- +AC_ARG_ENABLE([gconf-peer], + [AS_HELP_STRING(--disable-gconf-peer,compile GConf native peers (disabled by --disable-jni) [default=yes])], + [case "${enableval}" in + yes) COMPILE_GCONF_PEER=yes ;; + no) COMPILE_GCONF_PEER=no ;; + *) COMPILE_GCONF_PEER=yes ;; + esac], + [COMPILE_GCONF_PEER=yes]) +AM_CONDITIONAL(CREATE_GCONF_PEER_LIBRARIES, test "x${COMPILE_GCONF_PEER}" = xyes) + +dnl ----------------------------------------------------------- +dnl GTK native peer error checking +dnl ----------------------------------------------------------- +AC_ARG_ENABLE([gconf-peers],,AC_MSG_ERROR([No --enable-gconf-peers (or --disable-gconf-peers) option; you want --enable-gconf-peer])) + + dnl ------------------------------------------------------------ dnl Whether to compile with -Werror or not (disabled by default) dnl ------------------------------------------------------------ @@ -432,6 +451,13 @@ if test "x${COMPILE_JNI}" = xyes; then AC_SUBST(XTEST_LIBS) fi + dnl gconf-peer + if test "x${COMPILE_GCONF_PEER}" = xyes; then + PKG_CHECK_MODULES(GCONF, gconf-2.0 >= 2.11.2) + AC_SUBST(GCONF_CFLAGS) + AC_SUBST(GCONF_LIBS) + fi + dnl Check for AWT related Qt4 if test "x${COMPILE_QT_PEER}" = xyes; then PKG_CHECK_MODULES(QT, QtCore QtGui >= 4.1.0, HAVE_QT4="yes", HAVE_QT4="no") @@ -719,6 +745,7 @@ native/jni/java-net/Makefile native/jni/java-nio/Makefile native/jni/java-util/Makefile native/jni/gtk-peer/Makefile +native/jni/gconf-peer/Makefile native/jni/qt-peer/Makefile native/jni/xmlj/Makefile native/jni/midi-alsa/Makefile diff --git a/gnu/java/util/prefs/GConfBasedFactory.java b/gnu/java/util/prefs/GConfBasedFactory.java new file mode 100644 index 000000000..ae734b609 --- /dev/null +++ b/gnu/java/util/prefs/GConfBasedFactory.java @@ -0,0 +1,78 @@ +/* GConfBasedFactory.java -- GConf based PreferencesFactory implementation + Copyright (C) 2006 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath 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, or (at your option) + any later version. + + GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + +package gnu.java.util.prefs; + +import java.util.prefs.Preferences; +import java.util.prefs.PreferencesFactory; + +/** + * Factory object that generates a Preferences nodes that are read from a GConf + * daemon. + * + * @author Mario Torre <neugens@limasoftware.net> + */ +public class GConfBasedFactory implements PreferencesFactory +{ + /** System preference root. */ + private static final Preferences systemPreferences + = new GConfBasedPreferences(null, "", false); + + /** User preference root. */ + private static final Preferences userPreferences + = new GConfBasedPreferences(null, "", true); + + /** + * Returns the system root preference node. + * + * @see java.util.prefs.PreferencesFactory#systemRoot() + */ + public Preferences systemRoot() + { + return systemPreferences; + } + + /** + * Returns the user root preference node corresponding to the calling user. + * + * @see java.util.prefs.PreferencesFactory#userRoot() + */ + public Preferences userRoot() + { + return userPreferences; + } +} diff --git a/gnu/java/util/prefs/GConfBasedPreferences.java b/gnu/java/util/prefs/GConfBasedPreferences.java new file mode 100644 index 000000000..cbedac5c8 --- /dev/null +++ b/gnu/java/util/prefs/GConfBasedPreferences.java @@ -0,0 +1,406 @@ +/* GConfBasedPreferences.java -- GConf based Preferences implementation + Copyright (C) 2006 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath 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, or (at your option) + any later version. + + GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + +package gnu.java.util.prefs; + +import gnu.java.util.prefs.gconf.GConfNativePeer; + +import java.security.Permission; + +import java.util.Iterator; +import java.util.List; +import java.util.prefs.AbstractPreferences; +import java.util.prefs.BackingStoreException; + +/** + * This is a GConf based preference implementation which writes the preferences + * as GConf key-value pairs. System Root is defined to be the + * <code>"/system"</code> directory of GConf for the current user, while User + * Root is <code>"/apps/java"</code>. These defaults can be modified by + * defining two system properties:<br /> + * <br /> + * User Root:<br /> + * <br /> + * + * <pre> + * gnu.java.util.prefs.gconf.user_root + * </pre> + * + * <br /> + * <br /> + * and System Root:<br /> + * <br /> + * + * <pre> + * gnu.java.util.prefs.gconf.system_root + * </pre> + * + * <br /> + * + * @author Mario Torre <neugens@limasoftware.net> + */ +public class GConfBasedPreferences + extends AbstractPreferences +{ + /** Get access to Runtime permission */ + private static final Permission PERMISSION + = new RuntimePermission("preferences"); + + /** CGonf client backend */ + private static GConfNativePeer backend = new GConfNativePeer(); + + /** Default user root path */ + private static final String DEFAULT_USER_ROOT = "/apps/java"; + + /** Default system root path */ + private static final String DEFAULT_SYSTEM_ROOT = "/system"; + + /** current node full path */ + private String node = ""; + + /** True if this is a preference node in the user tree, false otherwise. */ + private final boolean isUser; + + /** + * Creates a preference root user node. + */ + public GConfBasedPreferences() + { + this(true); + } + + /** + * Creates a preference root node. When <code>isUser</code> is true it will + * be user node otherwise it will be a system node. + */ + public GConfBasedPreferences(boolean isUser) + { + this(null, "", isUser); + } + + /** + * Creates a new preference node given a parent node and a name, which has to + * be relative to its parent. When <code>isUser</code> is true it will be user + * node otherwise it will be a system node. + * + * @param parent The parent node of this newly created node. + * @param name A name relative to the parent node. + * @param isUser Set to <code>true</code> initializes this node to be + * a user node, <code>false</code> initialize it to be a system node. + */ + public GConfBasedPreferences(AbstractPreferences parent, String name, + boolean isUser) + { + super(parent, name); + this.isUser = isUser; + + // stores the fully qualified name of this node + this.node = this.getRealRoot(isUser) + this.absolutePath(); + + boolean nodeExist = backend.nodeExist(this.node); + + this.newNode = !nodeExist; + backend.startWatchingNode(this.node); + } + + /** + * Returns a child node with the given name. + * If the child node does not exists, it will be created. + * + * @param name The name of the requested node. + * @return A new reference to the node, creating the node if it is necessary. + */ + protected AbstractPreferences childSpi(String name) + { + // we don't check anything here, if the node is a new node this will be + // detected in the constructor, so we simply return a new reference to + // the requested node. + return new GConfBasedPreferences(this, name, this.isUser); + } + + /** + * Returns an array of names of the children of this preference node. + * If the current node does not have children, the returned array will be + * of <code>size</code> 0 (that is, not <code>null</code>). + * + * @return A <code>String</code> array of names of children of the current + * node. + * @throws BackingStoreException if this operation cannot be completed. + */ + protected String[] childrenNamesSpi() throws BackingStoreException + { + List nodeList = backend.getChildrenNodes(this.node); + String[] nodes = new String[nodeList.size()]; + nodeList.toArray(nodes); + + return nodes; + } + + /** + * Suggest a flush to the backend. Actually, this is only a suggestion as + * GConf handles this for us asynchronously. More over, both sync and flush + * have the same meaning in this class, so calling sync has exactly the same + * effect. + * + * @see #sync + * @throws BackingStoreException if this operation cannot be completed. + */ + public void flush() throws BackingStoreException + { + backend.suggestSync(); + } + + /** + * Request a flush. + * + * @see #flush + * @throws BackingStoreException if this operation cannot be completed. + */ + protected void flushSpi() throws BackingStoreException + { + this.flush(); + } + + /** + * Returns all of the key in this preference node. + * If the current node does not have preferences, the returned array will be + * of size zero. + * + * @return A <code>String</code> array of keys stored under the current + * node. + * @throws BackingStoreException if this operation cannot be completed. + */ + protected String[] keysSpi() throws BackingStoreException + { + List keyList = backend.getKeys(this.node); + String[] keys = new String[keyList.size()]; + keyList.toArray(keys); + + return keys; + } + + /** + * Does a recursive postorder traversal of the preference tree, starting from + * the given directory invalidating every preference found in the node. + * + * @param directory The name of the starting directory (node) + */ + private void postorderRemove(String directory) + { + try + { + // gets the listing of directories in this node + List dirs = backend.getChildrenNodes(directory); + + if (dirs.size() != 0) + { + String currentDir = null; + + for (Iterator itr = dirs.iterator(); itr.hasNext();) + { + currentDir = (String) itr.next(); + + // recursive search inside this directory + postorderRemove(currentDir); + } + } + + // remove all the keys associated to this directory + List entries = backend.getKeys(directory); + + if (entries.size() != 0) + { + String key = null; + + for (Iterator keys = entries.iterator(); keys.hasNext();) + { + key = (String) keys.next(); + this.removeSpi(key); + } + } + } + catch (BackingStoreException ex) + { + /* ignore */ + } + } + + /** + * Stores the given key-value pair into this preference node. + * + * @param key The key of this preference. + * @param value The value of this preference. + */ + protected void putSpi(String key, String value) + { + backend.setString(this.getGConfKey(key), value); + } + + /** + * Removes this preference node, including all its children. + * Also removes the preferences associated. + */ + protected void removeNodeSpi() throws BackingStoreException + { + this.postorderRemove(this.node); + this.flush(); + } + + /** + * Removes the given key from this preference node. + * If the key does not exist, no operation is performed. + * + * @param key The key to remove. + */ + protected void removeSpi(String key) + { + backend.unset(this.getGConfKey(key)); + } + + /** + * Suggest a sync to the backend. Actually, this is only a suggestion as GConf + * handles this for us asynchronously. More over, both sync and flush have the + * same meaning in this class, so calling flush has exactly the same effect. + * + * @see #flush + * @throws BackingStoreException if this operation cannot be completed due to + * a failure in the backing store, or inability to communicate with + * it. + */ + public void sync() throws BackingStoreException + { + this.flush(); + } + + /** + * Request a sync. + * + * @see #sync + * @throws BackingStoreException if this operation cannot be completed due to + * a failure in the backing store, or inability to communicate with + * it. + */ + protected void syncSpi() throws BackingStoreException + { + this.sync(); + } + + /** + * Returns the value of the given key. + * If the keys does not have a value, or there is an error in the backing + * store, <code>null</code> is returned instead. + * + * @param key The key to retrieve. + * @return The value associated with the given key. + */ + protected String getSpi(String key) + { + return backend.getKey(this.getGConfKey(key)); + } + + /** + * Returns <code>true</code> if this preference node is a user node, + * <code>false</code> if is a system preference node. + * + * @return <code>true</code> if this preference node is a user node, + * <code>false</code> if is a system preference node. + */ + public boolean isUserNode() + { + return this.isUser; + } + + /* + * PRIVATE METHODS + */ + + /** + * Builds a GConf key string suitable for operations on the backend. + * + * @param key The key to convert into a valid GConf key. + * @return A valid Gconf key. + */ + private String getGConfKey(String key) + { + + String nodeName = ""; + + if (this.node.endsWith("/")) + { + nodeName = this.node + key; + } + else + { + nodeName = this.node + "/" + key; + } + + return nodeName; + } + + /** + * Builds the root node to use for this preference. + * + * @param isUser Defines if this node is a user (<code>true</code>) or system + * (<code>false</code>) node. + * @return The real root of this preference tree. + */ + private String getRealRoot(boolean isUser) + { + // not sure about this, we should have already these permissions... + SecurityManager security = System.getSecurityManager(); + + if (security != null) + { + security.checkPermission(PERMISSION); + } + + String root = null; + + if (isUser) + { + root = System.getProperty("gnu.java.util.prefs.gconf.user_root", + DEFAULT_USER_ROOT); + } + else + { + root = System.getProperty("gnu.java.util.prefs.gconf.system_root", + DEFAULT_SYSTEM_ROOT); + } + + return root; + } +} diff --git a/gnu/java/util/prefs/gconf/GConfNativePeer.java b/gnu/java/util/prefs/gconf/GConfNativePeer.java new file mode 100644 index 000000000..8d773f916 --- /dev/null +++ b/gnu/java/util/prefs/gconf/GConfNativePeer.java @@ -0,0 +1,262 @@ +/* GConfNativePeer.java -- GConf based preference peer for native methods + Copyright (C) 2006 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath 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, or (at your option) + any later version. + + GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.util.prefs.gconf; + +import java.util.List; +import java.util.prefs.BackingStoreException; + +/** + * Native peer for GConf based preference backend. + * + * @author Mario Torre <neugens@limasoftware.net> + * @version 1.0 + */ +public final class GConfNativePeer +{ + /** + * Object to achieve locks for methods that need to be synchronized. + */ + private static final Object[] semaphore = new Object[0]; + + /** + * Creates a new instance of GConfNativePeer + */ + public GConfNativePeer() + { + synchronized (semaphore) + { + init_class(); + } + } + + /** + * Queries whether the node <code>node</code> exists in theGConf database. + * Returns <code>true</code> or <code>false</code>. + * + * @param node the node to check. + */ + public boolean nodeExist(String node) + { + if (node.endsWith("/")) + { + node = node.substring(0, node.length() - 1); + } + return gconf_client_dir_exists(node); + } + + /** + * Add the node <code>node</code> to the list of nodes the GConf will watch. + * An event is raised everytime this node is changed. You can add a node + * multiple times. + * + * @param node the node to track. + */ + public void startWatchingNode(String node) + { + if (node.endsWith("/")) + { + node = node.substring(0, node.length() - 1); + } + gconf_client_add_dir(node); + } + + /** + * Remove the node <code>node</code> to the list of nodes the GConf is + * watching. Note that if a node has been added multiple times, you must + * remove it the same number of times before the remove takes effect. + * + * @param node the node you don't want to track anymore. + */ + public void stopWatchingNode(String node) + { + if (node.endsWith("/")) + { + node = node.substring(0, node.length() - 1); + } + gconf_client_remove_dir(node); + } + + /** + * Change the value of key to val. Automatically creates the key if it didn't + * exist before (ie it was unset or it only had a default value). + * + * @param key the key to alter (or add). + * @param value the new value for this key. + * @return true if the key was updated, false otherwise. + */ + public boolean setString(String key, String value) + { + if (key.endsWith("/")) + { + key = key.substring(0, key.length() - 1); + } + return gconf_client_set_string(key, value); + } + + /** + * Unsets the value of key; if key is already unset, has no effect. Depending + * on the GConf daemon, unsetting a key may have the side effect to remove it + * completely form the database. + * + * @param key the key to unset. + * @return true on success, false if the key was not updated. + */ + public boolean unset(String key) + { + if (key.endsWith("/")) + { + key = key.substring(0, key.length() - 1); + } + return gconf_client_unset(key); + } + + /** + * Gets the value of a configuration key. + * + * @param key the configuration key. + * @return the values of this key, null if the key is not valid. + */ + public String getKey(String key) + { + if (key.endsWith("/")) + { + key = key.substring(0, key.length() - 1); + } + return gconf_client_get_string(key); + } + + /** + * Lists the key in the given node. Does not list subnodes. Keys names are the + * stripped names (name relative to the current node) of the kyes stored in + * this node. + * + * @param node the node where keys are stored. + * @return a java.util.List of keys. If there are no keys in the given node, a + * list of size 0 is returned. + */ + public List getKeys(String node) throws BackingStoreException + { + if (node.endsWith("/")) + { + node = node.substring(0, node.length() - 1); + } + return gconf_client_gconf_client_all_keys(node); + } + + /** + * Lists the subnodes in <code>node</code>. The returned list contains + * allocated strings. Each string is the name relative tho the given node. + * + * @param node the node to get subnodes from. If there are no subnodes in the + * given node, a list of size 0 is returned. + */ + public List getChildrenNodes(String node) throws BackingStoreException + { + if (node.endsWith("/")) + { + node = node.substring(0, node.length() - 1); + } + return gconf_client_gconf_client_all_nodes(node); + } + + /** + * Suggest to the backend GConf daemon to synch with the database. + */ + public void suggestSync() throws BackingStoreException + { + gconf_client_suggest_sync(); + } + + protected void finalize() throws Throwable + { + try + { + synchronized (semaphore) + { + finalize_class(); + } + } + finally + { + super.finalize(); + } + } + + /* ***** native methods ***** */ + + /* + * Basicly, these are one to one mappings to GConfClient functions. + * GConfClient instances are handled by the native layer, and are hidden from + * the main java class. + */ + + /** */ + native static final private void init_id_cache(); + + native static final private void init_class(); + + native static final private void finalize_class(); + + native static final protected boolean gconf_client_dir_exists(String node); + + native static final protected void gconf_client_add_dir(String node); + + native static final protected void gconf_client_remove_dir(String node); + + native static final protected boolean gconf_client_set_string(String key, + String value); + + native static final protected String gconf_client_get_string(String key); + + native static final protected boolean gconf_client_unset(String key); + + native static final protected void gconf_client_suggest_sync(); + + native static final protected List gconf_client_gconf_client_all_nodes( + String node); + + native static final protected List gconf_client_gconf_client_all_keys( + String node); + + static + { + System.loadLibrary("gconfpeer"); + init_id_cache(); + } +} diff --git a/include/Makefile.am b/include/Makefile.am index 5913f67ba..0b90e85e5 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -117,11 +117,15 @@ $(top_srcdir)/include/gnu_java_awt_peer_qt_QtFileDialogPeer.h \ $(top_srcdir)/include/gnu_java_awt_peer_qt_QtContainerPeer.h \ $(top_srcdir)/include/gnu_java_awt_peer_qt_QtEmbeddedWindowPeer.h +GCONF_PREFS_FILES = \ +$(top_srcdir)/include/gnu_java_util_prefs_gconf_GConfNativePeer.h + H_FILES = \ $(SOUND_H_FILES) \ $(XMLJ_H_FILES) \ $(GTKPEER_H_FILES) \ $(QTPEER_H_FILES) \ +$(GCONF_PREFS_FILES) \ $(top_srcdir)/include/gnu_java_net_VMPlainDatagramSocketImpl.h \ $(top_srcdir)/include/gnu_java_net_VMPlainSocketImpl.h \ $(top_srcdir)/include/gnu_java_net_local_LocalSocketImpl.h \ @@ -172,6 +176,9 @@ $(top_srcdir)/include/gnu_javax_sound_midi_alsa_%.h: $(top_builddir)/$(CLASSDIR) $(top_srcdir)/include/gnu_javax_sound_midi_dssi_%.h: $(top_builddir)/$(CLASSDIR)/gnu/javax/sound/midi/dssi/%.class $(JAVAH) -o $@ gnu.javax.sound.midi.dssi.$* +$(top_srcdir)/include/gnu_java_util_prefs_gconf_%.h: $(top_builddir)/$(CLASSDIR)/java/util/prefs/gconf/%.class + $(JAVAH) -o $@ gnu.java.util.prefs.gconf.$* + $(top_srcdir)/include/gnu_java_net_VMPlainDatagramSocketImpl.h: $(top_srcdir)/vm/reference/gnu/java/net/VMPlainDatagramSocketImpl.java $(JAVAH) -o $@ gnu.java.net.VMPlainDatagramSocketImpl $(top_srcdir)/include/gnu_java_net_VMPlainSocketImpl.h: $(top_srcdir)/vm/reference/gnu/java/net/VMPlainSocketImpl.java diff --git a/include/gnu_java_util_prefs_gconf_GConfNativePeer.h b/include/gnu_java_util_prefs_gconf_GConfNativePeer.h new file mode 100644 index 000000000..ec902cbb8 --- /dev/null +++ b/include/gnu_java_util_prefs_gconf_GConfNativePeer.h @@ -0,0 +1,30 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ + +#ifndef __gnu_java_util_prefs_gconf_GConfNativePeer__ +#define __gnu_java_util_prefs_gconf_GConfNativePeer__ + +#include <jni.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +JNIEXPORT void JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_init_1id_1cache (JNIEnv *env, jclass); +JNIEXPORT void JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_init_1class (JNIEnv *env, jclass); +JNIEXPORT void JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_finalize_1class (JNIEnv *env, jclass); +JNIEXPORT jboolean JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1dir_1exists (JNIEnv *env, jclass, jstring); +JNIEXPORT void JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1add_1dir (JNIEnv *env, jclass, jstring); +JNIEXPORT void JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1remove_1dir (JNIEnv *env, jclass, jstring); +JNIEXPORT jboolean JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1set_1string (JNIEnv *env, jclass, jstring, jstring); +JNIEXPORT jstring JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1get_1string (JNIEnv *env, jclass, jstring); +JNIEXPORT jboolean JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1unset (JNIEnv *env, jclass, jstring); +JNIEXPORT void JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1suggest_1sync (JNIEnv *env, jclass); +JNIEXPORT jobject JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1gconf_1client_1all_1nodes (JNIEnv *env, jclass, jstring); +JNIEXPORT jobject JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1gconf_1client_1all_1keys (JNIEnv *env, jclass, jstring); + +#ifdef __cplusplus +} +#endif + +#endif /* __gnu_java_util_prefs_gconf_GConfNativePeer__ */ diff --git a/native/jni/Makefile.am b/native/jni/Makefile.am index 64cd35a51..2b205826c 100644 --- a/native/jni/Makefile.am +++ b/native/jni/Makefile.am @@ -20,14 +20,19 @@ if CREATE_QT_PEER_LIBRARIES CLASSPATH_QT_PEER_DIR = qt-peer endif +if CREATE_GCONF_PEER_LIBRARIES + CLASSPATH_GCONF_PEER_DIR = gconf-peer +endif + if CREATE_XMLJ_LIBRARY XMLJDIR = xmlj endif SUBDIRS = classpath $(JNIDIRS) \ - $(ALSADIR) $(DSSIDIR) $(GTKDIR) $(CLASSPATH_QT_PEER_DIR) $(XMLJDIR) + $(ALSADIR) $(DSSIDIR) $(GTKDIR) $(CLASSPATH_QT_PEER_DIR) $(XMLJDIR) \ + $(CLASSPATH_GCONF_PEER_DIR) DIST_SUBDIRS = classpath java-io java-lang java-net java-nio java-util \ - gtk-peer qt-peer xmlj midi-alsa midi-dssi + gtk-peer gconf-peer qt-peer xmlj midi-alsa midi-dssi all-local: cd $(top_srcdir) && $(SHELL) ./scripts/check_jni_methods.sh diff --git a/native/jni/gconf-peer/GConfNativePeer.c b/native/jni/gconf-peer/GConfNativePeer.c new file mode 100644 index 000000000..e9dc73d1a --- /dev/null +++ b/native/jni/gconf-peer/GConfNativePeer.c @@ -0,0 +1,519 @@ +/* GConfNativePeer.c -- Implements native methods for class GConfNativePeer + Copyright (C) 2003, 2004 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath 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, or (at your option) + any later version. + + GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + +#include <stdio.h> +#include <string.h> + +#include <jni.h> + +#include <glib.h> +#include <gconf/gconf-client.h> + +#include "jcl.h" + +#include "gnu_java_util_prefs_gconf_GConfNativePeer.h" + +/* + * Cached id, methods and objects + */ + +/** Reference count */ +static int reference_count = 0; + +/** GConfClient backend */ +static GConfClient *client = NULL; + +/** java.util.ArrayList class */ +static jclass jlist_class = NULL; + +/** java.util.ArrayList constructor id */ +static jmethodID jlist_init_id = NULL; + +/** ava.util.ArrayList add id */ +static jmethodID jlist_add_id = NULL; + +/* ***** PRIVATE FUNCTIONS DELCARATION ***** */ + +/** + * Gets the reference of the default GConfClient and initialize the + * the type system. + * The client reference should be released with g_object_unref after use. + */ +static void init_gconf_client (void); + +/** + * Throws a new runtime exception after a failure, with the given message. + */ +static void throw_exception (JNIEnv *env, const char *msg); + +/** + * Throws the given exception after a failure, with the given message. + */ +static void +throw_exception_by_name (JNIEnv *env, const char *name, const char *msg); + +/** + * Return a reference to a java.util.ArrayList class. + */ +static gboolean set_jlist_class (JNIEnv *env); + +/** + * Builds a new reference to a new java.util.ArrayList instace. + * The instance should be freed by the caller after use. + */ +static jclass get_jlist_reference (JNIEnv *env, jclass jlist_class); + +/* ***** END: PRIVATE FUNCTIONS DELCARATION ***** */ + +/* ***** NATIVE FUNCTIONS ***** */ + +/* + * Class: gnu_java_util_prefs_gconf_GConfNativePeer + * Method: init_class + * Signature: ()V + */ +JNIEXPORT void +JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_init_1class + (JNIEnv *env, jclass clazz) +{ + if (reference_count == 0) { + Java_gnu_java_util_prefs_gconf_GConfNativePeer_init_1id_1chache + (env, clazz); + return; + } + + reference_count++; +} /* Java_gnu_java_util_prefs_gconf_GConfNativePeer_init_1class */ + +/* + * Class: gnu_java_util_prefs_gconf_GConfNativePeer + * Method: init_id_chache + * Signature: ()V + */ +JNIEXPORT void +JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_init_1id_1cache + (JNIEnv *env, jclass clazz __attribute__ ((unused))) +{ + reference_count++; + + init_gconf_client (); + + /* if client is null, there is probably an out or memory */ + if (client == NULL) { + /* release the string and throw a runtime exception */ + throw_exception (env, + "Unable to initialize GConfClient in native code\n"); + return; + } + + /* ***** java.util.ArrayList ***** */ + if (set_jlist_class (env) == FALSE) { + throw_exception (env, + "Unable to get valid reference to java.util.List in native code\n"); + return; + } +} /* Java_gnu_java_util_prefs_gconf_GConfNativePeer_init_1id_1cache */ + +/* + * Class: gnu_java_util_prefs_gconf_GConfNativePeer + * Method: gconf_client_gconf_client_all_keys + * Signature: (Ljava/lang/String;)Ljava/util/List; + */ +JNIEXPORT jobject JNICALL +Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1gconf_1client_1all_1keys + (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring node) +{ + const char *dir = NULL; + GError *err = NULL; + GSList *entries = NULL; + + /* java.util.ArrayList */ + jobject jlist = NULL; + + dir = JCL_jstring_to_cstring(env, node); + if (dir == NULL) { + return NULL; + } + + entries = gconf_client_all_entries (client, dir, &err); + if (err != NULL) { + throw_exception_by_name (env, "java/util/prefs/BackingStoreException", + err->message); + g_error_free (err); + err = NULL; + + JCL_free_cstring(env, node, dir); + return NULL; + } + + jlist = get_jlist_reference (env, jlist_class); + if (jlist == NULL) { + throw_exception_by_name (env, "java/util/prefs/BackingStoreException", + "Unable to get java.util.List reference in native code\n"); + JCL_free_cstring(env, node, dir); + g_slist_foreach (entries, (GFunc) gconf_entry_free, NULL); + g_slist_free (entries); + return NULL; + } + + GSList* tmp = entries; + while (tmp != NULL) { + const char *_val = gconf_entry_get_key(tmp->data); + _val = strrchr (_val, '/'); ++_val; + (*env)->CallBooleanMethod(env, jlist, jlist_add_id, + (*env)->NewStringUTF(env, _val)); + tmp = g_slist_next (tmp); + } + + /* clean up things */ + JCL_free_cstring(env, node, dir); + g_slist_foreach (entries, (GFunc) gconf_entry_free, NULL); + g_slist_free (entries); + + return jlist; +} /* Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1gconf_1client_1all_1keys */ + +/* + * Class: gnu_java_util_prefs_gconf_GConfNativePeer + * Method: gconf_client_gconf_client_all_nodes + * Signature: (Ljava/lang/String;)Ljava/util/List; + */ +JNIEXPORT jobject JNICALL +Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1gconf_1client_1all_1nodes + (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring node) +{ + const char *dir = NULL; + GError *err = NULL; + GSList *entries = NULL; + + /* java.util.ArrayList */ + jobject jlist = NULL; + + dir = JCL_jstring_to_cstring(env, node); + if (dir == NULL) { + return NULL; + } + + entries = gconf_client_all_dirs (client, dir, &err); + if (err != NULL) { + throw_exception_by_name (env, "java/util/prefs/BackingStoreException", + err->message); + g_error_free (err); + err = NULL; + JCL_free_cstring(env, node, dir); + return NULL; + } + + jlist = get_jlist_reference (env, jlist_class); + if (jlist == NULL) { + throw_exception_by_name (env, "java/util/prefs/BackingStoreException", + "Unable to get java.util.List reference in native code\n"); + JCL_free_cstring(env, node, dir); + g_slist_foreach (entries, (GFunc) gconf_entry_free, NULL); + g_slist_free (entries); + return NULL; + } + + GSList* tmp = entries; + while (tmp != NULL) { + const char *_val = tmp->data; + _val = strrchr (_val, '/'); ++_val; + (*env)->CallBooleanMethod(env, jlist, jlist_add_id, + (*env)->NewStringUTF(env, _val)); + tmp = g_slist_next (tmp); + } + + /* clean up things */ + JCL_free_cstring(env, node, dir); + g_slist_foreach (entries, (GFunc) gconf_entry_free, NULL); + g_slist_free (entries); + + return jlist; +} /* Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1gconf_1client_1all_1nodes */ + +/* + * Class: gnu_java_util_prefs_gconf_GConfNativePeer + * Method: gconf_client_suggest_sync + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1suggest_1sync + (JNIEnv *env, jclass clazz __attribute__ ((unused))) +{ + GError *err = NULL; + + gconf_client_suggest_sync (client, &err); + if (err != NULL) { + throw_exception_by_name (env, "java/util/prefs/BackingStoreException", + err->message); + g_error_free (err); + err = NULL; + } +} /* Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1suggest_1sync */ + +/* + * Class: gnu_java_util_prefs_gconf_GConfNativePeer + * Method: gconf_client_unset + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL +Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1unset + (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring key) +{ + const char *_key = NULL; + gboolean result = JNI_FALSE; + + _key = JCL_jstring_to_cstring(env, key); + if (_key == NULL) { + return JNI_FALSE; + } + + result = gconf_client_unset (client, _key, NULL); + + JCL_free_cstring(env, key, _key); + + return result; +} /* Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1unset */ + +/* + * Class: gnu_java_util_prefs_gconf_GConfNativePeer + * Method: gconf_client_get_string + * Signature: (Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1get_1string + (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring key) +{ + const char *_key = NULL; + const char *_value = NULL; + jstring result = NULL; + + _key = JCL_jstring_to_cstring(env, key); + if (_key == NULL) { + return NULL; + } + + _value = gconf_client_get_string (client, _key, NULL); + JCL_free_cstring(env, key, _key); + + result = (*env)->NewStringUTF (env, _value); + g_free ((gpointer) _value); + + return result; +} /* Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1get_1string */ + +/* + * Class: gnu_java_util_prefs_gconf_GConfNativePeer + * Method: gconf_client_set_string + * Signature: (Ljava/lang/String;Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL +Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1set_1string + (JNIEnv *env, jclass clazz __attribute__ ((unused)), + jstring key, jstring value) +{ + const char *_key = NULL; + const char *_value = NULL; + + gboolean result = JNI_FALSE; + + /* load an UTF string from the virtual machine. */ + _key = JCL_jstring_to_cstring (env, key); + _value = JCL_jstring_to_cstring (env, value); + if (_key == NULL && _value == NULL) { + return JNI_FALSE; + } + + result = gconf_client_set_string (client, _key, _value, NULL); + + JCL_free_cstring (env, key, _key); + JCL_free_cstring (env, value, _value); + + return (jboolean) result; +} /* Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1set_1string */ + +/* + * Class: gnu_java_util_prefs_gconf_GConfNativePeer + * Method: gconf_client_remove_dir + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1remove_1dir + (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring node) +{ + const char *dir = NULL; + + dir = JCL_jstring_to_cstring (env, node); + if (dir == NULL) { + return NULL; + } + + gconf_client_remove_dir (client, dir, NULL); + + JCL_free_cstring (env, node, dir); +} /* Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1remove_1dir */ + +/* + * Class: gnu_java_util_prefs_gconf_GConfNativePeer + * Method: gconf_client_add_dir + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1add_1dir + (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring node) +{ + const char *dir = NULL; + + dir = JCL_jstring_to_cstring (env, node); + if (dir == NULL) { + return NULL; + } + + /* ignore errors */ + gconf_client_add_dir (client, dir, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL); + + JCL_free_cstring (env, node, dir); +} /* Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1add_1dir */ + +/* + * Class: gnu_java_util_prefs_gconf_GConfNativePeer + * Method: gconf_client_dir_exists + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL +Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1dir_1exists + (JNIEnv *env, jclass clazz, jstring node) +{ + const char *dir = NULL; + jboolean value = JNI_FALSE; + + dir = JCL_jstring_to_cstring (env, node); + if (dir == NULL) { + return NULL; + } + + /* we ignore errors here */ + value = gconf_client_dir_exists (client, dir, NULL); + + JCL_free_cstring (env, node, dir); + + return value; +} /* Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1dir_1exists */ + +/* + * Class: gnu_java_util_prefs_gconf_GConfNativePeer + * Method: finalize_class + * Signature: ()V + */ +JNIEXPORT void +JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_finalize_1class + (JNIEnv *env, jclass clazz) +{ + if (reference_count == 0) { + /* last reference, free all resources and return */ + g_object_unref (G_OBJECT (client)); + + (*env)->DeleteGlobalRef (env, jlist_class); + + jlist_class = NULL; + jlist_init_id = NULL; + jlist_add_id = NULL; + + return; + } + + reference_count--; +} /* Java_gnu_java_util_prefs_gconf_GConfNativePeer_finalize_1class */ + +/* ***** END: NATIVE FUNCTIONS ***** */ + +/* ***** PRIVATE FUNCTIONS IMPLEMENTATION ***** */ + +static void throw_exception (JNIEnv *env, const char *msg) +{ + throw_exception_by_name (env, "java/lang/RuntimeException", msg); +} /* throw_exception */ + +static void +throw_exception_by_name (JNIEnv *env, const char *name, const char *msg) +{ + JCL_ThrowException(env, name, msg); +} /* throw_exception */ + +static void init_gconf_client (void) +{ + client = gconf_client_get_default (); + g_type_init(); +} /* init_gconf_client */ + +static gboolean set_jlist_class (JNIEnv *env) +{ + jclass local_jlist_class = NULL; + + /* gets a reference to the ArrayList class */ + local_jlist_class = JCL_FindClass (env, "java/util/ArrayList"); + if (local_jlist_class == NULL) { + return FALSE; + } + + jlist_class = (*env)->NewGlobalRef(env, local_jlist_class); + (*env)->DeleteLocalRef(env, local_jlist_class); + if (jlist_class == NULL) { + return FALSE; + } + + /* and initialize it */ + jlist_init_id = (*env)->GetMethodID (env, jlist_class, "<init>", "()V"); + if (jlist_init_id == NULL) { + return FALSE; + } + + jlist_add_id = (*env)->GetMethodID (env, jlist_class, "add", + "(Ljava/lang/Object;)Z"); + if (jlist_add_id == NULL) { + return FALSE; + } + + return TRUE; +} /* set_jlist_class */ + +static jobject get_jlist_reference (JNIEnv *env, jclass jlist_class) +{ + return (*env)->NewObject(env, jlist_class, jlist_init_id); +} /* get_jlist_reference */ + +/* ***** END: PRIVATE FUNCTIONS IMPLEMENTATION ***** */ diff --git a/native/jni/gconf-peer/Makefile.am b/native/jni/gconf-peer/Makefile.am new file mode 100644 index 000000000..f0213d710 --- /dev/null +++ b/native/jni/gconf-peer/Makefile.am @@ -0,0 +1,14 @@ +nativeexeclib_LTLIBRARIES = libgconfpeer.la + +libgconfpeer_la_SOURCES = GConfNativePeer.c + +libgtkpeer_la_LIBADD = $(top_builddir)/native/jni/classpath/native_state.lo \ + $(top_builddir)/native/jni/classpath/jcl.lo + +AM_LDFLAGS = @CLASSPATH_MODULE@ @GCONF_LIBS@ +#@CLASSPATH_MODULE@ @GCONF_LIBS@ @CAIRO_LIBS@ @FREETYPE2_LIBS@ \ +# @PANGOFT2_LIBS@ @X_PRE_LIBS@ @X_LIBS@ @X_EXTRA_LIBS@ -lX11 -lXtst + +AM_CPPFLAGS = @CLASSPATH_INCLUDES@ + +AM_CFLAGS = @WARNING_CFLAGS@ @ERROR_CFLAGS@ @GCONF_CFLAGS@ diff --git a/scripts/check_jni_methods.sh b/scripts/check_jni_methods.sh index 999e143ec..ffdc7b571 100755 --- a/scripts/check_jni_methods.sh +++ b/scripts/check_jni_methods.sh @@ -37,6 +37,9 @@ cat > $TMPFILE3 << EOF -Java_gnu_java_awt_peer_gtk_GtkMenuComponentPeer_dispose -Java_java_lang_VMSystem_arraycopy -Java_java_lang_VMSystem_identityHashCode +-Java_gnu_java_util_prefs_gconf_GConfNativePeer_finalize_1class +-Java_gnu_java_util_prefs_gconf_GConfNativePeer_init_1id_1cache +-Java_gnu_java_util_prefs_gconf_GConfNativePeer_init_1class EOF # Compare again silently. |