package com.baselet.generator.java.jp;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.baselet.generator.java.Field;
import com.baselet.generator.java.JavaClass;
import com.baselet.generator.java.Method;
import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.PackageDeclaration;
import com.github.javaparser.ast.body.BodyDeclaration;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.ConstructorDeclaration;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.ModifierSet;
import com.github.javaparser.ast.body.TypeDeclaration;
public class JpJavaClass implements JavaClass {
private final Logger log = LoggerFactory.getLogger(JpJavaClass.class);
private CompilationUnit cu;
private final List<MethodDeclaration> methods = new ArrayList<MethodDeclaration>();
private final List<ConstructorDeclaration> constructors = new ArrayList<ConstructorDeclaration>();
private ClassOrInterfaceDeclaration clazz;
private final List<FieldDeclaration> fields = new ArrayList<FieldDeclaration>();
public JpJavaClass(String filename) throws ClassParserException {
FileInputStream in = null;
try {
in = new FileInputStream(filename);
cu = JavaParser.parse(in);
} catch (Throwable e) { // catch all exceptions and errors (otherwise stuff like a renamed jpg file would silently fail)
throw new ClassParserException("Cannot parse " + filename + ": " + e.getMessage(), e);
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
log.error("Error while closing file " + filename, e);
}
}
extractInformation(filename);
}
private void extractInformation(String filename) throws ClassParserException {
List<TypeDeclaration> types = cu.getTypes();
for (TypeDeclaration type : types) {
if (type instanceof ClassOrInterfaceDeclaration) {
clazz = (ClassOrInterfaceDeclaration) type;
}
List<BodyDeclaration> members = type.getMembers();
for (BodyDeclaration member : members) {
if (member instanceof FieldDeclaration) {
fields.add((FieldDeclaration) member);
}
else if (member instanceof ConstructorDeclaration) {
constructors.add((ConstructorDeclaration) member);
}
else if (member instanceof MethodDeclaration) {
methods.add((MethodDeclaration) member);
}
}
}
if (clazz == null) {
throw new ClassParserException("No toplevel type declaration found in " + filename + ".");
}
}
@Override
public String getName() {
return clazz.getName().toString();
}
@Override
public Field[] getFields() {
Field[] newFields = new Field[fields.size()];
int i = 0;
for (FieldDeclaration field : fields) {
newFields[i] = new JpField(field);
i++;
}
return newFields;
}
@Override
public Method[] getMethods() {
Method[] newMethods = new Method[methods.size() + constructors.size()];
int i = 0;
for (ConstructorDeclaration constructor : constructors) {
newMethods[i] = new JpConstructor(constructor);
i++;
}
for (MethodDeclaration method : methods) {
newMethods[i] = new JpMethod(method);
i++;
}
return newMethods;
}
@Override
public ClassRole getRole() {
if (clazz.isInterface()) {
return ClassRole.INTERFACE;
}
else if ((clazz.getModifiers() & ModifierSet.ABSTRACT) != 0) {
return ClassRole.ABSTRACT;
}
else {
return ClassRole.CLASS;
}
}
@Override
public String getPackage() {
PackageDeclaration packageDecl = cu.getPackage();
if (packageDecl == null) {
return "";
}
String packageWithExtra = packageDecl.toString().replace("package ", "");
return packageWithExtra.substring(0, packageWithExtra.lastIndexOf(";"));
}
}