All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jsonschema2pojo.ant.Jsonschema2PojoTask Maven / Gradle / Ivy

There is a newer version: 0.4.23-fork.3
Show newest version
/**
 * 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.ant;

import static org.apache.commons.lang3.StringUtils.*;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
import org.jsonschema2pojo.AllFileFilter;
import org.jsonschema2pojo.AnnotationStyle;
import org.jsonschema2pojo.Annotator;
import org.jsonschema2pojo.GenerationConfig;
import org.jsonschema2pojo.Jsonschema2Pojo;
import org.jsonschema2pojo.NoopAnnotator;
import org.jsonschema2pojo.SourceType;
import org.jsonschema2pojo.URLProtocol;
import org.jsonschema2pojo.rules.RuleFactory;
import org.jsonschema2pojo.util.URLUtil;

/**
 * When invoked, this task reads one or more
 * JSON Schema documents and generates DTO
 * style Java classes for data binding.
 * 

* See jsonschema2pojo.googlecode.com. * * @see Writing Your Own * Task */ public class Jsonschema2PojoTask extends Task implements GenerationConfig { private boolean generateBuilders; private boolean includeConstructors = false; private boolean usePrimitives; private String source; private File targetDirectory; private String targetPackage; private boolean skip; private char[] propertyWordDelimiters = new char[] { '-', ' ', '_' }; private boolean useLongIntegers; private boolean useDoubleNumbers = true; private boolean useBigDecimals = false; private boolean includeHashcodeAndEquals = true; private boolean includeToString = true; private AnnotationStyle annotationStyle = AnnotationStyle.JACKSON; private Class customAnnotator = NoopAnnotator.class; private Class customRuleFactory = RuleFactory.class; private boolean includeJsr303Annotations = false; private SourceType sourceType = SourceType.JSONSCHEMA; private Path classpath; private boolean removeOldOutput = false; private String outputEncoding = "UTF-8"; private boolean useJodaDates = false; private boolean useJodaLocalDates = false; private boolean useJodaLocalTimes = false; private boolean useCommonsLang3 = false; private boolean parcelable = false; private boolean serializable = false; private boolean initializeCollections = true; private String classNamePrefix = ""; private String classNameSuffix = ""; private String[] fileExtensions = new String[] {}; private boolean constructorsRequiredPropertiesOnly = false; private boolean includeAdditionalProperties = true; private boolean includeAccessors = true; private String targetVersion = "1.6"; private boolean includeDynamicAccessors = false; private String dateTimeType = null; private String timeType = null; private String dateType = null; /** * Execute this task (it's expected that all relevant setters will have been * called by Ant to provide task configuration before this method * is called). * * @throws BuildException * if this task cannot be completed due to some error reading * schemas, generating types or writing output .java files. */ @Override public void execute() throws BuildException { if (skip) { return; } if (source == null) { log("source attribute is required but was not set"); return; } // attempt to parse the url URL sourceURL; try { sourceURL = URLUtil.parseURL(source); } catch (IllegalArgumentException e) { log(String.format("Invalid schema source provided: %s", source)); return; } // if url is a file, ensure it exists if (URLUtil.parseProtocol(sourceURL.toString()) == URLProtocol.FILE) { File sourceFile = new File(sourceURL.getFile()); if (!sourceFile.exists()) { log(sourceFile.getAbsolutePath() + " cannot be found"); return; } } if (targetDirectory == null) { log("targetDirectory attribute is required but was not set"); return; } ClassLoader extendedClassloader = buildExtendedClassloader(); Thread.currentThread().setContextClassLoader(extendedClassloader); try { Jsonschema2Pojo.generate(this); } catch (IOException e) { throw new BuildException("Error generating classes from JSON Schema file(s) " + source, e); } } /** * Build a classloader using the additional elements specified in * classpath and classpathRef. * * @return a new classloader that includes the extra path elements found in * the classpath and classpathRef config * values */ private ClassLoader buildExtendedClassloader() { final List classpathUrls = new ArrayList(); for (String pathElement : getClasspath().list()) { try { classpathUrls.add(new File(pathElement).toURI().toURL()); } catch (MalformedURLException e) { throw new BuildException("Unable to use classpath entry as it could not be understood as a valid URL: " + pathElement, e); } } final ClassLoader parentClassloader = Thread.currentThread().getContextClassLoader(); return AccessController.doPrivileged(new PrivilegedAction() { @Override public ClassLoader run() { return new URLClassLoader(classpathUrls.toArray(new URL[classpathUrls.size()]), parentClassloader); } }); } /** * Sets the 'includeConstructors' property of this class * * @param includeConstructors * Whether to generate constructors or not. */ public void setIncludeConstructors(boolean includeConstructors) { this.includeConstructors = includeConstructors; } /** * Sets the 'constructorsRequiredPropertiesOnly' property of this class. * * @param constructorsRequiredPropertiesOnly * Whether generated constructors should have parameters for all * properties, or only required ones. */ public void setConstructorsRequiredPropertiesOnly(boolean constructorsRequiredPropertiesOnly) { this.constructorsRequiredPropertiesOnly = constructorsRequiredPropertiesOnly; } /** * Sets the 'generateBuilders' property of this class. * * @param generateBuilders * Whether to generate builder-style methods of the form * withXxx(value) (that return this), * alongside the standard, void-return setters. *

* Default: false. */ public void setGenerateBuilders(boolean generateBuilders) { this.generateBuilders = generateBuilders; } /** * Sets the 'usePrimitives' property of this class. * * @param usePrimitives * Whether to use primitives (long, * double , boolean) instead of wrapper * types where possible when generating bean properties (has the * side-effect of making those properties non-null). *

* Default: false. */ public void setUsePrimitives(boolean usePrimitives) { this.usePrimitives = usePrimitives; } /** * Sets the 'useLongIntegers' property of this class * * @param useLongIntegers * Whether to use the java type long (or * {@link java.lang.Long}) instead of int (or * {@link java.lang.Integer}) when representing the JSON Schema * type 'integer'. */ public void setUseLongIntegers(boolean useLongIntegers) { this.useLongIntegers = useLongIntegers; } /** * Sets the 'useDoubleNumbers' property of this class * * @param useDoubleNumbers * Whether to use the java type double (or * {@link java.lang.Double}) instead of float (or * {@link java.lang.Float}) when representing the JSON Schema * type 'number'. */ public void setUseDoubleNumbers(boolean useDoubleNumbers) { this.useDoubleNumbers = useDoubleNumbers; } /** * Sets the 'useBigDecimals' property of this class * * @param useBigDecimals * Whether to use the java type BigDecimal * instead of float (or {@link java.lang.Float}) * when representing the JSON Schema type 'number'. Note that * this overrides useDoubleNumbers. */ public void setUseBigDecimals(boolean useBigDecimals) { this.useBigDecimals = useBigDecimals; } /** * Sets schema file (or directory containing schema files) that should be * used for input. * * @param source * Location of the JSON Schema file(s). Note: this may refer to a * single file or a directory of files. */ public void setSource(String source) { this.source = source; } /** * Sets the target (output) directory for generated source files. * * @param targetDirectory * Target directory for generated Java source files. */ public void setTargetDirectory(File targetDirectory) { this.targetDirectory = targetDirectory; } /** * Sets the target package for generated types. * * @param targetPackage * Package name used for generated Java classes (for types where * a fully qualified name has not been supplied in the schema * using the 'javaType' property). */ public void setTargetPackage(String targetPackage) { this.targetPackage = targetPackage; } /** * Sets the 'skip' property of this task. * * @param skip * whether to skip execution of this task */ public void setSkip(boolean skip) { this.skip = skip; } /** * @param propertyWordDelimiters * a string containing all of the characters that should be * considered as word delimiters when creating Java Bean property * names from JSON property names. If blank or not set, JSON * properties will be considered to contain a single word when * creating Java Bean property names. */ public void setPropertyWordDelimiters(String propertyWordDelimiters) { this.propertyWordDelimiters = defaultString(propertyWordDelimiters).toCharArray(); } /** * Sets the 'includeHashcodeAndEquals' property of this class * * @param includeHashcodeAndEquals * Whether to include hashCode and * equals methods in generated Java types. */ public void setIncludeHashcodeAndEquals(boolean includeHashcodeAndEquals) { this.includeHashcodeAndEquals = includeHashcodeAndEquals; } /** * Sets the 'includeToString' property of this class * * @param includeToString * Whether to include a toString method in generated * Java types. */ public void setIncludeToString(boolean includeToString) { this.includeToString = includeToString; } /** * Sets the 'annotationStyle' property of this class * * @param annotationStyle * The style of annotations to use in the generated Java types. */ public void setAnnotationStyle(AnnotationStyle annotationStyle) { this.annotationStyle = annotationStyle; } /** * Sets the 'customAnnotator' property of this class * * @param customAnnotator * A custom annotator to use to annotate the generated types */ @SuppressWarnings("unchecked") public void setCustomAnnotator(String customAnnotator) { if (isNotBlank(customAnnotator)) { try { this.customAnnotator = (Class) Class.forName(customAnnotator); } catch (ClassNotFoundException e) { throw new IllegalArgumentException(e); } } else { this.customAnnotator = NoopAnnotator.class; } } @SuppressWarnings("unchecked") public void setCustomRuleFactory(String customRuleFactory) { if (isNotBlank(customRuleFactory)) { try { this.customRuleFactory = (Class) Class.forName(customRuleFactory); } catch (ClassNotFoundException e) { throw new IllegalArgumentException(e); } } else { this.customRuleFactory = RuleFactory.class; } } /** * Sets the 'includeJsr303Annotations' property of this class * * @param includeJsr303Annotations * Whether to include * JSR-303 * annotations (for schema rules like minimum, maximum, etc) in * generated Java types. */ public void setIncludeJsr303Annotations(boolean includeJsr303Annotations) { this.includeJsr303Annotations = includeJsr303Annotations; } /** * Sets the 'sourceType' property of this class * * @param sourceType * The type of input documents that will be read *

* Supported values: *

    *
  • jsonschema
  • *
  • json
  • *
*/ public void setSourceType(SourceType sourceType) { this.sourceType = sourceType; } /** * Sets the 'removeOldOutput' property of this class * * @param removeOldOutput * Whether to empty the target directory before generation * occurs, to clear out all source files that have been generated * previously. Be warned, when activated this * option will cause jsonschema2pojo to indiscriminately * delete the entire contents of the target directory (all files * and folders) before it begins generating sources. */ public void setRemoveOldOutput(boolean removeOldOutput) { this.removeOldOutput = removeOldOutput; } /** * Sets the 'outputEncoding' property of this class * * @param outputEncoding * The character encoding that should be used when writing the * generated Java source files */ public void setOutputEncoding(String outputEncoding) { this.outputEncoding = outputEncoding; } /** * Sets the 'useJodaDates' property of this class * * @param useJodaDates * Whether to use {@link org.joda.time.DateTime} instead of * {@link java.util.Date} when adding date type fields to * generated Java types. */ public void setUseJodaDates(boolean useJodaDates) { this.useJodaDates = useJodaDates; } /** * Sets the 'useJodaLocalDates' property of this class * * @param useJodaLocalDates * Whether to use {@link org.joda.time.LocalDate} instead of * string when adding string fields of format date (not * date-time) to generated Java types. */ public void setUseJodaLocalDates(boolean useJodaLocalDates) { this.useJodaLocalDates = useJodaLocalDates; } /** * Sets the 'useJodaLocalTimes' property of this class * * @param useJodaLocalTimes * Whether to use {@link org.joda.time.LocalTime} instead of * string when adding string fields of format time (not * date-time) to generated Java types. */ public void setUseJodaLocalTimes(boolean useJodaLocalTimes) { this.useJodaLocalTimes = useJodaLocalTimes; } /** * Sets the 'useCommonsLang3' property of this class * * @param useCommonsLang3 * Whether to use commons-lang 3.x imports instead of * commons-lang 2.x imports when adding equals, hashCode and * toString methods. */ public void setUseCommonsLang3(boolean useCommonsLang3) { this.useCommonsLang3 = useCommonsLang3; } /** * Sets the 'parcelable' property of this class * * @param parcelable * Whether to make the generated types 'parcelable' (for Android * development). */ public void setParcelable(boolean parcelable) { this.parcelable = parcelable; } /** * Sets the 'serializable' property of this class * * @param serializable * Whether to make the generated types 'serializable'. */ public void setSerializable(boolean serializable) { this.serializable = serializable; } /** * Sets the 'initializeCollections' property of this class * * @param initializeCollections * Whether to initialize collections with empty instance or null. */ public void setInitializeCollections(boolean initializeCollections) { this.initializeCollections = initializeCollections; } /** * Sets the 'classNamePrefix' property of this class * * @param classNamePrefix * Whether to add a prefix to generated classes. */ public void setClassNamePrefix(String classNamePrefix) { this.classNamePrefix = classNamePrefix; } /** * Sets the 'classNameSuffix' property of this class * * @param classNameSuffix * Whether to add a suffix to generated classes. */ public void setClassNameSuffix(String classNameSuffix) { this.classNameSuffix = classNameSuffix; } /** * Sets the 'fileExtensions' property of this class * * @param classNameSuffix * The array of strings that should be considered as file * extensions and therefore not included in class names. */ public void setFileExtensions(String[] fileExtensions) { this.fileExtensions = fileExtensions; } /** * Sets the 'includeAdditionalProperties' property of this class * * @param includeAdditionalProperties * Whether to allow 'additional properties' support in objects. * Setting this to false will disable additional properties * support, regardless of the input schema(s). */ public void setIncludeAdditionalProperties(boolean includeAdditionalProperties) { this.includeAdditionalProperties = includeAdditionalProperties; } /** * Sets the 'includeAccessors' property of this class * * @param includeAccessors * Whether to include getters/setters or to omit these accessor * methods and create public fields instead. */ public void setIncludeAccessors(boolean includeAccessors) { this.includeAccessors = includeAccessors; } /** * Sets the 'targetVersion' property of this class * * @param targetVersion * The target version for generated source files. *

* Default: 1.6. */ public void setTargetVersion(String targetVersion) { this.targetVersion = targetVersion; } /** * Sets the 'includeDynamicAccessors' property of this class * * @param includeDynamicAccessors * Whether to include dynamic getters, setters, and builders or to omit these methods. */ public void setIncludeDynamicAccessors(boolean includeDynamicAccessors) { this.includeDynamicAccessors = includeDynamicAccessors; } @Override public boolean isGenerateBuilders() { return generateBuilders; } @Override public boolean isUsePrimitives() { return usePrimitives; } @Override public Iterator getSource() { return Collections.singleton(URLUtil.parseURL(source)).iterator(); } @Override public File getTargetDirectory() { return targetDirectory; } @Override public String getTargetPackage() { return targetPackage; } @Override public char[] getPropertyWordDelimiters() { return propertyWordDelimiters.clone(); } /** * Should this task be skipped? (don't read schemas, don't generate types) * * @return true if this task is disabled */ public boolean isSkip() { return skip; } @Override public boolean isUseLongIntegers() { return useLongIntegers; } @Override public boolean isUseDoubleNumbers() { return useDoubleNumbers; } @Override public boolean isIncludeHashcodeAndEquals() { return includeHashcodeAndEquals; } @Override public boolean isIncludeToString() { return includeToString; } @Override public AnnotationStyle getAnnotationStyle() { return annotationStyle; } @Override public Class getCustomAnnotator() { return customAnnotator; } @Override public Class getCustomRuleFactory() { return customRuleFactory; } @Override public boolean isIncludeJsr303Annotations() { return includeJsr303Annotations; } @Override public SourceType getSourceType() { return sourceType; } public Path createClasspath() { if (classpath == null) { classpath = new Path(getProject()); } return classpath.createPath(); } public void setClasspath(Path classpath) { if (this.classpath == null) { this.classpath = classpath; } else { this.classpath.append(classpath); } } public void setClasspathRef(Reference classpathRef) { createClasspath().setRefid(classpathRef); } public Path getClasspath() { return (classpath == null) ? new Path(getProject()) : classpath; } @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; } @Override public FileFilter getFileFilter() { return new AllFileFilter(); } @Override public boolean isInitializeCollections() { return initializeCollections; } @Override public String getClassNamePrefix() { return classNamePrefix; } @Override public String getClassNameSuffix() { return classNameSuffix; } @Override public String[] getFileExtensions() { return fileExtensions; } @Override public boolean isIncludeConstructors() { return includeConstructors; } @Override public boolean isConstructorsRequiredPropertiesOnly() { return constructorsRequiredPropertiesOnly; } @Override public boolean isIncludeAdditionalProperties() { return includeAdditionalProperties; } @Override public boolean isIncludeAccessors() { return includeAccessors; } @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 isUseBigDecimals() { return useBigDecimals; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy