Source Code Cross Referenced for Properties.java in  » 6.0-JDK-Modules » j2me » java » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » java.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * @(#)Properties.java	1.70 06/10/10
003:         *
004:         * Copyright  1990-2006 Sun Microsystems, Inc. All Rights Reserved.  
005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER  
006:         *   
007:         * This program is free software; you can redistribute it and/or  
008:         * modify it under the terms of the GNU General Public License version  
009:         * 2 only, as published by the Free Software Foundation.   
010:         *   
011:         * This program is distributed in the hope that it will be useful, but  
012:         * WITHOUT ANY WARRANTY; without even the implied warranty of  
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  
014:         * General Public License version 2 for more details (a copy is  
015:         * included at /legal/license.txt).   
016:         *   
017:         * You should have received a copy of the GNU General Public License  
018:         * version 2 along with this work; if not, write to the Free Software  
019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  
020:         * 02110-1301 USA   
021:         *   
022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa  
023:         * Clara, CA 95054 or visit www.sun.com if you need additional  
024:         * information or have any questions. 
025:         *
026:         */
027:
028:        package java.util;
029:
030:        import java.io.IOException;
031:        import java.io.PrintStream;
032:        import java.io.PrintWriter;
033:        import java.io.InputStream;
034:        import java.io.InputStreamReader;
035:        import java.io.BufferedReader;
036:        import java.io.OutputStream;
037:        import java.io.OutputStreamWriter;
038:        import java.io.BufferedWriter;
039:        import java.util.Hashtable;
040:
041:        /**
042:         * The <code>Properties</code> class represents a persistent set of
043:         * properties. The <code>Properties</code> can be saved to a stream
044:         * or loaded from a stream. Each key and its corresponding value in
045:         * the property list is a string.
046:         * <p>
047:         * A property list can contain another property list as its
048:         * "defaults"; this second property list is searched if
049:         * the property key is not found in the original property list.
050:         * <p>
051:         * Because <code>Properties</code> inherits from <code>Hashtable</code>, the
052:         * <code>put</code> and <code>putAll</code> methods can be applied to a
053:         * <code>Properties</code> object.  Their use is strongly discouraged as they
054:         * allow the caller to insert entries whose keys or values are not
055:         * <code>Strings</code>.  The <code>setProperty</code> method should be used
056:         * instead.  If the <code>store</code> or <code>save</code> method is called
057:         * on a "compromised" <code>Properties</code> object that contains a
058:         * non-<code>String</code> key or value, the call will fail.
059:         * <p>
060:         * <a name="encoding"></a>
061:         * When saving properties to a stream or loading them from a stream, the
062:         * ISO 8859-1 character encoding is used. For characters that cannot be directly
063:         * represented in this encoding,
064:         * <a href="http://java.sun.com/docs/books/jls/html/3.doc.html#100850">Unicode escapes</a>
065:         * are used; however, only a single 'u' character is allowed in an escape sequence.
066:         * The native2ascii tool can be used to convert property files to and from
067:         * other character encodings.
068:         * 
069:         * @see <a href="../../../tooldocs/solaris/native2ascii.html">native2ascii tool for Solaris</a>
070:         * @see <a href="../../../tooldocs/windows/native2ascii.html">native2ascii tool for Windows</a>
071:         *
072:         * @author  Arthur van Hoff
073:         * @author  Michael McCloskey
074:         * @version 1.61, 05/03/00
075:         * @since   JDK1.0
076:         */
077:        public class Properties extends Hashtable {
078:            /**
079:             * use serialVersionUID from JDK 1.1.X for interoperability
080:             */
081:            private static final long serialVersionUID = 4112578634029874840L;
082:
083:            /**
084:             * A property list that contains default values for any keys not
085:             * found in this property list.
086:             *
087:             * @serial
088:             */
089:            protected Properties defaults;
090:
091:            /**
092:             * Creates an empty property list with no default values.
093:             */
094:            public Properties() {
095:                this (null);
096:            }
097:
098:            /**
099:             * Creates an empty property list with the specified defaults.
100:             *
101:             * @param   defaults   the defaults.
102:             */
103:            public Properties(Properties defaults) {
104:                this .defaults = defaults;
105:            }
106:
107:            /**
108:             * Calls the <tt>Hashtable</tt> method <code>put</code>. Provided for
109:             * parallelism with the <tt>getProperty</tt> method. Enforces use of
110:             * strings for property keys and values. The value returned is the
111:             * result of the <tt>Hashtable</tt> call to <code>put</code>.
112:             *
113:             * @param key the key to be placed into this property list.
114:             * @param value the value corresponding to <tt>key</tt>.
115:             * @return     the previous value of the specified key in this property
116:             *             list, or <code>null</code> if it did not have one.
117:             * @see #getProperty
118:             * @since    1.2
119:             */
120:            public synchronized Object setProperty(String key, String value) {
121:                return put(key, value);
122:            }
123:
124:            private static final String keyValueSeparators = "=: \t\r\n\f";
125:
126:            private static final String strictKeyValueSeparators = "=:";
127:
128:            private static final String specialSaveChars = "=: \t\r\n\f#!";
129:
130:            private static final String whiteSpaceChars = " \t\r\n\f";
131:
132:            /**
133:             * Reads a property list (key and element pairs) from the input
134:             * stream.  The stream is assumed to be using the ISO 8859-1
135:             * character encoding; that is each byte is one Latin1 character.
136:             * Characters not in Latin1, and certain special characters, can
137:             * be represented in keys and elements using escape sequences
138:             * similar to those used for character and string literals (see <a
139:             * href="http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#100850">&sect;3.3</a>
140:             * and <a
141:             * href="http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#101089">&sect;3.10.6</a>
142:             * of the <i>Java Language Specification</i>).
143:             *
144:             * The differences from the character escape sequences used for
145:             * characters and strings are:
146:             *
147:             * <ul>
148:             * <li> Octal escapes are not recognized.
149:             *
150:             * <li> The character sequence <code>\b</code> does <i>not</i>
151:             * represent a backspace character.
152:             *
153:             * <li> The method does not treat a backslash character,
154:             * <code>\</code>, before a non-valid escape character as an
155:             * error; the backslash is silently dropped.  For example, in a
156:             * Java string the sequence <code>"\z"</code> would cause a
157:             * compile time error.  In contrast, this method silently drops
158:             * the backslash.  Therefore, this method treats the two character
159:             * sequence <code>"\b"</code> as equivalent to the single
160:             * character <code>'b'</code>.
161:             *
162:             * <li> Escapes are not necessary for single and double quotes;
163:             * however, by the rule above, single and double quote characters
164:             * preceded by a backslash still yield single and double quote
165:             * characters, respectively.
166:             *
167:             * </ul>
168:             *
169:             * An <code>IllegalArgumentException</code> is thrown if a
170:             * malformed Unicode escape appears in the input.
171:             *
172:             * <p>
173:             * This method processes input in terms of lines.  A natural line
174:             * of input is terminated either by a set of line terminator
175:             * characters (<code>\n</code> or <code>\r</code> or
176:             * <code>\r\n</code>) or by the end of the file.  A natural line
177:             * may be either a blank line, a comment line, or hold some part
178:             * of a key-element pair.  The logical line holding all the data
179:             * for a key-element pair may be spread out across several adjacent
180:             * natural lines by escaping the line terminator sequence with a
181:             * backslash character, <code>\</code>.  Note that a comment line
182:             * cannot be extended in this manner; every natural line that is a
183:             * comment must have its own comment indicator, as described
184:             * below.  If a logical line is continued over several natural
185:             * lines, the continuation lines receive further processing, also
186:             * described below.  Lines are read from the input stream until
187:             * end of file is reached.
188:             *
189:             * <p>
190:             * A natural line that contains only white space characters is
191:             * considered blank and is ignored.  A comment line has an ASCII
192:             * <code>'#'</code> or <code>'!'</code> as its first non-white
193:             * space character; comment lines are also ignored and do not
194:             * encode key-element information.  In addition to line
195:             * terminators, this method considers the characters space
196:             * (<code>' '</code>, <code>'&#92;u0020'</code>), tab
197:             * (<code>'\t'</code>, <code>'&#92;u0009'</code>), and form feed
198:             * (<code>'\f'</code>, <code>'&#92;u000C'</code>) to be white
199:             * space.
200:             *
201:             * <p>
202:             * If a logical line is spread across several natural lines, the
203:             * backslash escaping the line terminator sequence, the line
204:             * terminator sequence, and any white space at the start the
205:             * following line have no affect on the key or element values.
206:             * The remainder of the discussion of key and element parsing will
207:             * assume all the characters constituting the key and element
208:             * appear on a single natural line after line continuation
209:             * characters have been removed.  Note that it is <i>not</i>
210:             * sufficient to only examine the character preceding a line
211:             * terminator sequence to to see if the line terminator is
212:             * escaped; there must be an odd number of contiguous backslashes
213:             * for the line terminator to be escaped.  Since the input is
214:             * processed from left to right, a non-zero even number of
215:             * 2<i>n</i> contiguous backslashes before a line terminator (or
216:             * elsewhere) encodes <i>n</i> backslashes after escape
217:             * processing.
218:             *
219:             * <p>
220:             * The key contains all of the characters in the line starting
221:             * with the first non-white space character and up to, but not
222:             * including, the first unescaped <code>'='</code>,
223:             * <code>':'</code>, or white space character other than a line
224:             * terminator. All of these key termination characters may be
225:             * included in the key by escaping them with a preceding backslash
226:             * character; for example,<p>
227:             *
228:             * <code>\:\=</code><p>
229:             *
230:             * would be the two-character key <code>":="</code>.  Line
231:             * terminator characters can be included using <code>\r</code> and
232:             * <code>\n</code> escape sequences.  Any white space after the
233:             * key is skipped; if the first non-white space character after
234:             * the key is <code>'='</code> or <code>':'</code>, then it is
235:             * ignored and any white space characters after it are also
236:             * skipped.  All remaining characters on the line become part of
237:             * the associated element string; if there are no remaining
238:             * characters, the element is the empty string
239:             * <code>&quot;&quot;</code>.  Once the raw character sequences
240:             * constituting the key and element are identified, escape
241:             * processing is performed as described above.
242:             *
243:             * <p>
244:             * As an example, each of the following three lines specifies the key
245:             * <code>"Truth"</code> and the associated element value
246:             * <code>"Beauty"</code>:
247:             * <p>
248:             * <pre>
249:             * Truth = Beauty
250:             *	Truth:Beauty
251:             * Truth			:Beauty
252:             * </pre>
253:             * As another example, the following three lines specify a single
254:             * property:
255:             * <p>
256:             * <pre>
257:             * fruits                           apple, banana, pear, \
258:             *                                  cantaloupe, watermelon, \
259:             *                                  kiwi, mango
260:             * </pre>
261:             * The key is <code>"fruits"</code> and the associated element is:
262:             * <p>
263:             * <pre>"apple, banana, pear, cantaloupe, watermelon, kiwi, mango"</pre>
264:             * Note that a space appears before each <code>\</code> so that a space
265:             * will appear after each comma in the final result; the <code>\</code>,
266:             * line terminator, and leading white space on the continuation line are
267:             * merely discarded and are <i>not</i> replaced by one or more other
268:             * characters.
269:             * <p>
270:             * As a third example, the line:
271:             * <p>
272:             * <pre>cheeses
273:             * </pre>
274:             * specifies that the key is <code>"cheeses"</code> and the associated
275:             * element is the empty string <code>""</code>.<p>
276:             *
277:             * @param      inStream   the input stream.
278:             * @exception  IOException  if an error occurred when reading from the
279:             *               input stream.
280:             * @throws	   IllegalArgumentException if the input stream contains a
281:             * 		   malformed Unicode escape sequence.
282:             */
283:            public synchronized void load(InputStream inStream)
284:                    throws IOException {
285:
286:                BufferedReader in = new BufferedReader(new InputStreamReader(
287:                        inStream, "8859_1"));
288:                while (true) {
289:                    // Get next line
290:                    String line = in.readLine();
291:                    if (line == null)
292:                        return;
293:
294:                    if (line.length() > 0) {
295:
296:                        // Find start of key
297:                        int len = line.length();
298:                        int keyStart;
299:                        for (keyStart = 0; keyStart < len; keyStart++)
300:                            if (whiteSpaceChars.indexOf(line.charAt(keyStart)) == -1)
301:                                break;
302:
303:                        // Blank lines are ignored
304:                        if (keyStart == len)
305:                            continue;
306:
307:                        // Continue lines that end in slashes if they are not comments
308:                        char firstChar = line.charAt(keyStart);
309:                        if ((firstChar != '#') && (firstChar != '!')) {
310:                            while (continueLine(line)) {
311:                                String nextLine = in.readLine();
312:                                if (nextLine == null)
313:                                    nextLine = "";
314:                                String loppedLine = line.substring(0, len - 1);
315:                                // Advance beyond whitespace on new line
316:                                int startIndex;
317:                                for (startIndex = 0; startIndex < nextLine
318:                                        .length(); startIndex++)
319:                                    if (whiteSpaceChars.indexOf(nextLine
320:                                            .charAt(startIndex)) == -1)
321:                                        break;
322:                                nextLine = nextLine.substring(startIndex,
323:                                        nextLine.length());
324:                                line = new String(loppedLine + nextLine);
325:                                len = line.length();
326:                            }
327:
328:                            // Find separation between key and value
329:                            int separatorIndex;
330:                            for (separatorIndex = keyStart; separatorIndex < len; separatorIndex++) {
331:                                char currentChar = line.charAt(separatorIndex);
332:                                if (currentChar == '\\')
333:                                    separatorIndex++;
334:                                else if (keyValueSeparators
335:                                        .indexOf(currentChar) != -1)
336:                                    break;
337:                            }
338:
339:                            // Skip over whitespace after key if any
340:                            int valueIndex;
341:                            for (valueIndex = separatorIndex; valueIndex < len; valueIndex++)
342:                                if (whiteSpaceChars.indexOf(line
343:                                        .charAt(valueIndex)) == -1)
344:                                    break;
345:
346:                            // Skip over one non whitespace key value separators if any
347:                            if (valueIndex < len)
348:                                if (strictKeyValueSeparators.indexOf(line
349:                                        .charAt(valueIndex)) != -1)
350:                                    valueIndex++;
351:
352:                            // Skip over white space after other separators if any
353:                            while (valueIndex < len) {
354:                                if (whiteSpaceChars.indexOf(line
355:                                        .charAt(valueIndex)) == -1)
356:                                    break;
357:                                valueIndex++;
358:                            }
359:                            String key = line.substring(keyStart,
360:                                    separatorIndex);
361:                            String value = (separatorIndex < len) ? line
362:                                    .substring(valueIndex, len) : "";
363:
364:                            // Convert then store key and value
365:                            key = loadConvert(key);
366:                            value = loadConvert(value);
367:                            put(key, value);
368:                        }
369:                    }
370:                }
371:            }
372:
373:            /*
374:             * Returns true if the given line is a line that must
375:             * be appended to the next line
376:             */
377:            private boolean continueLine(String line) {
378:                int slashCount = 0;
379:                int index = line.length() - 1;
380:                while ((index >= 0) && (line.charAt(index--) == '\\'))
381:                    slashCount++;
382:                return (slashCount % 2 == 1);
383:            }
384:
385:            /*
386:             * Converts encoded &#92;uxxxx to unicode chars
387:             * and changes special saved chars to their original forms
388:             */
389:            private String loadConvert(String theString) {
390:                char aChar;
391:                int len = theString.length();
392:                StringBuffer outBuffer = new StringBuffer(len);
393:
394:                for (int x = 0; x < len;) {
395:                    aChar = theString.charAt(x++);
396:                    if (aChar == '\\') {
397:                        aChar = theString.charAt(x++);
398:                        if (aChar == 'u') {
399:                            // Read the xxxx
400:                            int value = 0;
401:                            for (int i = 0; i < 4; i++) {
402:                                aChar = theString.charAt(x++);
403:                                switch (aChar) {
404:                                case '0':
405:                                case '1':
406:                                case '2':
407:                                case '3':
408:                                case '4':
409:                                case '5':
410:                                case '6':
411:                                case '7':
412:                                case '8':
413:                                case '9':
414:                                    value = (value << 4) + aChar - '0';
415:                                    break;
416:                                case 'a':
417:                                case 'b':
418:                                case 'c':
419:                                case 'd':
420:                                case 'e':
421:                                case 'f':
422:                                    value = (value << 4) + 10 + aChar - 'a';
423:                                    break;
424:                                case 'A':
425:                                case 'B':
426:                                case 'C':
427:                                case 'D':
428:                                case 'E':
429:                                case 'F':
430:                                    value = (value << 4) + 10 + aChar - 'A';
431:                                    break;
432:                                default:
433:                                    throw new IllegalArgumentException(
434:                                            "Malformed \\uxxxx encoding.");
435:                                }
436:                            }
437:                            outBuffer.append((char) value);
438:                        } else {
439:                            if (aChar == 't')
440:                                aChar = '\t';
441:                            else if (aChar == 'r')
442:                                aChar = '\r';
443:                            else if (aChar == 'n')
444:                                aChar = '\n';
445:                            else if (aChar == 'f')
446:                                aChar = '\f';
447:                            outBuffer.append(aChar);
448:                        }
449:                    } else
450:                        outBuffer.append(aChar);
451:                }
452:                return outBuffer.toString();
453:            }
454:
455:            /*
456:             * Converts unicodes to encoded &#92;uxxxx
457:             * and writes out any of the characters in specialSaveChars
458:             * with a preceding slash
459:             */
460:            private String saveConvert(String theString, boolean escapeSpace) {
461:                int len = theString.length();
462:                StringBuffer outBuffer = new StringBuffer(len * 2);
463:
464:                for (int x = 0; x < len; x++) {
465:                    char aChar = theString.charAt(x);
466:                    switch (aChar) {
467:                    case ' ':
468:                        if (x == 0 || escapeSpace)
469:                            outBuffer.append('\\');
470:
471:                        outBuffer.append(' ');
472:                        break;
473:                    case '\\':
474:                        outBuffer.append('\\');
475:                        outBuffer.append('\\');
476:                        break;
477:                    case '\t':
478:                        outBuffer.append('\\');
479:                        outBuffer.append('t');
480:                        break;
481:                    case '\n':
482:                        outBuffer.append('\\');
483:                        outBuffer.append('n');
484:                        break;
485:                    case '\r':
486:                        outBuffer.append('\\');
487:                        outBuffer.append('r');
488:                        break;
489:                    case '\f':
490:                        outBuffer.append('\\');
491:                        outBuffer.append('f');
492:                        break;
493:                    default:
494:                        if ((aChar < 0x0020) || (aChar > 0x007e)) {
495:                            outBuffer.append('\\');
496:                            outBuffer.append('u');
497:                            outBuffer.append(toHex((aChar >> 12) & 0xF));
498:                            outBuffer.append(toHex((aChar >> 8) & 0xF));
499:                            outBuffer.append(toHex((aChar >> 4) & 0xF));
500:                            outBuffer.append(toHex(aChar & 0xF));
501:                        } else {
502:                            if (specialSaveChars.indexOf(aChar) != -1)
503:                                outBuffer.append('\\');
504:                            outBuffer.append(aChar);
505:                        }
506:                    }
507:                }
508:                return outBuffer.toString();
509:            }
510:
511:            /**
512:             * Calls the <code>store(OutputStream out, String header)</code> method
513:             * and suppresses IOExceptions that were thrown.
514:             *
515:             * @deprecated This method does not throw an IOException if an I/O error
516:             * occurs while saving the property list.  As of the Java 2 platform v1.2, the preferred
517:             * way to save a properties list is via the <code>store(OutputStream out,
518:             * String header)</code> method.
519:             *
520:             * @param   out      an output stream.
521:             * @param   header   a description of the property list.
522:             * @exception  ClassCastException  if this <code>Properties</code> object
523:             *             contains any keys or values that are not <code>Strings</code>.
524:             */
525:            public synchronized void save(OutputStream out, String header) {
526:                try {
527:                    store(out, header);
528:                } catch (IOException e) {
529:                }
530:            }
531:
532:            /**
533:             * Writes this property list (key and element pairs) in this
534:             * <code>Properties</code> table to the output stream in a format suitable
535:             * for loading into a <code>Properties</code> table using the
536:             * {@link #load(InputStream) load} method.
537:             * The stream is written using the ISO 8859-1 character encoding.
538:             * <p>
539:             * Properties from the defaults table of this <code>Properties</code>
540:             * table (if any) are <i>not</i> written out by this method.
541:             * <p>
542:             * If the header argument is not null, then an ASCII <code>#</code>
543:             * character, the header string, and a line separator are first written
544:             * to the output stream. Thus, the <code>header</code> can serve as an
545:             * identifying comment.
546:             * <p>
547:             * Next, a comment line is always written, consisting of an ASCII
548:             * <code>#</code> character, the current date and time (as if produced
549:             * by the <code>toString</code> method of <code>Date</code> for the
550:             * current time), and a line separator as generated by the Writer.
551:             * <p>
552:             * Then every entry in this <code>Properties</code> table is
553:             * written out, one per line. For each entry the key string is
554:             * written, then an ASCII <code>=</code>, then the associated
555:             * element string. Each character of the key and element strings
556:             * is examined to see whether it should be rendered as an escape
557:             * sequence. The ASCII characters <code>\</code>, tab, form feed,
558:             * newline, and carriage return are written as <code>\\</code>,
559:             * <code>\t</code>, <code>\f</code> <code>\n</code>, and
560:             * <code>\r</code>, respectively. Characters less than
561:             * <code>&#92;u0020</code> and characters greater than
562:             * <code>&#92;u007E</code> are written as
563:             * <code>&#92;u</code><i>xxxx</i> for the appropriate hexadecimal
564:             * value <i>xxxx</i>.  For the key, all space characters are
565:             * written with a preceding <code>\</code> character.  For the
566:             * element, leading space characters, but not embedded or trailing
567:             * space characters, are written with a preceding <code>\</code>
568:             * character. The key and element characters <code>#</code>,
569:             * <code>!</code>, <code>=</code>, and <code>:</code> are written
570:             * with a preceding backslash to ensure that they are properly loaded.
571:             * <p>
572:             * After the entries have been written, the output stream is flushed.  The
573:             * output stream remains open after this method returns.
574:             *
575:             * @param   out      an output stream.
576:             * @param   header   a description of the property list.
577:             * @exception  IOException if writing this property list to the specified
578:             *             output stream throws an <tt>IOException</tt>.
579:             * @exception  ClassCastException  if this <code>Properties</code> object
580:             *             contains any keys or values that are not <code>Strings</code>.
581:             * @exception  NullPointerException  if <code>out</code> is null.
582:             * @since 1.2
583:             */
584:            public synchronized void store(OutputStream out, String header)
585:                    throws IOException {
586:                BufferedWriter awriter;
587:                awriter = new BufferedWriter(new OutputStreamWriter(out,
588:                        "8859_1"));
589:                if (header != null)
590:                    writeln(awriter, "#" + header);
591:                writeln(awriter, "#" + new Date().toString());
592:                for (Enumeration e = keys(); e.hasMoreElements();) {
593:                    String key = (String) e.nextElement();
594:                    String val = (String) get(key);
595:                    key = saveConvert(key, true);
596:
597:                    /* No need to escape embedded and trailing spaces for value, hence
598:                     * pass false to flag.
599:                     */
600:                    val = saveConvert(val, false);
601:                    writeln(awriter, key + "=" + val);
602:                }
603:                awriter.flush();
604:            }
605:
606:            private static void writeln(BufferedWriter bw, String s)
607:                    throws IOException {
608:                bw.write(s);
609:                bw.newLine();
610:            }
611:
612:            /**
613:             * Searches for the property with the specified key in this property list.
614:             * If the key is not found in this property list, the default property list,
615:             * and its defaults, recursively, are then checked. The method returns
616:             * <code>null</code> if the property is not found.
617:             *
618:             * @param   key   the property key.
619:             * @return  the value in this property list with the specified key value.
620:             * @see     #setProperty
621:             * @see     #defaults
622:             */
623:            public String getProperty(String key) {
624:                Object oval = super .get(key);
625:                String sval = (oval instanceof  String) ? (String) oval : null;
626:                return ((sval == null) && (defaults != null)) ? defaults
627:                        .getProperty(key) : sval;
628:            }
629:
630:            /**
631:             * Searches for the property with the specified key in this property list.
632:             * If the key is not found in this property list, the default property list,
633:             * and its defaults, recursively, are then checked. The method returns the
634:             * default value argument if the property is not found.
635:             *
636:             * @param   key            the hashtable key.
637:             * @param   defaultValue   a default value.
638:             *
639:             * @return  the value in this property list with the specified key value.
640:             * @see     #setProperty
641:             * @see     #defaults
642:             */
643:            public String getProperty(String key, String defaultValue) {
644:                String val = getProperty(key);
645:                return (val == null) ? defaultValue : val;
646:            }
647:
648:            /**
649:             * Returns an enumeration of all the keys in this property list,
650:             * including distinct keys in the default property list if a key
651:             * of the same name has not already been found from the main
652:             * properties list.
653:             *
654:             * @return  an enumeration of all the keys in this property list, including
655:             *          the keys in the default property list.
656:             * @see     java.util.Enumeration
657:             * @see     java.util.Properties#defaults
658:             */
659:            public Enumeration propertyNames() {
660:                Hashtable h = new Hashtable();
661:                enumerate(h);
662:                return h.keys();
663:            }
664:
665:            /**
666:             * Prints this property list out to the specified output stream.
667:             * This method is useful for debugging.
668:             *
669:             * @param   out   an output stream.
670:             */
671:            public void list(PrintStream out) {
672:                out.println("-- listing properties --");
673:                Hashtable h = new Hashtable();
674:                enumerate(h);
675:                for (Enumeration e = h.keys(); e.hasMoreElements();) {
676:                    String key = (String) e.nextElement();
677:                    String val = (String) h.get(key);
678:                    if (val.length() > 40) {
679:                        val = val.substring(0, 37) + "...";
680:                    }
681:                    out.println(key + "=" + val);
682:                }
683:            }
684:
685:            /**
686:             * Prints this property list out to the specified output stream.
687:             * This method is useful for debugging.
688:             *
689:             * @param   out   an output stream.
690:             * @since   JDK1.1
691:             */
692:            /*
693:             * Rather than use an anonymous inner class to share common code, this
694:             * method is duplicated in order to ensure that a non-1.1 compiler can
695:             * compile this file.
696:             */
697:            public void list(PrintWriter out) {
698:                out.println("-- listing properties --");
699:                Hashtable h = new Hashtable();
700:                enumerate(h);
701:                for (Enumeration e = h.keys(); e.hasMoreElements();) {
702:                    String key = (String) e.nextElement();
703:                    String val = (String) h.get(key);
704:                    if (val.length() > 40) {
705:                        val = val.substring(0, 37) + "...";
706:                    }
707:                    out.println(key + "=" + val);
708:                }
709:            }
710:
711:            /**
712:             * Enumerates all key/value pairs in the specified hastable.
713:             * @param h the hashtable
714:             */
715:            private synchronized void enumerate(Hashtable h) {
716:                if (defaults != null) {
717:                    defaults.enumerate(h);
718:                }
719:                for (Enumeration e = keys(); e.hasMoreElements();) {
720:                    String key = (String) e.nextElement();
721:                    h.put(key, get(key));
722:                }
723:            }
724:
725:            /**
726:             * Convert a nibble to a hex character
727:             * @param	nibble	the nibble to convert.
728:             */
729:            private static char toHex(int nibble) {
730:                return hexDigit[(nibble & 0xF)];
731:            }
732:
733:            /** A table of hex digits */
734:            private static final char[] hexDigit = { '0', '1', '2', '3', '4',
735:                    '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
736:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.