How to access property files for an Eclipse Internationalization (I18N) Java custom rule

Hello Community

I am writing a custom rule that checks if all Messages Objects method invocation string arguments are available in the specified Messages.properties file. All Strings are externalized into Messages.properties file (non java!) with key-value-pairs.

I tried to get the path with the JavaFileScanner context and check if there is a Messages.properties in that path, but this only works for files that are in the same folder as the analyzed file.

The issue is the location of the Messages.properties file. Sometimes it’s located in the same folder as the analyzed file, sometimes it’s located in another folder.

Is there another way to access these Messages.properties files?

I am using:
Sonar Plugin api 6.7
Sonar Java Plugin 5.1.0.13090

Many thanks in advance

Hello @tlg,

From my point of view, with a classical “java custom rules plugin” approach, it’s going to be pretty difficult to achieve what you want without having to search for property files all the time.

I think you should have a look here to think a little bit bigger and move from a custom rules plugin to a real plugin (which would still act as a custom plugin for java, but not only): https://docs.sonarqube.org/display/DEV/Developing+a+Plugin

Maybe the best approach would be to add a new sensor to your custom plugin, which would collect properties files. You’ll then probably need two passes, to be sure to collect all the properties files in a first pass. However I don’t really know how it’s going to impact the way the custom rules are triggered. I didn’t tried.

As a idea of a Sensor implementation, you may start with the following:

import org.sonar.api.batch.Phase;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;

@Phase(name = Phase.Name.PRE) // to force execution order
public class MyCustomPluginSensor implements Sensor {

  private final FileSystem fs;

  // fileSystem is going to be injected at runtime (don't forget to register the sensor in your Plugin class)
  public MyCustomPluginSensor(FileSystem fs) {
    this.fs = fs;
  }

  public Iterable<InputFile> propertyFiles() {
    return fs.inputFiles(fs.predicates().matchesPathPattern("**/*.properties"));
  }

  @Override
  public void describe(SensorDescriptor descriptor) {
    // TODO describe sensor
  }

  @Override
  public void execute(SensorContext context) {
    // TODO do something when triggered ? Collected property files ?
  }
}

Note that it’s up to you know to be able to feed the custom rules with the files which will be collected by the sensor. You may want to have a look on github at our other open sources plugin to see how sensors are working.

Hope this helps,
Michael

Note that I moved your topic in the “plugin development” forum.

2 Likes