Current Project in Application Component

I'm trying to figure out what module a virtual file belongs to using the BulkListener interface and subscribing to VirtualFileManager.VFS_CHANGES. I found one solution somewhere else, but it needs an instance of project and I'm not sure where to get that from. The only thing I've found so far is all open projects which doesn't help.

 
@Override
public void before(@NotNull List<? extends VFileEvent> events) {

    for (VFileEvent event : events) {

        VirtualFile file = event.getFile();
        if
(file != null && file.isInLocalFileSystem()) {
          // Where should an instance for Project come from?
 
             Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(file);
 
        }
    }
}


The reason I'm doing this is so I can webdav files to a remote server if they belong to a certain module type. Maybe this should be a module component instead? All modules of the same type will need to have access to project settings as well. Thanks for the help.

6 comments
Comment actions Permalink

In an application component, there is no such thing as "current project". There is also no such thing as "a module that a virtual file belongs to". You can have multiple open projects which share the same content roots, in which case the virtual file will belong to multiple modules in several different projects.

Therefore, you do in fact need to enumerate all open projects, and check whether any of them contains the modules for which your synchronization is enabled.

0
Comment actions Permalink

Thanks Yole that's very helpful! I wasn't thinking about the problem correctly, but it makes more sense now. I still have a quesion though. When you say the following:

yole wrote:

Therefore, you do in fact need to enumerate all open projects, and check whether any of them contains the modules for which your synchronization is enabled.


I'm able to loop through all the projects and get the module for file, however I'm not able to get the module type to check if it's the module I would like to sync. I can see it in the debugger as myModuleType, however there is no method exposed to get the module type from a Module object. How would you recommend I go about this?

And maybe I'm going about this problem completely wrong.

I need certain local filesystem roots, which I was going be the module root, to sync to a webdav root location. I've actually used the local deployments for this before, but you need a separate program to mount a webdav folder so my goal is to get this working directly in intellij without needing a separate application.

I've also written a filesystem watcher in python that does syncs the files, but again I would like to make an intellij plugin. I think I just need to understand the best way to tackle this problem through the openapi. I also plan to support full filesystem options with the LocalFileOperationsHandler as it looks like that covers all the other File operations besides the save action.

Again thanks for the help! I feel like I'm making decent progress, it's just a huge system to get my brain wrapped around.

0
Comment actions Permalink

The API is inverted here (for dependency reasons): to get the module type of a module, you need to call ModuleType.get(module).

0
Comment actions Permalink

Great that worked perfectly! I'll keep beating down this path to see what I can come up with. Would marking the webdav roots as sources be a good approach for syncing to a remote root be a good approach? Are source roots easilly accesible through the api?

My code now looks like this in case anyone else has this question as well.

@Override public void after(@NotNull List<? extends VFileEvent> events) {     for (VFileEvent event : events) {         VirtualFile virtualFile = event.getFile();         Project[] projects = ProjectManager.getInstance().getOpenProjects();         if (virtualFile != null && virtualFile.isInLocalFileSystem()) {             for (Project project : projects) {                 Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(virtualFile);                 if (module != null && ModuleType.get(module).getId().equals(DWModuleType.getID())) {                     System.out.println(virtualFile.getCanonicalPath());                 }             }         }     } }


Thanks!

0
Comment actions Permalink

To access the source roots through the API, use ModuleRootManager.getInstance(module).getSourceRoots().


0
Comment actions Permalink

That worked great! Thank you! This seems to get me the files I want to upload and is a good start. I'm not sure it's the best approach, but it works for now.

@Override public void after(@NotNull List<? extends VFileEvent> events) {     for (VFileEvent event : events) {         VirtualFile virtualFile = event.getFile();         Project[] projects = ProjectManager.getInstance().getOpenProjects();         if (virtualFile != null && virtualFile.isInLocalFileSystem()) {             for (Project project : projects) {                 Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(virtualFile);                 if (module != null && ModuleType.get(module).getId().equals(DWModuleType.getID())) {                     for (VirtualFile sourceRoot : ModuleRootManager.getInstance(module).getSourceRoots()) {                         if (virtualFile.getPath().contains(sourceRoot.getPath())) {                             System.out.println(virtualFile.getPath());                         }                     }                 }             }         }     } }

0

Please sign in to leave a comment.