JavaParser only showing comment, not JavaDoc - java

Disclaimer: I am only a lowly trainee, so please forgive me if I made elementary mistakes :(
I am writing an automatic API generator, and the classes need JavaDoc as well as comments because some of the values the API contains shouldn't be written down in the JavaDoc (exampleResponse for example).
However, it seems that the comments above the individual Methods replace the Javadoc, so when I want to get the description from the JavaDoc (which i want to do so I don't have to write it again in the comments), I have a problem.
Using getJavadoc() always returns null. I also attempted to use getOrphanComments(), but it returned null. Did I misunderstand the documentation? I assumed if I wrote two comments above a method, the top one would move to orphanComments for that method.
Is there any way to work around this?

Let the MethodDeclaration object is method
than you can get java doc using
if( method.hasComment() && method.getComment() instanceof JavadocComment ){
JavadocComment javaDoc = (JavadocComment)method.getComment();
// now you can get the content using
String content = javaDoc.getContent();
}

For the following types:
public final String name;
public final String signature;
public final String returnType;
public final Type returnFullType; // com.github.javaparser.ast.type.Type
public final String body;
public final String[] modifiers;
public final String[] parameterNames;
public final String[] parameterTypes;
public final Type[] parameterFullTypes; // com.github.javaparser.ast.type.Type
public final String[] exceptions;
public final String jdComment;
public final MethodDeclaration nativeJP_API_reference; // com.github.javaparser.ast.body.MethodDeclaration
This is a constructor for a class Method of my own concoction:
Method (MethodDeclaration md)
{
NodeList<Modifier> ml = md.getModifiers();
NodeList<Parameter> pl = md.getParameters();
NodeList<ReferenceType> te = md.getThrownExceptions();
this.nativeJP_API_reference = md;
this.name = md.getNameAsString();
this.signature = md.getDeclarationAsString();
this.returnType = md.getType().toString();
this.returnFullType = md.getType();
this.body = md.getBody().isPresent() ? md.getBody().get().toString() : null; // In ConstructorDeclaration, this is an Optional<BlockStmt>, not here!
this.modifiers = new String[ml.size()];
this.parameterNames = new String[pl.size()];
this.parameterTypes = new String[pl.size()];
this.parameterFullTypes = new com.github.javaparser.ast.type.Type[pl.size()];
this.exceptions = new String[te.size()];
this.jdComment = md.hasJavaDocComment() ? md.getJavadocComment().get().toString() : null;
int i = 0;
for (Parameter p : pl)
{
parameterNames[i] = p.getName().toString();
parameterTypes[i] = p.getType().toString();
parameterFullTypes[i] = p.getType();
i++;
}
i = 0;
for (Modifier m : ml) modifiers[i++] = m.toString();
i = 0;
for (ReferenceType r : te) exceptions[i++] = r.toString();;
}

Related

Cant convert enum type to short and vice versa

In one class I have this code
public class RPCMessage implements Serializable{
public static final short REQUEST = 0;
public static final short REPLY = 1;
public enum MessageType{REQUEST, REPLY};
private MessageType messageType;
public MessageType getMessageType() {
return messageType;
}
public void setMessageType(MessageType messageType) {
this.messageType = messageType;
}
}
I another class I try to access it but it gives me error there.
Error Code:
int buffSize = c.lenInBytes();
ByteBuffer bb = ByteBuffer.allocate(buffSize);
short typeNum = (short) c.getMessageType();
int index = 0;
bb.putShort(0,typeNum);
index+=2;
Also error in setting the same attribute
RPCMessage c = new RPCMessage();
ByteBuffer bb = ByteBuffer.wrap(mData);
int index = 0;
c.setMessageType(bb.getShort(index));
index += 2;
I am quite new to Java programming. Please help me out with this. Thanks in advance :)
The implementation is not appropriate in your case.
I will try to elaborate the use of Enums :
Your RPCMessage class should be something like :
public class RPCMessage implements Serializable {
//public static final short REQUEST = 0; // Not required
//public static final short REPLY = 1; // Not required
public enum MessageType {
REQUEST((short)0),
REPLY((short)1);
private short enumVar;
private MessageType(short var){
enumVar = var;
}
};
private MessageType messageType;
public MessageType getMessageType() {
return messageType;
}
public void setMessageType(MessageType messageType) {
this.messageType = messageType;
}
}
Your second snippet should look like :
//int buffSize = c.lenInBytes();
//ByteBuffer bb = ByteBuffer.allocate(buffSize);
short typeNum = (short) c.getMessageType().enumVar; // Only tested this line
//int index = 0;
//bb.putShort(0,typeNum);
//index+=2;
Your third snippet should look like :
RPCMessage c = new RPCMessage();
//ByteBuffer bb = ByteBuffer.wrap(mData);
//int index = 0;
//c.setMessageType(bb.getShort(index));
c.setMessageType(MessageType.REPLY); // You can change this line as per your need
//index += 2;
To test the enum I have used below main function in RPCMessage class
public static void main(String[] args) {
RPCMessage c = new RPCMessage();
//int buffSize = 0;
c.setMessageType(MessageType.REPLY);
//ByteBuffer bb = ByteBuffer.allocate(buffSize);
short typeNum = (short) c.getMessageType().enumVar;
//int index = 0;
//bb.putShort(0,typeNum);
//index+=2;
System.out.println(typeNum);
}
Please note that the above answer will need appropriate changes as per your need.
I have provided just the part related to enum to let you understand it in easy way.
There are more eloquent ways to use the enum.
For more details on enum please check :
https://www.javacodegeeks.com/2015/09/how-and-when-to-use-enums-and-annotations.html
In case you are wondering between use of enum vs constants you can refer :
https://codereview.stackexchange.com/questions/125415/best-practice-for-constant-class-in-java/125416#125416

Does it make sense to have input parameters to a class?

I created a class of DocumentFilter type as follows:
public class CustomDocumentFilter extends DocumentFilter
{
private StyledDocument styledDocument;
private JTextPane panetxt;
public CustomDocumentFilter(JTextPane panetxt) {
this.panetxt = panetxt; // Not really necessary
this.styledDocument = panetxt.getStyledDocument();
}
private final StyleContext styleContext = StyleContext.getDefaultStyleContext();
Pattern pattern = buildPattern(mystring);
private Pattern buildPattern(String mystring)
{
StringBuilder sb = new StringBuilder();
String[] toke = StringUtils.split(mystring,",");
for (String token : toke) {
sb.append("\\b");
sb.append(token);
}
if (sb.length() > 0) {
sb.deleteCharAt(sb.length() - 1);
}
Pattern p = Pattern.compile(sb.toString());
return p;
}
My question is: how to include mystring within the call of CustomDocumentFilter?:
//String mystring="lalala";
((AbstractDocument) editeur.getDocument()).setDocumentFilter(new CustomDocumentFilter(editeur));
EDIT:
Regarding the first way Jonathan suggests, I get this:
error: cannot find symbol Pattern pattern = buildPattern(mystring); ^ symbol: variable mystring location: class TextEditor.CustomDocumentFilter
I don't know if it has to do with the Pattern clause
Not 100% sure what is desired from the description. But I think your simply trying to ask how to get your local string value into your new CustomDocumentFilter object.
Well that is simple and you have choices! More than the two I show here.
first easy way is to add it to the constructor
public CustomDocumentFilter(JTextPane panetxt, String myString) {
...
pattern = buildPattern(mystring);
}
((AbstractDocument) editeur.getDocument()).setDocumentFilter(new CustomDocumentFilter(editeur, myString));
another way is to use a method that returns the object
public CustomDocumentFilter myFunction(String myString) {
pattern = buildPattern(mystring);
return this;
}
((AbstractDocument) editeur.getDocument()).setDocumentFilter(new CustomDocumentFilter(editeur).myFunction(myString));

Unable to create new object

I created these two files in java and they don't compile. This error comes up:
cannot find symbol C02FootprintV1".
Why doesn't the program recognize the object? I am new to this.
How could I fix this problem?
public class CO2FootprintV1 {
private double myGallonsUsed;
private double myTonsCO2;
private double myPoundsCO2;
CO2FootprintV1(double gals) {
myGallonsUsed = gals;
}
public void calcTonsCO2() {
myTonsCO2 = myGallonsUsed * 0.878;
}
public double getTonsCO2() {
return myTonsCO2;
}
public void convertTonsToPoundsCO2() {
myPoundsCO2 = myTonsCO2 * 220462262;
}
public double getPoundsCO2() {
return myPoundsCO2;
}
}
public class CO2FootprintV1Tester {
public static void main(String[] args) {
double gals;
double tonsCO2, poundsCO2;
gals = 1300;
CO2FootprintV1 object = new C02FootprintV1(gals);
object.calcTonsCO2();
tonsCO2 = object.getTonsCO2();
object.convertTonsToPoundsCO2();
poundsCO2 = object.getPoundsCO2();
}
}
On the line
CO2FootprintV1 object = new C02FootprintV1(gals);
you have C02 (see zero two) on the right hand side, you meant for it to be
CO2FootprintV1 object = new CO2FootprintV1(gals);
or CO2 (see oh two). Also, you should consider that the error messages your tools give you might be correct.
Just change:
CO2FootprintV1 object = new C02FootprintV1(gals);
to:
CO2FootprintV1 object = new CO2FootprintV1(gals);
That's why it is important to have good naming practice.
You put a "0" (cero) instead of an "O" (letter):
CO2FootprintV1 object = new C02FootprintV1(gals);
Try this:
CO2FootprintV1 object = new CO2FootprintV1(gals);

Associating a pair of Strings in Java 7 and looping over them

Given the following code:-
//setup code and import statements, including:
private static String baseURL = Environment.getTestWebsiteURL();
public static String articleOneName = ArticleCreationTest.getArticleOneName();
public static String articleTwoName = ArticleCreationTest.getArticleTwoName();
public static String articleThreeName = ArticleCreationTest.getArticleThreeName();
public static String articleOnePath = ArticleCreationTest.getArticleOnePath();
public static String articleTwoPath = ArticleCreationTest.getArticleTwoPath();
public static String articleThreePath = ArticleCreationTest.getArticleThreePath();
public static String[] articlesPathArray = {articleOnePath, articleTwoPath, articleThreePath}
#BeforeClass
public static void setup() {
driver = Driver.getURL();
for (String s : articlesArray) {
if (s == null) {
//tell me which articles could not be found
System.out.println("Could not find an article for: " + s + " , perhaps it wasn't created in the prior test");
} else {
//assuming array holds some path values, append to the baseURL
driver.get(baseURL + s);
}
}
#Test...
//run some test assertions against the baseURL + path website page that is returned
I need the code to loop through wherever the path variable holds a value and run tests. The current solution is not helpful wherever the prior ArticleCreationTest fails to generate the article, because the variable simply contains null. So the text is: "Could not find an article for: null, perhaps it wasn't created in the prior test".
What I really need is to associate the articleName with the articlePath so the message is something like: "Could not find ArticleOne: perhaps is wasn't created", and then run the tests against all that were created. Perhaps some kind of hashmap or 2D array?
Based on the code given,
public static String articleOneName = ArticleCreationTest.getArticleOneName();
public static String articleTwoName = ArticleCreationTest.getArticleTwoName();
public static String articleThreeName = ArticleCreationTest.getArticleThreeName();
public static String articleOnePath = ArticleCreationTest.getArticleOnePath();
public static String articleTwoPath = ArticleCreationTest.getArticleTwoPath();
public static String articleThreePath = ArticleCreationTest.getArticleThreePath();
public static String[] articlesPathArray = {articleOnePath, articleTwoPath, articleThreePath}
It seems like, it is a list of articleNames and articlePaths
List<String> acticleNames = new ArrayList<String>();
List<String> acticlePaths = new ArrayList<String>();
The List will contain the Strings to be checked, which can be used for the tests.
I need the code to loop through wherever the path variable holds a
value and run tests
You can check this condition by checking if (s != null), currently you are checking for
if (s == null)

Java XML Serializing, Missing fields in file

this is the issue at hand, when trying to serialize the class below with the code below i'm getting is the below xml file without all the strings in the class.
The Class (some static values have changed but basically it), I left out all the generated get\set but they are all there with public access modifiers.
public class NotificationConfiguration implements Serializable
{
public static final String PORT_KEY = "mail.smtp.port";
public static final String DEFAULT_PORT_VALUE = "587";
public static final String TTL_KEY = "mail.smtp.starttls.enable";
public static final String DEFAULT_TTL_VALUE = "true";
public static final String AUTH_KEY = "mail.smtp.auth";
public static final String DEFAULT_AUTH_VALUE = "true";
public static final String MAIL_SERVER_KEY = "mail.smtp.host";
public static final String DEFAULT_MAIL_CLIENT_HOST = "smtp.gmail.com";
public static final String DEFAULT_MAIL_CLIENT_USERNAME = "*********";
public static final String DEFAULT_MAIL_CLIENT_PASSWORD = "*********";
public static final String DEFAULT_MAIL_CLIENT_ADDRESS = "*********";
public static final String DEFAULT_ADMIN_EMAIL = "*********";
public static final long DEFAULT_MAIL_INTERVAL = 24*60*60*1000; //One time a day default
public static final String SAVED_FOLDER_NAME = "C:\\Library";
public static final String SAVED_FILE_NAME = "C:\\Library\\NotificationCfg.xml";
private String portValue = DEFAULT_PORT_VALUE;
private String ttlValue = DEFAULT_TTL_VALUE;
private String authValue = DEFAULT_AUTH_VALUE;
private String mailClientHost = DEFAULT_MAIL_CLIENT_HOST;
private String mailClientUserName = DEFAULT_MAIL_CLIENT_USERNAME;
private String mailClientPassword = DEFAULT_MAIL_CLIENT_PASSWORD;
private String mailClientAddress = DEFAULT_MAIL_CLIENT_ADDRESS;
private String adminEMail = DEFAULT_ADMIN_EMAIL;
private boolean overdueSubsNotificationEnabled = false;
private boolean adminReportNotificationEnabled = false;
private long mailInterval =
}
The code used to serialize, which also creates the folder if missing.
public void storeChanges()
{
try
{
try
{
File f = new File(NotificationConfiguration.SAVED_FOLDER_NAME);
f.mkdir();
}
catch (Exception e){}
XMLEncoder encoder = new XMLEncoder( new BufferedOutputStream(new FileOutputStream(NotificationConfiguration.SAVED_FILE_NAME)));
encoder.writeObject(notificationConfig);
encoder.close();
System.out.println(LOG_CONFIGURATION_STORED);
}
catch (Exception ex)
{
System.out.println(LOG_CONFIGURATION_NOT_STORED + ex.getMessage());
}
}
The XML file received, with no exceptions thrown while serializing.
It basically just has the long value.
XMLEncoder encodes information about how to restore your object. If field values haven't changed from their defaults, XMLEncoder doesn't store anything.
This can cause confusion.
Hence, my rules of thumb when using XMLEncoder are:
1. don't initialize fields. don't do private String foo = DEFAULT_FOO;
2. don't do anything in the default constructor.
3. have some other method, or factory that will give you a "default" setup if needed.
I highly recommend to read again the XMLEncoder Javadoc
I will point out the main differences with the binary serialization we all know.
to restore the instance it need the class definition available to the JVM
It serializes only the data. And only the modified from default data.
As result of the 2 points above - is that there is no reason to serialize Static final values - they are part of the class definition.
The binary serialization on the other hand does serialize the class definition and can load from byte stream a class that was not available to the JVM before.
That is why you got results that you see. It Ok this is behavior by design and you use it right. It seems just not to be what you need.
By the way see what Xstream has to offer.
What is SAVED_FOLDER_NAME ? Is that like a factory object and did you by any chance call setMailInterval on that object?
Could that be that only mailInterval has a getter?
Just looked again the question apparently there is getter for all fields so ...

Categories