package org.outerj.daisy.diff;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Locale;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import org.outerj.daisy.diff.html.HTMLDiffer;
import org.outerj.daisy.diff.html.HtmlSaxDiffOutput;
import org.outerj.daisy.diff.html.TextNodeComparator;
import org.outerj.daisy.diff.html.dom.DomTreeBuilder;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
public class Main {
static boolean quietMode = false;
public static void main(String[] args) throws URISyntaxException {
if (args.length < 2)
help();
boolean htmlDiff = true;
boolean htmlOut = true;
String outputFileName = "daisydiff.htm";
String[] css = new String[]{};
InputStream oldStream = null;
InputStream newStream = null;
try {
for (int i = 2; i < args.length; i++) {
String[] split = args[i].split("=");
if (split[0].equalsIgnoreCase("--file")) {
outputFileName = split[1];
} else if (split[0].equalsIgnoreCase("--type")) {
if (split[1].equalsIgnoreCase("tag")) {
htmlDiff = false;
}
} else if (split[0].equalsIgnoreCase("--css")) {
css = split[1].split(";");
} else if (split[0].equalsIgnoreCase("--output")) {
if (split[1].equalsIgnoreCase("xml")) {
htmlOut = false;
}
} else if (split[0].equals("--q")){
quietMode = true;
} else{
help();
}
}
File outputFile= new File(outputFileName);
try {
outputFile.createNewFile(); // Fail if outputFileName is malformed. Otherwise result.setResult() below would silently supress an exception (at least with jdk1.8.0_65). Then calling postProcess.endDocument() below would fail with confusing "javax.xml.transform.TransformerException: org.xml.sax.SAXException: setResult() must be called prior to startDocument()."
}
catch( IOException e ) {
System.err.println( "Filepath " +outputFileName+ " is malformed, or some of its folders don't exist, or you don't have write access." );
return;
}
if (!quietMode){
System.out.println("Daisy Diff https://github.com/DaisyDiff/DaisyDiff");
System.out.println("Comparing documents: " +args[0]+ " and " +args[1] );
System.out.println( "Diff type: " +(
htmlDiff
? "html"
: "tag"
) );
System.out.println("Writing "+(htmlOut?"html":"xml")+" output to " + outputFileName);
}
if(css.length>0){
if (!quietMode)
System.out.println("Adding external css files:");
for(String cssLink:css){
System.out.println(" "+cssLink);
}
}
if (!quietMode){
System.out.println("");
System.out.print(".");
}
SAXTransformerFactory tf = (SAXTransformerFactory) TransformerFactory
.newInstance();
TransformerHandler result = tf.newTransformerHandler();
// If the file path were malformed, then the following
result.setResult(new StreamResult(outputFile));
if (args[0].startsWith("http://")) {
oldStream = new URI(args[0]).toURL().openStream();
}
else {
oldStream = new FileInputStream(args[0]);
}
if (args[1].startsWith("http://")) {
newStream = new URI(args[1]).toURL().openStream();
}
else {
newStream = new FileInputStream(args[1]);
}
XslFilter filter = new XslFilter();
if (htmlDiff) {
ContentHandler postProcess = htmlOut? filter.xsl(result,
"xslfilter/htmlheader.xsl"):result;
Locale locale = Locale.getDefault();
String prefix = "diff";
HtmlCleaner cleaner = new HtmlCleaner();
InputSource oldSource = new InputSource(oldStream);
InputSource newSource = new InputSource(newStream);
DomTreeBuilder oldHandler = new DomTreeBuilder();
cleaner.cleanAndParse(oldSource, oldHandler);
System.out.print(".");
TextNodeComparator leftComparator = new TextNodeComparator(
oldHandler, locale);
DomTreeBuilder newHandler = new DomTreeBuilder();
cleaner.cleanAndParse(newSource, newHandler);
System.out.print(".");
TextNodeComparator rightComparator = new TextNodeComparator(
newHandler, locale);
postProcess.startDocument();
postProcess.startElement("", "diffreport", "diffreport",
new AttributesImpl());
doCSS(css, postProcess);
postProcess.startElement("", "diff", "diff",
new AttributesImpl());
HtmlSaxDiffOutput output = new HtmlSaxDiffOutput(postProcess,
prefix);
HTMLDiffer differ = new HTMLDiffer(output);
differ.diff(leftComparator, rightComparator);
System.out.print(".");
postProcess.endElement("", "diff", "diff");
postProcess.endElement("", "diffreport", "diffreport");
postProcess.endDocument();
} else {
ContentHandler postProcess = htmlOut? filter.xsl(result,
"xslfilter/tagheader.xsl"):result;
postProcess.startDocument();
postProcess.startElement("", "diffreport", "diffreport",
new AttributesImpl());
postProcess.startElement("", "diff", "diff",
new AttributesImpl());
System.out.print(".");
InputStreamReader oldReader = null;
BufferedReader oldBuffer = null;
InputStreamReader newISReader = null;
BufferedReader newBuffer = null;
try {
oldReader = new InputStreamReader(oldStream);
oldBuffer = new BufferedReader(oldReader);
newISReader = new InputStreamReader(newStream);
newBuffer = new BufferedReader(newISReader);
DaisyDiff.diffTag(oldBuffer, newBuffer, postProcess);
} catch (Exception e) {
e.printStackTrace();
} finally {
oldBuffer.close();
newBuffer.close();
oldReader.close();
newISReader.close();
}
System.out.print(".");
postProcess.endElement("", "diff", "diff");
postProcess.endElement("", "diffreport", "diffreport");
postProcess.endDocument();
}
} catch (Throwable e) {
if (quietMode){
System.out.println(e);
} else {
e.printStackTrace();
if (e.getCause() != null) {
e.getCause().printStackTrace();
}
if (e instanceof SAXException) {
((SAXException) e).getException().printStackTrace();
}
help();
}
} finally {
try {
if(oldStream != null) oldStream.close();
} catch (IOException e) {
//ignore this exception
}
try {
if(newStream != null) newStream.close();
} catch (IOException e) {
//ignore this exception
}
}
if (quietMode)
System.out.println();
else
System.out.println("done");
}
private static void doCSS(String[] css, ContentHandler handler) throws SAXException {
handler.startElement("", "css", "css",
new AttributesImpl());
for(String cssLink : css){
AttributesImpl attr = new AttributesImpl();
attr.addAttribute("", "href", "href", "CDATA", cssLink);
attr.addAttribute("", "type", "type", "CDATA", "text/css");
attr.addAttribute("", "rel", "rel", "CDATA", "stylesheet");
handler.startElement("", "link", "link",
attr);
handler.endElement("", "link", "link");
}
handler.endElement("", "css", "css");
}
private static void help() {
System.out.println("==========================");
System.out.println("DAISY DIFF HELP:");
System.out.println("java -jar daisydiff.jar [oldHTML] [newHTML]");
System.out
.println("--file=[filename] - Write output to the specified file.");
System.out
.println("--type=[html/tag] - Use the html (default) diff algorithm or the tag diff.");
System.out.println("--css=[cssfile1;cssfile2;cssfile3] - Add external CSS files.");
System.out.println("--output=[html/xml] - Write html (default) or xml output.");
System.out.println("--q - Generate less console output.");
System.out.println("");
System.out.println("EXAMPLES: ");
System.out.println("(1)");
System.out
.println("java -jar daisydiff.jar http://web.archive.org/web/20070107145418/http://news.bbc.co.uk/ http://web.archive.org/web/20070107182640/http://news.bbc.co.uk/ --css=http://web.archive.org/web/20070107145418/http://news.bbc.co.uk/nol/shared/css/news_r5.css");
System.out.println("(2)");
System.out.println("java -jar daisydiff.jar http://cocoondev.org/wiki/291-cd/version/15/part/SimpleDocumentContent/data http://cocoondev.org/wiki/291-cd/version/17/part/SimpleDocumentContent/data --css=http://cocoondev.org/resources/skins/daisysite/css/daisy.css --output=xml --file=daisysite.htm");
System.out.println("==========================");
System.exit(0);
}
}