├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── README.txt ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── github │ │ └── vincentrussell │ │ └── json │ │ └── datagenerator │ │ ├── CLIMain.java │ │ ├── JsonDataGenerator.java │ │ ├── JsonDataGeneratorException.java │ │ ├── TokenResolver.java │ │ ├── functions │ │ ├── Function.java │ │ ├── FunctionInvocation.java │ │ ├── FunctionRegistry.java │ │ ├── impl │ │ │ ├── AbstractAddDates.java │ │ │ ├── AddDays.java │ │ │ ├── AddHours.java │ │ │ ├── AddMinutes.java │ │ │ ├── AddMonths.java │ │ │ ├── AddSeconds.java │ │ │ ├── AddWeeks.java │ │ │ ├── AddYears.java │ │ │ ├── Alpha.java │ │ │ ├── AlphaNumeric.java │ │ │ ├── Bool.java │ │ │ ├── City.java │ │ │ ├── Company.java │ │ │ ├── Concat.java │ │ │ ├── CountriesList.java │ │ │ ├── Country.java │ │ │ ├── Date.java │ │ │ ├── DateFormat.java │ │ │ ├── Email.java │ │ │ ├── FirstName.java │ │ │ ├── FunctionUtils.java │ │ │ ├── Gender.java │ │ │ ├── Get.java │ │ │ ├── Hex.java │ │ │ ├── Index.java │ │ │ ├── Ipv4.java │ │ │ ├── Ipv6.java │ │ │ ├── LastName.java │ │ │ ├── LoremIpsum.java │ │ │ ├── ObjectId.java │ │ │ ├── Phone.java │ │ │ ├── Put.java │ │ │ ├── Random.java │ │ │ ├── RandomDouble.java │ │ │ ├── RandomFloat.java │ │ │ ├── RandomInteger.java │ │ │ ├── RandomLong.java │ │ │ ├── Regexify.java │ │ │ ├── Repeat.java │ │ │ ├── ResetIndex.java │ │ │ ├── Ssn.java │ │ │ ├── State.java │ │ │ ├── Street.java │ │ │ ├── Substring.java │ │ │ ├── SystemProperty.java │ │ │ ├── Time.java │ │ │ ├── Timestamp.java │ │ │ ├── TimestampSeconds.java │ │ │ ├── ToLower.java │ │ │ ├── ToTimestamp.java │ │ │ ├── ToTimestampSeconds.java │ │ │ ├── ToUpper.java │ │ │ ├── UUID.java │ │ │ ├── Username.java │ │ │ └── package-info.java │ │ └── package-info.java │ │ ├── impl │ │ ├── ByteArrayBackupToFileOutputStream.java │ │ ├── FunctionReplacingReader.java │ │ ├── FunctionTokenResolver.java │ │ ├── IndexHolder.java │ │ ├── JsonDataGeneratorImpl.java │ │ ├── NonCloseableBufferedOutputStream.java │ │ ├── TimeoutInputStream.java │ │ └── package-info.java │ │ └── package-info.java └── jjtree │ └── FunctionParser.jjt └── test ├── java └── com │ └── github │ └── vincentrussell │ └── json │ └── datagenerator │ ├── CLIMainTest.java │ ├── JsonDataGeneratorTest.java │ ├── functions │ ├── FunctionRegistryTest.java │ └── impl │ │ └── DefaultFunctionsTest.java │ ├── impl │ ├── ByteArrayBackupToFileOutputStreamTest.java │ ├── FunctionTokenResolverTest.java │ └── NonCloseableBufferedOutputStreamTest.java │ └── parser │ └── FunctionJJTreeTest.java └── resources ├── approvals └── JsonDataGeneratorTest │ ├── copyDoubleNestedJson.json │ ├── copyJson.json │ ├── foreignCharacters.json │ ├── indexFunctionNested.forapproval.json │ ├── indexFunctionNested.json │ ├── indexFunctionSimple.forapproval.json │ ├── indexFunctionSimple.json │ ├── invalidFunction.json │ ├── multiThreadedTests.json │ ├── overflowWithActualCharacters │ ├── putGetTest.json │ ├── repeatNonFunctionJsonArray.json │ ├── resetIndex.json │ ├── zeroRepeat.json │ └── zeroRepeatRange.json ├── checkstyle ├── checkstyle_checks.xml └── checkstyle_suppressions.xml ├── clptr-excludes.properties ├── code-style └── eclipse-java-google-style.xml ├── copyDoubleNestedJson.json ├── copyJson.json ├── foreignCharacters.json ├── foreignCharactersWithinTokenResolver.json ├── indexFunctionNested.json ├── indexFunctionSimple.json ├── invalidFunction.json ├── large_repeats.json ├── loremipsum.txt ├── putGetTest.json ├── repeatFunctionInvalid.json ├── repeatFunctionJsonArrayNoQuotes.json ├── repeatFunctionJsonArrayQuotes.json ├── repeatFunctionRangeJsonArrayNoQuotes.json ├── repeatNonFunctionJsonArray.json ├── resetIndex.json ├── simple.json ├── xmlfunctionWithRepeat.xml ├── zeroRepeat.json └── zeroRepeatRange.json /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | target/ 3 | *.iml 4 | *~ 5 | dependency-reduced-pom.xml 6 | *.releaseBackup 7 | release.properties 8 | *.versionsBackup 9 | .classpath 10 | .project 11 | .settings/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - openjdk8 5 | 6 | install: mvn clean verify 7 | 8 | notifications: 9 | email: 10 | recipients: 11 | - vincent.russell@gmail.com 12 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | 2 | release process: 3 | 4 | mvn versions:set -DnewVersion=1.0 5 | git add . 6 | git commit -m "preparing for release 1.0" 7 | git tag json-data-generator-1.0 8 | mvn clean deploy -P release 9 | mvn versions:set -DnewVersion=1.1-SNAPSHOT 10 | git add . 11 | git commit -m "preparing for development version 1.1" 12 | -------------------------------------------------------------------------------- /src/main/java/com/github/vincentrussell/json/datagenerator/CLIMain.java: -------------------------------------------------------------------------------- 1 | package com.github.vincentrussell.json.datagenerator; 2 | 3 | import com.github.vincentrussell.json.datagenerator.functions.FunctionRegistry; 4 | import com.github.vincentrussell.json.datagenerator.impl.JsonDataGeneratorImpl; 5 | import com.github.vincentrussell.json.datagenerator.impl.NonCloseableBufferedOutputStream; 6 | import com.github.vincentrussell.json.datagenerator.impl.TimeoutInputStream; 7 | import org.apache.commons.cli.CommandLine; 8 | import org.apache.commons.cli.CommandLineParser; 9 | import org.apache.commons.cli.DefaultParser; 10 | import org.apache.commons.cli.HelpFormatter; 11 | import org.apache.commons.cli.Option; 12 | import org.apache.commons.cli.Options; 13 | import org.apache.commons.cli.ParseException; 14 | import org.apache.commons.io.IOUtils; 15 | 16 | import java.io.File; 17 | import java.io.FileInputStream; 18 | import java.io.FileNotFoundException; 19 | import java.io.FileOutputStream; 20 | import java.io.IOException; 21 | import java.io.InputStream; 22 | import java.io.OutputStream; 23 | import java.nio.charset.StandardCharsets; 24 | import java.util.Arrays; 25 | import java.util.Comparator; 26 | import java.util.List; 27 | import java.util.TimeZone; 28 | import java.util.concurrent.TimeUnit; 29 | 30 | /** 31 | * Main class for command line interface 32 | */ 33 | public final class CLIMain { 34 | 35 | private static TimeZone DEFAULT_TIMEZONE = TimeZone.getDefault(); 36 | 37 | public static final String ENTER_JSON_TEXT = "Enter input json:\n\n "; 38 | 39 | /** 40 | * default constructor 41 | */ 42 | private CLIMain() { 43 | 44 | } 45 | 46 | private static Options buildOptions() { 47 | Options options = new Options(); 48 | 49 | Option o = new Option("s", "sourceFile", true, 50 | "the source file."); 51 | o.setRequired(false); 52 | options.addOption(o); 53 | 54 | o = new Option("d", "destinationFile", true, 55 | "the destination file. Defaults to System.out"); 56 | o.setRequired(false); 57 | options.addOption(o); 58 | 59 | o = new Option("f", "functionClasses", true, 60 | "additional function classes that are on the classpath " 61 | + "and should be loaded"); 62 | o.setRequired(false); 63 | o.setArgs(Option.UNLIMITED_VALUES); 64 | options.addOption(o); 65 | 66 | 67 | o = new Option("i", "interactiveMode", false, 68 | "interactive mode"); 69 | o.setRequired(false); 70 | options.addOption(o); 71 | 72 | o = new Option("t", "timeZone", true, 73 | "default time zone to use when dealing with dates"); 74 | o.setRequired(false); 75 | options.addOption(o); 76 | 77 | o = new Option("p", "pipeMode", false, 78 | "pipe mode"); 79 | o.setRequired(false); 80 | options.addOption(o); 81 | 82 | 83 | return options; 84 | } 85 | 86 | /** 87 | * main method for command line interface 88 | * @param args arguments for command line interface 89 | * @throws IOException if there is an error reading from the input or writing to the output 90 | * @throws JsonDataGeneratorException if there is an error running the json data converter 91 | * @throws ParseException if the cli arguments cannot be parsed 92 | * @throws ClassNotFoundException if the addition classes passed in with -f cannot be found 93 | */ 94 | @SuppressWarnings("checkstyle:linelength") 95 | public static void main(final String[] args) throws IOException, 96 | JsonDataGeneratorException, ParseException, ClassNotFoundException { 97 | try { 98 | TimeZone.setDefault(DEFAULT_TIMEZONE); 99 | 100 | Options options = buildOptions(); 101 | 102 | 103 | CommandLineParser parser = new DefaultParser(); 104 | HelpFormatter help = new HelpFormatter(); 105 | help.setOptionComparator(new OptionComparator(Arrays.asList("s", "d", "f", "i", "t", "p"))); 106 | 107 | CommandLine cmd = null; 108 | try { 109 | cmd = parser.parse(options, args); 110 | 111 | String source = cmd.getOptionValue("s"); 112 | boolean interactiveMode = cmd.hasOption('i'); 113 | boolean pipeMode = cmd.hasOption('p'); 114 | String[] functionClasses = cmd.getOptionValues("f"); 115 | String timeZone = cmd.getOptionValue("t"); 116 | 117 | 118 | if (timeZone != null) { 119 | TimeZone.setDefault(TimeZone.getTimeZone(timeZone)); 120 | } 121 | 122 | 123 | FunctionRegistry functionRegistry = new FunctionRegistry(); 124 | if (functionClasses != null) { 125 | for (String functionClass : functionClasses) { 126 | functionRegistry.registerClass(Class.forName(functionClass)); 127 | } 128 | } 129 | 130 | if (interactiveMode) { 131 | System.out.println(ENTER_JSON_TEXT); 132 | try (InputStream inputStream = new TimeoutInputStream(System.in, 133 | 1, TimeUnit.SECONDS); 134 | OutputStream outputStream = new NonCloseableBufferedOutputStream( 135 | System.out)) { 136 | IOUtils.write("\n\n\n\n\n", outputStream, StandardCharsets.UTF_8); 137 | JsonDataGenerator jsonDataGenerator = new JsonDataGeneratorImpl(functionRegistry); 138 | jsonDataGenerator.generateTestDataJson(inputStream, outputStream); 139 | } 140 | System.exit(0); 141 | } else if (pipeMode) { 142 | JsonDataGenerator jsonDataGenerator = new JsonDataGeneratorImpl(functionRegistry); 143 | jsonDataGenerator.generateTestDataJson(System.in, System.out); 144 | System.exit(0); 145 | } 146 | 147 | String destination = cmd.getOptionValue("d"); 148 | 149 | if (source == null) { 150 | throw new ParseException("Missing required option: s or i"); 151 | } 152 | 153 | File sourceFile = new File(source); 154 | File destinationFile = destination != null ? new File(destination) : null; 155 | 156 | if (!sourceFile.exists()) { 157 | throw new FileNotFoundException(source + " cannot be found"); 158 | } 159 | 160 | if (destination != null && destinationFile.exists()) { 161 | throw new IOException(destination + " already exists"); 162 | } 163 | 164 | 165 | JsonDataGenerator jsonDataGenerator = new JsonDataGeneratorImpl(functionRegistry); 166 | try (InputStream inputStream = new FileInputStream(sourceFile); 167 | OutputStream outputStream = destinationFile != null 168 | ? new FileOutputStream(destinationFile) 169 | : new NonCloseableBufferedOutputStream(System.out)) { 170 | jsonDataGenerator.generateTestDataJson(inputStream, outputStream); 171 | } 172 | 173 | } catch (ParseException e) { 174 | System.err.println(e.getMessage()); 175 | help.printHelp(CLIMain.class.getName(), options, true); 176 | throw e; 177 | } 178 | } finally { 179 | TimeZone.setDefault(DEFAULT_TIMEZONE); 180 | } 181 | 182 | } 183 | 184 | 185 | /** 186 | * helper {@link Comparator} to wort arguments in help 187 | */ 188 | private static class OptionComparator implements Comparator