This is an automated email from the ASF dual-hosted git repository.
mgrigorov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/avro.git
The following commit(s) were added to refs/heads/master by this push:
new d87a99d53 AVRO-3698: SpecificData.getClassName must replace reserved
words (#2048)
d87a99d53 is described below
commit d87a99d532719ba6f619ba68e07dbaa77fe4f84e
Author: 정승현 <[email protected]>
AuthorDate: Tue Jan 10 20:42:32 2023 +0900
AVRO-3698: SpecificData.getClassName must replace reserved words (#2048)
---
.../org/apache/avro/specific/SpecificData.java | 24 ++++++++++++++++++++--
.../org/apache/avro/specific/TestSpecificData.java | 7 +++++++
.../avro/compiler/specific/SpecificCompiler.java | 3 ++-
3 files changed, 31 insertions(+), 3 deletions(-)
diff --git
a/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java
b/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java
index 966acb5fc..0476b2e2f 100644
--- a/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java
+++ b/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java
@@ -91,6 +91,8 @@ public class SpecificData extends GenericData {
public static final String KEY_CLASS_PROP = "java-key-class";
public static final String ELEMENT_PROP = "java-element-class";
+ public static final char RESERVED_WORD_ESCAPE_CHAR = '$';
+
/**
* Reserved words from
* https://docs.oracle.com/javase/specs/jls/se16/html/jls-3.html require
@@ -329,8 +331,26 @@ public class SpecificData extends GenericData {
String name = schema.getName();
if (namespace == null || "".equals(namespace))
return name;
- String dot = namespace.endsWith("$") ? "" : "."; // back-compatibly handle
$
- return namespace + dot + name;
+
+ StringBuilder classNameBuilder = new StringBuilder();
+ String[] words = namespace.split("\\.");
+
+ for (int i = 0; i < words.length; i++) {
+ String word = words[i];
+ classNameBuilder.append(word);
+
+ if (RESERVED_WORDS.contains(word)) {
+ classNameBuilder.append(RESERVED_WORD_ESCAPE_CHAR);
+ }
+
+ if (i != words.length - 1 || !word.endsWith("$")) { // back-compatibly
handle $
+ classNameBuilder.append(".");
+ }
+ }
+
+ classNameBuilder.append(name);
+
+ return classNameBuilder.toString();
}
// cache for schemas created from Class objects. Use ClassValue to avoid
diff --git
a/lang/java/avro/src/test/java/org/apache/avro/specific/TestSpecificData.java
b/lang/java/avro/src/test/java/org/apache/avro/specific/TestSpecificData.java
index 0db2a8b44..4fe9abb6b 100644
---
a/lang/java/avro/src/test/java/org/apache/avro/specific/TestSpecificData.java
+++
b/lang/java/avro/src/test/java/org/apache/avro/specific/TestSpecificData.java
@@ -178,4 +178,11 @@ public class TestSpecificData {
// Expected error
}
}
+
+ @Test
+ void classNameContainingReservedWords() {
+ final Schema schema = Schema.createRecord("AnyName", null,
"db.public.table", false);
+
+ assertEquals("db.public$.table.AnyName",
SpecificData.getClassName(schema));
+ }
}
diff --git
a/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
b/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
index 6f46845bb..baa2fd793 100644
---
a/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
+++
b/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
@@ -61,6 +61,7 @@ import org.slf4j.LoggerFactory;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.avro.specific.SpecificData.RESERVED_WORDS;
+import static org.apache.avro.specific.SpecificData.RESERVED_WORD_ESCAPE_CHAR;
/**
* Generate specific Java interfaces and classes for protocols and schemas.
@@ -1126,7 +1127,7 @@ public class SpecificCompiler {
}
if (reservedWords.contains(word) || (isMethod && reservedWords
.contains(Character.toLowerCase(word.charAt(0)) + ((word.length() > 1)
? word.substring(1) : "")))) {
- return word + "$";
+ return word + RESERVED_WORD_ESCAPE_CHAR;
}
return word;
}