You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by aj...@apache.org on 2009/01/28 04:57:48 UTC
svn commit: r738356 - in /incubator/jspwiki/trunk: ./ src/com/ecyrd/jspwiki/
src/com/ecyrd/jspwiki/ui/migrator/ src/com/ecyrd/jspwiki/util/
tests/com/ecyrd/jspwiki/ui/migrator/ tests/com/ecyrd/jspwiki/util/ tests/etc/
Author: ajaquith
Date: Wed Jan 28 03:57:46 2009
New Revision: 738356
URL: http://svn.apache.org/viewvc?rev=738356&view=rev
Log:
Checked in BundleMigrator, which makes it easier to move, rename, or delete resource bundle messages across a range of property files with a single command. This necessitated changes to CommentedProperties, because it was not properly parsing multi-line messages.
Added:
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/ui/migrator/BundleMigrator.java
incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/ui/migrator/BundleMigratorTest.java
Modified:
incubator/jspwiki/trunk/ChangeLog
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/Release.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/util/CommentedProperties.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/util/FileUtil.java
incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/ui/migrator/AllTests.java
incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/util/CommentedPropertiesTest.java
incubator/jspwiki/trunk/tests/etc/test.properties
Modified: incubator/jspwiki/trunk/ChangeLog
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/ChangeLog?rev=738356&r1=738355&r2=738356&view=diff
==============================================================================
--- incubator/jspwiki/trunk/ChangeLog (original)
+++ incubator/jspwiki/trunk/ChangeLog Wed Jan 28 03:57:46 2009
@@ -1,3 +1,12 @@
+2009-01-27 Andrew Jaquith <ajaquith AT apache DOT org>
+
+ * 3.0.0-svn-56
+
+ * Checked in BundleMigrator, which makes it easier to move, rename,
+ or delete resource bundle messages across a range of property files
+ with a single command. This necessitated changes to CommentedProperties,
+ because it was not properly parsing multi-line messages.
+
2009-01-23 Harry Metske <me...@apache.org>
* 3.0.0-svn-55
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/Release.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/Release.java?rev=738356&r1=738355&r2=738356&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/Release.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/Release.java Wed Jan 28 03:57:46 2009
@@ -77,7 +77,7 @@
* <p>
* If the build identifier is empty, it is not added.
*/
- public static final String BUILD = "55";
+ public static final String BUILD = "56";
/**
* This is the generic version string you should use
Added: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/ui/migrator/BundleMigrator.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/ui/migrator/BundleMigrator.java?rev=738356&view=auto
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/ui/migrator/BundleMigrator.java (added)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/ui/migrator/BundleMigrator.java Wed Jan 28 03:57:46 2009
@@ -0,0 +1,414 @@
+package com.ecyrd.jspwiki.ui.migrator;
+
+import java.io.*;
+import java.util.*;
+
+import com.ecyrd.jspwiki.util.CommentedProperties;
+
+/**
+ * Utility class for copying, moving, deleting and renaming message keys between
+ * two message bundles.
+ */
+public class BundleMigrator
+{
+
+ public static class Bundle
+ {
+ private final Map<Locale, File> m_bundleFiles = new HashMap<Locale, File>();
+
+ private final Map<Locale, Properties> m_bundleProps = new HashMap<Locale, Properties>();
+
+ private final File m_baseFile;
+
+ private Properties m_baseProps;
+
+ /**
+ * Constructs a new Bundle whose base file name is supplied. During
+ * construction, the base bundle file is verified by appending
+ * <code>.properties</code> to the base name and testing that the
+ * resulting file exists. For example, if the base file
+ * <code>src/Default</code> is passed, the file
+ * <code>src/Default.properties</code> will be checked. If the file is
+ * found, all possible combinations of bundle files are checked next,
+ * for example <code>src/Default_en.properties</code>,
+ * <code>src/Default_fr.properties</code>, and so on. If the base
+ * bundle file does not exist, this method throws an
+ * IllegalArgumentException.
+ *
+ * @param baseFile the path to the base bundle file, minus the trailing
+ * locale suffix and <code>.properties</code> extension
+ * @throws FileNotFoundException if the base bundle file does not exist
+ */
+ public Bundle( String baseFile ) throws FileNotFoundException
+ {
+ super();
+ m_baseFile = new File( baseFile + ".properties" );
+ m_baseProps = new CommentedProperties();
+ findBundleFiles( baseFile );
+ }
+
+ /**
+ * Returns the path to the bundle file for a supplied Locale.
+ *
+ * @param locale if <code>null</code>, the base file will be returned
+ * @return the file
+ */
+ public File getFile( Locale locale )
+ {
+ return locale == null ? m_baseFile : m_bundleFiles.get( locale );
+ }
+
+ /**
+ * Returns the Locales associated with this Bundle.
+ *
+ * @return the collection of Locale objects
+ */
+ public Collection<Locale> getLocales()
+ {
+ return Collections.unmodifiableSet( m_bundleFiles.keySet() );
+ }
+
+ /**
+ * Returns the Properties object for a supplied Locale.
+ *
+ * @param locale if <code>null</code>, the base Properties object
+ * will be returned
+ * @return the file
+ */
+ public Properties getProperties( Locale locale )
+ {
+ return locale == null ? m_baseProps : m_bundleProps.get( locale );
+ }
+
+ /**
+ * Loads the set of bundle files from disk.
+ */
+ public void load() throws IOException
+ {
+ // Load the default properties file first
+ m_baseProps.load( new FileInputStream( m_baseFile ) );
+
+ // Now load one for each Locale
+ for( Map.Entry<Locale, File> entry : m_bundleFiles.entrySet() )
+ {
+ Properties props = new CommentedProperties();
+ props.load( new FileInputStream( entry.getValue() ) );
+ m_bundleProps.put( entry.getKey(), props );
+ }
+ }
+
+ /**
+ * Saves the set of bundle files to disk.
+ *
+ * @throws IOException
+ */
+ public void save() throws IOException
+ {
+ // Save the default properties file firs
+ m_baseProps.store( new FileOutputStream( m_baseFile ), null );
+
+ // Now store each Locale's file
+ for( Map.Entry<Locale, File> entry : m_bundleFiles.entrySet() )
+ {
+ Properties props = m_bundleProps.get( entry.getKey() );
+ props.store( new FileOutputStream( entry.getValue() ), null );
+ }
+ }
+
+ /**
+ * Populates a Bundle, starting with a supplied base file and iterating
+ * through every possible Locale combination.
+ *
+ * @param baseFile the path to the base bundle file, minus the trailing
+ * locale and <code>.properties</code>
+ */
+ protected void findBundleFiles( String baseFile ) throws FileNotFoundException
+ {
+ File baseBundle = new File( baseFile + ".properties" );
+ if( !baseBundle.exists() )
+ {
+ throw new FileNotFoundException( "Bundle file " + baseBundle.toString() + " not found." );
+ }
+
+ // Add all bundle files that exist in the file system
+ Locale[] locales = Locale.getAvailableLocales();
+ for( Locale locale : locales )
+ {
+ File file = new File( baseFile + "_" + locale.toString() + ".properties" );
+ if( file.exists() )
+ {
+ m_bundleFiles.put( locale, file );
+ m_bundleProps.put( locale, new CommentedProperties() );
+ }
+ }
+ }
+ }
+
+ private Bundle m_source;
+
+ /**
+ * Constructs a new BundleMigrator.
+ */
+ public BundleMigrator()
+ {
+ super();
+ }
+
+ /**
+ * Copies a message key from the source Bundle to a target Bundle.
+ *
+ * @param key the name of the key to copy
+ * @param target the target Bundle
+ */
+ public void copy( String key, Bundle target ) throws IOException
+ {
+ // Look for the property in the base file
+ String value = m_source.getProperties( null ).getProperty( key );
+ if( value == null )
+ {
+ throw new IllegalArgumentException( "Key " + key + " not found in bundle." );
+ }
+
+ // Load the source and target bundles
+ m_source.load();
+ target.load();
+
+ // Copy the base property file's key first
+ Properties props = target.getProperties( null );
+ props.put( key, value );
+
+ // Copy the key for each locale file
+ Collection<Locale> locales = m_source.getLocales();
+ for( Locale locale : locales )
+ {
+ props = m_source.getProperties( locale );
+ value = props.getProperty( key );
+ if( value != null )
+ {
+ props = target.getProperties( locale );
+ if( props != null )
+ {
+ props.put( key, value );
+ }
+ }
+ }
+
+ // Save the target bundle
+ target.save();
+ }
+
+ /**
+ * Returns the source {@link Bundle} for the BundleMigrator to operate on.
+ *
+ * @return the source bundle
+ */
+ public Bundle getSource()
+ {
+ return m_source;
+ }
+
+ /**
+ * Moves a message key from the source Bundle to a target Bundle.
+ *
+ * @param key the name of the key to move
+ * @param target the target Bundle
+ */
+ public void move( String key, Bundle target ) throws IOException
+ {
+ copy( key, target );
+ remove( key );
+ }
+
+ /**
+ * Deletes a message key from the source Bundle.
+ *
+ * @param key the name of the key to remove
+ */
+ public void remove( String key ) throws IOException
+ {
+ // Look for the property in the base file
+ String value = m_source.getProperties( null ).getProperty( key );
+ if( value == null )
+ {
+ throw new IllegalArgumentException( "Key " + key + " not found in bundle." );
+ }
+
+ // Load the source bundle
+ m_source.load();
+
+ // Rename the base property file's key first
+ Properties props = m_source.getProperties( null );
+ props.remove( key );
+
+ // Remove the key from each locale file
+ Collection<Locale> locales = m_source.getLocales();
+ for( Locale locale : locales )
+ {
+ props = m_source.getProperties( locale );
+ value = props.getProperty( key );
+ if( value != null )
+ {
+ props.remove( key );
+ }
+ }
+
+ // Save the bundle
+ m_source.save();
+ }
+
+ /**
+ * Renames a message key contained in the source Bundle.
+ *
+ * @param key the name of the key to change
+ * @param newKey the new name for the key
+ */
+ public void rename( String key, String newKey ) throws IOException
+ {
+ // Look for the property in the base file
+ String value = m_source.getProperties( null ).getProperty( key );
+ if( value == null )
+ {
+ throw new IllegalArgumentException( "Key " + key + " not found in bundle." );
+ }
+ if( newKey == null )
+ {
+ throw new IllegalArgumentException( "New key name must not be null." );
+ }
+
+ // Load the source bundle
+ m_source.load();
+
+ // Rename the base property file's key first
+ Properties props = m_source.getProperties( null );
+ props.remove( key );
+ props.put( newKey, value );
+
+ // Rename the key in each locale file
+ Collection<Locale> locales = m_source.getLocales();
+ for( Locale locale : locales )
+ {
+ props = m_source.getProperties( locale );
+ value = props.getProperty( key );
+ if( value != null )
+ {
+ props.remove( key );
+ props.put( newKey, value );
+ }
+ }
+
+ // Save the bundle
+ m_source.save();
+
+ }
+
+ /**
+ * Sets the source {@link Bundle} to operate on, and loads it.
+ *
+ * @param source the Bundle to operate on
+ * @throws FileNotFoundException if the base bundle file does not exist
+ */
+ public void setBundle( Bundle source ) throws IOException
+ {
+ m_source = source;
+ source.load();
+ }
+
+ /**
+ * <p>
+ * Command-line interface to BundleMigrator. The general syntax for running
+ * BundleMigrator is:
+ * </p>
+ * <blockquote>
+ * <code>BundleMigrator <var>action source keyname [destination | newkeyname]</var></code>
+ * </blockquote>
+ * <p>
+ * ...where <var>action</var> is an action verb: <code>copy</code>,
+ * <code>delete</code>, <code>move</code> or <code>rename</code>.
+ * </p>
+ * <p>
+ * The <code>source</code> parameter indicates the path to the base bundle
+ * file, minus the trailing locale suffix and <code>.properties</code>
+ * extension; for example, <code>etc/i18n/CoreResources</code>. The
+ * <code>destination</code> parameter indicates the destination bundle for
+ * move and rename actions.
+ * </p>
+ * <p>
+ * The <code>keyname</code> denotes the key to copy, move, delete or
+ * rename. When renaming a key, <code>newkeyname</code> denotes the new
+ * key name.
+ * </p>
+ * <p>
+ * Here are examples for the entire set of valid commands:
+ * </p>
+ * <blockquote>
+ * <code>BundleMigrator rename src/i18n/CoreResources error.oldname error.newname<br/>
+ * BundleMigrator delete src/i18n/CoreResources error.oldname<br/>
+ * BundleMigrator copy src/i18n/CoreResources error.oldname src/i18n/templates/default<br/>
+ * BundleMigrator move src/i18n/CoreResources error.oldname src/i18n/templates/default</code></blockquote>
+ *
+ * @param args the command line arguments
+ */
+ public static final void main( String[] args )
+ {
+ String validSyntax = "BundleMigrator action source keyname [newkeyname | destination]";
+ if( args.length == 0 )
+ {
+ System.err.println( "Too few arguments. Valid syntax: " + validSyntax );
+ System.err.println( "Valid actions are: copy, delete, move, and rename." );
+ return;
+ }
+
+ try
+ {
+ // Get the verb and source bundle
+ String action = args[0].trim();
+ Bundle source = new Bundle( args[1].trim() );
+ String key = args[2].trim();
+ BundleMigrator migrator = new BundleMigrator();
+ migrator.setBundle( source );
+
+ // Execute the action
+ if( "delete".equals( action ) )
+ {
+ if ( wrongNumberArgs( 3, args, "BundleMigrator delete source keyname" ) ) { return; }
+ migrator.remove( key );
+ }
+ else if( "rename".equals( action ) )
+ {
+ if ( wrongNumberArgs( 4, args, "BundleMigrator rename source keyname newkeyname" ) ) { return; }
+ String newKey = args[3].trim();
+ migrator.rename( key, newKey );
+ }
+ else if( "copy".equals( action ) )
+ {
+ if ( wrongNumberArgs( 4, args, "BundleMigrator copy source keyname destination" ) ) { return; }
+ Bundle destination = new Bundle( args[3].trim() );
+ migrator.copy( key, destination );
+ }
+ else if( "move".equals( action ) )
+ {
+ if ( wrongNumberArgs( 4, args, "BundleMigrator move source keyname destination" ) ) { return; }
+ Bundle destination = new Bundle( args[3].trim() );
+ migrator.move( key, destination );
+ }
+ else
+ {
+ System.err.println( "Invalid syntax. Valid syntax is: " + validSyntax );
+ }
+ }
+ catch ( IOException e )
+ {
+ System.err.println( "Error: " + e.getMessage() );
+ }
+ }
+
+ private static boolean wrongNumberArgs( int requiredArgs, String[] args, String validSyntax )
+ {
+ if( args.length != requiredArgs )
+ {
+ System.out.println( "Wrong number of arguments. Valid syntax: " + validSyntax );
+ return true;
+ }
+ return false;
+ }
+}
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/util/CommentedProperties.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/util/CommentedProperties.java?rev=738356&r1=738355&r2=738356&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/util/CommentedProperties.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/util/CommentedProperties.java Wed Jan 28 03:57:46 2009
@@ -21,16 +21,15 @@
package com.ecyrd.jspwiki.util;
import java.io.*;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Map.Entry;
-
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Extends {@link java.util.Properties} by providing support for comment
- * preservation. When the properties are written to disk, previous
- * comments present in the file are preserved.
+ * preservation. When the properties are written to disk, previous comments
+ * present in the file are preserved.
+ *
* @author Andrew Jaquith
* @since 2.4.22
*/
@@ -38,7 +37,18 @@
{
private static final long serialVersionUID = 8057284636436329669L;
- private String m_propertyString;
+ /** Map with property names as keys, and comments as values. */
+ private Map<String, String> m_propertyComments = new HashMap<String, String>();
+
+ /**
+ * Ordered map with property names inserted in the order encountered in the
+ * text file.
+ */
+ private Set<Object> m_keys = new LinkedHashSet<Object>();
+
+ private String m_trailingComment = null;
+
+ private final String m_br;
/**
* @see java.util.Properties#Properties()
@@ -46,53 +56,52 @@
public CommentedProperties()
{
super();
+ m_br = System.getProperty( "line.separator" );
}
/**
- * Creates new properties.
- *
- * @param defaultValues A list of default values, which are used if in subsequent gets
- * a key is not found.
+ * Creates new properties.
+ *
+ * @param defaultValues A list of default values, which are used if in
+ * subsequent gets a key is not found.
*/
public CommentedProperties( Properties defaultValues )
{
super( defaultValues );
+ m_br = System.getProperty( "line.separator" );
}
/**
- * {@inheritDoc}
+ * {@inheritDoc}
*/
@Override
public synchronized void load( InputStream inStream ) throws IOException
{
// Load the file itself into a string
- m_propertyString = FileUtil.readContents( inStream, "ISO-8859-1" );
+ String propertyString = FileUtil.readContents( inStream, "ISO-8859-1" );
// Now load it into the properties object as normal
- super.load( new ByteArrayInputStream( m_propertyString.getBytes("ISO-8859-1") ) );
+ super.load( new ByteArrayInputStream( propertyString.getBytes( "ISO-8859-1" ) ) );
+
+ // Load all of the comments
+ loadComments( propertyString );
}
/**
- * Loads properties from a file opened by a supplied Reader.
- *
- * @param in The reader to read properties from
- * @throws IOException in case something goes wrong.
+ * Loads properties from a file opened by a supplied Reader.
+ *
+ * @param in The reader to read properties from
+ * @throws IOException in case something goes wrong.
*/
public synchronized void load( Reader in ) throws IOException
{
- m_propertyString = FileUtil.readContents( in );
+ String propertyString = FileUtil.readContents( in );
// Now load it into the properties object as normal
- super.load( new ByteArrayInputStream( m_propertyString.getBytes("ISO-8859-1") ) );
- }
+ super.load( new ByteArrayInputStream( propertyString.getBytes( "ISO-8859-1" ) ) );
- /**
- * {@inheritDoc}
- */
- @Override
- public synchronized Object setProperty( String key, String value )
- {
- return put(key, value);
+ // Load all of the comments
+ loadComments( propertyString );
}
/**
@@ -101,7 +110,7 @@
@Override
public synchronized void store( OutputStream out, String comments ) throws IOException
{
- byte[] bytes = m_propertyString.getBytes("ISO-8859-1");
+ byte[] bytes = toString().getBytes( "ISO-8859-1" );
FileUtil.copyContents( new ByteArrayInputStream( bytes ), out );
out.flush();
}
@@ -110,135 +119,247 @@
* {@inheritDoc}
*/
@Override
- public synchronized Object put( Object arg0, Object arg1 )
+ public synchronized String toString()
{
- // Write the property to the stored string
- writeProperty( arg0, arg1 );
+ StringBuilder b = new StringBuilder();
+ for( Object key : m_keys )
+ {
+ Object value = get( key );
+ String comment = m_propertyComments.get( key );
+ if( comment != null )
+ {
+ b.append( comment );
+ b.append( m_br );
+ }
+ printProperty( b, key, value );
+ }
- // Return the result of from the superclass properties object
- return super.put(arg0, arg1);
+ // Now print the keys we did not encounter (i.e., were added after the
+ // load method)
+ for( Map.Entry<Object, Object> entry : this.entrySet() )
+ {
+ String key = entry.getKey().toString();
+ if( !m_keys.contains( key ) )
+ {
+ Object value = entry.getValue();
+ printProperty( b, key, value );
+ }
+ }
+
+ // Add any trailing comments
+ if( m_trailingComment != null )
+ {
+ b.append( m_trailingComment );
+ b.append( m_br );
+ }
+ return b.toString();
+ }
+
+ private void printProperty( StringBuilder b, Object key, Object value )
+ {
+ b.append( key.toString() );
+ b.append( ' ' );
+ b.append( '=' );
+ b.append( ' ' );
+ b.append( value.toString() );
+ b.append( m_br );
}
/**
- * {@inheritDoc}
+ * Trims whitespace from property line strings: \n \r \u0020 \t \u0009 \f
+ * \u000c space
*/
- @SuppressWarnings("unchecked")
- @Override
- public synchronized void putAll( Map arg0 )
+ private static final Pattern LINE_TRIMMER = Pattern.compile( "^[ \\r\\n\\t\\f]*(.*?)[ \\r\\n\\t\\f]*$" );
+
+ /**
+ * Determines if a line consists entirely of whitespace.
+ */
+ private static final Pattern BLANK_LINE_DETECTOR = Pattern.compile( "^[ \\r\\n\\t\\f]*$" );
+
+ /**
+ * Parses the comments from the properties file (stored as a string)
+ */
+ private void loadComments( String propertyString ) throws IOException
{
- // Shove all of the entries into the property string
- for( Iterator it = arg0.entrySet().iterator(); it.hasNext(); )
+ LineNumberReader reader = new LineNumberReader( new StringReader( propertyString ) );
+ String line = null;
+ boolean inProperty = false;
+ String comment = null;
+ while ( (line = reader.readLine()) != null )
{
- Entry entry = (Entry)it.next();
- writeProperty( entry.getKey(), entry.getValue() );
+ // Trim line of leading/trailing whitespace
+ Matcher m = LINE_TRIMMER.matcher( line );
+ if( m.matches() )
+ {
+ String text = m.group( 1 );
+
+ // Is first character ! or #? We are in a comment line...
+ boolean isComment = text.startsWith( "#" ) || text.startsWith( "!" );
+ boolean isWhitespace = BLANK_LINE_DETECTOR.matcher( text ).matches();
+ if( isComment )
+ {
+ comment = comment == null ? text : comment + m_br + text;
+ inProperty = false;
+ }
+
+ // If all whitespace and part of comment, append it
+ else if( isWhitespace && !inProperty )
+ {
+ comment = comment == null ? text : comment + m_br + text;
+ }
+
+ // Otherwise, see if we're starting a new property key
+ else if( !inProperty )
+ {
+ // If we are, lookup the key and add the comment
+ String key = extractKey( text );
+ if( key != null )
+ {
+ String value = getProperty( key );
+ if( value != null && comment != null )
+ {
+ m_propertyComments.put( key, comment );
+ m_keys.add( key );
+ }
+ inProperty = true;
+ comment = null;
+ }
+ }
+ }
}
- // Call the superclass method
- super.putAll(arg0);
+ // Any leftover comments are "trailing" comments that go at the end of
+ // the file
+ m_trailingComment = comment;
+
+ reader.close();
}
/**
- * {@inheritDoc}
+ * Extracts a key name from a trimmed line of text, which may include
+ * escaped characters.
+ *
+ * @param text
+ * @return the key
*/
- @Override
- public synchronized Object remove( Object key )
+ protected String extractKey( String text )
{
- // Remove from the property string
- deleteProperty( key );
-
- // Call the superclass method
- return super.remove(key);
+ char[] chars = text.toCharArray();
+ char lastChar = ' ';
+ for( int i = 0; i < chars.length; i++ )
+ {
+ char ch = chars[i];
+ switch( ch )
+ {
+ case ' ':
+ case '\t':
+ case ':':
+ case '=':
+ case '\f': {
+ if( lastChar != '\'' )
+ {
+ return text.substring( 0, i );
+ }
+ }
+ }
+ }
+ return null;
}
/**
- * {@inheritDoc}
+ * Returns the comment for a supplied key, as parsed by the
+ * {@link #load(Reader)} or {@link #load(InputStream)} methods, <em>or</em>
+ * as supplied to the{@link #setProperty(String, String, String)} method.
+ *
+ * @param key the key to look up
+ * @return the comment (including the trailing <code>!</code> or
+ * <code>#</code> character, or <code>null</code> if not found
*/
- @Override
- public synchronized String toString()
+ public String getComment( String key )
{
- return m_propertyString;
+ return(m_propertyComments.get( key ));
}
- private void deleteProperty( Object arg0 )
+ /**
+ * Sets a property value for a supplied key, and adds a comment that will be
+ * written to disk when the {@link #store(OutputStream, String)} method is
+ * called. This method behaves otherwise identically to
+ * {@link #setProperty(String, String)}.
+ *
+ * @param key the string key to store
+ * @param value the property value associated with the key
+ * @param comment the comment to add
+ * @return the the previous value of the specified key in this property
+ * list, or <code>null</code> if it did not have one.
+ */
+ public synchronized Object setProperty( String key, String value, String comment )
{
- // Get key and value
- if ( arg0 == null )
- {
- throw new IllegalArgumentException( "Key cannot be null." );
- }
- String key = arg0.toString();
-
- // Iterate through each line and replace anything matching our key
- int idx = 0;
- while( ( idx < m_propertyString.length() ) && ( ( idx = m_propertyString.indexOf( key, idx ) ) != -1 ) )
+ if( key != null )
{
- int prevret = m_propertyString.lastIndexOf( "\n", idx );
- if ( prevret != -1 )
+ if( comment != null )
{
- // Commented lines are skipped
- if ( m_propertyString.charAt( prevret + 1 ) == '#' )
+ comment = comment.trim();
+ if( !comment.startsWith( "#" ) )
{
- idx += key.length();
- continue;
+ comment = "# " + comment;
}
+ m_propertyComments.put( key, comment );
}
-
- // If "=" present, delete the entire line
- int eqsign = m_propertyString.indexOf( "=", idx );
- if ( eqsign != -1 )
- {
- int ret = m_propertyString.indexOf( "\n", eqsign );
- m_propertyString = TextUtil.replaceString( m_propertyString, prevret, ret, "" );
- return;
- }
+ m_keys.add( key );
}
+ return super.setProperty( key, value );
}
- private void writeProperty( Object arg0, Object arg1 )
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized Object setProperty( String key, String value )
{
- // Get key and value
- if ( arg0 == null )
- {
- throw new IllegalArgumentException( "Key cannot be null." );
- }
- if ( arg1 == null )
+ return setProperty( key, value, null );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized Object put( Object key, Object value )
+ {
+ if( key != null )
{
- arg1 = "";
+ m_keys.add( key );
}
- String key = arg0.toString();
- String value = TextUtil.native2Ascii( arg1.toString() );
+ return super.put( key, value );
+ }
- // Iterate through each line and replace anything matching our key
- int idx = 0;
- while( ( idx < m_propertyString.length() ) && ( ( idx = m_propertyString.indexOf( key, idx ) ) != -1 ) )
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized void putAll( Map<? extends Object, ? extends Object> t )
+ {
+ for( Object key : t.keySet() )
{
- int prevret = m_propertyString.lastIndexOf( "\n", idx );
- if ( prevret != -1 )
- {
- // Commented lines are skipped
- if ( m_propertyString.charAt( prevret + 1 ) == '#' )
- {
- idx += key.length();
- continue;
- }
- }
-
- // If "=" present, replace everything in line after it
- int eqsign = m_propertyString.indexOf( "=", idx );
- if ( eqsign != -1 )
+ if( key != null )
{
- int ret = m_propertyString.indexOf( "\n", eqsign );
- if ( ret == -1 )
- {
- ret = m_propertyString.length();
- }
- m_propertyString = TextUtil.replaceString( m_propertyString, eqsign + 1, ret, value );
- return;
+ m_keys.add( key );
}
}
+ super.putAll( t );
+ }
- // If it was not found, we'll add it to the end.
- m_propertyString += "\n" + key + " = " + value + "\n";
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized Object remove( Object key )
+ {
+ if( key != null )
+ {
+ m_propertyComments.remove( key );
+ m_keys.remove( key );
+ }
+ return super.remove( key );
}
}
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/util/FileUtil.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/util/FileUtil.java?rev=738356&r1=738355&r2=738356&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/util/FileUtil.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/util/FileUtil.java Wed Jan 28 03:57:46 2009
@@ -39,7 +39,6 @@
{
/** Size of the buffer used when copying large chunks of data. */
private static final int BUFFER_SIZE = 4096;
- private static final Logger log = LoggerFactory.getLogger(FileUtil.class);
/**
* Private constructor prevents instantiation.
@@ -118,6 +117,7 @@
{
StringBuilder result = new StringBuilder();
+ Logger log = LoggerFactory.getLogger(FileUtil.class);
log.info("Running simple command "+command+" in "+directory);
Process process = Runtime.getRuntime().exec( command, null, new File(directory) );
@@ -293,6 +293,7 @@
}
catch( Exception e )
{
+ Logger log = LoggerFactory.getLogger(FileUtil.class);
log.error("Not able to close the stream while reading contents.");
}
}
Modified: incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/ui/migrator/AllTests.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/ui/migrator/AllTests.java?rev=738356&r1=738355&r2=738356&view=diff
==============================================================================
--- incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/ui/migrator/AllTests.java (original)
+++ incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/ui/migrator/AllTests.java Wed Jan 28 03:57:46 2009
@@ -29,6 +29,7 @@
public static Test suite()
{
TestSuite suite = new TestSuite("JSP migration tests");
+ suite.addTest( BundleMigratorTest.suite() );
suite.addTest( JspDocumentTest.suite() );
suite.addTest( JspParserTest.suite() );
suite.addTest( JSPWikiJspTransformerTest.suite() );
Added: incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/ui/migrator/BundleMigratorTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/ui/migrator/BundleMigratorTest.java?rev=738356&view=auto
==============================================================================
--- incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/ui/migrator/BundleMigratorTest.java (added)
+++ incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/ui/migrator/BundleMigratorTest.java Wed Jan 28 03:57:46 2009
@@ -0,0 +1,346 @@
+/*
+ JSPWiki - a JSP-based WikiWiki clone.
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package com.ecyrd.jspwiki.ui.migrator;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.util.Collection;
+import java.util.Locale;
+import java.util.Properties;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import com.ecyrd.jspwiki.ui.migrator.BundleMigrator.Bundle;
+import com.ecyrd.jspwiki.util.CommentedProperties;
+
+public class BundleMigratorTest extends TestCase
+{
+ private static final String[] LOCALES = { "", "en", "de", "zh_CN" };
+ public static Test suite()
+ {
+ return new TestSuite( BundleMigratorTest.class );
+ }
+ private String m_source = null;
+
+ private String m_dest = null;
+
+ public void setUp() throws Exception
+ {
+ // Create dummy property files
+ String tmpdir = System.getProperty( "java.io.tmpdir" );
+ File tmp = new File( tmpdir );
+ for( String locale : LOCALES )
+ {
+ // Create sample "to" and "from" property files
+ Properties sourceProps = new CommentedProperties();
+ sourceProps.put( "source.name", "Full name_" + locale );
+ sourceProps.put( "source.email", "E-mail_" + locale );
+ sourceProps.put( "source.password", "Password_" + locale );
+ File sourcePropfile = new File( tmp, ( locale.length() == 0 ? "source" : "source_" + locale ) + ".properties" );
+ sourceProps.store( new FileOutputStream( sourcePropfile), null );
+ m_source = tmpdir + "/source";
+
+ Properties destProps = new CommentedProperties();
+ destProps.put( "dest.timeZone", "Time zone_" + locale );
+ destProps.put( "dest.orientation", "Orientation_" + locale );
+ File destPropfile = new File( tmp, ( locale.length() == 0 ? "dest" : "dest_" + locale ) + ".properties" );
+ destProps.store( new FileOutputStream( destPropfile), null );
+ m_dest = tmpdir + "/dest";
+ }
+ }
+
+ public void tearDown() throws Exception
+ {
+ // Delete dummy property files
+ File tmp = new File( System.getProperty( "java.io.tmpdir" ) );
+ for( String locale : LOCALES )
+ {
+ // Delete sample "to" and "from" property files
+ File sourcePropfile = new File( tmp, ( locale.length() == 0 ? "source" : "source_" + locale ) + ".properties" );
+ //sourcePropfile.delete();
+
+ File destPropfile = new File( tmp, ( locale.length() == 0 ? "dest" : "dest_" + locale ) + ".properties" );
+ //destPropfile.delete();
+ }
+ }
+
+ public void testCopyKey() throws Exception
+ {
+ Bundle source = new Bundle( m_source );
+ BundleMigrator m = new BundleMigrator();
+ m.setBundle( source );
+
+ // Move a key to target
+ Bundle target = new Bundle( m_dest );
+ m.copy( "source.name", target );
+
+ // Verify the contents were copied to target
+ source = new Bundle( m_dest );
+ source.load();
+ Properties p;
+
+ p = source.getProperties( null );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_", p.get( "source.name" ) );
+
+ p = source.getProperties( new Locale( "en" ) );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_en", p.get( "source.name" ) );
+
+ p = source.getProperties( new Locale( "de" ) );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_de", p.get( "source.name" ) );
+
+ p = source.getProperties( new Locale( "zh", "CN" ) );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_zh_CN", p.get( "source.name" ) );
+ }
+
+ public void testMoveKey() throws Exception
+ {
+ Bundle source = new Bundle( m_source );
+ BundleMigrator m = new BundleMigrator();
+ m.setBundle( source );
+
+ // Move a key to target
+ Bundle target = new Bundle( m_dest );
+ m.move( "source.name", target );
+
+ // Verify the key was deleted from source
+ source = new Bundle( m_source );
+ source.load();
+ Properties p;
+
+ p = source.getProperties( null );
+ assertEquals( 2, p.size() );
+ assertEquals( null, p.get( "source.name" ) );
+
+ p = source.getProperties( new Locale( "en" ) );
+ assertEquals( 2, p.size() );
+ assertEquals( null, p.get( "source.name" ) );
+
+ p = source.getProperties( new Locale( "de" ) );
+ assertEquals( 2, p.size() );
+ assertEquals( null, p.get( "source.name" ) );
+
+ p = source.getProperties( new Locale( "zh", "CN" ) );
+ assertEquals( 2, p.size() );
+ assertEquals( null, p.get( "source.name" ) );
+
+ // Verify the key was copied to target
+ target = new Bundle( m_dest );
+ target.load();
+ p = target.getProperties( null );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_", p.get( "source.name" ) );
+
+ p = target.getProperties( new Locale( "en" ) );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_en", p.get( "source.name" ) );
+
+ p = target.getProperties( new Locale( "de" ) );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_de", p.get( "source.name" ) );
+
+ p = target.getProperties( new Locale( "zh", "CN" ) );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_zh_CN", p.get( "source.name" ) );
+ }
+
+ public void testLoadBundle() throws Exception
+ {
+ Bundle b = new Bundle( m_source );
+ // Check that there isn't anything in there yet
+ Properties p;
+
+ p = b.getProperties( null );
+ assertEquals( 0, p.size() );
+ p = b.getProperties( new Locale( "en" ) );
+ assertEquals( 0, p.size() );
+ p = b.getProperties( new Locale( "de" ) );
+ assertEquals( 0, p.size() );
+ p = b.getProperties( new Locale( "zh", "CN" ) );
+ assertEquals( 0, p.size() );
+
+ // Load the files
+ b.load();
+
+ // Verify the contents were loaded
+ p = b.getProperties( null );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_", p.get( "source.name" ) );
+
+ p = b.getProperties( new Locale( "en" ) );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_en", p.get( "source.name" ) );
+
+ p = b.getProperties( new Locale( "de" ) );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_de", p.get( "source.name" ) );
+
+ p = b.getProperties( new Locale( "zh", "CN" ) );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_zh_CN", p.get( "source.name" ) );
+ }
+
+ public void testNewBundle() throws Exception
+ {
+ // Source: verify the base file and all other files
+ Bundle bundle = new Bundle( m_source );
+ assertEquals( new File( m_source + ".properties" ), bundle.getFile( null ) );
+ Collection<Locale> map = bundle.getLocales();
+ assertEquals( 3, map.size() );
+ assertNotNull( bundle.getFile( new Locale( "en" ) ) );
+ assertNotNull( bundle.getFile( new Locale( "de" ) ) );
+ assertNotNull( bundle.getFile( new Locale( "zh", "CN" ) ) );
+
+ // Dest: verify the base file and all other files
+ bundle = new Bundle( m_dest );
+ assertEquals( new File( m_dest + ".properties" ), bundle.getFile( null ) );
+ assertEquals( 3, map.size() );
+ assertNotNull( bundle.getFile( new Locale( "en" ) ) );
+ assertNotNull( bundle.getFile( new Locale( "de" ) ) );
+ assertNotNull( bundle.getFile( new Locale( "zh", "CN" ) ) );
+ }
+
+ public void testRemoveKey() throws Exception
+ {
+ Bundle b = new Bundle( m_source );
+ BundleMigrator m = new BundleMigrator();
+ m.setBundle( b );
+
+ // Remove a key, then save
+ m.remove( "source.name" );
+
+ // Reload & verify key was deleted
+ b = new Bundle( m_source );
+ b.load();
+
+ // Verify the contents were loaded
+ Properties p;
+ p = b.getProperties( null );
+ assertEquals( 2, p.size() );
+
+ p = b.getProperties( new Locale( "en" ) );
+ assertEquals( 2, p.size() );
+
+ p = b.getProperties( new Locale( "de" ) );
+ assertEquals( 2, p.size() );
+
+ p = b.getProperties( new Locale( "zh", "CN" ) );
+ assertEquals( 2, p.size() );
+ }
+
+ public void testRenameKey() throws Exception
+ {
+ Bundle b = new Bundle( m_source );
+ BundleMigrator m = new BundleMigrator();
+ m.setBundle( b );
+
+ // Rename a key, then save
+ m.rename( "source.name", "source.rename" );
+
+ // Reload & verify key was deleted
+ b = new Bundle( m_source );
+ b.load();
+
+ // Verify the contents were loaded
+ Properties p;
+ p = b.getProperties( null );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_", p.get( "source.rename" ) );
+
+ p = b.getProperties( new Locale( "en" ) );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_en", p.get( "source.rename" ) );
+
+ p = b.getProperties( new Locale( "de" ) );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_de", p.get( "source.rename" ) );
+
+ p = b.getProperties( new Locale( "zh", "CN" ) );
+ assertEquals( 3, p.size() );
+ assertEquals( "Full name_zh_CN", p.get( "source.rename" ) );
+ }
+
+ public void testSaveBundle() throws Exception
+ {
+ Bundle b = new Bundle( m_source );
+ b.load();
+
+ // Modify the properties by adding a new key
+ Properties p;
+ p = b.getProperties( null );
+ p.put( "new.key", "Value_" );
+ p = b.getProperties( new Locale( "en" ) );
+ p.put( "new.key", "Value_en" );
+ p = b.getProperties( new Locale( "de" ) );
+ p.put( "new.key", "Value_de" );
+ p = b.getProperties( new Locale( "zh", "CN" ) );
+ p.put( "new.key", "Value_zh_CN" );
+
+ // Save 'em
+ b.save();
+
+ // Reload & verify contents were saved
+ b = new Bundle( m_source );
+ b.load();
+
+ // Verify the contents were loaded
+ p = b.getProperties( null );
+ assertEquals( 4, p.size() );
+ assertEquals( "Value_", p.get( "new.key" ) );
+
+ p = b.getProperties( new Locale( "en" ) );
+ assertEquals( 4, p.size() );
+ assertEquals( "Value_en", p.get( "new.key" ) );
+
+ p = b.getProperties( new Locale( "de" ) );
+ assertEquals( 4, p.size() );
+ assertEquals( "Value_de", p.get( "new.key" ) );
+
+ p = b.getProperties( new Locale( "zh", "CN" ) );
+ assertEquals( 4, p.size() );
+ assertEquals( "Value_zh_CN", p.get( "new.key" ) );
+ }
+
+ public void testSetSource() throws Exception
+ {
+ BundleMigrator m = new BundleMigrator();
+
+ // Try with a bundle base file that obviously does not exist
+ try
+ {
+ m.setBundle( new Bundle( "src/Default" ) );
+ }
+ catch( FileNotFoundException e )
+ {
+ // Good! This is what we expect
+ }
+
+ // Try with one that does exist
+ m.setBundle( new Bundle( "etc/i18n/CoreResources" ) );
+ }
+
+}
Modified: incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/util/CommentedPropertiesTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/util/CommentedPropertiesTest.java?rev=738356&r1=738355&r2=738356&view=diff
==============================================================================
--- incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/util/CommentedPropertiesTest.java (original)
+++ incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/util/CommentedPropertiesTest.java Wed Jan 28 03:57:46 2009
@@ -21,11 +21,7 @@
package com.ecyrd.jspwiki.util;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
@@ -37,73 +33,107 @@
public class CommentedPropertiesTest extends TestCase
{
- Properties m_props = new CommentedProperties();
-
+ CommentedProperties m_props = new CommentedProperties();
+
public void setUp() throws IOException
{
InputStream in = CommentedPropertiesTest.class.getClassLoader().getResourceAsStream( "test.properties" );
m_props.load( in );
in.close();
}
-
+
public void testLoadProperties()
{
- assertEquals( 5, m_props.keySet().size() );
+ assertEquals( 6, m_props.keySet().size() );
assertEquals( "Foo", m_props.get( "testProp1" ) );
assertEquals( "Bar", m_props.get( "testProp2" ) );
assertEquals( "", m_props.get( "testProp3" ) );
assertEquals( "FooAgain", m_props.get( "testProp4" ) );
assertEquals( "BarAgain", m_props.get( "testProp5" ) );
- assertNull( m_props.get( "testProp6" ) );
-
- // String we read in, including comments is 208 bytes
- assertEquals( 208, m_props.toString().length() );
+ assertNotNull( m_props.get( "testProp6" ) );
+ assertNull( m_props.get( "testProp7" ) );
}
-
+
public void testSetProperty()
{
+ int propsLen = m_props.toString().length();
m_props.setProperty( "testProp1", "newValue" );
-
+
// Length of stored string should now be 5 bytes more
- assertEquals( 208+5, m_props.toString().length() );
+ assertEquals( propsLen + 5, m_props.toString().length() );
assertTrue( m_props.toString().indexOf( "newValue" ) != -1 );
-
- // Create new property; should add 21 (1+7+3+9+1) bytes
+
+ // Create new property; should add 20 (7+3+9+1) bytes
m_props.setProperty( "newProp", "newValue2" );
m_props.containsKey( "newProp" );
m_props.containsValue( "newValue2" );
- assertEquals( 208+5+21, m_props.toString().length() );
+ assertEquals( propsLen + 5 + 20, m_props.toString().length() );
assertTrue( m_props.toString().indexOf( "newProp = newValue2" ) != -1 );
}
+
+ public void testGetComment()
+ {
+ String cr = System.getProperty( "line.separator" );
+ assertEquals( "# This is a sample properties file with comments", m_props.getComment( "testProp1" ) );
+ assertEquals( "# This is a comment" + cr + "# with two lines", m_props.getComment( "testProp2" ) );
+ assertEquals( "# This is a property with no value", m_props.getComment( "testProp3" ) );
+ assertEquals( "# Two final properties", m_props.getComment( "testProp4" ) );
+ assertEquals( null, m_props.getComment( "testProp5" ) );
+ assertEquals( "# This is a property that spans more than 1 line", m_props.getComment( "testProp6" ) );
+ }
+
+ public void testSetComment()
+ {
+ m_props.setProperty( "testProp7", "TestValue","This is a comment" );
+ assertEquals( "TestValue", m_props.getProperty( "testProp7" ) );
+ assertEquals( "# This is a comment", m_props.getComment( "testProp7" ) );
+
+ // Make sure it was actually added to the string returned by toString()
+ assertTrue( m_props.toString().contains( "# This is a comment\ntestProp7 = TestValue" ) );
+ }
+ public void testMultilineProperties()
+ {
+ assertTrue( m_props.containsKey( "testProp6" ) );
+ assertEquals( "Your new properties have been saved to jspwiki.properties.", m_props.get( "testProp6" ) );
+ }
+
public void testRemove()
{
- // Remove prop 1; length of stored string should be 14 (1+9+1+3) bytes less
+ int propsLen = m_props.toString().length();
+
+ // Remove prop 1; length of stored string should be 16 (9+3+3+1) bytes
+ // less for property
+ // and 49 bytes less for the comment above it. Total difference: 65
+ // bytes
m_props.remove( "testProp1" );
assertFalse( m_props.containsKey( "testProp1" ) );
- assertEquals( 208-14, m_props.toString().length() );
-
- // Remove prop 2; length of stored string should be 15 (1+9+2+3) bytes less
+ assertEquals( propsLen - 65, m_props.toString().length() );
+
+ // Remove prop 2; length of stored string should be 55 (20+19+16) bytes
+ // less
m_props.remove( "testProp2" );
assertFalse( m_props.containsKey( "testProp2" ) );
- assertEquals( 208-14-15, m_props.toString().length() );
-
- // Remove prop 3; length of stored string should be 11 (1+9+1) bytes less
+ assertEquals( propsLen - 65 - 55, m_props.toString().length() );
+
+ // Remove prop 3; length of stored string should be 48 (35+13) bytes
+ // less
m_props.remove( "testProp3" );
assertFalse( m_props.containsKey( "testProp3" ) );
- assertEquals( 208-14-15-11, m_props.toString().length() );
-
- // Remove prop 4; length of stored string should be 19 (1+9+1+8) bytes less
+ assertEquals( propsLen - 65 - 55 - 48, m_props.toString().length() );
+
+ // Remove prop 4; length of stored string should be 44 (23+21) bytes
+ // less
m_props.remove( "testProp4" );
assertFalse( m_props.containsKey( "testProp4" ) );
- assertEquals( 208-14-15-11-19, m_props.toString().length() );
-
- // Remove prop 5; length of stored string should be 19 (1+9+1+8) bytes less
+ assertEquals( propsLen - 65 - 55 - 48 - 44, m_props.toString().length() );
+
+ // Remove prop 5; length of stored string should be 21 bytes less
m_props.remove( "testProp5" );
assertFalse( m_props.containsKey( "testProp5" ) );
- assertEquals( 208-14-15-11-19-19, m_props.toString().length() );
+ assertEquals( propsLen - 65 - 55 - 48 - 44 - 21, m_props.toString().length() );
}
-
+
public void testStore() throws Exception
{
// Write results to a new file
@@ -111,14 +141,14 @@
OutputStream out = new FileOutputStream( outFile );
m_props.store( out, null );
out.close();
-
+
// Load the file into new props object; should return identical strings
Properties props2 = new CommentedProperties();
InputStream in = CommentedPropertiesTest.class.getClassLoader().getResourceAsStream( "test2.properties" );
props2.load( in );
in.close();
assertEquals( m_props.toString(), props2.toString() );
-
+
// Remove props1, 2, 3 & resave props to new file
m_props.remove( "testProp1" );
m_props.remove( "testProp2" );
@@ -127,7 +157,7 @@
out = new FileOutputStream( outFile );
m_props.store( out, null );
out.close();
-
+
// Load the new file; should not have props1/2/3 & is shorter
Properties props3 = new CommentedProperties();
in = CommentedPropertiesTest.class.getClassLoader().getResourceAsStream( "test3.properties" );
@@ -139,15 +169,15 @@
assertFalse( props3.containsKey( "testProp3" ) );
assertTrue( props3.containsKey( "testProp4" ) );
assertTrue( props3.containsKey( "testProp5" ) );
-
+
// Clean up
File file = getFile( "test2.properties" );
- if ( file != null && file.exists() )
+ if( file != null && file.exists() )
{
file.delete();
}
file = getFile( "test3.properties" );
- if ( file != null && file.exists() )
+ if( file != null && file.exists() )
{
file.delete();
}
@@ -157,22 +187,22 @@
{
// Get the test.properties file
URL url = CommentedPropertiesTest.class.getClassLoader().getResource( "test.properties" );
- if ( url == null )
+ if( url == null )
{
throw new IllegalStateException( "Very odd. We can't find test.properties!" );
}
-
+
// Construct new file in same directory
- File testFile = new File( new URI(url.toString()) );
+ File testFile = new File( new URI( url.toString() ) );
File dir = testFile.getParentFile();
return new File( dir, file );
}
-
+
private File getFile( String name )
{
// Get the test.properties file
URL url = CommentedPropertiesTest.class.getClassLoader().getResource( name );
- if ( url == null )
+ if( url == null )
{
throw new IllegalStateException( "Very odd. We can't find test.properties!" );
}
@@ -181,9 +211,9 @@
try
{
- file = new File( new URI(url.toString()) );
+ file = new File( new URI( url.toString() ) );
}
- catch (URISyntaxException e)
+ catch( URISyntaxException e )
{
// TODO Auto-generated catch block
e.printStackTrace();
@@ -191,11 +221,9 @@
return file;
}
-
+
public static Test suite()
{
return new TestSuite( CommentedPropertiesTest.class );
}
}
-
-
Modified: incubator/jspwiki/trunk/tests/etc/test.properties
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/etc/test.properties?rev=738356&r1=738355&r2=738356&view=diff
==============================================================================
--- incubator/jspwiki/trunk/tests/etc/test.properties (original)
+++ incubator/jspwiki/trunk/tests/etc/test.properties Wed Jan 28 03:57:46 2009
@@ -2,6 +2,7 @@
testProp1=Foo
# This is a comment
+# with two lines
testProp2 =Bar
# This is a property with no value
@@ -10,3 +11,7 @@
testProp4=FooAgain
testProp5=BarAgain
+# This is a property that spans more than 1 line
+testProp6=Your new properties have been saved \
+ to jspwiki.properties.
+
\ No newline at end of file