Package com.bazaarvoice.jolt

Source Code of com.bazaarvoice.jolt.DiffyTool

/*
* Copyright 2013 Bazaarvoice, Inc.
*
* 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 com.bazaarvoice.jolt;

import com.fasterxml.jackson.core.JsonParseException;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.Namespace;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Map;

public class DiffyTool {

    public static void main( String[] args ) {
        int exitCode = runDiffy( args ) ? 0 : 1;
        System.exit( exitCode );
    }

    /**
     * The logic for running DiffyTool has been captured in a helper method that returns a boolean to facilitate unit testing.
     * Since System.exit terminates the JVM it would not be practical to test the main method.
     *
     * @param args the arguments from the command line input
     * @return true if two inputs were read with no differences, false if differences were found or an error was encountered
     */
    protected static boolean runDiffy( String[] args ) {
        ArgumentParser parser = ArgumentParsers.newArgumentParser( "diffy" )
                .description( "Jolt CLI Diffy Tool. This tool will ingest two JSON inputs (from files or standard input) and " +
                        "perform the Jolt Diffy operation to detect any differences. The program will return and exit code of " +
                        "0 if no differences are found or a 1 if a difference is found or an error is encountered." )
                .defaultHelp( true );

        File nullFile = null;
        parser.addArgument( "filePath1" ).help( "File path to feed to Input #1 for the Diffy operation. " +
                "This file should contain properly formatted JSON." )
                .type( Arguments.fileType().verifyExists().verifyIsFile().verifyCanRead() );
        parser.addArgument( "filePath2" ).help( "File path to feed to Input #2 for the Diffy operation. " +
                "This file should contain properly formatted JSON. " +
                "This argument is mutually exclusive with -i; one or the other should be specified." )
                .type( Arguments.fileType().verifyExists().verifyIsFile().verifyCanRead() )
                .nargs( "?" ).setDefault( nullFile );   // these last two method calls make filePath2 optional

        parser.addArgument( "-s" ).help( "Diffy will suppress output and run silently." )
                .action( Arguments.storeTrue() );
        parser.addArgument( "-a" ).help( "Diffy will not consider array order when detecting differences" )
                .action( Arguments.storeTrue() );
        parser.addArgument( "-i" ).help( "Diffy will use standard in as input for Input #2 rather than the filePath2 argument. " +
                "Standard in should contain properly formatted JSON." )
                .action( Arguments.storeTrue() );

        Namespace ns;
        try {
            ns = parser.parseArgs( args );
        } catch ( ArgumentParserException e ) {
            parser.handleError( e );
            return false;
        }

        boolean suppressOutput = ns.getBoolean( "s" );

        Diffy diffy;
        if ( ns.getBoolean( "a" ) ) {
            diffy = new ArrayOrderObliviousDiffy();
        } else {
            diffy = new Diffy();
        }

        Map<String, Object> objectMap1 = createObjectMapFromFile( (File) ns.get( "filePath1" ), suppressOutput );
        Map<String, Object> objectMap2;

        if ( ns.getBoolean( "i" ) ) {
            try {
                objectMap2 = JsonUtils.jsonToMap( System.in );
            } catch ( IOException e ) {
                if ( e instanceof JsonParseException ) {
                    printOutput( suppressOutput, "Standard input did not contain properly formatted JSON." );
                } else {
                    printOutput( suppressOutput, "Failed to process standard input." );
                }
                return false;
            }
        } else {
            File file = (File) ns.get( "filePath2" );
            if ( file == null ) {
                printOutput( suppressOutput, "Second file path is required if standard input (-i) is not utilized." );
                return false;
            } else {
                objectMap2 = createObjectMapFromFile( file, suppressOutput );
            }
        }

        Diffy.Result result = diffy.diff( objectMap1, objectMap2 );

        if ( result.isEmpty() ) {
            printOutput( suppressOutput, "Diffy found no differences" );
            return true;
        } else {
            try {
                printOutput( suppressOutput, "Differences found. Input #1 contained this:\n" +
                        JsonUtils.toPrettyJsonString( result.expected ) + "\n" +
                        "Input #2 contained this:\n" +
                        JsonUtils.toPrettyJsonString( result.actual ) );
            } catch ( IOException e ) {
                printOutput( suppressOutput, "Differences found, but diffy encountered an error while writing the result." );
            } finally {
                return false;
            }
        }
    }

    /**
     * Uses the File to build a Map containing JSON data found in the file. This method will
     * exit with an error code of 1 if has any trouble opening the file or the file did not
     * contain properly formatted JSON (i.e. the JSON parser was unable to parse its contents)
     *
     * @return the Map containing the JSON data
     */
    private static Map<String, Object> createObjectMapFromFile( File file, boolean suppressOutput ) {
        Map<String, Object> objectMap = null;
        try {
            FileInputStream inputStream = new FileInputStream( file );
            objectMap = JsonUtils.jsonToMap( inputStream );
            inputStream.close();
            return objectMap;
        } catch ( IOException e ) {
            if ( e instanceof JsonParseException ) {
                printOutput( suppressOutput, "File " + file.getAbsolutePath() + " did not contain properly formatted JSON." );
            } else {
                printOutput( suppressOutput, "Failed to open file: " + file.getAbsolutePath() );
            }
            System.exit( 1 );
        }
        return objectMap;
    }

    /**
     * Prints the given string to standard out, or doesn't, based on the suppressOutput flag
     */
    private static void printOutput( boolean suppressOutput, String output ) {
        if ( !suppressOutput ) {
            System.out.println( output );
        }
    }
}
TOP

Related Classes of com.bazaarvoice.jolt.DiffyTool

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.