how to get module?

Hi,

How can I get the module which corresponds to a VirtualFile. For example if there is VirtualFile named dir then I can call dir.getProject() to obtain the respective project. Is there a similar getModule() method to obtain the respective Module object.

10 comments
Comment actions Permalink

com.intellij.openapi.roots.ProjectFileIndex#getModuleForFile or com.intellij.openapi.roots.FileIndexFacade#getModuleForFile.

BTW I just found that by using Go To Symbol and searching for getModuleForFile in the Community source. In this case I cheated because I knew the method already existed, but generally the methods in the platform are named very consistently and this is a really useful way of finding functionality. If the obvious name (getModuleForFile or maybe getModuleByFile) didn't work I might search for *module*file and see what comes up. You can find all sorts of interesting things this way.

0
Comment actions Permalink

VirtualFile doesn't have method getProject() and it can't have it because if several projects are open the same VirtualFile may be used in several projects.
See ModuleUtil class.

0
Comment actions Permalink

Thank you Colin. That's exactly what I've been looking for. And also thanks for the little trick :)

0
Comment actions Permalink

Hi Alexander,

Actually VirtualFile has a getProject() method. I was looking for getModule() method.

0
Comment actions Permalink

Check again, com.intellij.openapi.vfs.VirtualFile doesn't have getProject() and it can't have it because IntelliJ virtual file system is implemented at application level, it is not related to projects. It is impossible to implement getProject() for file.

0
Comment actions Permalink

My bad. You're right. VirtualFile doesn't have a getProject() method. I've confused it with a PsiDirectory. BTW I suppose there isn't a single method to find out the base dir of the module, from a PsiDirectory

0
Comment actions Permalink

'Base dir of the module' is a bad term. Module file (*.iml) may be stored anywhere (and unlikely you care). Module may have any amount of content roots and each content root may have any amount of source roots, test source roots, etc. I think you need one of those:
ProjectFileIndex.getSourceRootForFile()
ProjectFileIndex.getContentRootForFile()

0
Comment actions Permalink

The real scenario is that I have a module hierarch like below

\UntitledProject
     \UntitledModule
          \src
               \main
                    \conf
                         settings.xml
                    \java (source root)
                         foo.java

When I add a new file template (a class) to java folder I need to add an entry to settings.xml file
I can get the 'java' folder as PsiDirectory and assume its name is 'javaPsiDir'

Then in order to find settings.xml I do following

final Module untitledModule = FileIndexFacade.getInstance(javaPsiDir.getProject()).getModuleForFile(javaPsiDir.getVirtualFile());
final VirtualFile untitledModuleDir = module.getModuleFile().getParent();
final VirtualFile settingsXmlFile = untitledModuleDir.findFileByRelativePath(
                "src + File.separator + "main + File.separator + "conf + File.separator + "settings.xml");

0
Comment actions Permalink

Avoid using getModuleFile(). It is *.iml that can be stored anywhere.
No need in File.separator, IntelliJ virtual file system works with '/' on all OSes. Native slash must be used in UI only.

Better would be

    final VirtualFile sourceRoot = ProjectFileIndex.SERVICE.getInstance(javaPsiDir.getProject()).getSourceRootForFile(javaPsiDir.getVirtualFile());
    if (sourceRoot != null) {
      final VirtualFile settingsXmlFile = sourceRoot.findFileByRelativePath("../conf/settings.xml");
    }
// or
    final VirtualFile contentRoot = ProjectFileIndex.SERVICE.getInstance(javaPsiDir.getProject()).getContentRootForFile(javaPsiDir.getVirtualFile());
    if (contentRoot != null) {
      final VirtualFile settingsXmlFile = contentRoot.findFileByRelativePath("src/main/conf/settings.xml");
    }

0
Comment actions Permalink

Thank you very much Alexander,

    final VirtualFile contentRoot = ProjectFileIndex.SERVICE.getInstance(javaPsiDir.getProject()).getContentRootForFile(javaPsiDir.getVirtualFile());
    if (contentRoot != null) {
      final VirtualFile settingsXmlFile = contentRoot.findFileByRelativePath("src/main/conf/settings.xml");
    }

approach seems quite elegent and straight forward.

0

Please sign in to leave a comment.