How to check if a ThemeResource exists or not?

I am localizing and I would like to have the capability of inheriting image resources for a theme from a default locale if no overriding resources are defined in a lang/country specific folder. To accomplish this I planned to anticipate the possibility of a lang/country folder with a custom overriding image for the current locale in a specific theme folder. In my resource loader I wanted to create a new ThemeResource and attempt to prepend the locale path and check if that resolved to an
existing
resource or not. If it did not resolve to an existing resource then I wanted to simply default to loading a resource without the locale path prepended. The problem with this approach though, is that I cannot find a way to actually check if the ThemeResource exists or not. Since a ThemeResource is dynamically bound there is no exists() method I can call to determine if it is available or not. I noticed there is a deprecated getRelativeLocation method on the Application class that would give the URI of an ApplicationResource, but even if this weren’t a deprecated method it wouldn’t be feasible for what I want to do, because I would like to locate a ThemeResource and test for existance, not an ApplicationResource.

Any ideas or suggestions? Thanks.

Okay, so I figured this out myself. I’ve posted my answer in case anyone is curious what I ended up doing for this.


ClassLoader loader = MyVaadinApplication.class.getClassLoader();
URL url = loader.getResource("VAADIN/themes/mytheme/" + localePrefixedPath);
if (url==null) 
{
   // No locale specific resource exists for this resource.
}

This probably works in your application but I want to point out that it is not a fully generic solution that could be applied by the framework.

Themes do not necessarily have to be in the application WAR and be served by the Vaadin servlet but can also e.g. be statically served by a front-end server. This is commonly the case on portals, but can also happen e.g. when an Apache front-end is used to serve static resources and only some requests are forwarded to the Vaadin servlet. Therefore, in the more general case, it can be impossible for the server to know what theme resources are actually available - only the client could find that out by trying to fetch them.

So what could be a good solution for this issue?

In the most general case, it is impossible for the server to know which ThemeResources will or will not be available from the network location of the client with the cookies currently present on the client etc. Some of the theme resources might come from the same server, some could come from elsewhere. Thus, the information can only be obtained by trying to access the resource from the client.

In most applications, theme resources do not depend on the session and you know about how the application is deployed (whether static resources are served from the WAR or not, …) and there is no strange network mapping/filtering/proxying/… between the client and the server so you might have a way to check what is available either directly on the server or by trying to access the resource with the same URL the client would use (not directly available on the server but needs to be put together from pieces taken from different places).

I was able to get around using something like this:

String r = “img/”+view+“.png”;
UI ui = UI.getCurrent();
InputStream s = ui.getSession().getService().getThemeResourceAsStream(this, ui.getTheme(), r);
if(s != null) {
b.setIcon(new ThemeResource(r));
IOUtils.closeQuietly(s);
}