    001    package calhoun.util;
    002
    003    import java.io.BufferedReader;
    004    import java.io.File;
    005    import java.io.FileInputStream;
    006    import java.io.IOException;
    007    import java.io.InputStreamReader;
    008    import java.io.PrintWriter;
    009    import java.io.Reader;
    010    import java.io.StringWriter;
    011    import java.util.ArrayList;
    012
    013    import bmsi.util.Diff;
    014    import bmsi.util.DiffPrint;
    015
    016    /**
    017     * Computes the 'diff' difference between two files. By default, whitespace in the files is ignored.
    018     */
    019    public class FileDiff
    020    {
    021            private String[] firstLines;
    022            private String[] secondLines;
    023
    024            private boolean closeReaders;
    025            private Reader firstLinesReader;
    026            private Reader secondLinesReader;
    027            private boolean ignoreWhitespace = true;
    028            private String commentLineIndicator;
    029            private Diff.change change = null;
    030
    031            public static boolean filesMatch(String first, String second) throws IOException {
    032                    return !new FileDiff(first, second).execute();
    033            }
    034
    035            /**     Constructor takes 2 file names - opens the files using UTF-8 encoding.
    036            */
    037            public FileDiff(String first, String second) throws IOException
    038            {
    039                    this(new InputStreamReader( new FileInputStream(first), "UTF-8" ), new InputStreamReader( new FileInputStream(second),"UTF-8"), true );
    040            }
    041
    042            /**     Constructor takes 2 Files - opens the files using UTF-8 encoding.
    043            */
    044            public FileDiff(File first, File second) throws IOException
    045            {
    046                    this(new InputStreamReader( new FileInputStream(first), "UTF-8" ), new InputStreamReader( new FileInputStream(second),"UTF-8"), true );
    047            }
    048
    049            public FileDiff(Reader first, Reader second)
    050            {
    051                    this( first,second, false );
    052            }
    053
    054            public FileDiff(Reader first, Reader second, boolean closeReaders )
    055            {
    056                    this.firstLinesReader = first;
    057                    this.secondLinesReader = second;
    058                    this.closeReaders = closeReaders;
    059            }
    060
    061            /**
    062             * Sets whether to ignore whitespace. By default, whitespace is ignored.
    063             * @see #getIgnoreWhitespace
    064             */
    065            public void setIgnoreWhitespace(boolean b)
    066            {
    067                    ignoreWhitespace = b;
    068            }
    069
    070            /**
    071             * @see #setIgnoreWhitespace
    072             */
    073            public boolean getIgnoreWhitespace()
    074            {
    075                    return ignoreWhitespace;
    076            }
    077
    078            /**
    079             * Sets the comment line indicator string.  If set, lines beginning with this string are not used in the diff comparison.
    080             * @see #getCommentLineIndicator
    081             */
    082            public void setCommentLineIndicator(String commentLineIndicator)
    083            {
    084                    this.commentLineIndicator = commentLineIndicator;
    085            }
    086
    087            /**
    088             * Gets the comment line indicator string.
    089             * @see #setCommentLineIndicator
    090             */
    091            public String getCommentLineIndicator()
    092            {
    093                    return commentLineIndicator;
    094            }
    095
    096            /**
    097             * @return whether the two files were different.
    098             * @see #toString
    099             */
    100            public boolean execute() throws IOException
    101            {
    102                    firstLines = readLines(firstLinesReader);
    103                    secondLines = readLines(secondLinesReader);
    104                    if ( closeReaders )
    105                    {
    106                            firstLinesReader.close();
    107                            secondLinesReader.close();
    108                    }
    109                    Diff diff = new Diff(firstLines, secondLines);
    110                    change = diff.diff_2(false);
    111                    return change != null;
    112            }
    113
    114            /**
    115             * @return a diff-style listing of the differences between the 2 files. If the files were identical,
    116             * returns the empty string ('').
    117             */
    118            @Override
    119            public String toString()
    120            {
    121                    if ( change != null )
    122                    {
    123                            DiffPrint.NormalPrint np = new DiffPrint.NormalPrint(firstLines, secondLines);
    124                            StringWriter str = new StringWriter();
    125                            PrintWriter writer = new PrintWriter(str);
    126                            np.setWriter(writer);
    127                            np.print_script(change);
    128                            writer.close();
    129                            return str.toString();
    130                    }
    131                    else
    132                    {
    133                            return "";
    134                    }
    135            }
    136
    137            private String[] readLines(Reader r) throws IOException
    138            {
    139                    BufferedReader reader = new BufferedReader(r);
    140                    ArrayList lines = new ArrayList();
    141                    String line;
    142                    while ( ( line = reader.readLine() ) != null )
    143                    {
    144                            if ( ignoreWhitespace )
    145                                    line = line.trim();
    146
    147                            if ( (!ignoreWhitespace || !"".equals(line)) &&
    148                                      (commentLineIndicator == null || !line.startsWith(commentLineIndicator)) )
    149                            {
    150                                    lines.add(line);
    151                            }
    152                    }
    153                    String[] result = new String[lines.size()];
    154                    return (String[])lines.toArray(result);
    155            }
    156    }