From e58593e69040a25373bb8e01d8632eb4e30bfb20 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Fri, 21 Aug 2020 14:32:35 +0200 Subject: [PATCH] [jOOQ/jOOQ#9744] Add to code generator specification --- .../org/jooq/codegen/AbstractGenerator.java | 11 ++++++ .../codegen/DefaultGeneratorStrategy.java | 36 ++++++++++++------ .../java/org/jooq/codegen/GenerationTool.java | 17 ++++++++- .../main/java/org/jooq/codegen/Generator.java | 11 ++++++ .../org/jooq/codegen/GeneratorStrategy.java | 11 ++++++ .../codegen/GeneratorStrategyWrapper.java | 11 ++++++ .../java/org/jooq/codegen/JavaGenerator.java | 6 +-- .../org/jooq/codegen/MatcherStrategy.java | 4 +- .../main/java/org/jooq/meta/jaxb/Target.java | 38 +++++++++++++++++++ .../resources/xsd/jooq-codegen-3.14.0.xsd | 4 ++ .../main/java/org/jooq/tools/StringUtils.java | 2 +- 11 files changed, 131 insertions(+), 20 deletions(-) diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/AbstractGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/AbstractGenerator.java index 0fde640ef7..afc95706ac 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/AbstractGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/AbstractGenerator.java @@ -44,6 +44,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.Arrays; import java.util.Collections; +import java.util.Locale; import java.util.Set; import org.jooq.meta.Database; @@ -1141,6 +1142,16 @@ abstract class AbstractGenerator implements Generator { this.targetEncoding = encoding; } + @Override + public Locale getTargetLocale() { + return strategy.getTargetLocale(); + } + + @Override + public void setTargetLocale(Locale targetLocale) { + strategy.setTargetLocale(targetLocale); + } + @Override public boolean getTargetClean() { return targetClean; diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/DefaultGeneratorStrategy.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/DefaultGeneratorStrategy.java index f87a05dc74..17c2b03e8e 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/DefaultGeneratorStrategy.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/DefaultGeneratorStrategy.java @@ -51,6 +51,7 @@ import static org.jooq.SQLDialect.POSTGRES; import java.util.ArrayList; import java.util.List; +import java.util.Locale; // ... import org.jooq.meta.ArrayDefinition; @@ -80,6 +81,7 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy { private String targetDirectory; private String targetPackage; + private Locale targetLocale = Locale.getDefault(); private boolean instanceFields = true; private boolean javaBeansGettersAndSetters = false; @@ -127,6 +129,16 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy { this.targetPackage = packageName; } + @Override + public Locale getTargetLocale() { + return targetLocale; + } + + @Override + public void setTargetLocale(Locale targetLocale) { + this.targetLocale = targetLocale; + } + // ------------------------------------------------------------------------- // Strategy methods // ------------------------------------------------------------------------- @@ -146,7 +158,7 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy { // [#6307] Some databases work with per-table namespacing for indexes, not per-schema namespacing. // In order to have non-ambiguous identifiers, we need to include the table name. else if (definition instanceof IndexDefinition && asList(MARIADB, MYSQL).contains(definition.getDatabase().getDialect().family())) - return ((IndexDefinition) definition).getTable().getOutputName().toUpperCase() + "_" + definition.getOutputName().toUpperCase(); + return ((IndexDefinition) definition).getTable().getOutputName().toUpperCase(targetLocale) + "_" + definition.getOutputName().toUpperCase(targetLocale); @@ -156,11 +168,11 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy { // [#9758] And then also for foreign keys else if (definition instanceof ForeignKeyDefinition && asList(POSTGRES).contains(definition.getDatabase().getDialect().family())) - return ((ForeignKeyDefinition) definition).getTable().getOutputName().toUpperCase() + "__" + definition.getOutputName().toUpperCase(); + return ((ForeignKeyDefinition) definition).getTable().getOutputName().toUpperCase(targetLocale) + "__" + definition.getOutputName().toUpperCase(targetLocale); // [#10481] Embeddables have a defining name (class name) and a referencing name (identifier name, member name). else if (definition instanceof EmbeddableDefinition) - return ((EmbeddableDefinition) definition).getReferencingOutputName().toUpperCase(); + return ((EmbeddableDefinition) definition).getReferencingOutputName().toUpperCase(targetLocale); @@ -168,7 +180,7 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy { else - return definition.getOutputName().toUpperCase(); + return definition.getOutputName().toUpperCase(targetLocale); } @@ -263,7 +275,7 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy { // [#2032] In multi-catalog setups, the catalog name goes into the package if (definition.getDatabase().getCatalogs().size() > 1) { sb.append("."); - sb.append(getJavaIdentifier(definition.getCatalog()).toLowerCase()); + sb.append(getJavaIdentifier(definition.getCatalog()).toLowerCase(targetLocale)); } if (!(definition instanceof CatalogDefinition)) { @@ -271,7 +283,7 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy { // [#282] In multi-schema setups, the schema name goes into the package if (definition.getDatabase().getSchemata().size() > 1) { sb.append("."); - sb.append(getJavaIdentifier(definition.getSchema()).toLowerCase()); + sb.append(getJavaIdentifier(definition.getSchema()).toLowerCase(targetLocale)); } if (!(definition instanceof SchemaDefinition)) { @@ -325,12 +337,12 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy { private String getJavaClassName0LC(Definition definition, Mode mode) { String result = getJavaClassName0(definition, mode); - return result.substring(0, 1).toLowerCase() + result.substring(1); + return result.substring(0, 1).toLowerCase(targetLocale) + result.substring(1); } private String getJavaClassName0LC(String outputName, Mode mode) { String result = getJavaClassName0(outputName, mode); - return result.substring(0, 1).toLowerCase() + result.substring(1); + return result.substring(0, 1).toLowerCase(targetLocale) + result.substring(1); } private String getJavaClassName0(Definition definition, Mode mode) { @@ -373,7 +385,7 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy { // [#330] [#6529] A UDT inside of a package is a PL/SQL RECORD type if (udt.getPackage() != null) - return "packages." + getJavaIdentifier(udt.getPackage()).toLowerCase() + ".udt"; + return "packages." + getJavaIdentifier(udt.getPackage()).toLowerCase(targetLocale) + ".udt"; else return "udt"; } @@ -384,10 +396,10 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy { RoutineDefinition routine = (RoutineDefinition) definition; if (routine.getPackage() instanceof UDTDefinition) { - return "udt." + getJavaIdentifier(routine.getPackage()).toLowerCase(); + return "udt." + getJavaIdentifier(routine.getPackage()).toLowerCase(targetLocale); } else if (routine.getPackage() != null) { - return "packages." + getJavaIdentifier(routine.getPackage()).toLowerCase(); + return "packages." + getJavaIdentifier(routine.getPackage()).toLowerCase(targetLocale); } else { return "routines"; @@ -405,7 +417,7 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy { // [#7125] An array inside of a package is a PL/SQL TABLE type if (array.getPackage() != null) - return "packages." + getJavaIdentifier(array.getPackage()).toLowerCase() + ".udt"; + return "packages." + getJavaIdentifier(array.getPackage()).toLowerCase(targetLocale) + ".udt"; else return "udt"; } diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/GenerationTool.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/GenerationTool.java index 177df61fd9..90fa7db868 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/GenerationTool.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/GenerationTool.java @@ -57,6 +57,7 @@ import java.sql.SQLException; import java.util.Arrays; import java.util.Comparator; import java.util.List; +import java.util.Locale; import java.util.Properties; import javax.sql.DataSource; @@ -85,6 +86,7 @@ import org.jooq.meta.jaxb.Strategy; import org.jooq.meta.jaxb.Target; // ... import org.jooq.tools.JooqLogger; +import org.jooq.tools.StringUtils; import org.jooq.tools.jdbc.JDBCUtils; import org.jooq.util.jaxb.tools.MiniJAXB; @@ -293,6 +295,16 @@ public class GenerationTool { if (g.getTarget() == null) g.setTarget(new Target()); + // [#9744] The is also needed in GenerationTool: + Locale locale = Locale.getDefault(); + if (!StringUtils.isBlank(g.getTarget().getLocale())) + + if (true) + locale = Locale.forLanguageTag(g.getTarget().getLocale()); + else + /* [java-8] */ + log.info("Locale support", "Locale support has been added for the Java 8+ distributions only"); + Database database = null; try { @@ -573,7 +585,7 @@ public class GenerationTool { log.info("Using custom schema version provider : " + svp); } catch (Exception ignore) { - if (d.getSchemaVersionProvider().toLowerCase().startsWith("select")) { + if (d.getSchemaVersionProvider().toLowerCase(locale).startsWith("select")) { svp = new SQLSchemaVersionProvider(connection, d.getSchemaVersionProvider()); log.info("Using SQL schema version provider : " + d.getSchemaVersionProvider()); } @@ -589,7 +601,7 @@ public class GenerationTool { log.info("Using custom catalog version provider : " + cvp); } catch (Exception ignore) { - if (d.getCatalogVersionProvider().toLowerCase().startsWith("select")) { + if (d.getCatalogVersionProvider().toLowerCase(locale).startsWith("select")) { cvp = new SQLCatalogVersionProvider(connection, d.getCatalogVersionProvider()); log.info("Using SQL catalog version provider : " + d.getCatalogVersionProvider()); } @@ -652,6 +664,7 @@ public class GenerationTool { if (g.getTarget().isClean() != null) generator.setTargetClean(g.getTarget().isClean()); + generator.setTargetLocale(locale); if (g.getGenerate().isIndexes() != null) generator.setGenerateIndexes(g.getGenerate().isIndexes()); diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/Generator.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/Generator.java index 8944fd6af2..8597b69785 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/Generator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/Generator.java @@ -39,6 +39,7 @@ package org.jooq.codegen; import java.io.Serializable; +import java.util.Locale; import org.jooq.meta.Database; import org.jooq.meta.jaxb.GeneratedAnnotationType; @@ -1028,4 +1029,14 @@ public interface Generator { * Whether the target package should be cleaned to contain only generated code after a generation run. */ void setTargetClean(boolean clean); + + /** + * The target locale. + */ + Locale getTargetLocale(); + + /** + *The target locale. + */ + void setTargetLocale(Locale targetLocale); } diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/GeneratorStrategy.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/GeneratorStrategy.java index fd768bc70e..af1c03d8a1 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/GeneratorStrategy.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/GeneratorStrategy.java @@ -40,6 +40,7 @@ package org.jooq.codegen; import java.io.File; import java.util.Collection; import java.util.List; +import java.util.Locale; import org.jooq.meta.AttributeDefinition; import org.jooq.meta.ColumnDefinition; @@ -78,6 +79,16 @@ public interface GeneratorStrategy { */ void setTargetPackage(String packageName); + /** + * @return Get the target locale for the current configuration + */ + Locale getTargetLocale(); + + /** + * Initialise the target locale + */ + void setTargetLocale(Locale targetLocale); + /** * Whether fields are instance fields (as opposed to static fields) */ diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/GeneratorStrategyWrapper.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/GeneratorStrategyWrapper.java index b457446548..93f9a1543d 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/GeneratorStrategyWrapper.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/GeneratorStrategyWrapper.java @@ -49,6 +49,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; @@ -110,6 +111,16 @@ class GeneratorStrategyWrapper extends AbstractGeneratorStrategy { delegate.setTargetPackage(packageName); } + @Override + public Locale getTargetLocale() { + return delegate.getTargetLocale(); + } + + @Override + public void setTargetLocale(Locale targetLocale) { + delegate.setTargetLocale(targetLocale); + } + @Override public void setInstanceFields(boolean instanceFields) { delegate.setInstanceFields(instanceFields); diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java index 65e4cfd8b4..41ec857e8a 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java @@ -647,7 +647,7 @@ public class JavaGenerator extends AbstractGenerator { // Check if we've previously encountered a Java type of the same case-insensitive, fully-qualified name. String name = getStrategy().getFullJavaClassName(definition); - String nameLC = name.toLowerCase(); + String nameLC = name.toLowerCase(getStrategy().getTargetLocale()); String existing = included.put(nameLC, name); if (existing == null) @@ -1454,7 +1454,7 @@ public class JavaGenerator extends AbstractGenerator { // Instance methods ship with a SELF parameter at the first position // [#1584] Static methods don't have that boolean instance = routine.getInParameters().size() > 0 - && routine.getInParameters().get(0).getInputName().toUpperCase().equals("SELF"); + && routine.getInParameters().get(0).getInputName().toUpperCase(getStrategy().getTargetLocale()).equals("SELF"); try { if (!routine.isSQLUsable()) { @@ -7908,7 +7908,7 @@ public class JavaGenerator extends AbstractGenerator { // [#5574] While MySQL usually reports actual values, it does report // a CURRENT_TIMESTAMP expression, inconsistently - if (d != null && d.toLowerCase().startsWith("current_timestamp")) + if (d != null && d.toLowerCase(getStrategy().getTargetLocale()).startsWith("current_timestamp")) sb.append("org.jooq.impl.DSL.field(\"") .append(escapeString(d)) .append("\""); diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/MatcherStrategy.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/MatcherStrategy.java index 832208abff..bbccf48493 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/MatcherStrategy.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/MatcherStrategy.java @@ -141,11 +141,11 @@ public class MatcherStrategy extends DefaultGeneratorStrategy { case AS_IS: return string; case LOWER: - return string.toLowerCase(); + return string.toLowerCase(getTargetLocale()); case LOWER_FIRST_LETTER: return StringUtils.toLC(string); case UPPER: - return string.toUpperCase(); + return string.toUpperCase(getTargetLocale()); case UPPER_FIRST_LETTER: return StringUtils.toUC(string); case CAMEL: diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/Target.java b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/Target.java index 2dee29da11..0f7e2d1f11 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/Target.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/Target.java @@ -38,6 +38,8 @@ public class Target implements Serializable, XMLAppendable @XmlElement(defaultValue = "UTF-8") @XmlJavaTypeAdapter(StringAdapter.class) protected String encoding = "UTF-8"; + @XmlJavaTypeAdapter(StringAdapter.class) + protected String locale; @XmlElement(defaultValue = "true") protected Boolean clean = true; @@ -95,6 +97,22 @@ public class Target implements Serializable, XMLAppendable this.encoding = value; } + /** + * The locale to be used with all locale specific operations. + * + */ + public String getLocale() { + return locale; + } + + /** + * The locale to be used with all locale specific operations. + * + */ + public void setLocale(String value) { + this.locale = value; + } + /** * Whether the target package should be cleaned to contain only generated code after a generation run. * @@ -149,6 +167,15 @@ public class Target implements Serializable, XMLAppendable return this; } + /** + * The locale to be used with all locale specific operations. + * + */ + public Target withLocale(String value) { + setLocale(value); + return this; + } + public Target withClean(Boolean value) { setClean(value); return this; @@ -159,6 +186,7 @@ public class Target implements Serializable, XMLAppendable builder.append("packageName", packageName); builder.append("directory", directory); builder.append("encoding", encoding); + builder.append("locale", locale); builder.append("clean", clean); } @@ -208,6 +236,15 @@ public class Target implements Serializable, XMLAppendable return false; } } + if (locale == null) { + if (other.locale!= null) { + return false; + } + } else { + if (!locale.equals(other.locale)) { + return false; + } + } if (clean == null) { if (other.clean!= null) { return false; @@ -227,6 +264,7 @@ public class Target implements Serializable, XMLAppendable result = ((prime*result)+((packageName == null)? 0 :packageName.hashCode())); result = ((prime*result)+((directory == null)? 0 :directory.hashCode())); result = ((prime*result)+((encoding == null)? 0 :encoding.hashCode())); + result = ((prime*result)+((locale == null)? 0 :locale.hashCode())); result = ((prime*result)+((clean == null)? 0 :clean.hashCode())); return result; } diff --git a/jOOQ-meta/src/main/resources/xsd/jooq-codegen-3.14.0.xsd b/jOOQ-meta/src/main/resources/xsd/jooq-codegen-3.14.0.xsd index 62c5c031cd..4299de0bfb 100644 --- a/jOOQ-meta/src/main/resources/xsd/jooq-codegen-3.14.0.xsd +++ b/jOOQ-meta/src/main/resources/xsd/jooq-codegen-3.14.0.xsd @@ -1608,6 +1608,10 @@ e.g. org.jooq.generated.schema1, org.jooq.generated.schema2]]> + + + + diff --git a/jOOQ/src/main/java/org/jooq/tools/StringUtils.java b/jOOQ/src/main/java/org/jooq/tools/StringUtils.java index a50f7e031c..65c4dc71b1 100644 --- a/jOOQ/src/main/java/org/jooq/tools/StringUtils.java +++ b/jOOQ/src/main/java/org/jooq/tools/StringUtils.java @@ -1370,7 +1370,7 @@ public final class StringUtils { } /** - * Change a string's first letter to lower case + * Change a string's first letter to upper case */ public static String toUC(String string) { if (string == null || string.isEmpty())