Annotate files based on filenames

Hello,

Summary:

I want to annotate (potentially empty) files in the project view based on file name with a problem descriptor.

Detail:

I intend to highlight/annotate suspicious files in the project that should perhaps not be checked in to source code management systems: things like ssh keys, certificates etc. These files may not have a registered reader in the IDE, and I do not necessarily want to read them: just to highlight them in the project tree view as suspicious based on the file name patterns.

I have explored using an Annotator, but it seems that annotators are most suited for scenarios when you have a language file and you intend to annotate content, like the "simple:" example in the documentation. LocalInspectionTool also seems promising, and overriding its "checkFile" gives me a PsiFile, however attaching a ProblemDescriptor to the file seems to require a PsiElement, which I don't necessarily have as I do not intend to "look" into the file, and I don't care if the file is empty.

It sounds like a very simple problem to solve, but unfortunately I don't know how to solve it! Any ideas would be very welcome.

I am happy for the inspection to be triggered automatically or manually invoked as part of a security analysis of the codebase.

Kind regards,
Dayo

6 comments
Comment actions Permalink

heya

in your file definition (which extends PsiFileBase) add this method:

@Override
public Icon getIcon(int flags) {
if(pathOk())  // you need to add this custom method.
       return super.getIcon(flags);
else
      return warningIcon(); // you need to add this custom method.
}

you could get file name with path like this:

 
String path = this.getVirtualFile().getCanonicalPath();



you would need to register file extensions etc.

but this way you would not need to peek into file content.

0
Comment actions Permalink

Thank you Imants for the suggestion! The problem is that there are potentially many file types that I am intereted in: currently over 400 extension and name types! I do not want to create and register a filetype for each, especially since I am not reading them :-)

In the end, I used a combination of an IconProvider and a TreeStructureProvider to solve the problem. The IconProvider looks at the file name to optionally layer a warning icon on the PsiFile icon, and the TreeStructureProvider allows me to "setTooltip" on the corresonding PsiFileNode's presentation, giving a reason for the warning icon.

Although this is potentially multiple passes over the same node (Icon and TreeStructure), the check I needed to do is very efficient, and is thus perhaps satisfactory for my needs.

Kind regard,
Dayo

0
Comment actions Permalink

this is a neat solution, Dayo.

I did not know about TreeStructureProvider. Thank you very much.

0
Comment actions Permalink

B-)

The solution is not perfect though, as I find that the IconProvider does not work with files that do not have an associated file type in the IDE. The jury is still out on how to layer a warning icon on those ones.

It seems the iconProvider simply ignores file nodes that do not have an associated file type and provides the default "white sheet" icon, I need to find a way to control that behaviour ;\

Kind regards,
Dayo

0
Comment actions Permalink

you could define one catch-all file type.

users could add to this file type missing file extensions through

Settings > Editor > File Types > Registered Patterns

0
Comment actions Permalink

Thanks Imants!

It would almost be impossible to add the extensions manually, but your suggestion was actually helpful and I ended up defining a FileType along with a FileTypeFactory to identify files of interest. For those that may be wondering what my final solution was, here goes:

  • Defined an IconProvider
    • in the getIcon method, I obtained the PsiElement's containing File and subsequently the name of that file, and checked whether it met my "suspicious" file criteria, returning an appropriate Icon if it does.
    • the IconProvider was registered in the "extensions" area of the plugin.xml as
       
      <iconProvider implementation = ... />
    • this did not catch all the relevant files I was interested in. It seems the IconProvider is called only for files that have an associated file type, this is solved in the next step
  • Defined a FileType that would represent the files of interest and a dummy Language that simply just returned an instance of the FileType
    • To wire this up I defined a FileTypeFactory, overriding its createFileTypes and passing an instance of FileType above and a FileNameMatcher to the FileTypeConsumer's "consume" method
    • The FileNameMatcher simply applied my pattern match in it's "accept" method to determine if a file name is "suspicious"
    • I finally wired the FileTypeFactory under the "extensions" area of plugin.xml as
    •  
      <fileTypeFactory implementation= ... />
  • Finally, the TreeStructureProvider provided the tootip (as described above) to explain why the warning icon was put on the file node in the project view, that too was registered as usual:
    •  
      <treeStructureProvider implementation= ... />


I wouldn't know if there are better ways of doing this, but that is the solution that worked 99% of the time! There is still one corner case though of a file, named id_dsa (the name of an ssh private key file) that seems to be opened by the system text editor. This file would not bodge: it shows the correct tooltip but not the correct icon. I don't know why ?:|, because the RSA equivalent, named id_rsa works, and they are both matched by name. I am not too fussed though, but it would be nice to nail down the reason - it could be another subtle nuance that I have not accounted for in the way the IntelliJ platform works.

Kind regards,
Dayo

0

Please sign in to leave a comment.