How to create directories for a package in a source root?

I have a PsiPackage instance for which I wish to create the corresponding directories in a source root, if they don't exist, so that I may create a Properties file in that package. The directories may not exist since our project requires that properties files are stored in a separate source root from the java files. Any hints on how to do this correctly?

What if I have multiple source roots in which these directories could be created? How do I show the source root chooser dialog that IDEA uses when creating a class in a package that spans multiple directories?

Thanks,
Gordon

0
Avatar
Permanently deleted user

Unfortunately this API is not opened, but if you don't mind dirty work you might want to look at com.intellij.idea.util.PackageUtil:

public static PsiDirectory findOrCreateDirectoryForPackage(Module module,
String packageName,
PsiDirectory baseDir,
boolean askUserToCreate);

The parameters' names are self-explanatory, I guess.

HTH,
Eugene.

0
Avatar
Permanently deleted user

Thanks, that takes care of actually creating the directories. I still have to figure out how to choose which module and baseDir to use since there may be multiple modules and source roots in which the user can choose to create the resource bundle. I'm envisioning a dialog which allows the user to select from a list of directories grouped by module. Is there something like that in IDEA that I can reuse?

0
Avatar
Permanently deleted user

Yes there is, but again, in closed API. See com.intellij.ide.util.DirectoryChooser class.

0
Avatar
Permanently deleted user

Have you looked at PackageUtil.getOrChooseDirectory ?

0
Avatar
Permanently deleted user

Going by the name, I assume that selects an existing directory for a package. In my case, the directory may not exist yet so the user has to select the module and base directory in which the package will be created.

0
Avatar
Permanently deleted user

I have a similiar requisite in my plugin where i have to create a class in a package that might not exist and in a source root of choice. Here's what i do:

+SourceFolder[] sourceFolders = ModuleRootManager.getInstance(getModule()).getContentEntries()[0].getSourceFolders();

PsiDirectory sourceDirectory;
if (sourceFolders.length > 1)
sourceDirectory = PackageUtil.getOrChooseDirectory((IdeView)DataManager.getInstance().getDataContext().getData(DataConstants.IDE_VIEW));
else
sourceDirectory = PsiManager.getInstance(getModule().getProject()).findDirectory(sourceFolders[0].getFile());

PsiDirectory classDirectory;
classDirectory = PackageUtil.findOrCreateDirectoryForPackage(getModule(), rootPackage, sourceDirectory, false);

if (classDirectory != null)
classDirectory.createClass(className);+

Hope this helps...

0
Avatar
Permanently deleted user

Thanks, that was exactly what I wanted.

I'm having another problem though. I create the properties file file with the following code snippet:

PsiDirectory pkgDir = PackageUtil.findOrCreateDirectoryForPackage(module, mPackage.getQualifiedName(), dir, false);
mPropertiesFile = PropertiesElementFactory.createPropertiesFile(mProject, "");
mPropertiesFile.setName(LOG_RESOURCES_FILENAME);
pkgDir.add(mPropertiesFile);

After this my plugin is able to manipulate the properties and everything seems to work, except that mPropertiesFile.getVirtualFile() returns null and the actual properties file is empty when I open it in the editor. Is there some step that I'm missing?

0
Avatar
Permanently deleted user

Well, I'm not 100% sure, but it seems that the factory returns non-physical file, i.e. with dummy virtual file. It makes no sense to add it to PsiDirectory (moreover an assertion should be added). Instead you should call PsiDirectory.createFile() and modify the contents later.

0
Avatar
Permanently deleted user

Ah, I see. I must just use the correct ".properties" extension and it will magically work. Cool :)

0
Avatar
Permanently deleted user

Another question :)

I'd like to keep the properties file sorted, since I'm just compulsive-obsessive like that. Unfortunately, PropertiesFile.addProperty() just appends to the end of the file. I tried writing my own insertion method which finds an existing property after which the new one should be inserted and then used addAfter on the PropertiesList to add the new one after it, but that gave me an unsupported operation error.

I could just recreate the contents of the file from a sorted copy of the names map every time I add a new property, but that seems rather inelegant and brute force. Is there a better way to do it?

0
Avatar
Permanently deleted user

I guess no. Please submit an issue to JIRA for adding PropertiesFile.addPropertyAfter(Property anchorProperty)

0

请先登录再写评论。