/**
* Copyright © 2010-2014 Nokia
*
* 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 org.jsonschema2pojo.cli;
import static org.apache.commons.lang3.StringUtils.*;
import java.io.File;
import java.io.FileFilter;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import org.jsonschema2pojo.AllFileFilter;
import org.jsonschema2pojo.AnnotationStyle;
import org.jsonschema2pojo.Annotator;
import org.jsonschema2pojo.GenerationConfig;
import org.jsonschema2pojo.InclusionLevel;
import org.jsonschema2pojo.NoopAnnotator;
import org.jsonschema2pojo.SourceSortOrder;
import org.jsonschema2pojo.SourceType;
import org.jsonschema2pojo.rules.RuleFactory;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
/**
* Describes and parses the command line arguments supported by the
* jsonschema2pojo CLI.
*/
public class Arguments implements GenerationConfig {
@Parameter(names = { "-h", "--help" }, description = "Print help information and exit")
private boolean showHelp = false;
@Parameter(names = { "-p", "--package" }, description = "A java package used for generated types")
private String targetPackage;
@Parameter(names = { "-t", "--target" }, description = "The target directory into which generated types will be written", required = true)
private File targetDirectory;
@Parameter(names = { "-s", "--source" }, description = "The source file(s) or directory(ies) from which JSON Schema will be read", required = true, converter = UrlConverter.class)
private List<URL> sourcePaths;
@Parameter(names = { "-b", "--generate-builders" }, description = "Generate builder-style methods as well as setters")
private boolean generateBuilderMethods = false;
@Parameter(names = { "-c", "--generate-constructors" }, description = "Generate constructors")
private boolean generateConstructors = false;
@Parameter(names = { "-r", "--constructors-required-only" }, description = "Generate constructors with only required fields")
private boolean constructorsRequiredPropertiesOnly = false;
@Parameter(names = { "-P", "--use-primitives" }, description = "Use primitives instead of wrapper types for bean properties")
private boolean usePrimitives = false;
@Parameter(names = { "-d", "--word-delimiters" }, description = "The characters that should be considered as word delimiters when creating Java Bean property names from JSON property names")
private String propertyWordDelimiters = "- _";
@Parameter(names = { "-l", "--long-integers" }, description = "Use long (or Long) instead of int (or Integer) when the JSON Schema type 'integer' is encountered")
private boolean useLongIntegers = false;
@Parameter(names = { "-bi", "--big-integers" }, description = "Use BigInteger instead of int (or Integer) when the JSON Schema type 'integer' is encountered. Note that this overrides -l/--long-integers")
private boolean useBigIntegers = false;
@Parameter(names = { "-f", "--float-numbers" }, description = "Use float (or Float) instead of double (or Double) when the JSON Schema type 'number' is encountered")
private boolean useFloatNumbers = false;
@Parameter(names = { "-i", "--big-decimals" }, description = "Use BigDecimal instead of double (or Double) when the JSON Schema type 'number' is encountered. Note that this overrides -f/--float-numbers")
private boolean useBigDecimals = false;
@Parameter(names = { "-E", "--omit-hashcode-and-equals" }, description = "Omit hashCode and equals methods in the generated Java types")
private boolean omitHashcodeAndEquals = false;
@Parameter(names = { "-S", "--omit-tostring" }, description = "Omit the toString method in the generated Java types")
private boolean omitToString = false;
@Parameter(names = { "-tse", "--tostring-excludes" }, description = "The fields that should be excluded from generated toString methods")
private String toStringExcludes = "";
@Parameter(names = { "-a", "--annotation-style" })
private AnnotationStyle annotationStyle = AnnotationStyle.JACKSON;
@Parameter(names = {"-il", "--inclusion-level"})
private InclusionLevel inclusionLevel = InclusionLevel.NON_NULL;
@Parameter(names = { "-A", "--custom-annotator" }, description = "The fully qualified class name of referring to a custom annotator class that implements org.jsonschema2pojo.Annotator " + "and will be used in addition to the --annotation-style. If you want to use a custom annotator alone, set --annotation-style to none", converter = ClassConverter.class)
private Class<? extends Annotator> customAnnotator = NoopAnnotator.class;
@Parameter(names = { "-F", "--custom-rule-factory" }, description = "The fully qualified class name of referring to a custom rule factory class that extends org.jsonschema2pojo.rules.RuleFactory " + "to create custom rules for code generation.", converter = ClassConverter.class)
private Class<? extends RuleFactory> customRuleFactory = RuleFactory.class;
@Parameter(names = { "-303", "--jsr303-annotations" }, description = "Add JSR-303/349 annotations to generated Java types.")
private boolean includeJsr303Annotations = false;
@Parameter(names = { "-305", "--jsr305-annotations" }, description = "Add JSR-305 annotations to generated Java types.")
private boolean includeJsr305Annotations = false;
@Parameter(names = { "-T", "--source-type" })
private SourceType sourceType = SourceType.JSONSCHEMA;
@Parameter(names = { "-R", "--remove-old-output" }, description = "Whether to empty the target directory before generation occurs, to clear out all source files that have been generated previously (indiscriminately deletes all files and folders).")
private boolean removeOldOutput = false;
@Parameter(names = { "-e", "--output-encoding" }, description = "The character encoding that should be used when writing the generated Java source files.")
private String outputEncoding = "UTF-8";
@Parameter(names = { "-j", "--joda-dates" }, description = "Whether to use org.joda.time.DateTime instead of java" + ".util.Date when adding date-time type fields to generated Java types.")
private boolean useJodaDates = false;
@Parameter(names = { "-jd", "--joda-local-dates" }, description = "Whether to use org.joda.time.LocalDate instead" + "of String when adding date type fields to generated Java types.")
private boolean useJodaLocalDates = false;
@Parameter(names = { "-jt", "--joda-local-times" }, description = "Whether to use org.joda.time.LocalTime instead" + "of String when adding time type fields to generated Java types.")
private boolean useJodaLocalTimes = false;
@Parameter(names = { "-dtt", "--datetime-class" }, description = "Specify datetime class")
private String dateTimeType;
@Parameter(names = { "-tt", "--time-class" }, description = "Specify time class")
private String timeType;
@Parameter(names = { "-dt", "--date-class" }, description = "Specify date class")
private String dateType;
@Parameter(names = { "-c3", "--commons-lang3" }, description = "Whether to use commons-lang 3.x imports instead of commons-lang 2.x imports when adding equals, hashCode and toString methods.")
private boolean useCommonsLang3 = false;
@Parameter(names = { "-pl", "--parcelable" }, description = "**EXPERIMENTAL** Whether to make the generated types 'parcelable' (for Android development).")
private boolean parcelable = false;
@Parameter(names = { "-sl", "--serializable" }, description = "Whether to make the generated types 'serializable'.")
private boolean serializable = false;
@Parameter(names = { "-N", "--null-collections" }, description = "Initialize Set and List fields to null instead of an empty collection.")
private boolean nullCollections = false;
@Parameter(names = { "-y", "--class-prefix" }, description = "Prefix for generated class.")
private String classNamePrefix = "";
@Parameter(names = { "-x", "--class-suffix" }, description = "Suffix for generated class.")
private String classNameSuffix = "";
@Parameter(names = { "-fe", "--file-extensions" }, description = "The extensions that should be considered as standard filename extensions when creating java class names.")
private String fileExtensions = "";
@Parameter(names = { "-D", "--enable-additional-properties" }, description = "Enable additional properties support on generated types, regardless of the input schema(s)")
private boolean isIncludeAdditionalProperties = false;
@Parameter(names = { "-da", "--disable-accessors" }, description = "Whether to omit getter/setter methods and create public fields instead.")
private boolean disableAccessors = false;
@Parameter(names = { "-tv", "--target-version" }, description = "The target version for generated source files.")
private String targetVersion = "1.6";
@Parameter(names = { "-ida", "--include-dynamic-accessors" }, description = "Include dynamic getter, setter, and builder support on generated types.")
private boolean includeDynamicAccessors = false;
@Parameter(names = { "-fd", "--format-dates" }, description = "Whether the fields of type `date` are formatted during serialization with a default pattern of `yyyy-MM-dd`")
private boolean formatDates = false;
@Parameter(names = { "-fdt", "--format-date-times" }, description = "Whether the fields of type `date-time` are formatted during serialization with a default pattern of `yyyy-MM-dd'T'HH:mm:ss.SSSZ` and timezone set to default value of `UTC`")
private boolean formatDateTimes = false;
@Parameter(names = { "-dp", "--date-pattern" }, description = "A custom pattern to use when formatting date fields during serialization")
private String customDatePattern;
@Parameter(names = { "-dtp", "--date-time-pattern" }, description = "A custom pattern to use when formatting date-time fields during serialization")
private String customDateTimePattern;
@Parameter(names = {"-rpd", "--ref-fragment-path-delimiters"}, description = "A string containing any characters that should act as path delimiters when resolving $ref fragments. By default, #, / and . are used in an attempt to support JSON Pointer and JSON Path.")
private String refFragmentPathDelimiters = "#/.";
@Parameter(names = { "-sso", "--source-sort-order" }, description = "The sort order to be applied to the source files. Available options are: OS, FILES_FIRST or SUBDIRS_FIRST")
private SourceSortOrder sourceSortOrder = SourceSortOrder.OS;
private static final int EXIT_OKAY = 0;
private static final int EXIT_ERROR = 1;
/**
* Parses command line arguments and populates this command line instance.
* <p>
* If the command line arguments include the "help" argument, or if the
* arguments have incorrect values or order, then usage information is
* printed to {@link System#out} and the program terminates.
*
* @param args
* the command line arguments
* @return an instance of the parsed arguments object
*/
public Arguments parse(String[] args) {
JCommander jCommander = new JCommander(this);
jCommander.setProgramName("jsonschema2pojo");
try {
jCommander.parse(args);
if (this.showHelp) {
jCommander.usage();
exit(EXIT_OKAY);
}
} catch (ParameterException e) {
System.err.println(e.getMessage());
jCommander.usage();
exit(EXIT_ERROR);
}
return this;
}
@Override
public Iterator<URL> getSource() {
return sourcePaths.iterator();
}
@Override
public File getTargetDirectory() {
return targetDirectory;
}
@Override
public String getTargetPackage() {
return targetPackage;
}
@Override
public boolean isGenerateBuilders() {
return generateBuilderMethods;
}
@Override
public boolean isUsePrimitives() {
return usePrimitives;
}
@Override
public char[] getPropertyWordDelimiters() {
return defaultString(propertyWordDelimiters).toCharArray();
}
@Override
public boolean isUseLongIntegers() {
return useLongIntegers;
}
@Override
public boolean isUseDoubleNumbers() {
return !useFloatNumbers;
}
@Override
public boolean isIncludeHashcodeAndEquals() {
return !omitHashcodeAndEquals;
}
@Override
public boolean isIncludeToString() {
return !omitToString;
}
@Override
public String[] getToStringExcludes() {
return defaultString(toStringExcludes).split(" ");
}
@Override
public AnnotationStyle getAnnotationStyle() {
return annotationStyle;
}
@Override
public InclusionLevel getInclusionLevel() {
return inclusionLevel;
}
@Override
public Class<? extends Annotator> getCustomAnnotator() {
return customAnnotator;
}
@Override
public Class<? extends RuleFactory> getCustomRuleFactory() {
return customRuleFactory;
}
@Override
public boolean isIncludeJsr303Annotations() {
return includeJsr303Annotations;
}
@Override
public boolean isIncludeJsr305Annotations() {
return includeJsr305Annotations;
}
@Override
public SourceType getSourceType() {
return sourceType;
}
@Override
public boolean isRemoveOldOutput() {
return removeOldOutput;
}
@Override
public String getOutputEncoding() {
return outputEncoding;
}
@Override
public boolean isUseJodaDates() {
return useJodaDates;
}
@Override
public boolean isUseJodaLocalDates() {
return useJodaLocalDates;
}
@Override
public boolean isUseJodaLocalTimes() {
return useJodaLocalTimes;
}
@Override
public boolean isUseCommonsLang3() {
return useCommonsLang3;
}
@Override
public boolean isParcelable() {
return parcelable;
}
@Override
public boolean isSerializable() {
return serializable;
}
protected void exit(int status) {
System.exit(status);
}
@Override
public FileFilter getFileFilter() {
return new AllFileFilter();
}
@Override
public boolean isInitializeCollections() {
return !nullCollections;
}
@Override
public String getClassNamePrefix() {
return classNamePrefix;
}
@Override
public String getClassNameSuffix() {
return classNameSuffix;
}
@Override
public String[] getFileExtensions() {
return defaultString(fileExtensions).split(" ");
}
@Override
public boolean isIncludeConstructors() {
return generateConstructors;
}
@Override
public boolean isConstructorsRequiredPropertiesOnly() {
return constructorsRequiredPropertiesOnly;
}
@Override
public boolean isIncludeAdditionalProperties() {
return isIncludeAdditionalProperties;
}
@Override
public boolean isIncludeAccessors() {
return !disableAccessors;
}
@Override
public String getTargetVersion() {
return targetVersion;
}
@Override
public boolean isIncludeDynamicAccessors() {
return includeDynamicAccessors;
}
@Override
public String getDateTimeType() {
return dateTimeType;
}
@Override
public String getDateType() {
return dateType;
}
@Override
public String getTimeType() {
return timeType;
}
@Override
public boolean isUseBigIntegers() {
return useBigIntegers;
}
@Override
public boolean isUseBigDecimals() {
return useBigDecimals;
}
@Override
public boolean isFormatDateTimes() {
return formatDateTimes;
}
@Override
public boolean isFormatDates() {
return formatDates;
}
@Override
public String getRefFragmentPathDelimiters() {
return refFragmentPathDelimiters;
}
@Override
public String getCustomDatePattern() {
return customDatePattern;
}
@Override
public String getCustomDateTimePattern() {
return customDateTimePattern;
}
@Override
public SourceSortOrder getSourceSortOrder() {
return sourceSortOrder;
}
}