/*
* 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.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.util;
import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import org.jooq.tools.JooqLogger;
/**
* A common base implementation for {@link Generator} objects
*
* @author Lukas Eder
*/
abstract class AbstractGenerator implements Generator {
private static final JooqLogger log = JooqLogger.getLogger(AbstractGenerator.class);
boolean generateDeprecated = true;
boolean generateRelations = true;
boolean generateInstanceFields = true;
boolean generateGeneratedAnnotation = true;
boolean useSchemaVersionProvider = false;
boolean useCatalogVersionProvider = false;
boolean generateRoutines = true;
boolean generateSequences = true;
boolean generateUDTs = true;
boolean generateTables = true;
boolean generateRecords = true;
boolean generatePojos = false;
boolean generatePojosEqualsAndHashCode = false;
boolean generatePojosToString = true;
boolean generateImmutablePojos = false;
boolean generateInterfaces = false;
boolean generateImmutableInterfaces = false;
boolean generateDaos = false;
boolean generateJPAAnnotations = false;
boolean generateValidationAnnotations = false;
boolean generateSpringAnnotations = false;
boolean generateQueues = true;
boolean generateLinks = true;
boolean generateGlobalObjectReferences = true;
boolean generateGlobalCatalogReferences = true;
boolean generateGlobalSchemaReferences = true;
boolean generateGlobalRoutineReferences = true;
boolean generateGlobalSequenceReferences = true;
boolean generateGlobalTableReferences = true;
boolean generateGlobalUDTReferences = true;
boolean generateGlobalQueueReferences = true;
boolean generateGlobalLinkReferences = true;
boolean generateFluentSetters = false;
boolean generateJavaBeansGettersAndSetters = false;
boolean generateVarargsSetters = true;
String generateFullyQualifiedTypes = "";
boolean generateJavaTimeTypes = false;
boolean generateTableValuedFunctions = false;
boolean generateEmptyCatalogs = false;
boolean generateEmptySchemas = false;
protected GeneratorStrategyWrapper strategy;
protected String targetEncoding = "UTF-8";
final Language language;
AbstractGenerator(Language language) {
this.language = language;
}
enum Language {
JAVA, SCALA, XML;
}
void logDatabaseParameters(Database db) {
String url = "";
try {
Connection connection = db.getConnection();
if (connection != null)
url = connection.getMetaData().getURL();
}
catch (SQLException ignore) {}
log.info("License parameters");
log.info("----------------------------------------------------------");
log.info(" Thank you for using jOOQ and jOOQ's code generator");
log.info("");
log.info("Database parameters");
log.info("----------------------------------------------------------");
log.info(" dialect", db.getDialect());
log.info(" URL", url);
log.info(" target dir", getTargetDirectory());
log.info(" target package", getTargetPackage());
log.info(" includes", Arrays.asList(db.getIncludes()));
log.info(" excludes", Arrays.asList(db.getExcludes()));
log.info(" includeExcludeColumns", db.getIncludeExcludeColumns());
log.info("----------------------------------------------------------");
}
void logGenerationRemarks(Database db) {
log.info("Generation remarks");
log.info("----------------------------------------------------------");
if (contains(db.getIncludes(), ',') && db.getIncluded().isEmpty())
log.info(" includes", "The <includes/> element takes a Java regular expression, not a comma-separated list. This might be why no objects were included.");
if (contains(db.getExcludes(), ',') && db.getExcluded().isEmpty())
log.info(" excludes", "The <excludes/> element takes a Java regular expression, not a comma-separated list. This might be why no objects were excluded.");
}
private boolean contains(String[] array, char c) {
if (array == null)
return false;
for (String string : array)
if (string != null && string.indexOf(c) > -1)
return true;
return false;
}
@Override
public void setStrategy(GeneratorStrategy strategy) {
this.strategy = new GeneratorStrategyWrapper(this, strategy, language);
}
@Override
public GeneratorStrategy getStrategy() {
return strategy;
}
@Override
public boolean generateDeprecated() {
return generateDeprecated;
}
@Override
public void setGenerateDeprecated(boolean generateDeprecated) {
this.generateDeprecated = generateDeprecated;
}
@Override
public boolean generateRelations() {
// [#2294] When DAOs are generated, relations must be generated, too
return generateRelations || generateTables || generateDaos;
}
@Override
public void setGenerateRelations(boolean generateRelations) {
this.generateRelations = generateRelations;
}
@Override
public boolean generateTableValuedFunctions() {
return generateTableValuedFunctions;
}
@Override
public void setGenerateTableValuedFunctions(boolean generateTableValuedFunctions) {
this.generateTableValuedFunctions = generateTableValuedFunctions;
}
@Override
public boolean generateInstanceFields() {
return generateInstanceFields;
}
@Override
public void setGenerateInstanceFields(boolean generateInstanceFields) {
this.generateInstanceFields = generateInstanceFields;
}
@Override
public boolean generateGeneratedAnnotation() {
// [#3121] [#4827] The schema and catalog versions are generated into
// @Generated annotations
return generateGeneratedAnnotation || useSchemaVersionProvider || useCatalogVersionProvider;
}
@Override
public void setGenerateGeneratedAnnotation(boolean generateGeneratedAnnotation) {
this.generateGeneratedAnnotation = generateGeneratedAnnotation;
}
@Override
public boolean useSchemaVersionProvider() {
return useSchemaVersionProvider;
}
@Override
public void setUseSchemaVersionProvider(boolean useSchemaVersionProvider) {
this.useSchemaVersionProvider = useSchemaVersionProvider;
}
@Override
public boolean useCatalogVersionProvider() {
return useCatalogVersionProvider;
}
@Override
public void setUseCatalogVersionProvider(boolean useCatalogVersionProvider) {
this.useCatalogVersionProvider = useCatalogVersionProvider;
}
@Override
public boolean generateRoutines() {
return generateRoutines;
}
@Override
public void setGenerateRoutines(boolean generateRoutines) {
this.generateRoutines = generateRoutines;
}
@Override
public boolean generateSequences() {
return generateSequences;
}
@Override
public void setGenerateSequences(boolean generateSequences) {
this.generateSequences = generateSequences;
}
@Override
public boolean generateUDTs() {
return generateUDTs;
}
@Override
public void setGenerateUDTs(boolean generateUDTs) {
this.generateUDTs = generateUDTs;
}
@Override
public boolean generateTables() {
// [#5525] When DAOs or records are generated, tables must be generated, too
return generateTables || generateRecords || generateDaos;
}
@Override
public void setGenerateTables(boolean generateTables) {
this.generateTables = generateTables;
}
@Override
public boolean generateRecords() {
// [#1280] When DAOs are generated, Records must be generated, too
return generateRecords || generateDaos;
}
@Override
public void setGenerateRecords(boolean generateRecords) {
this.generateRecords = generateRecords;
}
@Override
public boolean generatePojos() {
// [#1339] When immutable POJOs are generated, POJOs must be generated
// [#1280] When DAOs are generated, POJOs must be generated, too
return generatePojos || generateImmutablePojos || generateDaos;
}
@Override
public void setGeneratePojos(boolean generatePojos) {
this.generatePojos = generatePojos;
}
@Override
public boolean generateImmutablePojos() {
return generateImmutablePojos;
}
@Override
public void setGenerateImmutablePojos(boolean generateImmutablePojos) {
this.generateImmutablePojos = generateImmutablePojos;
}
@Override
public boolean generateInterfaces() {
return generateInterfaces || generateImmutableInterfaces;
}
@Override
public void setGenerateInterfaces(boolean generateInterfaces) {
this.generateInterfaces = generateInterfaces;
}
@Override
public boolean generateImmutableInterfaces() {
return generateImmutableInterfaces || (generateInterfaces && generateImmutablePojos);
}
@Override
public void setGenerateImmutableInterfaces(boolean generateImmutableInterfaces) {
this.generateImmutableInterfaces = generateImmutableInterfaces;
}
@Override
public boolean generateDaos() {
return generateDaos;
}
@Override
public void setGenerateDaos(boolean generateDaos) {
this.generateDaos = generateDaos;
}
@Override
public boolean generateJPAAnnotations() {
return generateJPAAnnotations;
}
@Override
public void setGenerateJPAAnnotations(boolean generateJPAAnnotations) {
this.generateJPAAnnotations = generateJPAAnnotations;
}
@Override
public boolean generateValidationAnnotations() {
return generateValidationAnnotations;
}
@Override
public void setGenerateValidationAnnotations(boolean generateValidationAnnotations) {
this.generateValidationAnnotations = generateValidationAnnotations;
}
@Override
public boolean generateSpringAnnotations() {
return generateSpringAnnotations;
}
@Override
public void setGenerateSpringAnnotations(boolean generateSpringAnnotations) {
this.generateSpringAnnotations = generateSpringAnnotations;
}
@Override
public boolean generateGlobalObjectReferences() {
return generateGlobalObjectReferences;
}
@Override
public void setGenerateGlobalObjectReferences(boolean generateGlobalObjectReferences) {
this.generateGlobalObjectReferences = generateGlobalObjectReferences;
}
@Override
public boolean generateGlobalCatalogReferences() {
return generateGlobalObjectReferences() && generateGlobalCatalogReferences;
}
@Override
public void setGenerateGlobalCatalogReferences(boolean globalCatalogReferences) {
this.generateGlobalCatalogReferences = globalCatalogReferences;
}
@Override
public boolean generateGlobalSchemaReferences() {
return generateGlobalObjectReferences() && generateGlobalSchemaReferences;
}
@Override
public void setGenerateGlobalSchemaReferences(boolean globalSchemaReferences) {
this.generateGlobalSchemaReferences = globalSchemaReferences;
}
@Override
public boolean generateGlobalRoutineReferences() {
return generateRoutines() && generateGlobalObjectReferences() && generateGlobalRoutineReferences;
}
@Override
public void setGenerateGlobalRoutineReferences(boolean generateGlobalRoutineReferences) {
this.generateGlobalRoutineReferences = generateGlobalRoutineReferences;
}
@Override
public boolean generateGlobalSequenceReferences() {
return generateSequences() && generateGlobalObjectReferences() && generateGlobalSequenceReferences;
}
@Override
public void setGenerateGlobalSequenceReferences(boolean generateGlobalSequenceReferences) {
this.generateGlobalSequenceReferences = generateGlobalSequenceReferences;
}
@Override
public boolean generateGlobalTableReferences() {
return generateTables() && generateGlobalObjectReferences() && generateGlobalTableReferences;
}
@Override
public void setGenerateGlobalTableReferences(boolean generateGlobalTableReferences) {
this.generateGlobalTableReferences = generateGlobalTableReferences;
}
@Override
public boolean generateGlobalUDTReferences() {
return generateUDTs() && generateGlobalObjectReferences() && generateGlobalUDTReferences;
}
@Override
public void setGenerateGlobalUDTReferences(boolean generateGlobalUDTReferences) {
this.generateGlobalUDTReferences = generateGlobalUDTReferences;
}
@Override
public boolean generateGlobalQueueReferences() {
return generateQueues() && generateGlobalObjectReferences() && generateGlobalQueueReferences;
}
@Override
public void setGenerateGlobalQueueReferences(boolean globalQueueReferences) {
this.generateGlobalQueueReferences = globalQueueReferences;
}
@Override
public boolean generateGlobalLinkReferences() {
return generateLinks() && generateGlobalObjectReferences() && generateGlobalLinkReferences;
}
@Override
public void setGenerateGlobalLinkReferences(boolean globalLinkReferences) {
this.generateGlobalLinkReferences = globalLinkReferences;
}
@Override
public boolean generateQueues() {
return generateQueues;
}
@Override
public void setGenerateQueues(boolean queues) {
this.generateQueues = queues;
}
@Override
public boolean generateLinks() {
return generateLinks;
}
@Override
public void setGenerateLinks(boolean links) {
this.generateLinks = links;
}
@Override
@Deprecated
public boolean fluentSetters() {
return generateFluentSetters();
}
@Override
@Deprecated
public void setFluentSetters(boolean fluentSetters) {
setGenerateFluentSetters(fluentSetters);
}
@Override
public boolean generateFluentSetters() {
return generateFluentSetters;
}
@Override
public void setGenerateFluentSetters(boolean fluentSetters) {
this.generateFluentSetters = fluentSetters;
}
@Override
public boolean generateJavaBeansGettersAndSetters() {
return generateJavaBeansGettersAndSetters;
}
@Override
public void setGenerateJavaBeansGettersAndSetters(boolean javaBeansGettersAndSetters) {
this.generateJavaBeansGettersAndSetters = javaBeansGettersAndSetters;
}
@Override
public boolean generateVarargsSetters() {
return generateVarargsSetters;
}
@Override
public void setGenerateVarargsSetters(boolean varargsSetters) {
this.generateVarargsSetters = varargsSetters;
}
@Override
public boolean generatePojosEqualsAndHashCode() {
return generatePojosEqualsAndHashCode;
}
@Override
public void setGeneratePojosEqualsAndHashCode(boolean generatePojosEqualsAndHashCode) {
this.generatePojosEqualsAndHashCode = generatePojosEqualsAndHashCode;
}
@Override
public boolean generatePojosToString() {
return generatePojosToString;
}
@Override
public void setGeneratePojosToString(boolean generatePojosToString) {
this.generatePojosToString = generatePojosToString;
}
@Override
@Deprecated
public String fullyQualifiedTypes() {
return generateFullyQualifiedTypes();
}
@Override
@Deprecated
public void setFullyQualifiedTypes(String fullyQualifiedTypes) {
setGenerateFullyQualifiedTypes(fullyQualifiedTypes);
}
@Override
public String generateFullyQualifiedTypes() {
return generateFullyQualifiedTypes;
}
@Override
public void setGenerateFullyQualifiedTypes(String generateFullyQualifiedTypes) {
this.generateFullyQualifiedTypes = generateFullyQualifiedTypes;
}
@Override
public boolean generateJavaTimeTypes() {
return generateJavaTimeTypes;
}
@Override
public void setGenerateJavaTimeTypes(boolean generateJavaTimeTypes) {
this.generateJavaTimeTypes = generateJavaTimeTypes;
}
@Override
public boolean generateEmptyCatalogs() {
return generateEmptyCatalogs;
}
@Override
public void setGenerateEmptyCatalogs(boolean generateEmptyCatalogs) {
this.generateEmptyCatalogs = generateEmptyCatalogs;
}
@Override
public boolean generateEmptySchemas() {
return generateEmptySchemas;
}
@Override
public void setGenerateEmptySchemas(boolean generateEmptySchemas) {
this.generateEmptySchemas = generateEmptySchemas;
}
// ----
@Override
public void setTargetDirectory(String directory) {
strategy.setTargetDirectory(directory);
}
@Override
public String getTargetDirectory() {
return strategy.getTargetDirectory();
}
@Override
public void setTargetPackage(String packageName) {
strategy.setTargetPackage(packageName);
}
@Override
public String getTargetPackage() {
return strategy.getTargetPackage();
}
@Override
public String getTargetEncoding() {
return targetEncoding;
}
@Override
public void setTargetEncoding(String encoding) {
this.targetEncoding = encoding;
}
/**
* If file is a directory, recursively empty its children.
* If file is a file, delete it.
*/
protected void empty(File file, String suffix) {
empty(file, suffix, Collections.<File>emptySet(), Collections.<File>emptySet());
}
/**
* If file is a directory, recursively empty its children.
* If file is a file, delete it, except if it is in the list of files to keep.
*/
protected void empty(File file, String suffix, Set<File> keep, Set<File> ignore) {
if (file != null) {
// Just a Murphy's Law safeguard in case a user misconfigures their config...
if (file.getParentFile() == null) {
log.warn("WARNING: Root directory configured for code generation. Not deleting anything from previous generations!");
return;
}
// [#5614] Don't go into these directories
for (File i : ignore)
if (file.getAbsolutePath().startsWith(i.getAbsolutePath()))
return;
if (file.isDirectory()) {
File[] children = file.listFiles();
if (children != null)
for (File child : children)
empty(child, suffix, keep, ignore);
File[] childrenAfterDeletion = file.listFiles();
// [#5556] Delete directory if empty after content was removed.
// Useful if a catalog / schema was dropped, or removed from code generation, or renamed
if (childrenAfterDeletion != null && childrenAfterDeletion.length == 0)
file.delete();
}
else if (file.getName().endsWith(suffix) && !keep.contains(file)) {
file.delete();
}
}
}
}