⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractpreferences.java

📁 java源代码 请看看啊 提点宝贵的意见
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            path.nextToken();  // Consume slash            if (!path.hasMoreTokens())                throw new IllegalArgumentException("Path ends with slash");            return child.nodeExists(path);        }    }    /**     * Implements the <tt>removeNode()</tt> method as per the specification in     * {@link Preferences#removeNode()}.     *     * <p>This implementation checks to see that this node is the root; if so,     * it throws an appropriate exception.  Then, it locks this node's parent,     * and calls a recursive helper method that traverses the subtree rooted at     * this node.  The recursive method locks the node on which it was called,     * checks that it has not already been removed, and then ensures that all     * of its children are cached: The {@link #childrenNamesSpi()} method is     * invoked and each returned child name is checked for containment in the     * child-cache.  If a child is not already cached, the {@link     * #childSpi(String)} method is invoked to create a <tt>Preferences</tt>     * instance for it, and this instance is put into the child-cache.  Then     * the helper method calls itself recursively on each node contained in its     * child-cache.  Next, it invokes {@link #removeNodeSpi()}, marks itself     * as removed, and removes itself from its parent's child-cache.  Finally,     * if there are any node change listeners, it enqueues a notification     * event for processing by the event dispatch thread.     *     * <p>Note that the helper method is always invoked with all ancestors up     * to the "closest non-removed ancestor" locked.     *     * @throws IllegalStateException if this node (or an ancestor) has already     *         been removed with the {@link #removeNode()} method.     * @throws UnsupportedOperationException if this method is invoked on      *         the root node.     * @throws BackingStoreException if this operation cannot be completed     *         due to a failure in the backing store, or inability to      *         communicate with it.     */    public void removeNode() throws BackingStoreException {        if (this==root)            throw new UnsupportedOperationException("Can't remove the root!");        synchronized(parent.lock) {            removeNode2();            parent.kidCache.remove(name);        }    }    /*     * Called with locks on all nodes on path from parent of "removal root"     * to this (including the former but excluding the latter).     */    private void removeNode2() throws BackingStoreException {        synchronized(lock) {            if (removed)                throw new IllegalStateException("Node already removed.");            // Ensure that all children are cached            String[] kidNames = childrenNamesSpi();            for (int i=0; i<kidNames.length; i++)                if (!kidCache.containsKey(kidNames[i]))                    kidCache.put(kidNames[i], childSpi(kidNames[i]));            // Recursively remove all cached children            for (Iterator i=kidCache.values().iterator(); i.hasNext(); )                ((AbstractPreferences)i.next()).removeNode2();            kidCache.clear();                        // Now we have no descendants - it's time to die!            removeNodeSpi();            removed = true;            parent.enqueueNodeRemovedEvent(this);        }    }    /**     * Implements the <tt>name</tt> method as per the specification in     * {@link Preferences#name()}.     *     * <p>This implementation merely returns the name that was     * passed to this node's constructor.     *     * @return this preference node's name, relative to its parent.     */    public String name() {        return name;    }    /**     * Implements the <tt>absolutePath</tt> method as per the specification in     * {@link Preferences#absolutePath()}.     *     * <p>This implementation merely returns the absolute path name that     * was computed at the time that this node was constructed (based on     * the name that was passed to this node's constructor, and the names     * that were passed to this node's ancestors' constructors).     *     * @return this preference node's absolute path name.     */    public String absolutePath() {        return absolutePath;    }    /**     * Implements the <tt>isUserNode</tt> method as per the specification in     * {@link Preferences#isUserNode()}.     *     * <p>This implementation compares this node's root node (which is stored     * in a private field) with the value returned by     * {@link Preferences#userRoot()}.  If the two object references are     * identical, this method returns true.     *     * @return <tt>true</tt> if this preference node is in the user     *         preference tree, <tt>false</tt> if it's in the system     *         preference tree.     */    public boolean isUserNode() {        Boolean result = (Boolean)          AccessController.doPrivileged( new PrivilegedAction() {                        public Object run() {                return new Boolean(root == Preferences.userRoot());            }        });        return result.booleanValue();    }    public void addPreferenceChangeListener(PreferenceChangeListener pcl) {        if (pcl==null)            throw new NullPointerException("Change listener is null.");        synchronized(lock) {            if (removed)                throw new IllegalStateException("Node has been removed.");            // Copy-on-write            PreferenceChangeListener[] old = prefListeners;            prefListeners = new PreferenceChangeListener[old.length + 1];            System.arraycopy(old, 0, prefListeners, 0, old.length);            prefListeners[old.length] = pcl;        }        startEventDispatchThreadIfNecessary();    }    public void removePreferenceChangeListener(PreferenceChangeListener pcl) {        synchronized(lock) {            if (removed)                throw new IllegalStateException("Node has been removed.");            if ((prefListeners == null) || (prefListeners.length == 0))                throw new IllegalArgumentException("Listener not registered.");            // Copy-on-write            PreferenceChangeListener[] newPl =                new PreferenceChangeListener[prefListeners.length - 1];            int i = 0;            while (i < newPl.length && prefListeners[i] != pcl)                newPl[i] = prefListeners[i++];            if (i == newPl.length &&  prefListeners[i] != pcl)                throw new IllegalArgumentException("Listener not registered.");            while (i < newPl.length)                newPl[i] = prefListeners[++i];            prefListeners = newPl;        }    }    public void addNodeChangeListener(NodeChangeListener ncl) {        if (ncl==null)            throw new NullPointerException("Change listener is null.");        synchronized(lock) {            if (removed)                throw new IllegalStateException("Node has been removed.");            // Copy-on-write            if (nodeListeners == null) {                nodeListeners = new NodeChangeListener[1];                nodeListeners[0] = ncl;            } else {                NodeChangeListener[] old = nodeListeners;                nodeListeners = new NodeChangeListener[old.length + 1];                System.arraycopy(old, 0, nodeListeners, 0, old.length);                nodeListeners[old.length] = ncl;            }        }        startEventDispatchThreadIfNecessary();    }    public void removeNodeChangeListener(NodeChangeListener ncl) {        synchronized(lock) {            if (removed)                throw new IllegalStateException("Node has been removed.");            if ((nodeListeners == null) || (nodeListeners.length == 0))                throw new IllegalArgumentException("Listener not registered.");            // Copy-on-write            NodeChangeListener[] newNl =                new NodeChangeListener[nodeListeners.length - 1];            int i = 0;            while (i < nodeListeners.length && nodeListeners[i] != ncl)                newNl[i] = nodeListeners[i++];            if (i == nodeListeners.length)                throw new IllegalArgumentException("Listener not registered.");            while (i < newNl.length)                newNl[i] = nodeListeners[++i];            nodeListeners = newNl;        }    }    // "SPI" METHODS    /**     * Put the given key-value association into this preference node.  It is     * guaranteed that <tt>key</tt> and <tt>value</tt> are non-null and of     * legal length.  Also, it is guaranteed that this node has not been     * removed.  (The implementor needn't check for any of these things.)     *     * <p>This method is invoked with the lock on this node held.     */    protected abstract void putSpi(String key, String value);    /**     * Return the value associated with the specified key at this preference     * node, or <tt>null</tt> if there is no association for this key, or the     * association cannot be determined at this time.  It is guaranteed that     * <tt>key</tt> is non-null.  Also, it is guaranteed that this node has     * not been removed.  (The implementor needn't check for either of these     * things.)      *     * <p> Generally speaking, this method should not throw an exception     * under any circumstances.  If, however, if it does throw an exception,     * the exception will be intercepted and treated as a <tt>null</tt>     * return value.     *     * <p>This method is invoked with the lock on this node held.     *     * @return the value associated with the specified key at this preference     *          node, or <tt>null</tt> if there is no association for this     *          key, or the association cannot be determined at this time.     */    protected abstract String getSpi(String key);    /**     * Remove the association (if any) for the specified key at this      * preference node.  It is guaranteed that <tt>key</tt> is non-null.     * Also, it is guaranteed that this node has not been removed.     * (The implementor needn't check for either of these things.)     *     * <p>This method is invoked with the lock on this node held.     */    protected abstract void removeSpi(String key);    /**      * Removes this preference node, invalidating it and any preferences that     * it contains.  The named child will have no descendants at the time this     * invocation is made (i.e., the {@link Preferences#removeNode()} method     * invokes this method repeatedly in a bottom-up fashion, removing each of     * a node's descendants before removing the node itself).     *     * <p>This method is invoked with the lock held on this node and its     * parent (and all ancestors that are being removed as a     * result of a single invocation to {@link Preferences#removeNode()}).     *     * <p>The removal of a node needn't become persistent until the     * <tt>flush</tt> method is invoked on this node (or an ancestor).     *     * <p>If this node throws a <tt>BackingStoreException</tt>, the exception     * will propagate out beyond the enclosing {@link #removeNode()}     * invocation.     *     * @throws BackingStoreException if this operation cannot be completed     *         due to a failure in the backing store, or inability to      *         communicate with it.     */    protected abstract void removeNodeSpi() throws BackingStoreException;    /**     * Returns all of the keys that have an associated value in this     * preference node.  (The returned array will be of size zero if     * this node has no preferences.)  It is guaranteed that this node has not     * been removed.     *     * <p>This method is invoked with the lock on this node held.     *     * <p>If this node throws a <tt>BackingStoreException</tt>, the exception     * will propagate out beyond the enclosing {@link #keys()} invocation.     *     * @return an array of the keys that have an associated value in this     *         preference node.     * @throws BackingStoreException if this operation cannot be completed     *         due to a failure in the backing store, or inability to      *         communicate with it.     */    protected abstract String[] keysSpi() throws BackingStoreException;    /**     * Returns the names of the children of this preference node.  (The

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -