From 5aeadd30179c66ef0d9ee8741a0f1b2656aded57 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Mon, 31 Aug 2020 17:38:49 +0200 Subject: [PATCH] [jOOQ/jOOQ#10561] Various compilation errors when schema, table, key names conflict --- .../java/org/jooq/codegen/JavaGenerator.java | 42 +++++------- .../java/org/jooq/codegen/JavaWriter.java | 68 ++++++++++++------- 2 files changed, 59 insertions(+), 51 deletions(-) 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 606d29c76e..1480d98f4f 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java @@ -757,6 +757,8 @@ public class JavaGenerator extends AbstractGenerator { boolean empty = true; JavaWriter out = newJavaWriter(new File(getFile(schema).getParentFile(), "Keys.java")); + out.refConflicts(getStrategy().getJavaIdentifiers(database.getUniqueKeys(schema))); + out.refConflicts(getStrategy().getJavaIdentifiers(database.getForeignKeys(schema))); printPackage(out, schema); printClassJavadoc(out, "A class modelling foreign key relationships and constraints of tables in " + schemaNameOrDefault(schema) + "."); @@ -874,6 +876,7 @@ public class JavaGenerator extends AbstractGenerator { } JavaWriter out = newJavaWriter(new File(getFile(schema).getParentFile(), "Indexes.java")); + out.refConflicts(getStrategy().getJavaIdentifiers(database.getIndexes(schema))); printPackage(out, schema); printClassJavadoc(out, "A class modelling indexes of tables in " + schemaNameOrDefault(schema) + "."); @@ -889,24 +892,20 @@ public class JavaGenerator extends AbstractGenerator { out.header("INDEX definitions"); out.println(); - for (TableDefinition table : database.getTables(schema)) { + for (IndexDefinition index : database.getIndexes(schema)) { try { - List indexes = table.getIndexes(); + final String keyId = getStrategy().getJavaIdentifier(index); + final int block = allIndexes.size() / INITIALISER_SIZE; - for (IndexDefinition index : indexes) { - final String keyId = getStrategy().getJavaIdentifier(index); - final int block = allIndexes.size() / INITIALISER_SIZE; + if (scala || kotlin) + out.println("val %s = Indexes%s.%s", keyId, block, keyId); + else + out.println("public static final %s %s = Indexes%s.%s;", Index.class, keyId, block, keyId); - if (scala || kotlin) - out.println("val %s = Indexes%s.%s", keyId, block, keyId); - else - out.println("public static final %s %s = Indexes%s.%s;", Index.class, keyId, block, keyId); - - allIndexes.add(index); - } + allIndexes.add(index); } catch (Exception e) { - log.error("Error while generating table " + table, e); + log.error("Error while generating index " + index, e); } } @@ -964,6 +963,8 @@ public class JavaGenerator extends AbstractGenerator { out.println("%s", semicolon); } + + private void printCreateIndex(JavaWriter out, IndexDefinition index) { String sortFieldSeparator = ""; StringBuilder orderFields = new StringBuilder(); @@ -2835,6 +2836,7 @@ public class JavaGenerator extends AbstractGenerator { protected void generateDomainReferences(SchemaDefinition schema) { log.info("Generating DOMAIN references"); JavaWriter out = newJavaWriter(new File(getFile(schema).getParentFile(), "Domains.java")); + out.refConflicts(getStrategy().getJavaIdentifiers(database.getDomains(schema))); final String schemaId = out.ref(getStrategy().getFullJavaIdentifier(schema), 2); @@ -5718,6 +5720,7 @@ public class JavaGenerator extends AbstractGenerator { protected void generateSequences(SchemaDefinition schema) { log.info("Generating sequences"); JavaWriter out = newJavaWriter(new File(getFile(schema).getParentFile(), "Sequences.java")); + out.refConflicts(getStrategy().getJavaIdentifiers(database.getSequences(schema))); printPackage(out, schema); printClassJavadoc(out, "Convenience access to all sequences in " + schemaNameOrDefault(schema) + "."); @@ -5728,15 +5731,12 @@ public class JavaGenerator extends AbstractGenerator { else out.println("public class Sequences {"); - boolean qualifySequenceClassReferences = containsConflictingDefinition(schema, database.getSequences(schema)); - for (SequenceDefinition sequence : database.getSequences(schema)) { final String seqTypeFull = getJavaType(sequence.getType(resolver(out)), out); final String seqType = out.ref(seqTypeFull); final String seqId = getStrategy().getJavaIdentifier(sequence); final String seqName = sequence.getOutputName(); - final String schemaId = qualifySequenceClassReferences ? getStrategy().getFullJavaIdentifier(schema) - : out.ref(getStrategy().getFullJavaIdentifier(schema), 2); + final String schemaId = out.ref(getStrategy().getFullJavaIdentifier(schema), 2); final String typeRef = getJavaTypeReference(sequence.getDatabase(), sequence.getType(resolver(out)), out); if (!printDeprecationIfUnknownType(out, seqTypeFull)) @@ -5818,14 +5818,6 @@ public class JavaGenerator extends AbstractGenerator { return "null"; } - private boolean containsConflictingDefinition(SchemaDefinition schema, List definitions) { - final String unqualifiedSchemaId = getStrategy().getJavaIdentifier(schema); - for (Definition def : definitions) - if (unqualifiedSchemaId.equals(getStrategy().getJavaIdentifier(def))) - return true; - return false; - } - protected void generateCatalog(CatalogDefinition catalog) { JavaWriter out = newJavaWriter(getFile(catalog)); log.info(""); diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaWriter.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaWriter.java index 6051c0b03c..e8d8eb4902 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaWriter.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaWriter.java @@ -8,6 +8,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -33,6 +34,7 @@ public class JavaWriter extends GeneratorWriter { private final Pattern fullyQualifiedTypes; private final boolean javadoc; + private final Set refConflicts; private final Set qualifiedTypes = new TreeSet<>(qualifiedTypeComparator()); private final Map unqualifiedTypes = new TreeMap<>(); private final String className; @@ -60,6 +62,7 @@ public class JavaWriter extends GeneratorWriter { this.isJava = file.getName().endsWith(".java"); this.isScala = file.getName().endsWith(".scala"); this.isKotlin = file.getName().endsWith(".kt"); + this.refConflicts = new HashSet<>(); this.fullyQualifiedTypes = fullyQualifiedTypes == null ? null : Pattern.compile(fullyQualifiedTypes); this.javadoc = javadoc; @@ -239,6 +242,11 @@ public class JavaWriter extends GeneratorWriter { return string; } + public JavaWriter refConflicts(List conflicts) { + this.refConflicts.addAll(conflicts); + return this; + } + @Override protected List ref(List clazz, int keepSegments) { List result = new ArrayList<>(clazz == null ? 0 : clazz.size()); @@ -247,43 +255,51 @@ public class JavaWriter extends GeneratorWriter { for (String c : clazz) { // Skip unqualified and primitive types - if (c.contains(".")) { + checks: { + if (!c.contains(".")) + break checks; + c = patchKotlinClasses(c); // com.example.Table.TABLE.COLUMN (with keepSegments = 3) - if (fullyQualifiedTypes == null || !fullyQualifiedTypes.matcher(c).matches()) { - Matcher m = TYPE_REFERENCE_PATTERN.matcher(c); + if (fullyQualifiedTypes != null && fullyQualifiedTypes.matcher(c).matches()) + break checks; - if (m.find()) { + Matcher m = TYPE_REFERENCE_PATTERN.matcher(c); + if (!m.find()) + break checks; - // [com, example, Table, TABLE, COLUMN] - List split = Arrays.asList(m.group(1).split("\\.")); + // [com, example, Table, TABLE, COLUMN] + List split = Arrays.asList(m.group(1).split("\\.")); - // com.example.Table - String qualifiedType = StringUtils.join(split.subList(0, split.size() - keepSegments + 1).toArray(), "."); + // com.example.Table + String qualifiedType = StringUtils.join(split.subList(0, split.size() - keepSegments + 1).toArray(), "."); - // Table - String unqualifiedType = split.get(split.size() - keepSegments); + // Table + String unqualifiedType = split.get(split.size() - keepSegments); - // Table.TABLE.COLUMN - String remainder = StringUtils.join(split.subList(split.size() - keepSegments, split.size()).toArray(), "."); + // Table.TABLE.COLUMN + String remainder = StringUtils.join(split.subList(split.size() - keepSegments, split.size()).toArray(), "."); - // [#9697] Don't import a class from a different package by the same name as this class - if ((!className.equals(unqualifiedType) || packageName != null && qualifiedType.equals(packageName + "." + className)) && - (!unqualifiedTypes.containsKey(unqualifiedType) || qualifiedType.equals(unqualifiedTypes.get(unqualifiedType)))) { + // [#9697] Don't import a class from a different package by the same name as this class + if ((className.equals(unqualifiedType) && (packageName == null || !qualifiedType.equals(packageName + "." + className))) + || (unqualifiedTypes.containsKey(unqualifiedType) && !qualifiedType.equals(unqualifiedTypes.get(unqualifiedType)))) + break checks; - unqualifiedTypes.put(unqualifiedType, qualifiedType); - qualifiedTypes.add(qualifiedType); - String generic = m.group(2); + // [#10561] Don't import type that conflicts with a local identifier + if (refConflicts.contains(unqualifiedType)) + break checks; - // Consider importing generic type arguments, recursively - c = remainder - + (PLAIN_GENERIC_TYPE_PATTERN.matcher(generic).matches() - ? generic.substring(0, 1) + ref(generic.substring(1, generic.length() - 1)) + generic.substring(generic.length() - 1) - : generic); - } - } - } + // [#10561] Don't import a class that conflicts with a local identifier + unqualifiedTypes.put(unqualifiedType, qualifiedType); + qualifiedTypes.add(qualifiedType); + String generic = m.group(2); + + // Consider importing generic type arguments, recursively + c = remainder + + (PLAIN_GENERIC_TYPE_PATTERN.matcher(generic).matches() + ? generic.substring(0, 1) + ref(generic.substring(1, generic.length() - 1)) + generic.substring(generic.length() - 1) + : generic); } // If any of the above tests fail, c will remain the unchanged,