diff --git a/zookeeper-jute/src/main/java/org/apache/jute/compiler/JField.java b/zookeeper-jute/src/main/java/org/apache/jute/compiler/JField.java
index 395c0b6a966..0d8f35bd0e5 100644
--- a/zookeeper-jute/src/main/java/org/apache/jute/compiler/JField.java
+++ b/zookeeper-jute/src/main/java/org/apache/jute/compiler/JField.java
@@ -18,6 +18,9 @@
package org.apache.jute.compiler;
+import org.apache.jute.compiler.generated.RccConstants;
+import org.apache.jute.compiler.generated.Token;
+
/**
*
*/
@@ -25,6 +28,21 @@ public class JField {
private JType mType;
private String mName;
+ /**
+ * {@link #mType} of token.
+ */
+ private Token mTypeToken;
+
+ private Token previousToken;
+
+ /**
+ * Since we can only get the comments before the token through the {@link Token#specialToken},
+ * we need to save the next token to get the end-of-line comment.
+ *
+ *
It may be the type of the next field, or it may be {@link RccConstants#RBRACE_TKN} of the class.
+ */
+ private Token nextToken;
+
/**
* Creates a new instance of JField.
*/
@@ -33,6 +51,30 @@ public JField(JType type, String name) {
mName = name;
}
+ public Token getTypeToken() {
+ return mTypeToken;
+ }
+
+ public void setTypeToken(Token typeToken) {
+ this.mTypeToken = typeToken;
+ }
+
+ public Token getNextToken() {
+ return nextToken;
+ }
+
+ public void setNextToken(Token nextToken) {
+ this.nextToken = nextToken;
+ }
+
+ public Token getPreviousToken() {
+ return previousToken;
+ }
+
+ public void setPreviousToken(Token previousToken) {
+ this.previousToken = previousToken;
+ }
+
public String getSignature() {
return mType.getSignature();
}
diff --git a/zookeeper-jute/src/main/java/org/apache/jute/compiler/JRecord.java b/zookeeper-jute/src/main/java/org/apache/jute/compiler/JRecord.java
index 618b4c50bb0..76ebc1731e4 100644
--- a/zookeeper-jute/src/main/java/org/apache/jute/compiler/JRecord.java
+++ b/zookeeper-jute/src/main/java/org/apache/jute/compiler/JRecord.java
@@ -22,10 +22,13 @@
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import org.apache.jute.compiler.generated.RccConstants;
+import org.apache.jute.compiler.generated.Token;
/**
*
@@ -36,11 +39,12 @@ public class JRecord extends JCompType {
private String mName;
private String mModule;
private List mFields;
+ private Token mRecordToken;
/**
* Creates a new instance of JRecord.
*/
- public JRecord(String name, ArrayList flist) {
+ public JRecord(String name, ArrayList flist, Token recordToken) {
super("struct " + name.substring(name.lastIndexOf('.') + 1),
name.replaceAll("\\.", "::"), getCsharpFQName(name), name, "Record", name, getCsharpFQName("IRecord"));
mFQName = name;
@@ -48,12 +52,17 @@ public JRecord(String name, ArrayList flist) {
mName = name.substring(idx + 1);
mModule = name.substring(0, idx);
mFields = flist;
+ mRecordToken = recordToken;
}
public String getName() {
return mName;
}
+ public Token getRecordToken() {
+ return mRecordToken;
+ }
+
public String getCsharpName() {
return "Id".equals(mName) ? "ZKId" : mName;
}
@@ -208,8 +217,17 @@ public void genCCode(FileWriter h, FileWriter c) throws IOException {
}
}
String recName = getName();
+
+ String recordComments = getRecordComments();
+ if (recordComments != null && !recordComments.isEmpty()) {
+ h.write(recordComments);
+ }
h.write("struct " + recName + " {\n");
for (JField f : mFields) {
+ String fieldComments = getCFieldComments(f);
+ if (fieldComments != null && !fieldComments.isEmpty()) {
+ h.write(fieldComments);
+ }
h.write(f.genCDecl());
}
h.write("};\n");
@@ -436,10 +454,18 @@ public void genJavaCode(File outputDirectory) throws IOException {
jj.write("import org.apache.jute.*;\n");
jj.write("import org.apache.jute.Record; // JDK14 needs explicit import due to clash with java.lang.Record\n");
jj.write("import org.apache.yetus.audience.InterfaceAudience;\n");
+ String recordComments = getRecordComments();
+ if (recordComments != null && !recordComments.isEmpty()) {
+ jj.write(recordComments);
+ }
jj.write("@InterfaceAudience.Public\n");
jj.write("public class " + getName() + " implements Record {\n");
for (Iterator i = mFields.iterator(); i.hasNext(); ) {
JField jf = i.next();
+ String fieldComments = getJavaFieldComments(jf);
+ if (fieldComments != null && !fieldComments.isEmpty()) {
+ jj.write(fieldComments);
+ }
jj.write(jf.genJavaDecl());
}
jj.write(" public " + getName() + "() {\n");
@@ -767,4 +793,122 @@ public static String getCsharpFQName(String name) {
}
return fQName.toString();
}
+
+ public String getJavaFieldComments(JField jField) {
+ return getFieldComments(jField, " ");
+ }
+
+ public String getCFieldComments(JField jField) {
+ return getFieldComments(jField, " ");
+ }
+
+ private String getFieldComments(JField jField, String indent) {
+ if (jField == null || jField.getTypeToken() == null || jField.getNextToken() == null) {
+ return "";
+ }
+
+ // get the comment before the line
+ Token beforeTheLineCommentToken = getCommentToken(jField.getTypeToken(), jField.getPreviousToken());
+ List comments = extractComments(beforeTheLineCommentToken, Integer.MAX_VALUE);
+
+ Token endOfLineCommentToken = getCommentToken(jField.getNextToken(), null);
+ if (endOfLineCommentToken != null && jField.getTypeToken().beginLine == endOfLineCommentToken.beginLine) {
+
+ comments.addAll(extractComments(endOfLineCommentToken, endOfLineCommentToken.beginLine));
+ }
+
+ return formatComments(indent, comments);
+ }
+
+ private Token getCommentToken(Token token, Token previousToken) {
+ if (token == null || token.specialToken == null) {
+ return null;
+ }
+
+ Token commentToken = token.specialToken;
+ while (commentToken.specialToken != null) {
+ commentToken = commentToken.specialToken;
+ }
+ // Skip end of line comment belong to previous token.
+ while (previousToken != null && commentToken != null && commentToken.beginLine == previousToken.endLine) {
+ commentToken = commentToken.next;
+ }
+ return commentToken;
+ }
+
+ public String getRecordComments() {
+ if (getRecordToken() == null || getRecordToken().specialToken == null) {
+ return "";
+ }
+
+ // get the comments before the class
+ Token commentToken = getCommentToken(getRecordToken(), null);
+ return formatComments("", extractComments(commentToken, Integer.MAX_VALUE));
+ }
+
+ private static String formatComments(String indent, List commentLines) {
+ if (commentLines == null || commentLines.isEmpty()) {
+ return "";
+ }
+
+ StringBuilder builder = new StringBuilder();
+ for (String line : commentLines) {
+ if (!line.isEmpty()) {
+ builder.append(indent).append(line);
+ }
+ builder.append(System.lineSeparator());
+ }
+
+ return builder.toString();
+ }
+
+ /**
+ * Extracts comments with indentation and line separator trimmed.
+ *
+ * Empty line is represented as empty string.
+ */
+ private static List extractComments(Token token, int endLine) {
+ List comments = new ArrayList<>();
+
+ if (token == null) {
+ return comments;
+ }
+
+ int nextLine = token.beginLine;
+ while (token != null && token.beginLine <= endLine) {
+ while (nextLine < token.beginLine) {
+ comments.add("");
+ nextLine++;
+ }
+ nextLine = token.endLine + 1;
+ switch (token.kind) {
+ case RccConstants.ONE_LINE_COMMENT:
+ comments.add(token.image);
+ break;
+ case RccConstants.MULTI_LINE_COMMENT: {
+ List lines = Arrays.asList(token.image.split("\r|\n|\r\n"));
+ // First line captures no indentation.
+ comments.add(lines.get(0));
+ int indentSpaces = token.beginColumn - 1;
+ for (int i = 1; i < lines.size(); i++) {
+ String line = lines.get(i);
+ int j = 0;
+ while (j < indentSpaces && j < line.length()) {
+ if (line.charAt(j) != ' ') {
+ break;
+ }
+ j++;
+ }
+ comments.add(line.substring(j));
+ }
+ }
+ break;
+ default:
+ throw new IllegalStateException("expect comment token, but get token kind " + token.kind);
+ }
+ token = token.next;
+ }
+
+ return comments;
+ }
}
diff --git a/zookeeper-jute/src/main/java/org/apache/jute/compiler/generated/rcc.jj b/zookeeper-jute/src/main/java/org/apache/jute/compiler/generated/rcc.jj
index 94d4f42f6b3..f97ebc3c6c4 100644
--- a/zookeeper-jute/src/main/java/org/apache/jute/compiler/generated/rcc.jj
+++ b/zookeeper-jute/src/main/java/org/apache/jute/compiler/generated/rcc.jj
@@ -111,32 +111,8 @@ SKIP :
SPECIAL_TOKEN :
{
- "//" : WithinOneLineComment
-}
-
- SPECIAL_TOKEN :
-{
- <("\n" | "\r" | "\r\n" )> : DEFAULT
-}
-
- MORE :
-{
- <~[]>
-}
-
-SPECIAL_TOKEN :
-{
- "/*" : WithinMultiLineComment
-}
-
- SPECIAL_TOKEN :
-{
- "*/" : DEFAULT
-}
-
- MORE :
-{
- <~[]>
+
+|
}
TOKEN :
@@ -274,21 +250,32 @@ JRecord Record() :
ArrayList flist = new ArrayList();
Token t;
JField f;
+ // Get the comments on the class token
+ Token recordTkn;
+ Token typeTkn;
+ Token previousToken = null;
}
{
-
+ recordTkn =
t =
{ rname = t.image; }
-
+ previousToken =
(
+ {typeTkn = getToken(1);}
f = Field()
{ flist.add(f); }
+ {
+ f.setTypeToken(typeTkn);
+ f.setPreviousToken(previousToken);
+ f.setNextToken(getToken(1));
+ previousToken = typeTkn;
+ }
)+
{
String fqn = curModuleName + "." + rname;
- JRecord r = new JRecord(fqn, flist);
+ JRecord r = new JRecord(fqn, flist, recordTkn);
recTab.put(fqn, r);
return r;
}
diff --git a/zookeeper-jute/src/test/java/org/apache/jute/compiler/JRecordTest.java b/zookeeper-jute/src/test/java/org/apache/jute/compiler/JRecordTest.java
new file mode 100644
index 00000000000..91eece84e17
--- /dev/null
+++ b/zookeeper-jute/src/test/java/org/apache/jute/compiler/JRecordTest.java
@@ -0,0 +1,344 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+package org.apache.jute.compiler;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import java.io.StringReader;
+import java.lang.reflect.Field;
+import java.util.List;
+import org.apache.jute.compiler.generated.ParseException;
+import org.apache.jute.compiler.generated.Rcc;
+import org.junit.jupiter.api.Test;
+
+@SuppressWarnings({"unchecked", "SameParameterValue"})
+public class JRecordTest {
+
+ @Test
+ public void testEndOfLineComments() throws ParseException, NoSuchFieldException, IllegalAccessException {
+ String juteStr = "module org.apache.zookeeper.data {\n"
+ + " // information explicitly stored by the server persistently\n"
+ + " class StatPersisted {\n"
+ + " long czxid; // created zxid\n"
+ + " long mzxid; // last modified zxid\n"
+ + " long ctime; /* created */\n"
+ + " long mtime; /** last modified */\n"
+ + " int version; /* version */ /* testComment1 */\n"
+ + " int cversion; /* child version */ /* child versionComment2 */ /* child versionComment3 */\n"
+ + " int aversion; /** acl version */ /** acl versionComment2 */ /** acl version */\n"
+ + " long ephemeralOwner; /* A multi-line end of line comment. */ /* Another multi-line end of line comment. */ /* Yet another\n"
+ + "end of line comment. */ /* Comment belong to new field */\n"
+ + " long pzxid; /* A multi-line end of line comment. */ /* Another multi-line end of line comment. */ /* Yet another\n"
+ + "end of line comment. */ /* Comment belong to new field */\n"
+ + " }\n"
+ + "}";
+
+ try (StringReader stringReader = new StringReader(juteStr)) {
+ Rcc parser = new Rcc(stringReader);
+ JFile jFile = parser.Input();
+ List mRecords = getField(jFile, "mRecords", List.class);
+ assertEquals(1, mRecords.size());
+
+ JRecord jRecord = mRecords.get(0);
+ assertEquals("StatPersisted", jRecord.getName());
+ List fields = jRecord.getFields();
+ assertFiled(fields);
+
+ assertEquals("// information explicitly stored by the server persistently\n", jRecord.getRecordComments());
+ assertEquals(" // created zxid\n", jRecord.getJavaFieldComments(fields.get(0)));
+ assertEquals(" // last modified zxid\n", jRecord.getJavaFieldComments(fields.get(1)));
+ assertEquals(" /* created */\n", jRecord.getJavaFieldComments(fields.get(2)));
+ assertEquals(" /** last modified */\n", jRecord.getJavaFieldComments(fields.get(3)));
+ assertEquals(" /* version */\n /* testComment1 */\n", jRecord.getJavaFieldComments(fields.get(4)));
+ assertEquals(" /* child version */\n /* child versionComment2 */\n /* child versionComment3 */\n", jRecord.getJavaFieldComments(fields.get(5)));
+ assertEquals(" /** acl version */\n /** acl versionComment2 */\n /** acl version */\n", jRecord.getJavaFieldComments(fields.get(6)));
+ assertEquals(
+ " /* A multi-line end of line comment. */\n"
+ + " /* Another multi-line end of line comment. */\n"
+ + " /* Yet another\n"
+ + " end of line comment. */\n", jRecord.getJavaFieldComments(fields.get(7)));
+ assertEquals(
+ " /* Comment belong to new field */\n"
+ + " /* A multi-line end of line comment. */\n"
+ + " /* Another multi-line end of line comment. */\n"
+ + " /* Yet another\n"
+ + " end of line comment. */\n", jRecord.getJavaFieldComments(fields.get(8)));
+ }
+ }
+
+ @Test
+ public void testCommentBeforeLineAndEndOfLine() throws ParseException, NoSuchFieldException, IllegalAccessException {
+ String juteStr = "module org.apache.zookeeper.data {\n"
+ + " /**\n"
+ + " * information explicitly stored by the server persistently\n"
+ + " */ \n"
+ + " class StatPersisted {\n"
+ + " // created zxid\n"
+ + " long czxid; // created zxid comment2\n"
+ + " /* last modified zxid */\n"
+ + " long mzxid; // last modified zxid comment2\n"
+ + " /* created */\n"
+ + " long ctime; // created comment2\n"
+ + " /* last modified */\n"
+ + " /* last modified */\n"
+ + " long mtime; // last modified comment2\n"
+ + " // version comment\n "
+ + " int version; /* version comment1 */ /* version\n comment2 */\n"
+ + " /** child version */\n"
+ + " /** child version */\n"
+ + " int cversion; /** child version */ // child version\n"
+ + " // acl version\n"
+ + " // acl version\n"
+ + " // acl version\n"
+ + " int aversion; // acl version\n"
+ + " // ephemeralOwner comment\n"
+ + " long ephemeralOwner; /* A multi-line end of line comment. */ /* Another multi-line end of line comment. */ /* Yet another\n"
+ + "end of line comment. */ /* Comment belong to new field */\n"
+ + " // pzxid comment\n"
+ + " long pzxid; /* A multi-line end of line comment. */ /* Another multi-line end of line comment. */ /* Yet another\n"
+ + "end of line comment. */ /* Comment belong to new field */\n"
+ + " }\n"
+ + "}";
+ try (StringReader stringReader = new StringReader(juteStr)) {
+ Rcc parser = new Rcc(stringReader);
+ JFile jFile = parser.Input();
+ List mRecords = getField(jFile, "mRecords", List.class);
+ assertEquals(1, mRecords.size());
+
+ JRecord jRecord = mRecords.get(0);
+ assertEquals("StatPersisted", jRecord.getName());
+ List fields = jRecord.getFields();
+ assertFiled(fields);
+
+ assertEquals("/**\n * information explicitly stored by the server persistently\n */\n", jRecord.getRecordComments());
+ assertEquals(" // created zxid\n // created zxid comment2\n", jRecord.getJavaFieldComments(fields.get(0)));
+ assertEquals(" /* last modified zxid */\n // last modified zxid comment2\n", jRecord.getJavaFieldComments(fields.get(1)));
+ assertEquals(" /* created */\n // created comment2\n", jRecord.getJavaFieldComments(fields.get(2)));
+ assertEquals(" /* last modified */\n /* last modified */\n // last modified comment2\n", jRecord.getJavaFieldComments(fields.get(3)));
+
+ assertEquals(" // version comment\n /* version comment1 */\n /* version\n comment2 */\n", jRecord.getJavaFieldComments(fields.get(4)));
+ assertEquals(" /** child version */\n /** child version */\n /** child version */\n // child version\n", jRecord.getJavaFieldComments(fields.get(5)));
+ assertEquals(" // acl version\n // acl version\n // acl version\n // acl version\n", jRecord.getJavaFieldComments(fields.get(6)));
+ assertEquals(
+ " // ephemeralOwner comment\n"
+ + " /* A multi-line end of line comment. */\n"
+ + " /* Another multi-line end of line comment. */\n"
+ + " /* Yet another\n"
+ + " end of line comment. */\n", jRecord.getJavaFieldComments(fields.get(7)));
+ assertEquals(
+ " /* Comment belong to new field */\n"
+ + " // pzxid comment\n"
+ + " /* A multi-line end of line comment. */\n"
+ + " /* Another multi-line end of line comment. */\n"
+ + " /* Yet another\n"
+ + " end of line comment. */\n", jRecord.getJavaFieldComments(fields.get(8)));
+ }
+ }
+
+ @Test
+ public void testCommentBeforeLine() throws ParseException, NoSuchFieldException, IllegalAccessException {
+ String juteStr = "module org.apache.zookeeper.data {\n"
+ + " // information explicitly stored by the server persistently\n"
+ + " // StatPersisted Comment1\n"
+ + " // StatPersisted Comment2\n"
+ + " class StatPersisted {\n"
+ + " // created zxid comment1\n"
+ + " // created zxid comment2\n"
+ + " // created zxid comment3\n"
+ + " long czxid;\n"
+ + " // last modified zxid\n"
+ + " // last modified zxid\n"
+ + " // last modified zxid\n"
+ + " long mzxid;\n"
+ + " /* created */\n"
+ + " /* created */\n"
+ + " /* created */\n"
+ + " long ctime;\n"
+ + " /** last modified */\n"
+ + " /** last modified */\n"
+ + " long mtime;\n"
+ + " /** version */\n"
+ + " /** version */\n"
+ + " int version;\n"
+ + " // child version\n"
+ + " /** child version */\n"
+ + " /** child version */\n"
+ + " int cversion;\n"
+ + " /* acl version */\n"
+ + " // acl version\n"
+ + " /* acl version */\n"
+ + " int aversion;\n"
+ + " // owner id if ephemeral, 0 otw\n"
+ + " long ephemeralOwner;\n"
+ + " // last modified children\n"
+ + " long pzxid;\n"
+ + " }\n"
+ + "}";
+ try (StringReader stringReader = new StringReader(juteStr)) {
+ Rcc parser = new Rcc(stringReader);
+ JFile jFile = parser.Input();
+ List mRecords = getField(jFile, "mRecords", List.class);
+ assertEquals(1, mRecords.size());
+
+ JRecord jRecord = mRecords.get(0);
+ assertEquals("StatPersisted", jRecord.getName());
+ List fields = jRecord.getFields();
+ assertFiled(fields);
+
+ assertEquals("// information explicitly stored by the server persistently\n// StatPersisted Comment1\n// StatPersisted Comment2\n", jRecord.getRecordComments());
+ assertEquals(" // created zxid comment1\n // created zxid comment2\n // created zxid comment3\n", jRecord.getJavaFieldComments(fields.get(0)));
+ assertEquals(" // last modified zxid\n // last modified zxid\n // last modified zxid\n", jRecord.getJavaFieldComments(fields.get(1)));
+ assertEquals(" /* created */\n /* created */\n /* created */\n", jRecord.getJavaFieldComments(fields.get(2)));
+ assertEquals(" /** last modified */\n /** last modified */\n", jRecord.getJavaFieldComments(fields.get(3)));
+ assertEquals(" /** version */\n /** version */\n", jRecord.getJavaFieldComments(fields.get(4)));
+ assertEquals(" // child version\n /** child version */\n /** child version */\n", jRecord.getJavaFieldComments(fields.get(5)));
+ assertEquals(" /* acl version */\n // acl version\n /* acl version */\n", jRecord.getJavaFieldComments(fields.get(6)));
+ assertEquals(" // owner id if ephemeral, 0 otw\n", jRecord.getJavaFieldComments(fields.get(7)));
+ assertEquals(" // last modified children\n", jRecord.getJavaFieldComments(fields.get(8)));
+ }
+ }
+
+ @Test
+ public void testMultiLineComments() throws ParseException, NoSuchFieldException, IllegalAccessException {
+ String juteStr = "module org.apache.zookeeper.data {\n"
+ + " /**\n"
+ + " * information explicitly stored by the server persistently\n"
+ + " */\n"
+ + " // StatPersisted Comment\n"
+ + " /* StatPersisted Comment */\n"
+ + " class StatPersisted {\n"
+ + " /**\n"
+ + " * created zxid\n"
+ + " */\n"
+ + " long czxid;\n"
+ + " /**\n"
+ + " * last modified zxid comment1\n"
+ + " */\n"
+ + " /**\n"
+ + " * last modified zxid comment2\n"
+ + " */\n"
+ + " long mzxid;\n"
+ + " /*\n"
+ + " * created\n"
+ + " */\n"
+ + " long ctime; /* multi-line\n"
+ + "end of line */\n"
+ + " /*\n"
+ + " last modified\n"
+ + " */"
+ + " long mtime; /* A multi-line end of line comment. */ /* Another multi-line end of line comment. */ /* Yet another\n"
+ + "end of line comment. */ /* Comment belong to new field */\n"
+ + " /* version comment */\n"
+ + " int version; // version\n"
+ + " /**\n"
+ + " * child version\n"
+ + " */\n"
+ + " /**\n"
+ + " * child version comment2\n"
+ + " */\n"
+ + " int cversion; // child version\n"
+ + " /* acl version */\n"
+ + " int aversion; /* acl version */ /* acl version */ // acl version\n"
+ + " /*\n"
+ + " ephemeralOwner comment\n"
+ + " */\n"
+ + " // ephemeralOwner comment\n"
+ + " /*\n"
+ + " ephemeralOwner comment\n"
+ + " */\n"
+ + " long ephemeralOwner; // owner id if ephemeral, 0 otw\n"
+ + " /*\n"
+ + " pzxid comment\n"
+ + " */\n"
+ + " long pzxid; // last modified children\n"
+ + " }\n"
+ + "}";
+ try (StringReader stringReader = new StringReader(juteStr)) {
+ Rcc parser = new Rcc(stringReader);
+ JFile jFile = parser.Input();
+ List mRecords = getField(jFile, "mRecords", List.class);
+ assertEquals(1, mRecords.size());
+
+ JRecord jRecord = mRecords.get(0);
+ assertEquals("StatPersisted", jRecord.getName());
+ List fields = jRecord.getFields();
+ assertFiled(fields);
+
+ assertEquals(
+ "/**\n"
+ + " * information explicitly stored by the server persistently\n"
+ + " */\n"
+ + "// StatPersisted Comment\n"
+ + "/* StatPersisted Comment */\n", jRecord.getRecordComments());
+ assertEquals(" /**\n * created zxid\n */\n", jRecord.getJavaFieldComments(fields.get(0)));
+ assertEquals(" /**\n * last modified zxid comment1\n */\n /**\n * last modified zxid comment2\n */\n",
+ jRecord.getJavaFieldComments(fields.get(1)));
+ assertEquals(" /*\n * created\n */\n /* multi-line\n end of line */\n", jRecord.getJavaFieldComments(fields.get(2)));
+ assertEquals(" /*\n last modified\n */\n"
+ + " /* A multi-line end of line comment. */\n"
+ + " /* Another multi-line end of line comment. */\n"
+ + " /* Yet another\n"
+ + " end of line comment. */\n", jRecord.getJavaFieldComments(fields.get(3)));
+ assertEquals(" /* Comment belong to new field */\n /* version comment */\n // version\n",
+ jRecord.getJavaFieldComments(fields.get(4)));
+ assertEquals(" /**\n * child version\n */\n /**\n * child version comment2\n */\n // child version\n",
+ jRecord.getJavaFieldComments(fields.get(5)));
+ assertEquals(" /* acl version */\n /* acl version */\n /* acl version */\n // acl version\n", jRecord.getJavaFieldComments(fields.get(6)));
+ assertEquals(" /*\n"
+ + " ephemeralOwner comment\n"
+ + " */\n"
+ + " // ephemeralOwner comment\n"
+ + " /*\n"
+ + " ephemeralOwner comment\n"
+ + " */\n"
+ + " // owner id if ephemeral, 0 otw\n", jRecord.getJavaFieldComments(fields.get(7)));
+ assertEquals(" /*\n pzxid comment\n */\n // last modified children\n", jRecord.getJavaFieldComments(fields.get(8)));
+ }
+ }
+
+ private void assertFiled(List fields) {
+ assertEquals(9, fields.size());
+ assertEquals("long", fields.get(0).getType().getJavaType());
+ assertEquals("czxid", fields.get(0).getName());
+ assertEquals("long", fields.get(1).getType().getJavaType());
+ assertEquals("mzxid", fields.get(1).getName());
+ assertEquals("long", fields.get(2).getType().getJavaType());
+ assertEquals("ctime", fields.get(2).getName());
+ assertEquals("long", fields.get(3).getType().getJavaType());
+ assertEquals("mtime", fields.get(3).getName());
+ assertEquals("int", fields.get(4).getType().getJavaType());
+ assertEquals("version", fields.get(4).getName());
+ assertEquals("int", fields.get(5).getType().getJavaType());
+ assertEquals("cversion", fields.get(5).getName());
+ assertEquals("int", fields.get(6).getType().getJavaType());
+ assertEquals("aversion", fields.get(6).getName());
+ assertEquals("long", fields.get(7).getType().getJavaType());
+ assertEquals("ephemeralOwner", fields.get(7).getName());
+ assertEquals("long", fields.get(8).getType().getJavaType());
+ assertEquals("pzxid", fields.get(8).getName());
+ }
+
+ private T getField(final Object target,
+ final String fieldName,
+ final Class fieldClassType) throws NoSuchFieldException, IllegalAccessException {
+ Class> targetClazz = target.getClass();
+ Field field = targetClazz.getDeclaredField(fieldName);
+ field.setAccessible(true);
+ return fieldClassType.cast(field.get(target));
+ }
+}