I am writing some code to parse java source code. I am experimenting with Eclipse JDT AST Parser. My code is given below. (Parsing code). I am testing the parser against a Mailer application that I wrote in Java (second code snippet). My parser is visiting all methods except the generateEmail() and the debug() methods. I have looked all over the place but I am not able to understand for the life of me why its happening. Can anyone tell me what I am doing wrong? Is it a memory issue? I am not getting any OutOfMemoryException
I want to visit the specific methods with the MethodVisitor method to get access to statements and variables in a particular method.
My Parsing code
public class RuleEngine {
public static void parse(String file) {
File java = new File(file);
ASTParser parser = ASTParser.newParser(AST.JLS3);
String code = readFile(java);
parser.setSource(code.toCharArray());
parser.setKind(ASTParser.K_COMPILATION_UNIT);
final CompilationUnit cu = (CompilationUnit) parser.createAST(null);
cu.accept(new ASTVisitor() {
public boolean visit(ImportDeclaration id) {
Name imp = id.getName();
debug("import", id.getName().getFullyQualifiedName());
return false;
}
public boolean visit(VariableDeclarationFragment node) {
SimpleName name = node.getName();
debug("var.declaration", (name.getFullyQualifiedName() + ":" + cu.getLineNumber(name.getStartPosition())));
return false; // do not continue
}
public boolean visit(MethodDeclaration method) {
debug("method", method.getName().getFullyQualifiedName());
debug("method.return", method.getReturnType2().toString());
List<SingleVariableDeclaration> params = method.parameters();
for(SingleVariableDeclaration param: params) {
debug("param", param.getName().getFullyQualifiedName());
}
Block methodBlock = method.getBody();
String myblock = methodBlock.toString();
methodVisitor(myblock);
return false;
}
});
}
public static void methodVisitor(String content) {
debug("entering met visitor", "1");
ASTParser metparse = ASTParser.newParser(AST.JLS3);
metparse.setSource(content.toCharArray());
metparse.setKind(ASTParser.K_STATEMENTS);
Block block = (Block) metparse.createAST(null);
block.accept(new ASTVisitor() {
public boolean visit(VariableDeclarationFragment var) {
debug("met.var", var.getName().getFullyQualifiedName());
return false;
}
public boolean visit(SimpleName node) {
debug("SimpleName node", node.getFullyQualifiedName());
return false;
}
public boolean visit(IfStatement myif) {
debug("if.statement", myif.toString());
return false;
}
});
}
public static void debug(String ref, String message) {
System.out.println(ref +": " + message);
}
public static void main(String[]args) {
parse("MailerDaemon.java");
}
This is my MailerDaemon Code
public boolean isBccMode() {
return bccMode;
}
public void setBccMode(boolean bccMode) {
this.bccMode = bccMode;
}
public void setServerPort(String serverPortAddr) {
String[] elems = serverPortAddr.split("\\:");
this.setServerAddr(elems[0]);
this.setSmtpPort(elems[1]);
}
public String getServerAddr() {
int i = 0;
return serverAddr;
}
public void setServerAddr(String serverAddr) {
this.serverAddr = serverAddr;
}
public boolean isSslOn() {
return isSslOn;
}
public void setSslOn(boolean isSslOn) {
this.isSslOn = isSslOn;
}
public String getSmtpPort() {
return smtpPort;
}
public void setSmtpPort(String smtpPort) {
this.smtpPort = smtpPort;
}
public String getFromEmail() {
return fromEmail;
}
public void setFromEmail(String fromEmail) {
this.fromEmail = fromEmail;
}
public String getToEmails() {
return toEmails;
}
public void setToEmails(String toEmails) {
this.toEmails = toEmails;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getCcList() {
return ccList;
}
public void setCcList(String ccList) {
this.ccList = ccList;
}
public String getBccList() {
return bccList;
}
public void setBccList(String bccList) {
this.bccList = bccList;
}
public String getFile() {
return file;
}
public void setFile(String file) {
debug("filename: " + file);
this.file = file;
}
public void generateEmail() {
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", this.getSmtpPort());
if(isSslOn()) {
props.put("mail.smtp.socketFactory.port", this.getSmtpPort());
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
}
props.put("mail.smtp.host", getServerAddr());
Session session = Session.getDefaultInstance(props, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(getUsername(), getPassword());
}
});
Message msg = new MimeMessage(session);
try {
msg.setFrom(new InternetAddress(this.getFromEmail()));
if (getToEmails() != null) {
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(getToEmails()));
} else if (isBccMode()) {
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(getFromEmail()));
}
//msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(getCcList()));
msg.setSubject(getSubject());
//msg.setText(getMessage());
MimeBodyPart messagePart = new MimeBodyPart();
messagePart.setText(getMessage());
/*
MimeBodyPart attachments = new MimeBodyPart();
FileDataSource fd = new FileDataSource(getFile());
attachments.setDataHandler(new DataHandler(fd));
attachments.setFileName(fd.getName());
*/
Multipart mp = new MimeMultipart();
mp.addBodyPart(messagePart);
//mp.addBodyPart(attachments);
msg.setContent(mp);
Transport.send(msg);
debug("Done. Closing Session...");
} catch (AddressException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void debug(String message) {
System.out.println("[DEBUG]: " + message);
}
I see no evident problem with your parsing code. I hope its failing somewhere when its trying to parse the
generateEmail()
method. Since the parser follows a sequential approach, thedebug()
method is also not getting parsed. Try to enclose the statements within thepublic boolean visit(MethodDeclaration method)
in a try-catch block with probably a Throwable clause.Also have a check for your
readFile()
method. One issue that is mostly seen while reading a file is missing to append new line character to each line. Not appending a new line results in erroneous construction of the code, especially when there are comments in the code. You may inspectcompilationUnit.getProblems()
method to check any such problems.@UnniKris - Thank you for your response. I changed the
readFile()
method and included a\n
after the newline was written to the StringBuilder. This worked. All my methods were successfully parsed.My code snippet for the readFile() method is posted here: