Watch for updated properties in Wicket

2019-07-19 08:28发布

问题:

In my current project we need to implement a way for texters to manage the wicket messages/internationalization via upload of property files.

Also see this question: Administrating internationalized wicket applications

As suggested there, I've implemented a custom IStringResourceLoader and added it at the beginning of the StringResourceLoader list to override any properties already in place:

getResourceSettings().getStringResourceLoaders().add(0, new CustomStringResourceLoader()); 

This however is not enough, because updates can happen and need to be loaded at runtime. StringResources are cached by wicket and updated only when the ResourceWatcher is triggered.

I found where Wicket adds the string resources to the watcher: the PropertiesFactory in the settings. The method to add a resource to the watcher is addToWatcher(...). However this method is protected and also the whole setup suggests this is used for development purposes and not for production.

I managed to use this method by extending PropertiesFactory and effectively creating a custom version to add to settings:

getResourceSettings().setPropertiesFactory(new CustomPropertiesFactory(getResourceSettings()));
getResourceSettings().setResourcePollFrequency(Duration.seconds(1));

So my Question is: I feel this is quite the circuitious solution. Is there another way to watch for changing properties files?

回答1:

My solution to the problem:

getResourceSettings().getStringResourceLoaders().add(0, new CustomResourceLoader());
getResourceSettings().getResourceFinders().add(new Path("/pathToResources"));
getResourceSettings().setResourcePollFrequency(Duration.seconds(1));

This inserts my CustomResourceLoader at the beginning of the list so all properties are first checked there.

The added Path tells the PropertiesFactory to look for resources in a given arbitrary directory outside of wicket.

I needed custom names for my resource files as well, I realized this in the CustomResourceLoader:

public String loadStringResource(final Class<?> clazz, final String key, final Locale locale, final String style, final String variation) {
    final String myResourceFilename = createCustomResourceFileName(locale); 
    final IPropertiesFactory pF = Application.get().getResourceSettings().getPropertiesFactory();
    final org.apache.wicket.resource.Properties props = pF.load(clazz, myResourceFilename);
    ...
}

When using the PropertiesFactory to load the files, it adds them to the internal IModificationWatcher automatically.

It turns out that part of the problem was, that the resource files are in a non-standard encoding. This can be fixed by adding a special IPropertyLoader to the PropertiesFactory in the settings:

((PropertiesFactory) getResourceSettings().getPropertiesFactory()).getPropertiesLoaders().add(0,
            new UtfPropertiesFilePropertiesLoader("properties", "your-favorite-encoding"));