All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
deepdiff.app.DeepDiff Maven / Gradle / Ivy
/*
* Copyright 2011 DeepDiff Contributors
*
* Licensed 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 deepdiff.app;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.log4j.Logger;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import deepdiff.core.DiffPointProcessor;
import deepdiff.core.DiffPointProcessorFactory;
import deepdiff.core.DiffScope;
import deepdiff.core.DiffUnitProcessor;
import deepdiff.core.DiffUnitProcessorFactory;
/**
* Main class for the DeepDiff application. This class handles parsing command-line options, loads
* the configuration file, and calls the configured processors on the specified scopes.
*/
public class DeepDiff {
private static final Logger log = Logger.getLogger(DeepDiff.class);
private static final String COMMAND_NAME = "deepdiff";
private static final String USAGE = COMMAND_NAME
+ " [-h | -f | -s ] ...";
/** Command-line option to specify the configuration file to use */
@SuppressWarnings("static-access")
static final Option O_FILE = OptionBuilder.hasArg().withArgName("file")
.withDescription("load configuration from file").create("f");
/** Command-line option to output sample file */
@SuppressWarnings("static-access")
static final Option O_SAMPLE = OptionBuilder.hasArg().withArgName("file")
.withDescription("output sample configuration file").create("s");
/** Command-line option to display help */
@SuppressWarnings("static-access")
static final Option O_HELP = OptionBuilder.withDescription("display help information").create(
"h");
private static final Options CONFIGURED_OPTIONS = new Options();
private static final String DEFAULT_CONFIG = "/default.conf.xml";
static {
// Initialize the options object
OptionGroup opts = new OptionGroup();
opts.addOption(O_FILE);
opts.addOption(O_SAMPLE);
opts.addOption(O_HELP);
CONFIGURED_OPTIONS.addOptionGroup(opts);
}
/**
* Entry point for the application
*
* @param args the command-line arguments
*/
public static void main(String[] args) {
CommandLine cl = parseCommandLine(args);
if (cl != null) { // Valid args
processCommand(cl);
} else { // Invalid args
System.exit(-1);
}
}
/**
* Parses a command-line
*
* @param args the command-line arguments
*
* @return the parsed command-line
*/
static CommandLine parseCommandLine(String[] args) {
CommandLineParser parser = new GnuParser();
CommandLine cl = null;
try {
cl = parser.parse(CONFIGURED_OPTIONS, args);
} catch (ParseException pe) {
System.err.println("Invalid command-line options: " + pe.getMessage());
System.err.println();
showUsage(new PrintWriter(System.err), CONFIGURED_OPTIONS);
}
return cl;
}
/**
* Process the command. Load the specified configuration file, and process scopes as specified
* within it.
*
* @param cl the commmand line options
*/
private static void processCommand(CommandLine cl) {
InputSource configSource = null;
log.debug("Processing command-line options...");
Option[] opts = cl.getOptions();
for (int i = 0; i < opts.length; i++) {
Option opt = opts[i];
if (O_HELP.getOpt().equals(opt.getOpt())) {
showUsage(new PrintWriter(System.out), CONFIGURED_OPTIONS);
} else if (O_SAMPLE.getOpt().equals(opt.getOpt())) {
String filePath = opt.getValue();
try {
copy(getDefaultConfigStream(), new File(filePath));
log.info("Wrote sample configuration file to " + filePath);
return;
} catch (IOException ex) {
log.fatal("Failed to write sample configuration file to " + filePath);
System.exit(-1);
}
} else if (O_FILE.getOpt().equals(opt.getOpt())) {
if (configSource == null) {
String filePath = opt.getValue();
File configFile = new File(filePath);
if (!configFile.exists()) {
log.fatal("Specified configuration file does not exist: " + filePath);
System.exit(-1);
}
try {
configSource = new InputSource(new FileReader(configFile));
} catch (IOException ex) {
log.fatal("Failed to read configuration file from " + filePath);
System.exit(-1);
}
} else {
log.fatal("Multiple -" + opt.getOpt() + " options specified");
PrintWriter pw = new PrintWriter(System.err);
showUsage(pw, CONFIGURED_OPTIONS);
System.exit(-1);
}
} else {
log.warn("Unknown option: " + opt.getOpt());
}
}
log.debug("Done processing command-line options");
if (configSource == null) { // Use default configuration
configSource = new InputSource(getDefaultConfigStream());
}
ConfigHandler configHandler = new ConfigHandler();
Collection scopes = new LinkedList();
try {
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
SAXParser parser = parserFactory.newSAXParser();
parser.parse(configSource, configHandler);
scopes.addAll(configHandler.getScopes());
} catch (SAXException saxe) {
log.fatal("Failure reading config", saxe);
System.exit(-1);
} catch (ParserConfigurationException pce) {
log.fatal("Failure reading config", pce);
System.exit(-1);
} catch (IOException ioe) {
log.fatal("Failure reading config", ioe);
System.exit(-1);
}
DiffUnitProcessor unitProcessor = DiffUnitProcessorFactory.getDefault();
DiffPointProcessor pointProcessor = DiffPointProcessorFactory.getDefault();
if (unitProcessor == null) {
log.fatal("No unit processor configured; exiting");
System.exit(-1);
}
if (pointProcessor == null) {
log.fatal("No point processor configured; exiting");
System.exit(-1);
}
List argList = cl.getArgList();
if (argList.size() % 2 != 0) {
log.fatal("Comparison scopes specified as command-line arguments must be in pairs.");
System.exit(-1);
}
for (int i = 0; i < argList.size(); i += 2) {
File root1 = new File((String) argList.get(i));
File root2 = new File((String) argList.get(i + 1));
DiffScope scope = DiffUnitProcessorFactory.createInitialScope(root1, root2);
scopes.add(scope);
}
if (scopes.isEmpty()) {
log.warn("No scopes found");
} else {
int i = 0;
for (Iterator it = scopes.iterator(); it.hasNext();) {
i++;
DiffScope scope = it.next();
log.info("Scanning scope " + i + "/" + scopes.size() + ": " + scope.getPath());
scope.scan(unitProcessor, pointProcessor);
}
log.info("Completed scanning");
}
}
private static InputStream getDefaultConfigStream() {
return DeepDiff.class.getResourceAsStream(DEFAULT_CONFIG);
}
/**
* Shows usage information for the application
*
* @param pw the PrintWriter to show the usage information on
* @param options the supported options
*/
private static void showUsage(PrintWriter pw, Options options) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp(pw, 80, USAGE,
"Files or directories to compare should be specified in pairs.", options, 1, 3, "",
false);
pw.flush();
}
private static void copy(InputStream inStream, File outFile) throws IOException {
ReadableByteChannel inChannel = Channels.newChannel(inStream);
try {
FileOutputStream os = new FileOutputStream(outFile);
try {
WritableByteChannel outChannel = os.getChannel();
try {
copy(inChannel, outChannel);
} finally {
outChannel.close();
}
} finally {
os.close();
}
} finally {
inChannel.close();
}
}
private static void copy(ReadableByteChannel src, WritableByteChannel dest) throws IOException {
ByteBuffer buffer = ByteBuffer.allocateDirect(4 * 1024);
while (src.read(buffer) != -1) {
buffer.flip();
dest.write(buffer);
buffer.compact();
}
buffer.flip();
while (buffer.hasRemaining()) {
dest.write(buffer);
}
}
}