📄 abstractpreferences.java
字号:
child = (AbstractPreferences)childCache.get(childName); if (child == null) { if (childName.length() > MAX_NAME_LENGTH) throw new IllegalArgumentException(childName); // Not in childCache yet so create a new sub node child = childSpi(childName); // XXX - check if node is new childCache.put(childName, child); } // Lock the child and go down synchronized(child.lock) { return child.getNode(childPath); } } /** * Returns true if the node that the path points to exists in memory or * in the backing store. Otherwise it returns false or an exception is * thrown. When this node is removed the only valid parameter is the * empty string (indicating this node), the return value in that case * will be false. * * @exception BackingStoreException when the backing store cannot be * reached * @exception IllegalStateException if this node has been removed * and the path is not the empty string (indicating this node) * @exception IllegalArgumentException if the path contains two or more * consecutive '/' characters, ends with a '/' charactor and is not the * string "/" (indicating the root node) or any name on the path is more * then 80 characters long */ public boolean nodeExists(String path) throws BackingStoreException { synchronized(lock) { if (isRemoved() && path.length() != 0) throw new IllegalStateException("Node removed"); // Is it a relative path? if (!path.startsWith("/")) { // Check if it is a valid path if (path.indexOf("//") != -1 || path.endsWith("/")) throw new IllegalArgumentException(path); return existsNode(path); } } // path started with a '/' so it is absolute // we drop the lock and start from the root (omitting the first '/') Preferences root = isUserNode() ? userRoot() : systemRoot(); return root.nodeExists(path.substring(1)); } private boolean existsNode(String path) throws BackingStoreException { // Empty String "" indicates this node if (path.length() == 0) return(!isRemoved()); // Calculate child name and rest of path String childName; String childPath; int nextSlash = path.indexOf('/'); if (nextSlash == -1) { childName = path; childPath = ""; } else { childName = path.substring(0, nextSlash); childPath = path.substring(nextSlash+1); } // Get the child node AbstractPreferences child; child = (AbstractPreferences)childCache.get(childName); if (child == null) { if (childName.length() > MAX_NAME_LENGTH) throw new IllegalArgumentException(childName); // Not in childCache yet so create a new sub node child = getChild(childName); if (child == null) return false; childCache.put(childName, child); } // Lock the child and go down synchronized(child.lock) { return child.existsNode(childPath); } } /** * Returns the child sub node if it exists in the backing store or null * if it does not exist. Called (indirectly) by <code>nodeExists()</code> * when a child node name can not be found in the cache. * <p> * Gets the lock on this node, calls <code>childrenNamesSpi()</code> to * get an array of all (possibly uncached) children and compares the * given name with the names in the array. If the name is found in the * array <code>childSpi()</code> is called to get an instance, otherwise * null is returned. * * @exception BackingStoreException when the backing store cannot be * reached */ protected AbstractPreferences getChild(String name) throws BackingStoreException { synchronized(lock) { // Get all the names (not yet in the cache) String[] names = childrenNamesSpi(); for (int i=0; i < names.length; i++) if (name.equals(names[i])) return childSpi(name); // No child with that name found return null; } } /** * Returns true if this node has been removed with the * <code>removeNode()</code> method, false otherwise. * <p> * Gets the lock on this node and then returns a boolean field set by * <code>removeNode</code> methods. */ protected boolean isRemoved() { synchronized(lock) { return removed; } } /** * Returns the parent preferences node of this node or null if this is * the root of the preferences tree. * <p> * Gets the lock on this node, checks that the node has not been removed * and returns the parent given to the constructor. * * @exception IllegalStateException if this node has been removed */ public Preferences parent() { synchronized(lock) { if (isRemoved()) throw new IllegalStateException("Node removed"); return parent; } } // export methods /** * XXX */ public void exportNode(OutputStream os) throws BackingStoreException, IOException { NodeWriter nodeWriter = new NodeWriter(this, os); nodeWriter.writePrefs(); } /** * XXX */ public void exportSubtree(OutputStream os) throws BackingStoreException, IOException { NodeWriter nodeWriter = new NodeWriter(this, os); nodeWriter.writePrefsTree(); } // preference entry manipulation methods /** * Returns an (possibly empty) array with all the keys of the preference * entries of this node. * <p> * This method locks this node and checks if the node has not been * removed, if it has been removed it throws an exception, then it returns * the result of calling <code>keysSpi()</code>. * * @exception BackingStoreException when the backing store cannot be * reached * @exception IllegalStateException if this node has been removed */ public String[] keys() throws BackingStoreException { synchronized(lock) { if (isRemoved()) throw new IllegalStateException("Node removed"); return keysSpi(); } } /** * Returns the value associated with the key in this preferences node. If * the default value of the key cannot be found in the preferences node * entries or something goes wrong with the backing store the supplied * default value is returned. * <p> * Checks that key is not null and not larger then 80 characters, * locks this node, and checks that the node has not been removed. * Then it calls <code>keySpi()</code> and returns * the result of that method or the given default value if it returned * null or throwed an exception. * * @exception IllegalArgumentException if key is larger then 80 characters * @exception IllegalStateException if this node has been removed * @exception NullPointerException if key is null */ public String get(String key, String defaultVal) { if (key.length() > MAX_KEY_LENGTH) throw new IllegalArgumentException(key); synchronized(lock) { if (isRemoved()) throw new IllegalStateException("Node removed"); String value; try { value = getSpi(key); } catch (Throwable t) { value = null; } if (value != null) { return value; } else { return defaultVal; } } } /** * Convenience method for getting the given entry as a boolean. * When the string representation of the requested entry is either * "true" or "false" (ignoring case) then that value is returned, * otherwise the given default boolean value is returned. * * @exception IllegalArgumentException if key is larger then 80 characters * @exception IllegalStateException if this node has been removed * @exception NullPointerException if key is null */ public boolean getBoolean(String key, boolean defaultVal) { String value = get(key, null); if ("true".equalsIgnoreCase(value)) return true; if ("false".equalsIgnoreCase(value)) return false; return defaultVal; } /** * Convenience method for getting the given entry as a byte array. * When the string representation of the requested entry is a valid * Base64 encoded string (without any other characters, such as newlines) * then the decoded Base64 string is returned as byte array, * otherwise the given default byte array value is returned. * * @exception IllegalArgumentException if key is larger then 80 characters * @exception IllegalStateException if this node has been removed * @exception NullPointerException if key is null */ public byte[] getByteArray(String key, byte[] defaultVal) { String value = get(key, null); byte[] b = null; if (value != null) { b = decode64(value); } if (b != null) return b; else return defaultVal; } /** * Helper method for decoding a Base64 string as an byte array. * Returns null on encoding error. This method does not allow any other * characters present in the string then the 65 special base64 chars. */ private static byte[] decode64(String s) { ByteArrayOutputStream bs = new ByteArrayOutputStream((s.length()/4)*3); char[] c = new char[s.length()]; s.getChars(0, s.length(), c, 0); // Convert from base64 chars int endchar = -1; for(int j = 0; j < c.length && endchar == -1; j++) { if (c[j] >= 'A' && c[j] <= 'Z') { c[j] -= 'A'; } else if (c[j] >= 'a' && c[j] <= 'z') { c[j] = (char) (c[j] + 26 - 'a'); } else if (c[j] >= '0' && c[j] <= '9') { c[j] = (char) (c[j] + 52 - '0'); } else if (c[j] == '+') { c[j] = 62; } else if (c[j] == '/') { c[j] = 63; } else if (c[j] == '=') { endchar = j; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -