abstractpreferences.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 1,237 行 · 第 1/3 页

JAVA
1,237
字号
			// 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 {
				return null; // encoding exception
			}
		}

		int remaining = endchar == -1 ? c.length : endchar;
		int i = 0;
		while (remaining > 0) {
			// Four input chars (6 bits) are decoded as three bytes as
			// 000000 001111 111122 222222

			byte b0 = (byte) (c[i] << 2);
			if (remaining >= 2) {
				b0 += (c[i + 1] & 0x30) >> 4;
			}
			bs.write(b0);

			if (remaining >= 3) {
				byte b1 = (byte) ((c[i + 1] & 0x0F) << 4);
				b1 += (byte) ((c[i + 2] & 0x3C) >> 2);
				bs.write(b1);
			}

			if (remaining >= 4) {
				byte b2 = (byte) ((c[i + 2] & 0x03) << 6);
				b2 += c[i + 3];
				bs.write(b2);
			}

			i += 4;
			remaining -= 4;
		}

		return bs.toByteArray();
	}

	/**
	 * Convenience method for getting the given entry as a double.
	 * When the string representation of the requested entry can be decoded
	 * with <code>Double.parseDouble()</code> then that double is returned,
	 * otherwise the given default double 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 double getDouble(String key, double defaultVal) {
		String value = get(key, null);

		if (value != null) {
			try {
				return Double.parseDouble(value);
			} catch (NumberFormatException nfe) { /* ignore */
			}
		}

		return defaultVal;
	}

	/**
	 * Convenience method for getting the given entry as a float.
	 * When the string representation of the requested entry can be decoded
	 * with <code>Float.parseFloat()</code> then that float is returned,
	 * otherwise the given default float 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 float getFloat(String key, float defaultVal) {
		String value = get(key, null);

		if (value != null) {
			try {
				return Float.parseFloat(value);
			} catch (NumberFormatException nfe) { /* ignore */
			}
		}

		return defaultVal;
	}

	/**
	 * Convenience method for getting the given entry as an integer.
	 * When the string representation of the requested entry can be decoded
	 * with <code>Integer.parseInt()</code> then that integer is returned,
	 * otherwise the given default integer 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 int getInt(String key, int defaultVal) {
		String value = get(key, null);

		if (value != null) {
			try {
				return Integer.parseInt(value);
			} catch (NumberFormatException nfe) { /* ignore */
			}
		}

		return defaultVal;
	}

	/**
	 * Convenience method for getting the given entry as a long.
	 * When the string representation of the requested entry can be decoded
	 * with <code>Long.parseLong()</code> then that long is returned,
	 * otherwise the given default long 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 long getLong(String key, long defaultVal) {
		String value = get(key, null);

		if (value != null) {
			try {
				return Long.parseLong(value);
			} catch (NumberFormatException nfe) { /* ignore */
			}
		}

		return defaultVal;
	}

	/**
	 * Sets the value of the given preferences entry for this node.
	 * Key and value cannot be null, the key cannot exceed 80 characters
	 * and the value cannot exceed 8192 characters.
	 * <p>
	 * The result will be immediatly visible in this VM, but may not be
	 * immediatly written to the backing store.
	 * <p>
	 * Checks that key and value are valid, locks this node, and checks that
	 * the node has not been removed. Then it calls <code>putSpi()</code>.
	 *
	 * @exception NullPointerException if either key or value are null
	 * @exception IllegalArgumentException if either key or value are to large
	 * @exception IllegalStateException when this node has been removed
	 */
	public void put(String key, String value) {
		if (key.length() > MAX_KEY_LENGTH || value.length() > MAX_VALUE_LENGTH)
			throw new IllegalArgumentException("key (" + key.length() + ")" + " or value (" + value.length() + ")" + " to large");
		synchronized (lock) {
			if (isRemoved())
				throw new IllegalStateException("Node removed");

			putSpi(key, value);

			// XXX - fire events
		}

	}

	/**
	 * Convenience method for setting the given entry as a boolean.
	 * The boolean is converted with <code>Boolean.toString(value)</code>
	 * and then stored in the preference entry as that string.
	 *
	 * @exception NullPointerException if key is null
	 * @exception IllegalArgumentException if the key length is to large
	 * @exception IllegalStateException when this node has been removed
	 */
	public void putBoolean(String key, boolean value) {
		put(key, String.valueOf(value));
		// XXX - Use when using 1.4 compatible Boolean
		// put(key, Boolean.toString(value));
	}

	/**
	 * Convenience method for setting the given entry as an array of bytes.
	 * The byte array is converted to a Base64 encoded string
	 * and then stored in the preference entry as that string.
	 * <p>
	 * Note that a byte array encoded as a Base64 string will be about 1.3
	 * times larger then the original length of the byte array, which means
	 * that the byte array may not be larger about 6 KB.
	 *
	 * @exception NullPointerException if either key or value are null
	 * @exception IllegalArgumentException if either key or value are to large
	 * @exception IllegalStateException when this node has been removed
	 */
	public void putByteArray(String key, byte[] value) {
		put(key, encode64(value));
	}

	/**
	 * Helper method for encoding an array of bytes as a Base64 String.
	 */
	private static String encode64(byte[] b) {
		StringBuffer sb = new StringBuffer((b.length / 3) * 4);

		int i = 0;
		int remaining = b.length;
		char c[] = new char[4];
		while (remaining > 0) {
			// Three input bytes are encoded as four chars (6 bits) as
			// 00000011 11112222 22333333

			c[0] = (char) ((b[i] & 0xFC) >> 2);
			c[1] = (char) ((b[i] & 0x03) << 4);
			if (remaining >= 2) {
				c[1] += (char) ((b[i + 1] & 0xF0) >> 4);
				c[2] = (char) ((b[i + 1] & 0x0F) << 2);
				if (remaining >= 3) {
					c[2] += (char) ((b[i + 2] & 0xC0) >> 6);
					c[3] = (char) (b[i + 2] & 0x3F);
				} else {
					c[3] = 64;
				}
			} else {
				c[2] = 64;
				c[3] = 64;
			}

			// Convert to base64 chars

⌨️ 快捷键说明

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