GetElementFromFQN

Apache NetBeans Wiki Index

Note: These pages are being reviewed.

Variant A: Using ClasspathInfo and a CancelableTask

public ElementHandle<TypeElement> getElementHandle(Project p, final String fqn)
{
    FileObject projRoot = p.getProjectDirectory();

    // actually, should find srcRoot using p.getLookup().lookup(Sources.class) and iterating over the SourceGroups.
    // This is cheating, but illustrative...
    FileObject srcRoot = projRoot.getFileObject("src").getFileObject("java");

    ClasspathInfo ci = ClasspathInfo.create(srcRoot);
    JavaSource js = JavaSource.create(ci);
    Searcher searcher = new Searcher(fqn);
    try
    {
        js.runUserActionTask(searcher, true);
    }
    catch (IOException ex)
    {
        // kvetch
    }

    if (searcher.handle == null)
    {
        throw new IllegalArgumentException("Cannot find class: " + fqn);
    }
}

private class Searcher implements CancellableTask<CompilationController>
{
    private String fqn;
    ElementHandle<TypeElement> handle;

    Searcher(String fqn)
    {
        this.fqn = fqn;
    }

    public void cancel() {}

    public void run(CompilationController info) throws Exception {
        TypeElement te = info.getElements().getTypeElement(fqn);
        handle = ElementHandle.create(te);
    }
}

Variant B: Using ClassIndex (+ How the get the sources?)

    private Collection<FileObject> findByClassName(FileObject fo, String fqnClassName) {

        Set<FileObject> files = new java.util.LinkedHashSet<FileObject>();

        ClassPath bootCp = ClassPath.getClassPath(fo, ClassPath.BOOT);
        ClassPath compileCp = ClassPath.getClassPath(fo, ClassPath.COMPILE);
        ClassPath sourcePath = ClassPath.getClassPath(fo, ClassPath.SOURCE);
        final ClasspathInfo info = ClasspathInfo.create(bootCp, compileCp, sourcePath);
        int lastIndexOfDot = fqnClassName.lastIndexOf(".");
        String simpleClassName;
        if (lastIndexOfDot > 0) {
            simpleClassName = fqnClassName.substring(lastIndexOfDot + 1);
        } else {
            simpleClassName = fqnClassName;
        }

        /**
         * Search in own project sources AND in sources of dependencies
         */
        final Set<ElementHandle<TypeElement>> result = info.getClassIndex().getDeclaredTypes(simpleClassName, ClassIndex.NameKind.SIMPLE_NAME, EnumSet.of(ClassIndex.SearchScope.SOURCE, ClassIndex.SearchScope.DEPENDENCIES));
        for (ElementHandle<TypeElement> te : result) {
            final String qualifiedName = te.getQualifiedName();
            if (!qualifiedName.equals(fqnClassName)) {
                continue;
            }

            //--> HURRAY: you found the matching elementHandle


            //BONUS: How the get the sources of an ElementHandle?

            //NOTE: will not return a file for a class without sources (f.e. maven dep without attached sources)
            final FileObject file = org.netbeans.api.java.source.SourceUtils.getFile(te, info);
            if (null != file) {
                files.add(file);
            }
        }
        return files;
    }