ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David McTavish <dmctav...@sandvine.com>
Subject RE: merging property files...
Date Wed, 24 Sep 2003 18:07:52 GMT
I have a mergeProperties task that does just this, and attempts to preserve
comments as well.

package com.sandvine.ant;

// java imports
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
// third-party imports
import org.apache.tools.ant.Task;
import org.apache.tools.ant.BuildException;


/**
 *  MergeProperties provides functionality to merge two separate .properties
 *  configuration files into one while preserving user comments.
 */
public class MergeProperties extends Task 
{
    /** determines source .properties file */
    private File mergeFile;
    /** determines property over-ride file */
    private File importFile;
    /** determines where final properties are saved */
    private File destFile;
    /** stores a collection of properties added to merged file */
    private HashMap map = new HashMap();


    /**
     *  Configures the source input file to read the source properties.
     *
     *  @param  file
     *      A File object representing the source .properties file to read.
     */
    public void setFile(final File file) 
    {
        mergeFile = file;
    }

    /**
     *  Configures the destination file to overwrite the properties provided
     *  in the source file.
     *
     *  @param  file
     *      A File object representing the destination file to merge the
     *      combined properties into.
     */
    public void setImportFile(final File file)
    {
        importFile = file;
    }

    /**
     *  Configures the destination file to write the combined properties.
     *
     *  @param  file
     *      A File object representing the destination file to merge the
     *      combined properties into.
     */
    public void setToFile(final File file)
    {
        destFile = file;
    }

    /**
     *  Method invoked by the ant framework to execute the action associated
     *  with this task.
     *
     *  @throws BuildException 
     *      Any fatal exception that occurs while processing the task
     */
    public void execute() throws BuildException 
    {
        // validate provided parameters
        validate();

        // read source .properties
        List newFile = new ArrayList();
        List source = loadFile(mergeFile, newFile);
        List merge = loadFile(importFile, newFile);

        // iterate through source, and write to file with updated properties
        writeFile(newFile);
    }

    /**
     *  Validate that the task parameters are valid.
     *
     *  @throws BuildException 
     *      if parameters are invalid
     */
    private void validate() throws BuildException 
    {
        map.clear();
        if (!importFile.canRead()) 
        {
            final String message = "Unable to read from " + importFile +
".";
            throw new BuildException(message);
        }
        if (!mergeFile.canRead()) 
        {
            final String message = "Unable to read from " + mergeFile + ".";
            throw new BuildException(message);
        }
        if (!destFile.canWrite()) 
        {
            try
            {
                destFile.createNewFile();
            }
            catch (IOException e)
            {
                throw new BuildException("Unable to write to " + destFile +
".");
            }
        }
    }

    /**
     *  Reads the contents of the selected file and returns them in a List
that
     *  contains String objects that represent each line of the file in the
     *  order that they were read.
     *
     *  @param  file
     *      The file to load the contents into a List.
     *  @return a List of the contents of the file where each line of the
file
     *      is stored as an individual String object in the List in the same
     *      physical order it appears in the file.
     *  @throws  BuildException
     *      An exception can occur if the version file is corrupted or the
     *      process is in someway interrupted
     */
    private List loadFile(File file, List fileContents) throws
BuildException
    {
        try
        {
            BufferedReader in = new BufferedReader(new FileReader(file));
            String curLine;
            String property;
            String comment = "";
            try
            {
                while ((curLine = in.readLine()) != null)
                {
                    curLine = curLine.trim();
                    if (curLine.startsWith("#"))
                    {
                        comment += curLine + "\r\n";
                    }
                    else if (curLine.indexOf("=") > 0)
                    {
                        while (curLine.endsWith("\\"))
                        {
                            curLine += "\r\n" + in.readLine().trim();
                        }
                        FileContents fc = new FileContents();
                        fc.name = curLine.substring(0,
curLine.indexOf("="));
                        fc.value = curLine;
                        fc.comment = comment;
                        comment = "";
                        if (fileContents.contains(fc))
                        {
                            FileContents existing = 
                                getExistingElement(fileContents, fc.name);
                            if (existing != null)
                            {
                                existing.value = fc.value;
                            }
                            else
                            {
                                fileContents.add(fc);
                            }
                        }
                        else
                        {
                            fileContents.add(fc);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw new BuildException("Could not read file:" + file, e);
            }
            finally
            {
                in.close();
            }
        }
        catch (IOException IOe)
        {
            // had an exception trying to open the file
            throw new BuildException("Could not read file:" + file, IOe);
        }
        return fileContents;
    }

    private FileContents getExistingElement(List list, String name)
    {
        Iterator i = list.iterator();
        while (i.hasNext())
        {
            FileContents fc = (FileContents) i.next();
            if (fc.getName().equals(name))
            {
                return fc;
            }
        }
        return null;
    }

    /**
     *  Writes the merged properties to a single file while preserving any
     *  comments.
     *
     *  @param  source
     *      A list containing the contents of the original source file
     *  @param  merge
     *      A list containing the contents of the file to merge
     *  @param  props
     *      A collection of properties with their values merged from both
files
     *  @throws BuildException
     *      if the destination file can't be created
     */
    private void writeFile(List fileContents) throws BuildException
    {
        Iterator iterate = fileContents.iterator();
        try
        {
            FileOutputStream out = new FileOutputStream(destFile);
            PrintStream p = new PrintStream(out);
            try
            {
                // write original file with updated values
                while (iterate.hasNext())
                {
                    FileContents fc = (FileContents) iterate.next();
                    if (fc.comment != null && !fc.comment.equals(""))
                    {
                        p.println();
                        p.print(fc.comment);
                    }
                    p.println(fc.value);
                }
            }
            catch (Exception e)
            {
                throw new BuildException("Could not write file: " +
destFile,
                    e);
            }
            finally
            {
                out.close();
            }
        }
        catch (IOException IOe)
        {
            throw new BuildException("Could not write file: " + destFile,
IOe);
        }
    }


    protected class FileContents
    {
        public String name;
        public String comment;
        public int order;
        public String value;
        
        public String getName()
        {
            return name;
        }
        
        
        public boolean equals(Object obj)
        {
            if (obj instanceof FileContents)
            {
                FileContents fc = (FileContents) obj;
                if (fc.getName().equals(name))
                {
                    return true;
                }
            }
            return false;
        }
    }

}


rgds,
d.



-----Original Message-----
From: Ciramella, EJ [mailto:ECiramella@emptoris.com]
Sent: Wednesday, September 24, 2003 2:03 PM
To: 'Ant Users List'
Subject: merging property files...


Is there a clever way to merge two property files?  The standard property
file needs to be updated with both edits to current property values and
additional properties.

Any suggestions before I go off the deep end?

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org


Mime
View raw message