package org.wikbook.codesource; import japa.parser.JavaParser; import japa.parser.ParseException; import japa.parser.ast.CompilationUnit; import japa.parser.ast.Node; import japa.parser.ast.body.BodyDeclaration; import japa.parser.ast.body.JavadocComment; import japa.parser.ast.body.TypeDeclaration; import org.wikbook.text.Position; import org.wikbook.text.TextArea; import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; /** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */ abstract class Visit { static class CU extends Visit { /** The current compilation unit. */ private final CompilationUnit compilationUnit; /** . */ final String source; /** . */ private final TextArea sb; /** . */ String pkg; /** . */ final List<TypeSource> types; CU(String source) throws ParseException { this.compilationUnit = JavaParser.parse(new ByteArrayInputStream(source.getBytes())); this.source = source; this.sb = new TextArea(source); this.types = new ArrayList<TypeSource>(); } @Override void appendPathPrefix(StringBuilder path) { if (pkg.length() > 0) { path.append(pkg.replace('.', '/')).append('/'); } } @Override void appendFQNPrefix(StringBuilder path) { if (pkg.length() > 0) { path.append(pkg).append('.'); } } @Override CU getCU() { return this; } } static class TD extends Visit { /** . */ final Visit parent; /** . */ final LinkedList<LinkedList<CodeSource>> stack = new LinkedList<LinkedList<CodeSource>>(); /** . */ Iterator<Signature> constructorSignatures; /** . */ Iterator<Signature> methodSignatures; /** . */ final TypeDeclaration decl; TD(Visit parent, TypeDeclaration decl) { this.parent = parent; this.decl = decl; } String getPath() { StringBuilder path = new StringBuilder(); parent.appendPathPrefix(path); path.append(decl.getName()); path.append(".class"); return path.toString(); } String getFQN() { StringBuilder fqn = new StringBuilder(); parent.appendFQNPrefix(fqn); fqn.append(decl.getName()); return fqn.toString(); } @Override void appendPathPrefix(StringBuilder path) { parent.appendPathPrefix(path); path.append(decl.getName()); path.append('$'); } @Override void appendFQNPrefix(StringBuilder path) { parent.appendFQNPrefix(path); path.append(decl.getName()); path.append('.'); } @Override CU getCU() { return parent.getCU(); } } abstract CU getCU(); abstract void appendPathPrefix(StringBuilder path); abstract void appendFQNPrefix(StringBuilder path); final String clip(Node node) { CU cu = getCU(); // Get offset of the fragment int from = cu.sb.offset(Position.get(node.getBeginLine() - 1, 0)); int to = cu.sb.offset(Position.get(node.getEndLine() - 1, node.getEndColumn())); // Get relevant chars return cu.source.substring(from, to); } final String javaDoc(BodyDeclaration node) { JavadocComment doc = node.getJavaDoc(); return doc != null ? clip(doc) : null; } final String getPkg() { return getCU().pkg; } final void accept(CompilationUnitVisitor visitor) { getCU().compilationUnit.accept(visitor, this); } }