commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ebo...@apache.org
Subject cvs commit: jakarta-commons/configuration/src/test/org/apache/commons/configuration TestPropertiesConfiguration.java
Date Thu, 03 Jun 2004 15:32:46 GMT
ebourg      2004/06/03 08:32:46

  Modified:    configuration/src/java/org/apache/commons/configuration
                        AbstractConfiguration.java
                        BasePropertiesConfiguration.java
               configuration/conf test.properties
               configuration/src/test/org/apache/commons/configuration
                        TestPropertiesConfiguration.java
  Log:
  Fixed Bug 27775, the list separator (comma) can be escaped with the \ character
  
  Revision  Changes    Path
  1.9       +7 -16     jakarta-commons/configuration/src/java/org/apache/commons/configuration/AbstractConfiguration.java
  
  Index: AbstractConfiguration.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/AbstractConfiguration.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- AbstractConfiguration.java	4 May 2004 22:27:10 -0000	1.8
  +++ AbstractConfiguration.java	3 Jun 2004 15:32:46 -0000	1.9
  @@ -42,18 +42,13 @@
       /** how big the initial arraylist for splitting up name value pairs */
       private static final int INITIAL_LIST_SIZE = 2;
   
  -
       /** start token */
       protected static final String START_TOKEN = "${";
       /** end token */
       protected static final String END_TOKEN = "}";
   
  -    /**
  -     * Empty constructor.
  -     */
  -    public AbstractConfiguration()
  -    {
  -    }
  +    /** The property delimiter used while parsing (a comma). */
  +    protected static final char DELIMITER = ',';
   
       /**
        * Add a property to the configuration. If it already exists then the value
  @@ -76,8 +71,7 @@
       {
           if (token instanceof String)
           {
  -            for(Iterator it = processString((String) token).iterator();
  -            it.hasNext();)
  +            for(Iterator it = processString((String) token).iterator(); it.hasNext();)
               {
                   addPropertyDirect(key, it.next());
               }
  @@ -238,7 +232,7 @@
       {
           List retList = new ArrayList(INITIAL_LIST_SIZE);
   
  -        if (token.indexOf(PropertiesTokenizer.DELIMITER) > 0)
  +        if (token.indexOf(DELIMITER) > 0)
           {
               PropertiesTokenizer tokenizer = new PropertiesTokenizer(token);
   
  @@ -1300,11 +1294,8 @@
        * separator is "," but commas into the property value are escaped
        * using the backslash in front.
        */
  -    class PropertiesTokenizer extends StringTokenizer
  +    static class PropertiesTokenizer extends StringTokenizer
       {
  -        /** The property delimiter used while parsing (a comma). */
  -        static final String DELIMITER = ",";
  -
           /**
            * Constructor.
            *
  @@ -1312,7 +1303,7 @@
            */
           public PropertiesTokenizer(String string)
           {
  -            super(string, DELIMITER);
  +            super(string, String.valueOf(DELIMITER));
           }
   
           /**
  
  
  
  1.8       +168 -56   jakarta-commons/configuration/src/java/org/apache/commons/configuration/BasePropertiesConfiguration.java
  
  Index: BasePropertiesConfiguration.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/BasePropertiesConfiguration.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- BasePropertiesConfiguration.java	2 Jun 2004 16:42:24 -0000	1.7
  +++ BasePropertiesConfiguration.java	3 Jun 2004 15:32:46 -0000	1.8
  @@ -30,6 +30,7 @@
   
   import org.apache.commons.lang.StringEscapeUtils;
   import org.apache.commons.lang.StringUtils;
  +import org.apache.commons.lang.exception.NestableRuntimeException;
   
   /**
    * loads the configuration from a properties file. <p>
  @@ -101,7 +102,7 @@
    *
    *      # commas may be escaped in tokens
    *      commas.excaped = Hi\, what'up?
  - * 
  + *
    *      # properties can reference other properties
    *      base.prop = /base
    *      first.prop = ${base.prop}/first
  @@ -150,19 +151,17 @@
        * encoding.
        *
        * @param input An InputStream.
  -     * @param enc An encoding.
  +     * @param encoding An encoding.
        * @exception ConfigurationException
        */
  -    public synchronized void load(InputStream input, String enc)
  -        throws ConfigurationException
  +    public synchronized void load(InputStream input, String encoding) throws ConfigurationException
       {
           PropertiesReader reader = null;
  -        if (enc != null)
  +        if (encoding != null)
           {
               try
               {
  -                reader =
  -                  new PropertiesReader(new InputStreamReader(input, enc));
  +                reader = new PropertiesReader(new InputStreamReader(input, encoding));
               }
               catch (UnsupportedEncodingException e)
               {
  @@ -174,46 +173,47 @@
           {
               reader = new PropertiesReader(new InputStreamReader(input));
           }
  +
           try {
  -        while (true)
  -        {
  -            String line = reader.readProperty();
  -            
  -            if (line == null)
  -            {
  -                break; // EOF
  -            }
  -            
  -            int equalSign = line.indexOf('=');
  -            if (equalSign > 0)
  +            while (true)
               {
  -                String key = line.substring(0, equalSign).trim();
  -                String value = line.substring(equalSign + 1).trim();
  +                String line = reader.readProperty();
   
  -                // Though some software (e.g. autoconf) may produce
  -                // empty values like foo=\n, emulate the behavior of
  -                // java.util.Properties by setting the value to the
  -                // empty string.
  +                if (line == null)
  +                {
  +                    break; // EOF
  +                }
   
  -                if (StringUtils.isNotEmpty(getInclude())
  -                    && key.equalsIgnoreCase(getInclude()))
  +                int equalSign = line.indexOf('=');
  +                if (equalSign > 0)
                   {
  -                    if (getIncludesAllowed())
  +                    String key = line.substring(0, equalSign).trim();
  +                    String value = line.substring(equalSign + 1).trim();
  +
  +                    // Though some software (e.g. autoconf) may produce
  +                    // empty values like foo=\n, emulate the behavior of
  +                    // java.util.Properties by setting the value to the
  +                    // empty string.
  +
  +                    if (StringUtils.isNotEmpty(getInclude())
  +                        && key.equalsIgnoreCase(getInclude()))
                       {
  -                        String [] files = StringUtils.split(value, ",");
  -                        for (int cnt = 0 ; cnt < files.length ; cnt++)
  +                        if (getIncludesAllowed())
                           {
  -                            load(getPropertyStream(files[cnt].trim()));
  +                            String [] files = StringUtils.split(value, DELIMITER);
  +                            for (int i = 0; i < files.length; i++)
  +                            {
  +                                load(getPropertyStream(files[i].trim()));
  +                            }
                           }
                       }
  -                }
  -                else
  -                {
  -                    addProperty(key, StringEscapeUtils.unescapeJava(value));
  +                    else
  +                    {
  +                        addProperty(key, unescapeJava(value));
  +                    }
                   }
               }
           }
  -        }
           catch (IOException ioe){
           	throw new ConfigurationException("Could not load configuration from input stream.",ioe);
           }
  @@ -226,8 +226,7 @@
        * @param filename name of the properties file
        * @throws ConfigurationException
        */
  -    public void save(String filename)
  -        throws ConfigurationException
  +    public void save(String filename) throws ConfigurationException
       {
           PropertiesWriter out = null;
           File file = new File(filename);
  @@ -240,20 +239,20 @@
           	for (Iterator i = this.getKeys(); i.hasNext();)
           	{
           		String key = (String) i.next();
  -        		String value = StringUtils.join(this.getStringArray(key), ", ");
  -        		out.writeProperty(key, value);
  +        		out.writeProperty(key, this.getStringArray(key));
           	}
           	out.flush();
           	out.close();
           }
  -        catch (IOException ioe){
  +        catch (IOException ioe)
  +        {
               try {
  -                if (out !=null){
  +                if (out != null){
                       out.close();
                   }
               }
               catch (IOException ioe2){
  -                
  +
               }
           	throw new ConfigurationException("Could not save to file " + filename,ioe);
           }
  @@ -309,8 +308,7 @@
        * backslash sign a the end of the line.  This is used to
        * concatenate multiple lines for readability.
        */
  -    class PropertiesReader
  -        extends LineNumberReader
  +    class PropertiesReader extends LineNumberReader
       {
           /**
            * Constructor.
  @@ -331,8 +329,7 @@
            *
            * @exception IOException
            */
  -        public String readProperty()
  -            throws IOException
  +        public String readProperty() throws IOException
           {
               StringBuffer buffer = new StringBuffer();
   
  @@ -371,8 +368,7 @@
       /**
        * This class is used to write properties lines.
        */
  -    class PropertiesWriter
  -        extends FileWriter
  +    class PropertiesWriter extends FileWriter
       {
           /**
            * Constructor.
  @@ -380,8 +376,7 @@
            * @param file the proerties file
            * @throws IOException
            */
  -        public PropertiesWriter(File file)
  -            throws IOException
  +        public PropertiesWriter(File file) throws IOException
           {
               super(file);
           }
  @@ -393,25 +388,142 @@
            * @param value
            * @exception IOException
            */
  -        public void writeProperty(String key, String value)
  -            throws IOException
  +        public void writeProperty(String key, String value) throws IOException
           {
               write(key);
               write(" = ");
  -            write(value != null ? StringEscapeUtils.escapeJava(value) : "");          
  
  +            if (value != null)
  +            {
  +                String v = StringEscapeUtils.escapeJava(value);
  +                v = StringUtils.replace(v, String.valueOf(DELIMITER), "\\" + DELIMITER);
  +                write(v);
  +            }
  +
               write('\n');
           }
   
           /**
  +         * Write a property.
  +         *
  +         * @param key The key of the property
  +         * @param values The array of values of the property
  +         */
  +        public void writeProperty(String key, String[] values) throws IOException
  +        {
  +            for (int i = 0; i < values.length; i++)
  +            {
  +                writeProperty(key, values[i]);
  +            }
  +        }
  +
  +        /**
            * Write a comment.
            *
            * @param comment
            * @exception IOException
            */
  -        public void writeComment(String comment)
  -            throws IOException
  +        public void writeComment(String comment) throws IOException
           {
               write("# " + comment + "\n");
           }
       } // class PropertiesWriter
  +
  +    /**
  +     * <p>Unescapes any Java literals found in the <code>String</code>
to a
  +     * <code>Writer</code>.</p> This is a slightly modified version of
the
  +     * StringEscapeUtils.unescapeJava() function in commons-lang that doesn't
  +     * drop escaped commas (i.e '\,').
  +     *
  +     * @param str  the <code>String</code> to unescape, may be null
  +     * @throws IllegalArgumentException if the Writer is <code>null</code>
  +     */
  +    protected static String unescapeJava(String str) {
  +
  +        if (str == null) {
  +            return null;
  +        }
  +        int sz = str.length();
  +        StringBuffer out = new StringBuffer(sz);
  +        StringBuffer unicode = new StringBuffer(4);
  +        boolean hadSlash = false;
  +        boolean inUnicode = false;
  +        for (int i = 0; i < sz; i++) {
  +            char ch = str.charAt(i);
  +            if (inUnicode) {
  +                // if in unicode, then we're reading unicode
  +                // values in somehow
  +                unicode.append(ch);
  +                if (unicode.length() == 4) {
  +                    // unicode now contains the four hex digits
  +                    // which represents our unicode character
  +                    try {
  +                        int value = Integer.parseInt(unicode.toString(), 16);
  +                        out.append((char) value);
  +                        unicode.setLength(0);
  +                        inUnicode = false;
  +                        hadSlash = false;
  +                    } catch (NumberFormatException nfe) {
  +                        throw new NestableRuntimeException("Unable to parse unicode value:
" + unicode, nfe);
  +                    }
  +                }
  +                continue;
  +            }
  +            if (hadSlash) {
  +                // handle an escaped value
  +                hadSlash = false;
  +                switch (ch) {
  +                    case '\\':
  +                        out.append('\\');
  +                        break;
  +                    case '\'':
  +                        out.append('\'');
  +                        break;
  +                    case '\"':
  +                        out.append('"');
  +                        break;
  +                    case 'r':
  +                        out.append('\r');
  +                        break;
  +                    case 'f':
  +                        out.append('\f');
  +                        break;
  +                    case 't':
  +                        out.append('\t');
  +                        break;
  +                    case 'n':
  +                        out.append('\n');
  +                        break;
  +                    case 'b':
  +                        out.append('\b');
  +                        break;
  +                    case DELIMITER:
  +                        out.append("\\");
  +                        out.append(DELIMITER);
  +                        break;
  +                    case 'u':
  +                        {
  +                            // uh-oh, we're in unicode country....
  +                            inUnicode = true;
  +                            break;
  +                        }
  +                    default :
  +                        out.append(ch);
  +                        break;
  +                }
  +                continue;
  +            } else if (ch == '\\') {
  +                hadSlash = true;
  +                continue;
  +            }
  +            out.append(ch);
  +        }
  +        if (hadSlash) {
  +            // then we're in the weird case of a \ at the end of the
  +            // string, let's output it anyway.
  +            out.append('\\');
  +        }
  +
  +        return out.toString();
  +    }
  +
   }
  
  
  
  1.4       +1 -0      jakarta-commons/configuration/conf/test.properties
  
  Index: test.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/configuration/conf/test.properties,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- test.properties	24 Feb 2004 13:08:03 -0000	1.3
  +++ test.properties	3 Jun 2004 15:32:46 -0000	1.4
  @@ -6,6 +6,7 @@
   include = include.properties
   
   test.unescape = This \n string \t contains \" escaped \\ characters
  +test.unescape.list-separator = This string contains \, an escaped list separator
   
   #
   # Other test properties
  
  
  
  1.6       +16 -7     jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestPropertiesConfiguration.java
  
  Index: TestPropertiesConfiguration.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestPropertiesConfiguration.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- TestPropertiesConfiguration.java	27 Feb 2004 17:41:34 -0000	1.5
  +++ TestPropertiesConfiguration.java	3 Jun 2004 15:32:46 -0000	1.6
  @@ -38,7 +38,6 @@
       protected void setUp() throws Exception
       {
           conf = new PropertiesConfiguration(testProperties);
  - 
       }
   
       public void testSave() throws Exception
  @@ -55,9 +54,9 @@
           conf.addProperty("array", list);
   
           conf.save(testSavePropertiesFile.getAbsolutePath());
  -        
  +
           PropertiesConfiguration checkConfig = new PropertiesConfiguration(testSavePropertiesFile.getAbsolutePath());
  -        for (Iterator i = conf.getKeys();i.hasNext();){
  +        for (Iterator i = conf.getKeys(); i.hasNext();){
           	String key = (String)i.next();
           	assertTrue(checkConfig.containsKey(key));
           	assertEquals(conf.getString(key),checkConfig.getString(key));
  @@ -75,7 +74,6 @@
   
       public void testLoadViaPropertyWithBasePath() throws Exception
       {
  -
           PropertiesConfiguration pc = new PropertiesConfiguration();
           pc.setBasePath(testBasePath);
           pc.setFileName("test.properties");
  @@ -86,7 +84,6 @@
   
       public void testLoadViaPropertyWithBasePath2() throws Exception
       {
  -
           PropertiesConfiguration pc = new PropertiesConfiguration();
           pc.setBasePath(testBasePath2);
           pc.setFileName("conf/test.properties");
  @@ -104,6 +101,18 @@
   
       public void testGetStringWithEscapedChars()
       {
  -        assertEquals("String with escaped characters", "This \n string \t contains \" escaped
\\ characters", conf.getString("test.unescape"));
  +        String property = conf.getString("test.unescape");
  +        assertEquals("String with escaped characters", "This \n string \t contains \" escaped
\\ characters", property);
  +    }
  +
  +    public void testGetStringWithEscapedComma()
  +    {
  +        String property = conf.getString("test.unescape.list-separator");
  +        assertEquals("String with an escaped list separator", "This string contains , an
escaped list separator", property);
  +    }
  +
  +    public void testUnescapeJava()
  +    {
  +        assertEquals("test\\,test", PropertiesConfiguration.unescapeJava("test\\,test"));
       }
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message