package org.incha.compiler.dom; import java.io.File; import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.IImportContainer; import org.eclipse.jdt.core.IInitializer; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.ILocalVariable; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IPackageDeclaration; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IParent; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeRoot; import org.eclipse.jdt.core.JavaModelException; import org.incha.core.JavaProject; import org.incha.ui.TaskProgressMonitor; import org.incha.utils.FileVisitor; import org.incha.utils.IoUtils; /** * Utilities para * */ public final class JavaDomUtils { /** * Solamente tiene metodos estaticos, no deberia ser nunca instanseada */ private JavaDomUtils() {} public static void visit(final IJavaElement e, final JavaDomVisitor v) throws JavaModelException { if(startJavaElement(v, e)) { if (e instanceof ICompilationUnit) { for (final IType type : ((ICompilationUnit) e).getTypes()) { visit(type, v); } } else if (e instanceof IParent) { final IJavaElement[] childs = ((IParent) e).getChildren(); for (final IJavaElement child : childs) { visit(child, v); } } } endJavaElement(v, e); } /** * @param v visitor. * @param e current element. */ private static boolean startJavaElement(final JavaDomVisitor v, final IJavaElement e) { if (e instanceof IImportContainer) { return v.startVisit((IImportContainer) e); } else if (e instanceof IPackageDeclaration){ return v.startVisit((IPackageDeclaration) e); } else if (e instanceof ILocalVariable){ return v.startVisit((ILocalVariable) e); } else if (e instanceof IField){ return v.startVisit((IField) e); } else if (e instanceof IInitializer){ return v.startVisit((IInitializer) e); } else if (e instanceof IMethod){ return v.startVisit((IMethod) e); } else if (e instanceof IType){ return v.startVisit((IType) e); } else if (e instanceof IPackageFragment){ return v.startVisit((IPackageFragment) e); } else if (e instanceof ITypeRoot){ return v.startVisit((ITypeRoot) e); } return false; } /** * @param v visitor. * @param e java element. */ private static void endJavaElement(final JavaDomVisitor v, final IJavaElement e) { if (e instanceof IImportContainer) { v.endVisit((IImportContainer) e); } else if (e instanceof IPackageDeclaration){ v.endVisit((IPackageDeclaration) e); } else if (e instanceof ILocalVariable){ v.endVisit((ILocalVariable) e); } else if (e instanceof IField){ v.endVisit((IField) e); } else if (e instanceof IInitializer){ v.endVisit((IInitializer) e); } else if (e instanceof IMethod){ v.endVisit((IMethod) e); } else if (e instanceof IType){ v.endVisit((IType) e); } else if (e instanceof IPackageFragment){ v.endVisit((IPackageFragment) e); } else if (e instanceof ITypeRoot){ v.endVisit((ITypeRoot) e); } } public static ICompilationUnit[] getCompilationUnits( final JavaProject project, final TaskProgressMonitor monitor) throws IOException { final int numberOfFiles = getNumberOfSources(project); final JavaDomBuilder builder = new JavaDomBuilder(project.getName()); monitor.beginTask("Compile project " + project.getName(), numberOfFiles); final List<ICompilationUnit> units = new LinkedList<ICompilationUnit>(); try { final List<File> sources = project.getBuildPath().getSources(); for (final File file : sources) { IoUtils.visitTo(file, new FileVisitor() { @Override public void exit(final File t) throws IOException { } @Override public boolean enter(final File t) throws IOException { if (monitor.isCanceled()) { return false; } if (t.isFile() && t.getName().endsWith(".java")) { units.add(builder.build(t, null)); monitor.worked(monitor.getProgress() + 1); } return true; } }); } } finally { monitor.done(); } return units.toArray(new ICompilationUnit[units.size()]); } /** * @param project * @return * @throws IOException */ private static int getNumberOfSources(final JavaProject project) throws IOException { final AtomicInteger i = new AtomicInteger(); final List<File> sources = project.getBuildPath().getSources(); for (final File file : sources) { IoUtils.visitTo(file, new FileVisitor() { @Override public void exit(final File t) throws IOException { } @Override public boolean enter(final File t) throws IOException { if (t.isFile() && t.getName().endsWith(".java")) { i.addAndGet(1); } return true; } }); } return 0; } /** * @param units * @return * @throws JavaModelException */ public static IType[] getAllTypes(final ICompilationUnit[] units) throws JavaModelException { final List<IType> types = new LinkedList<IType>(); for (final ICompilationUnit unit : units) { for (final IType t : unit.getTypes()) { types.add(t); } } return types.toArray(new IType[types.size()]); } /** * @param type the type to test. * @param types type. * @return * @throws JavaModelException */ public static boolean hasSupertype(final IType type, final IType[] types) throws JavaModelException { final String superTypeName = type.getSuperclassName(); if (superTypeName != null) { for (final IType t : types) { if (superTypeName.equals(t.getFullyQualifiedName())) { return true; } } } return false; } /** * Returns top declaring type of the IMember object by recursivly walking through the types that declare the object. * @param member * IMember object to evaluate * @return * Top declaring type of this object, or object itself if is top in the nesting hierarchy */ public static IType getTopDeclaringType(final IMember member) { if (member==null) return null; if ((member.getDeclaringType()==null) && (member instanceof IType)) return (IType) member; IType type=member.getDeclaringType(); while (type.getDeclaringType()!=null) { type=type.getDeclaringType(); } return type; } /** * @param unit * @return * @throws JavaModelException */ public static List<IJavaElement> getAllNodes(final ICompilationUnit unit) throws JavaModelException { final List<IJavaElement> result = new LinkedList<IJavaElement>(); visit(unit, new JavaDomVisitorAdapter() { @Override public boolean startVisit(final IPackageDeclaration e) { result.add(e); return true; } @Override public boolean startVisit(final ILocalVariable e) { result.add(e); return true; } @Override public boolean startVisit(final IPackageFragment e) { result.add(e); return true; } @Override public boolean startVisit(final IType e) { result.add(e); return true; } @Override public boolean startVisit(final IMethod e) { result.add(e); return true; } @Override public boolean startVisit(final IInitializer e) { result.add(e); return true; } @Override public boolean startVisit(final IField e) { result.add(e); return true; } @Override public boolean startVisit(final IImportContainer e) { result.add(e); return true; } }); return result; } /** * @param unit * @return * @throws JavaModelException */ public static List<IMember> getAllMembers(final ICompilationUnit unit) throws JavaModelException { final List<IMember> result = new LinkedList<IMember>(); visit(unit, new JavaDomVisitorAdapter() { @Override public boolean startVisit(final IType e) { result.add(e); return true; } @Override public boolean startVisit(final IMethod e) { result.add(e); return true; } @Override public boolean startVisit(final IField e) { result.add(e); return true; } }); return result; } }