/[classpath]/classpath/java/util/Properties.java
ViewVC logotype

Diff of /classpath/java/util/Properties.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.13 by mark, Tue Jan 22 22:27:01 2002 UTC revision 1.14 by ericb, Fri Feb 22 02:09:40 2002 UTC
# Line 1  Line 1 
1  /* java.util.Properties  /* Properties.java -- a set of persistent properties
2     Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.     Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
# Line 40  package java.util; Line 40  package java.util;
40  import java.io.*;  import java.io.*;
41    
42  /**  /**
43     * A set of persistent properties, which can be saved or loaded from a stream.
44     * A property list may also contain defaults, searched if the main list
45     * does not contain a property for a given key.
46     *
47   * An example of a properties file for the german language is given   * An example of a properties file for the german language is given
48   * here.  This extends the example given in ListResourceBundle.   * here.  This extends the example given in ListResourceBundle.
49   * Create a file MyResource_de.properties with the following contents   * Create a file MyResource_de.properties with the following contents
50   * and put it in the CLASSPATH.  (The character   * and put it in the CLASSPATH.  (The character
51   * <code>\</code><code>u00e4</code> is the german &auml;)   * <code>\</code><code>u00e4</code> is the german &auml;)
52   *   *
53   * <pre>   * <pre>
54   * s1=3   * s1=3
55   * s2=MeineDisk   * s2=MeineDisk
# Line 71  import java.io.*; Line 75  import java.io.*;
75   * this, you should use the <code>get/setProperty</code> method instead   * this, you should use the <code>get/setProperty</code> method instead
76   * of <code>get/put</code>.   * of <code>get/put</code>.
77   *   *
78   * @see PropertyResourceBundle   * Properties are saved in ISO 8859-1 encoding, using Unicode escapes with
79     * a single <code>u</code> for any character which cannot be represented.
80     *
81   * @author Jochen Hoenicke   * @author Jochen Hoenicke
82     * @author Eric Blake <ebb9@email.byu.edu>
83     * @see PropertyResourceBundle
84     * @status updated to 1.4
85   */   */
86  public class Properties extends Hashtable  public class Properties extends Hashtable
87  {  {
88    /**    /**
89     * The property list that contains default values for any keys not     * The property list that contains default values for any keys not
90     * in this property list.       * in this property list.
91       *
92       * @serial the default properties
93     */     */
94    protected Properties defaults;    protected Properties defaults;
95    
96      /**
97       * Compatible with JDK 1.0+.
98       */
99    private static final long serialVersionUID = 4112578634029874840L;    private static final long serialVersionUID = 4112578634029874840L;
100    
101    /**    /**
102     * Creates a new empty property list.     * Creates a new empty property list with no default values.
103     */     */
104    public Properties()    public Properties()
105    {    {
# Line 94  public class Properties extends Hashtabl Line 108  public class Properties extends Hashtabl
108    
109    /**    /**
110     * Create a new empty property list with the specified default values.     * Create a new empty property list with the specified default values.
111     * @param defaults a Properties object containing the default values.     *
112       * @param defaults a Properties object containing the default values
113     */     */
114    public Properties(Properties defaults)    public Properties(Properties defaults)
115    {    {
# Line 102  public class Properties extends Hashtabl Line 117  public class Properties extends Hashtabl
117    }    }
118    
119    /**    /**
120       * Adds the given key/value pair to this properties.  This calls
121       * the hashtable method put.
122       *
123       * @param key the key for this property
124       * @param value the value for this property
125       * @return The old value for the given key
126       * @see #getProperty(String)
127       * @since 1.2
128       */
129      public Object setProperty(String key, String value)
130      {
131        return put(key, value);
132      }
133    
134      /**
135     * Reads a property list from an input stream.  The stream should     * Reads a property list from an input stream.  The stream should
136     * have the following format: <br>     * have the following format: <br>
137     *     *
# Line 120  public class Properties extends Hashtabl Line 150  public class Properties extends Hashtabl
150     *     *
151     * Escape sequences <code>\t, \n, \r, \\, \", \', \!, \#, \ </code>(a     * Escape sequences <code>\t, \n, \r, \\, \", \', \!, \#, \ </code>(a
152     * space), and unicode characters with the     * space), and unicode characters with the
153     * <code>\</code><code>u</code>xxxx notation are detected, and     * <code>\\u</code><em>xxxx</em> notation are detected, and
154     * converted to the corresponding single character. <br>     * converted to the corresponding single character. <br>
155     *     *
156     * <pre>     * <pre>
# Line 132  public class Properties extends Hashtabl Line 162  public class Properties extends Hashtabl
162     * weekdays: Sunday,Monday,Tuesday,Wednesday,\     * weekdays: Sunday,Monday,Tuesday,Wednesday,\
163     *           Thursday,Friday,Saturday     *           Thursday,Friday,Saturday
164     * # The safest way to include a space at the end of a value:     * # The safest way to include a space at the end of a value:
165     * label   = Name:\<code></code>u0020     * label   = Name:\\u0020
166     * </pre>     * </pre>
167     *     *
168     * @param in the input stream     * @param in the input stream
169     * @exception IOException if an error occurred when reading     * @throws IOException if an error occurred when reading the input
170     * from the input.  */     */
171    public void load(InputStream inStream) throws IOException    public void load(InputStream inStream) throws IOException
172    {    {
173      // The spec says that the file must be encoded using ISO-8859-1.      // The spec says that the file must be encoded using ISO-8859-1.
174      BufferedReader reader =      BufferedReader reader =
175        new BufferedReader(new InputStreamReader(inStream, "ISO-8859-1"));        new BufferedReader(new InputStreamReader(inStream, "ISO-8859-1"));
176      String line;      String line;
177        
178      while ((line = reader.readLine()) != null)      while ((line = reader.readLine()) != null)
179        {        {
180          char c = 0;          char c = 0;
181          int pos = 0;          int pos = 0;
182          while (pos < line.length()          while (pos < line.length()
183                 && Character.isWhitespace(c = line.charAt(pos)))                 && Character.isWhitespace(c = line.charAt(pos)))
184            pos++;            pos++;
185    
186          // If line is empty or begins with a comment character,          // If line is empty or begins with a comment character,
187          // skip this line.          // skip this line.
188          if (pos == line.length() || c == '#' || c == '!')          if (pos == line.length() || c == '#' || c == '!')
189            continue;            continue;
190    
191          // The characters up to the next Whitespace, ':', or '='          // The characters up to the next Whitespace, ':', or '='
192          // describe the key.  But look for escape sequences.          // describe the key.  But look for escape sequences.
193          StringBuffer key = new StringBuffer();          StringBuffer key = new StringBuffer();
194          while (pos < line.length()          while (pos < line.length()
195                 && !Character.isWhitespace(c = line.charAt(pos++))                 && ! Character.isWhitespace(c = line.charAt(pos++))
196                 && c != '=' && c != ':')                 && c != '=' && c != ':')
197            {            {
198              if (c == '\\')              if (c == '\\')
199                {                {
200                  if (pos == line.length())                  if (pos == line.length())
201                    {                    {
202                      // The line continues on the next line.                      // The line continues on the next line.
203                      line = reader.readLine();                      line = reader.readLine();
204                      pos = 0;                      pos = 0;
205                      while (pos < line.length()                      while (pos < line.length()
206                             && Character.isWhitespace(c = line.charAt(pos)))                             && Character.isWhitespace(c = line.charAt(pos)))
207                        pos++;                        pos++;
208                    }                    }
209                  else                  else
210                    {                    {
211                      c = line.charAt(pos++);                      c = line.charAt(pos++);
212                      switch (c)                      switch (c)
213                        {                        {
214                        case 'n':                        case 'n':
215                          key.append('\n');                          key.append('\n');
216                          break;                          break;
217                        case 't':                        case 't':
218                          key.append('\t');                          key.append('\t');
219                          break;                          break;
220                        case 'r':                        case 'r':
221                          key.append('\r');                          key.append('\r');
222                          break;                          break;
223                        case 'u':                        case 'u':
224                          if (pos + 4 <= line.length())                          if (pos + 4 <= line.length())
225                            {                            {
226                              char uni = (char) Integer.parseInt                              char uni = (char) Integer.parseInt
227                                (line.substring(pos, pos + 4), 16);                                (line.substring(pos, pos + 4), 16);
228                              key.append(uni);                              key.append(uni);
229                              pos += 4;                              pos += 4;
230                            }     // else throw exception?                            }        // else throw exception?
231                          break;                          break;
232                        default:                        default:
233                          key.append(c);                          key.append(c);
234                          break;                          break;
235                        }                        }
236                    }                    }
237                }                }
238              else              else
239                key.append(c);                key.append(c);
240            }            }
241    
242          boolean isDelim = (c == ':' || c == '=');          boolean isDelim = (c == ':' || c == '=');
243          while (pos < line.length()          while (pos < line.length()
244                 && Character.isWhitespace(c = line.charAt(pos)))                 && Character.isWhitespace(c = line.charAt(pos)))
245            pos++;            pos++;
246    
247          if (!isDelim && (c == ':' || c == '='))          if (! isDelim && (c == ':' || c == '='))
248            {            {
249              pos++;              pos++;
250              while (pos < line.length()              while (pos < line.length()
251                     && Character.isWhitespace(c = line.charAt(pos)))                     && Character.isWhitespace(c = line.charAt(pos)))
252                pos++;                pos++;
253            }            }
254    
255          StringBuffer element = new StringBuffer(line.length() - pos);          StringBuffer element = new StringBuffer(line.length() - pos);
256          while (pos < line.length())          while (pos < line.length())
257            {            {
258              c = line.charAt(pos++);              c = line.charAt(pos++);
259              if (c == '\\')              if (c == '\\')
260                {                {
261                  if (pos == line.length())                  if (pos == line.length())
262                    {                    {
263                      // The line continues on the next line.                      // The line continues on the next line.
264                      line = reader.readLine();                      line = reader.readLine();
265                      pos = 0;                      pos = 0;
266                      while (pos < line.length()                      while (pos < line.length()
267                             && Character.isWhitespace(c = line.charAt(pos)))                             && Character.isWhitespace(c = line.charAt(pos)))
268                        pos++;                        pos++;
269                      element.ensureCapacity(line.length() - pos +                      element.ensureCapacity(line.length() - pos +
270                                             element.length());                                             element.length());
271                    }                    }
272                  else                  else
273                    {                    {
274                      c = line.charAt(pos++);                      c = line.charAt(pos++);
275                      switch (c)                      switch (c)
276                        {                        {
277                        case 'n':                        case 'n':
278                          element.append('\n');                          element.append('\n');
279                          break;                          break;
280                        case 't':                        case 't':
281                          element.append('\t');                          element.append('\t');
282                          break;                          break;
283                        case 'r':                        case 'r':
284                          element.append('\r');                          element.append('\r');
285                          break;                          break;
286                        case 'u':                        case 'u':
287                          if (pos + 4 <= line.length())                          if (pos + 4 <= line.length())
288                            {                            {
289                              char uni = (char) Integer.parseInt                              char uni = (char) Integer.parseInt
290                                (line.substring(pos, pos + 4), 16);                                (line.substring(pos, pos + 4), 16);
291                              element.append(uni);                              element.append(uni);
292                              pos += 4;                              pos += 4;
293                            }     // else throw exception?                            }        // else throw exception?
294                          break;                          break;
295                        default:                        default:
296                          element.append(c);                          element.append(c);
297                          break;                          break;
298                        }                        }
299                    }                    }
300                }                }
301              else              else
302                element.append(c);                element.append(c);
303            }            }
304          put(key.toString(), element.toString());          put(key.toString(), element.toString());
305        }        }
306    }    }
307    
308    /**    /**
309     * Calls <code>store(OutputStream out, String header)</code> and     * Calls <code>store(OutputStream out, String header)</code> and
310     * ignores the IOException that may be thrown.     * ignores the IOException that may be thrown.
311     * @deprecated use store instead.     *
312     * @exception ClassCastException if this property contains any key or     * @param out the stream to write to
313     * value that isn't a string.     * @param header a description of the property list
314       * @throws ClassCastException if this property contains any key or
315       *         value that are not strings
316       * @deprecated use {@link #store(OutputStream, String)} instead
317     */     */
318    public void save(OutputStream out, String header)    public void save(OutputStream out, String header)
319    {    {
320      try      try
321        {        {
322          store(out, header);          store(out, header);
323        }        }
324      catch (IOException ex)      catch (IOException ex)
325        {        {
# Line 294  public class Properties extends Hashtabl Line 327  public class Properties extends Hashtabl
327    }    }
328    
329    /**    /**
330     * Writes the key/value pairs to the given output stream. <br>     * Writes the key/value pairs to the given output stream, in a format
331       * suitable for <code>load</code>. <br>
332     *     *
333     * If header is not null, this method writes a comment containing     * If header is not null, this method writes a comment containing
334     * the header as first line to the stream.  The next line (or first     * the header as first line to the stream.  The next line (or first
# Line 308  public class Properties extends Hashtabl Line 342  public class Properties extends Hashtabl
342     * preceeded by a backslash.  Spaces are preceded with a backslash,     * preceeded by a backslash.  Spaces are preceded with a backslash,
343     * if and only if they are at the beginning of the key.  Characters     * if and only if they are at the beginning of the key.  Characters
344     * that are not in the ascii range 33 to 127 are written in the     * that are not in the ascii range 33 to 127 are written in the
345     * <code>\</code><code>u</code>xxxx Form.     * <code>\</code><code>u</code>xxxx Form.<br>
346       *
347       * Following the listing, the output stream is flushed but left open.
348     *     *
349     * @param out the output stream     * @param out the output stream
350     * @param header the header written in the first line, may be null.     * @param header the header written in the first line, may be null
351     * @exception ClassCastException if this property contains any key or     * @throws ClassCastException if this property contains any key or
352     * value that isn't a string.     *         value that isn't a string
353       * @throws IOException if writing to the stream fails
354       * @throws NullPointerException if out is null
355       * @since 1.2
356     */     */
357    public void store(OutputStream out, String header) throws IOException    public void store(OutputStream out, String header) throws IOException
358    {    {
359      // The spec says that the file must be encoded using ISO-8859-1.      // The spec says that the file must be encoded using ISO-8859-1.
360      PrintWriter writer      PrintWriter writer
361        = new PrintWriter(new OutputStreamWriter (out, "ISO-8859-1"));        = new PrintWriter(new OutputStreamWriter(out, "ISO-8859-1"));
362      if (header != null)      if (header != null)
363        writer.println("#" + header);        writer.println("#" + header);
364      writer.println("#" + new Date().toString());      writer.println("#" + new Date());
365      list(writer);      list(writer);
366      writer.flush();      writer.flush();
367    }    }
368    
369    /**    /**
    * Adds the given key/value pair to this properties.  This calls  
    * the hashtable method put.  
    * @param key the key for this property  
    * @param value the value for this property  
    * @return The old value for the given key.  
    * @since JDK1.2 */  
   public Object setProperty(String key, String value)  
   {  
     return put(key, value);  
   }  
   
   /**  
370     * Gets the property with the specified key in this property list.     * Gets the property with the specified key in this property list.
371     * If the key is not found, the default property list is searched.     * If the key is not found, the default property list is searched.
372     * If the property is not found in default or the default of     * If the property is not found in the default, null is returned.
373     * default, null is returned.     *
374     * @param key The key for this property.     * @param key The key for this property
375     * @param defaulValue A default value     * @return the value for the given key, or null if not found
376     * @return The value for the given key, or null if not found.     * @throws ClassCastException if this property contains any key or
377     * @exception ClassCastException if this property contains any key or     *         value that isn't a string
378     * value that isn't a string.     * @see #defaults
379       * @see #setProperty(String, String)
380       * @see #getProperty(String, String)
381     */     */
382    public String getProperty(String key)    public String getProperty(String key)
383    {    {
# Line 358  public class Properties extends Hashtabl Line 387  public class Properties extends Hashtabl
387    /**    /**
388     * Gets the property with the specified key in this property list.  If     * Gets the property with the specified key in this property list.  If
389     * the key is not found, the default property list is searched.  If the     * the key is not found, the default property list is searched.  If the
390     * property is not found in default or the default of default, the     * property is not found in the default, the specified defaultValue is
391     * specified defaultValue is returned.     * returned.
392     * @param key The key for this property.     *
393       * @param key The key for this property
394     * @param defaulValue A default value     * @param defaulValue A default value
395     * @return The value for the given key.     * @return The value for the given key
396     * @exception ClassCastException if this property contains any key or     * @throws ClassCastException if this property contains any key or
397     * value that isn't a string.     *         value that isn't a string
398       * @see #defaults
399       * @see #setProperty(String, String)
400     */     */
401    public String getProperty(String key, String defaultValue)    public String getProperty(String key, String defaultValue)
402    {    {
# Line 372  public class Properties extends Hashtabl Line 404  public class Properties extends Hashtabl
404      // Eliminate tail recursion.      // Eliminate tail recursion.
405      do      do
406        {        {
407          String value = (String) prop.get(key);          String value = (String) prop.get(key);
408          if (value != null)          if (value != null)
409            return value;            return value;
410          prop = prop.defaults;          prop = prop.defaults;
411        }        }
412      while (prop != null);      while (prop != null);
413      return defaultValue;      return defaultValue;
414    }    }
415    
   private final void addHashEntries(Hashtable base)  
   {  
     if (defaults != null)  
       defaults.addHashEntries(base);  
     Enumeration keys = keys();  
     while (keys.hasMoreElements())  
       base.put(keys.nextElement(), base);  
   }  
   
416    /**    /**
417     * Returns an enumeration of all keys in this property list, including     * Returns an enumeration of all keys in this property list, including
418     * the keys in the default property list.     * the keys in the default property list.
419       *
420       * @return an Enumeration of all defined keys
421     */     */
422    public Enumeration propertyNames()    public Enumeration propertyNames()
423    {    {
# Line 408  public class Properties extends Hashtabl Line 433  public class Properties extends Hashtabl
433    }    }
434    
435    /**    /**
436       * Writes the key/value pairs to the given print stream.  They are
437       * written in the way described in the method store. This does not visit
438       * the keys in the default properties.
439       *
440       * @param out the stream, where the key/value pairs are written to
441       * @throws ClassCastException if this property contains any key or
442       *         value that isn't a string
443       * @see #store(OutputStream, String)
444       */
445      public void list(PrintStream out)
446      {
447        Enumeration keys = keys();
448        Enumeration elts = elements();
449        while (keys.hasMoreElements())
450          {
451            String key = (String) keys.nextElement();
452            String elt = (String) elts.nextElement();
453            String output = formatForOutput(key, elt);
454            out.println(output);
455          }
456      }
457    
458      /**
459       * Writes the key/value pairs to the given print writer.  They are
460       * written in the way, described in the method store.
461       *
462       * @param out the writer, where the key/value pairs are written to
463       * @throws ClassCastException if this property contains any key or
464       *         value that isn't a string
465       * @see #store(OutputStream, String)
466       * @see #list(PrintStream)
467       * @since 1.1
468       */
469      public void list(PrintWriter out)
470      {
471        Enumeration keys = keys();
472        Enumeration elts = elements();
473        while (keys.hasMoreElements())
474          {
475            String key = (String) keys.nextElement();
476            String elt = (String) elts.nextElement();
477            String output = formatForOutput(key, elt);
478            out.println(output);
479          }
480      }
481    
482      /**
483     * Formats a key/value pair for output in a properties file.     * Formats a key/value pair for output in a properties file.
484     * See store for a description of the format.     * See store for a description of the format.
485     * @param key the key.     *
486     * @param value the value.     * @param key the key
487     * @see #store     * @param value the value
488       * @see #store(OutputStream, String)
489     */     */
490    private String formatForOutput(String key, String value)    private String formatForOutput(String key, String value)
491    {    {
# Line 422  public class Properties extends Hashtabl Line 495  public class Properties extends Hashtabl
495      boolean head = true;      boolean head = true;
496      for (int i = 0; i < key.length(); i++)      for (int i = 0; i < key.length(); i++)
497        {        {
498          char c = key.charAt(i);          char c = key.charAt(i);
499          switch (c)          switch (c)
500            {            {
501            case '\n':            case '\n':
502              result.append("\\n");              result.append("\\n");
503              break;              break;
504            case '\r':            case '\r':
505              result.append("\\r");              result.append("\\r");
506              break;              break;
507            case '\t':            case '\t':
508              result.append("\\t");              result.append("\\t");
509              break;              break;
510            case '\\':            case '\\':
511              result.append("\\\\");              result.append("\\\\");
512              break;              break;
513            case '!':            case '!':
514              result.append("\\!");              result.append("\\!");
515              break;              break;
516            case '#':            case '#':
517              result.append("\\#");              result.append("\\#");
518              break;              break;
519            case '=':            case '=':
520              result.append("\\=");              result.append("\\=");
521              break;              break;
522            case ':':            case ':':
523              result.append("\\:");              result.append("\\:");
524              break;              break;
525            case ' ':            case ' ':
526              result.append("\\ ");              result.append("\\ ");
527              break;              break;
528            default:            default:
529              if (c < 32 || c > '~')              if (c < 32 || c > '~')
530                {                {
531                  String hex = Integer.toHexString(c);                  String hex = Integer.toHexString(c);
532                  result.append("\\u0000".substring(0, 6 - hex.length()));                  result.append("\\u0000".substring(0, 6 - hex.length()));
533                  result.append(hex);                  result.append(hex);
534                }                }
535              else              else
536                  result.append(c);                  result.append(c);
537            }            }
538          if (c != 32)          if (c != 32)
539            head = false;            head = false;
540        }        }
541      result.append('=');      result.append('=');
542      head = true;      head = true;
543      for (int i = 0; i < value.length(); i++)      for (int i = 0; i < value.length(); i++)
544        {        {
545          char c = value.charAt(i);          char c = value.charAt(i);
546          switch (c)          switch (c)
547            {            {
548            case '\n':            case '\n':
549              result.append("\\n");              result.append("\\n");
550              break;              break;
551            case '\r':            case '\r':
552              result.append("\\r");              result.append("\\r");
553              break;              break;
554            case '\t':            case '\t':
555              result.append("\\t");              result.append("\\t");
556              break;              break;
557            case '\\':            case '\\':
558              result.append("\\\\");              result.append("\\\\");
559              break;              break;
560            case '!':            case '!':
561              result.append("\\!");              result.append("\\!");
562              break;              break;
563            case '#':            case '#':
564              result.append("\\#");              result.append("\\#");
565              break;              break;
566            case ' ':            case ' ':
567              result.append(head ? "\\ " : " ");              result.append(head ? "\\ " : " ");
568              break;              break;
569            default:            default:
570              if (c < 32 || c > '~')              if (c < 32 || c > '~')
571                {                {
572                  String hex = Integer.toHexString(c);                  String hex = Integer.toHexString(c);
573                  result.append("\\u0000".substring(0, 6 - hex.length()));                  result.append("\\u0000".substring(0, 6 - hex.length()));
574                  result.append(hex);                  result.append(hex);
575                }                }
576              else              else
577                result.append(c);                result.append(c);
578            }            }
579          if (c != 32)          if (c != 32)
580            head = false;            head = false;
581        }        }
582      return result.toString();      return result.toString();
583    }    }
584    
585    /**    /**
586     * Writes the key/value pairs to the given print stream.  They are     * Recursively grabs the keys from the default properties.
587     * written in the way, described in the method store.     *
588     * @param out the stream, where the key/value pairs are written to.     * @param base the hashtable to place the keys in
    * @exception ClassCastException if this property contains any key or  
    * value that isn't a string.  
    * @see #store  
    */  
   public void list(PrintStream out)  
   {  
     Enumeration keys = keys();  
     Enumeration elts = elements();  
     while (keys.hasMoreElements())  
       {  
         String key = (String) keys.nextElement();  
         String elt = (String) elts.nextElement();  
         String output = formatForOutput(key, elt);  
         out.println(output);  
       }  
   }  
   
   /**  
    * Writes the key/value pairs to the given print writer.  They are  
    * written in the way, described in the method store.  
    * @param out the writer, where the key/value pairs are written to.  
    * @exception ClassCastException if this property contains any key or  
    * value that isn't a string.  
    * @see #store  
    * @see #list(java.io.PrintStream)  
    * @since JDK1.1  
589     */     */
590    public void list(PrintWriter out)    private final void addHashEntries(Hashtable base)
591    {    {
592        if (defaults != null)
593          defaults.addHashEntries(base);
594      Enumeration keys = keys();      Enumeration keys = keys();
     Enumeration elts = elements();  
595      while (keys.hasMoreElements())      while (keys.hasMoreElements())
596        {        base.put(keys.nextElement(), base);
         String key = (String) keys.nextElement();  
         String elt = (String) elts.nextElement();  
         String output = formatForOutput(key, elt);  
         out.println(output);  
       }  
597    }    }
598  }  }

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26