📄 differenceengine.java
字号:
/* JSPWiki - a JSP-based WikiWiki clone. Copyright (C) 2001-2002 Janne Jalkanen (Janne.Jalkanen@iki.fi) This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package com.ecyrd.jspwiki;import java.util.Properties;import java.util.Vector;import java.io.File;import java.io.IOException;import java.io.BufferedReader;import java.io.StringReader;import java.io.StringWriter;import java.io.PrintWriter;import java.io.Writer;import org.apache.log4j.Category;// import org.suigeneris.diff.*;/** * Provides access to making a 'diff' between two Strings. * Can be commanded to use a diff program or to use an internal diff. * * @author Janne Jalkanen * @author Erik Bunn */public class DifferenceEngine{ private static final Category log = Category.getInstance(DifferenceEngine.class); /** Determines the command to be used for 'diff'. This program must be able to output diffs in the unified format. It defaults to 'diff -u %s1 %s2'.*/ public static final String PROP_DIFFCOMMAND = "jspwiki.diffCommand"; private static final char DIFF_ADDED_SYMBOL = '+'; private static final char DIFF_REMOVED_SYMBOL = '-'; private static final String CSS_DIFF_ADDED = "<tr><td bgcolor=\"#99FF99\" class=\"diffadd\">"; private static final String CSS_DIFF_REMOVED = "<tr><td bgcolor=\"#FF9933\" class=\"diffrem\">"; private static final String CSS_DIFF_UNCHANGED = "<tr><td class=\"diff\">"; private static final String CSS_DIFF_CLOSE = "</td></tr>"; /** Default diff command */ private String m_diffCommand = null; private String m_encoding; private boolean m_useInternalDiff = true; /** * Creates a new DifferenceEngine. * * @param props The contents of jspwiki.properties * @param encoding The character encoding used for making the diff. */ public DifferenceEngine( Properties props, String encoding ) { m_diffCommand = props.getProperty( PROP_DIFFCOMMAND ); m_useInternalDiff = (m_diffCommand == null); m_encoding = encoding; } private String getContentEncoding() { return m_encoding; } /** * Returns a raw, text format diff of its arguments. This diff can then * be fed to the <TT>colorizeDiff()</TT>, below. * * @see #colorizeDiff */ public String makeDiff( String p1, String p2 ) { if( m_useInternalDiff ) { return makeDiffWithBMSI( p1, p2 ); } else { return makeDiffWithProgram( p1, p2 ); } } /* // Makes a diff with JRCS routines, but BMSI is slightly better. private String makeDiffWithJRCS( String p1, String p2 ) { try { Object[] first = Diff.stringToArray(p1); Object[] second = Diff.stringToArray(p2); Revision diff = Diff.diff( first, second ); return diff.toUnifiedString(); } catch( DifferentiationFailedException e ) { log.error("Diff failed", e); } return null; } */ /** * Makes a diff using the BMSI utility package. * We use our own diff printer, which makes things * easier. */ private String makeDiffWithBMSI( String p1, String p2 ) { try { String[] first = stringToArray(p1); String[] second = stringToArray(p2); bmsi.util.Diff diff = new bmsi.util.Diff( first, second ); bmsi.util.Diff.change script = diff.diff_2(false); if( script == null ) { // No differences. return ""; } StringWriter sw = new StringWriter(); bmsi.util.DiffPrint.Base p = new WriterPrint( first, second, sw ); p.print_script( script ); return sw.toString(); } catch( IOException e ) { log.error("Diff failed", e); } return null; } /** * Writes a diff in a human-readable form, as opposed to your * standard average diff. * * Lifted from org.mahlen.hula.utils.VersionUtil. * @author Mahlen Morris * @author Janne Jalkanen */ // FIXME: Must somehow add contextual diffs as well. private class WriterPrint extends bmsi.util.DiffPrint.NormalPrint { public WriterPrint( String[] a, String[] b, Writer w ) { super( a, b ); outfile = new PrintWriter( w ); } protected void print_range_length( int a, int b ) { outfile.print( b-a+1 ); } /** * This method no longer emulates any known diff format. */ protected void print_hunk(bmsi.util.Diff.change hunk) { /* Determine range of line numbers involved in each file. */ analyze_hunk(hunk); if (deletes == 0 && inserts == 0) return; /* Print out the line number header for this hunk */ if( inserts != 0 && deletes == 0 ) { outfile.print("At line "); print_number_range('-', first0, last0); outfile.print(" added "); print_range_length(first1, last1); outfile.print(" line" + ((last1-first1 == 0)? "." : "s.") ); } else if( deletes != 0 && inserts == 0 ) { outfile.print("Removed line"+((last0-first0 == 0)? " " : "s ")); print_number_range('-', first0, last0); // outfile.print(" removed "); // print_range_length(first1, last1); // outfile.print(" line" + ((last1-first1 == 0)? "." : "s.") ); } else { if( last0-first0 == 0 ) { outfile.print("Line "); print_number_range('-', first0, last0); outfile.print(" was replaced by "); } else { outfile.print("Lines "); print_number_range('-', first0, last0); outfile.print(" were replaced by "); } outfile.print( "line"+((last1-first1 == 0) ? " " : "s ")); print_number_range('-', first1, last1); } outfile.println(); /* Print the lines that the first file has. */ if (deletes != 0) for (int i = first0; i <= last0; i++) print_1_line("- ", file0[i]); /* if (inserts != 0 && deletes != 0) outfile.println("==="); */ /* Print the lines that the second file has. */ if (inserts != 0) for (int i = first1; i <= last1; i++) print_1_line("+ ", file1[i]); } } /** * Again, lifted from org.mahlen.hula.utils.VersionUtil. */ private static String[] stringToArray(String str) throws IOException { BufferedReader rdr = new BufferedReader(new StringReader(str)); Vector s = new Vector(); for(;;) { String line = rdr.readLine(); if (line == null) break; s.addElement(line); } String[] a = new String[s.size()]; s.copyInto(a); return a; } /** * Makes the diff by calling "diff" program. */ private String makeDiffWithProgram( String p1, String p2 ) { File f1 = null, f2 = null; String diff = null; try { f1 = FileUtil.newTmpFile( p1, getContentEncoding() ); f2 = FileUtil.newTmpFile( p2, getContentEncoding() ); String cmd = TextUtil.replaceString( m_diffCommand, "%s1", f1.getPath() ); cmd = TextUtil.replaceString( cmd, "%s2", f2.getPath() ); String output = FileUtil.runSimpleCommand( cmd, f1.getParent() ); // FIXME: Should this rely on the system default encoding? diff = new String(output.getBytes("ISO-8859-1"), getContentEncoding() ); } catch( IOException e ) { log.error("Failed to do file diff",e); } catch( InterruptedException e ) { log.error("Interrupted",e); } finally { if( f1 != null ) f1.delete(); if( f2 != null ) f2.delete(); } return diff; } /** * Goes through output provided by a diff command and inserts * HTML tags to make the result more legible. * Currently colors lines starting with a + green, * those starting with - reddish (hm, got to think of * color blindness here...). */ public String colorizeDiff( String diffText ) throws IOException { String line = null; String start = null; String stop = null; if( diffText == null ) { return "Invalid diff - probably something wrong with server setup."; } BufferedReader in = new BufferedReader( new StringReader( diffText ) ); StringBuffer out = new StringBuffer(); out.append("<table class=\"diff\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n"); while( ( line = in.readLine() ) != null ) { stop = CSS_DIFF_CLOSE; if( line.length() > 0 ) { switch( line.charAt( 0 ) ) { case DIFF_ADDED_SYMBOL: start = CSS_DIFF_ADDED; break; case DIFF_REMOVED_SYMBOL: start = CSS_DIFF_REMOVED; break; default: start = CSS_DIFF_UNCHANGED; } } else { start = CSS_DIFF_UNCHANGED; } out.append( start ); out.append( line.trim() ); out.append( stop + "\n" ); } out.append("</table>\n"); return( out.toString() ); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -