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())