📄 properties.java
字号:
{ String value = (String) prop.get(key); if (value != null) return value; prop = prop.defaults; } while (prop != null); return null; } /** * Gets the property with the specified key in this property list. If * the key is not found, the default property list is searched. If the * property is not found in the default, the specified defaultValue is * returned. * * @param key The key for this property * @param defaultValue A default value * @return The value for the given key * @throws ClassCastException if this property contains any key or * value that isn't a string * @see #defaults * @see #setProperty(String, String) */ public String getProperty(String key, String defaultValue) { String prop = getProperty(key); if (prop == null) prop = defaultValue; return prop; } /** * Returns an enumeration of all keys in this property list, including * the keys in the default property list. * * @return an Enumeration of all defined keys */ public Enumeration propertyNames() { // We make a new Set that holds all the keys, then return an enumeration // for that. This prevents modifications from ruining the enumeration, // as well as ignoring duplicates. Properties prop = this; Set s = new HashSet(); // Eliminate tail recursion. do { s.addAll(prop.keySet()); prop = prop.defaults; } while (prop != null); return Collections.enumeration(s); } /** * Prints the key/value pairs to the given print stream. This is * mainly useful for debugging purposes. * * @param out the print stream, where the key/value pairs are written to * @throws ClassCastException if this property contains a key or a * value that isn't a string * @see #list(PrintWriter) */ public void list(PrintStream out) { PrintWriter writer = new PrintWriter (out); list (writer); } /** * Prints the key/value pairs to the given print writer. This is * mainly useful for debugging purposes. * * @param out the print writer where the key/value pairs are written to * @throws ClassCastException if this property contains a key or a * value that isn't a string * @see #list(PrintStream) * @since 1.1 */ public void list(PrintWriter out) { out.println ("-- listing properties --"); Iterator iter = entrySet ().iterator (); int i = size (); while (--i >= 0) { Map.Entry entry = (Map.Entry) iter.next (); out.print ((String) entry.getKey () + "="); // JDK 1.3/1.4 restrict the printed value, but not the key, // to 40 characters, including the truncating ellipsis. String s = (String ) entry.getValue (); if (s != null && s.length () > 40) out.println (s.substring (0, 37) + "..."); else out.println (s); } out.flush (); } /** * Formats a key or value for output in a properties file. * See store for a description of the format. * * @param str the string to format * @param buffer the buffer to add it to * @param key true if all ' ' must be escaped for the key, false if only * leading spaces must be escaped for the value * @see #store(OutputStream, String) */ private void formatForOutput(String str, StringBuilder buffer, boolean key) { if (key) { buffer.setLength(0); buffer.ensureCapacity(str.length()); } else buffer.ensureCapacity(buffer.length() + str.length()); boolean head = true; int size = str.length(); for (int i = 0; i < size; i++) { char c = str.charAt(i); switch (c) { case '\n': buffer.append("\\n"); break; case '\r': buffer.append("\\r"); break; case '\t': buffer.append("\\t"); break; case ' ': buffer.append(head ? "\\ " : " "); break; case '\\': case '!': case '#': case '=': case ':': buffer.append('\\').append(c); break; default: if (c < ' ' || c > '~') { String hex = Integer.toHexString(c); buffer.append("\\u0000".substring(0, 6 - hex.length())); buffer.append(hex); } else buffer.append(c); } if (c != ' ') head = key; } } /** * <p> * Encodes the properties as an XML file using the UTF-8 encoding. * The format of the XML file matches the DTD * <a href="http://java.sun.com/dtd/properties.dtd"> * http://java.sun.com/dtd/properties.dtd</a>. * </p> * <p> * Invoking this method provides the same behaviour as invoking * <code>storeToXML(os, comment, "UTF-8")</code>. * </p> * * @param os the stream to output to. * @param comment a comment to include at the top of the XML file, or * <code>null</code> if one is not required. * @throws IOException if the serialization fails. * @throws NullPointerException if <code>os</code> is null. * @since 1.5 */ public void storeToXML(OutputStream os, String comment) throws IOException { storeToXML(os, comment, "UTF-8"); } /** * <p> * Encodes the properties as an XML file using the supplied encoding. * The format of the XML file matches the DTD * <a href="http://java.sun.com/dtd/properties.dtd"> * http://java.sun.com/dtd/properties.dtd</a>. * </p> * * @param os the stream to output to. * @param comment a comment to include at the top of the XML file, or * <code>null</code> if one is not required. * @param encoding the encoding to use for the XML output. * @throws IOException if the serialization fails. * @throws NullPointerException if <code>os</code> or <code>encoding</code> * is null. * @since 1.5 */ public void storeToXML(OutputStream os, String comment, String encoding) throws IOException { if (os == null) throw new NullPointerException("Null output stream supplied."); if (encoding == null) throw new NullPointerException("Null encoding supplied."); try { DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); DOMImplementation domImpl = registry.getDOMImplementation("LS 3.0"); DocumentType doctype = domImpl.createDocumentType("properties", null, "http://java.sun.com/dtd/properties.dtd"); Document doc = domImpl.createDocument(null, "properties", doctype); Element root = doc.getDocumentElement(); if (comment != null) { Element commentElement = doc.createElement("comment"); commentElement.appendChild(doc.createTextNode(comment)); root.appendChild(commentElement); } Iterator iterator = entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); Element entryElement = doc.createElement("entry"); entryElement.setAttribute("key", (String) entry.getKey()); entryElement.appendChild(doc.createTextNode((String) entry.getValue())); root.appendChild(entryElement); } DOMImplementationLS loadAndSave = (DOMImplementationLS) domImpl; LSSerializer serializer = loadAndSave.createLSSerializer(); LSOutput output = loadAndSave.createLSOutput(); output.setByteStream(os); output.setEncoding(encoding); serializer.write(doc, output); } catch (ClassNotFoundException e) { throw (IOException) new IOException("The XML classes could not be found.").initCause(e); } catch (InstantiationException e) { throw (IOException) new IOException("The XML classes could not be instantiated.") .initCause(e); } catch (IllegalAccessException e) { throw (IOException) new IOException("The XML classes could not be accessed.") .initCause(e); } } /** * <p> * Decodes the contents of the supplied <code>InputStream</code> as * an XML file, which represents a set of properties. The format of * the XML file must match the DTD * <a href="http://java.sun.com/dtd/properties.dtd"> * http://java.sun.com/dtd/properties.dtd</a>. * </p> * * @param in the input stream from which to receive the XML data. * @throws IOException if an I/O error occurs in reading the input data. * @throws InvalidPropertiesFormatException if the input data does not * constitute an XML properties * file. * @throws NullPointerException if <code>in</code> is null. * @since 1.5 */ public void loadFromXML(InputStream in) throws IOException, InvalidPropertiesFormatException { if (in == null) throw new NullPointerException("Null input stream supplied."); try { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(false); /* Don't use the URI */ XMLReader parser = factory.newSAXParser().getXMLReader(); PropertiesHandler handler = new PropertiesHandler(); parser.setContentHandler(handler); parser.setProperty("http://xml.org/sax/properties/lexical-handler", handler); parser.parse(new InputSource(in)); } catch (SAXException e) { throw (InvalidPropertiesFormatException) new InvalidPropertiesFormatException("Error in parsing XML."). initCause(e); } catch (ParserConfigurationException e) { throw (IOException) new IOException("An XML parser could not be found."). initCause(e); } } /** * This class deals with the parsing of XML using * <a href="http://java.sun.com/dtd/properties.dtd"> * http://java.sun.com/dtd/properties.dtd</a>. * * @author Andrew John Hughes (gnu_andrew@member.fsf.org) * @since 1.5 */ private class PropertiesHandler extends DefaultHandler2 { /** * The current key. */ private String key; /** * The current value. */ private String value; /** * A flag to check whether a valid DTD declaration has been seen. */ private boolean dtdDeclSeen; /** * Constructs a new Properties handler. */ public PropertiesHandler() { key = null; value = null; dtdDeclSeen = false; } /** * <p> * Captures the start of the DTD declarations, if they exist. * A valid properties file must declare the following doctype: * </p> * <p> * <code>!DOCTYPE properties SYSTEM * "http://java.sun.com/dtd/properties.dtd"</code> * </p> * * @param name the name of the document type. * @param publicId the public identifier that was declared, or * null if there wasn't one. * @param systemId the system identifier that was declared, or * null if there wasn't one. * @throws SAXException if some error occurs in parsing. */ public void startDTD(String name, String publicId, String systemId) throws SAXException { if (name.equals("properties") && publicId == null && systemId.equals("http://java.sun.com/dtd/properties.dtd")) { dtdDeclSeen = true; } else throw new SAXException("Invalid DTD declaration: " + name); } /** * Captures the start of an XML element. * * @param uri the namespace URI. * @param localName the local name of the element inside the namespace. * @param qName the local name qualified with the namespace URI. * @param attributes the attributes of this element. * @throws SAXException if some error occurs in parsing. */ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equals("entry")) { int index = attributes.getIndex("key"); if (index != -1) key = attributes.getValue(index); } else if (qName.equals("comment") || qName.equals("properties")) { /* Ignore it */ } else throw new SAXException("Invalid tag: " + qName); } /** * Captures characters within an XML element. * * @param ch the array of characters. * @param start the start index of the characters to use. * @param length the number of characters to use from the start index on. * @throws SAXException if some error occurs in parsing. */ public void characters(char[] ch, int start, int length) throws SAXException { if (key != null) value = new String(ch,start,length); } /** * Captures the end of an XML element. * * @param uri the namespace URI. * @param localName the local name of the element inside the namespace. * @param qName the local name qualified with the namespace URI. * @throws SAXException if some error occurs in parsing. */ public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equals("entry")) { if (value == null) value = ""; setProperty(key, value); key = null; value = null; } } /** * Captures the end of the XML document. If a DTD declaration has * not been seen, the document is erroneous and an exception is thrown. * * @throws SAXException if the correct DTD declaration didn't appear. */ public void endDocument() throws SAXException { if (!dtdDeclSeen) throw new SAXException("No appropriate DTD declaration was seen."); } } // class PropertiesHandler} // class Properties
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -