- 

Available since OmniFaces 3.6

This ResourceHandler generates the manifest.json based on any WebAppManifest found in the runtime classpath.

Usage

  1. Create a class which extends WebAppManifest in your web application project.
  2. Give it the appropriate CDI scope annotation, e.g ApplicationScoped, SessionScoped or even RequestScoped (note that a ViewScoped obviously won't work).
  3. Override properties accordingly conform the rules in the W3 spec.
  4. Note: you do not need to explicitly register this resource handler. It's already automatically registered.

Here's a concrete example:

package com.example;

import java.util.Arrays;
import java.util.Collection;
import javax.enterprise.context.ApplicationScoped;

import org.omnifaces.resourcehandler.WebAppManifest;

@ApplicationScoped
public class ExampleWebAppManifest extends WebAppManifest {

    @Override
    public String getName() {
        return "Example Application Name";
    }

    @Override
    public String getShortName() {
        return "EAN";
    }

    @Override
    public Collection<ImageResource> getIcons() {
        return Arrays.asList(
            ImageResource.of("logo.svg"),
            ImageResource.of("logo-120x120.png", Size.SIZE_120),
            ImageResource.of("logo-180x180.png", Size.SIZE_180),
            ImageResource.of("logo-192x192.png", Size.SIZE_192),
            ImageResource.of("logo-512x512.png", Size.SIZE_512)
        );
    }

    @Override
    public String getThemeColor() {
        return "#cc9900";
    }

    @Override
    public String getBackgroundColor() {
        return "#ffffff";
    }

    @Override
    public Display getDisplay() {
        return Display.STANDALONE;
    }

    @Override
    public Collection<Category> getCategories() {
        return Arrays.asList(Category.BUSINESS, Category.FINANCE);
    }

    @Override
    public Collection<RelatedApplication> getRelatedApplications() {
        return Arrays.asList(
            RelatedApplication.of(Platform.PLAY, "https://play.google.com/store/apps/details?id=com.example.app1", "com.example.app1"),
            RelatedApplication.of(Platform.ITUNES, "https://itunes.apple.com/app/example-app1/id123456789")
        );
    }
}

Finally reference it in your template exactly as follows, with the exact library name of omnifaces and exact resource name of manifest.json. You cannot change these values.

<link rel="manifest" href="#{resource['omnifaces:manifest.json']}" crossorigin="use-credentials" />

The crossorigin attribute is optional, you can drop it, but it's mandatory if you've put the SessionScoped annotation on your WebAppManifest bean, else the browser won't retain the session cookies while downloading the manifest.json and then this resource handler won't be able to maintain the cachability. See next section.

Caching

Basically, the CDI scope annotation being used is determinative for the autogenerated v= query parameter indicating the last modified timestamp. If you make your WebAppManifest bean RequestScoped, then it'll change on every request and the browser will be forced to re-download it. If you can however guarantee that the properties of your WebAppManifest are static, and thus you can safely make it ApplicationScoped, then the v= query parameter will basically represent the timestamp of the first time the bean is instantiated.

Demo

The #{resource['omnifaces:manifest.json']} is already configured on this showcase web application via an application scoped ManifestJson bean as shown below. Rightclick the page and View Source and explore the <link rel="manifest">. It should point to the autogenerated manifest.json file.

Demo
Demo source code
package org.omnifaces.showcase;

import static java.util.Arrays.asList;

import java.util.Collection;

import javax.enterprise.context.ApplicationScoped;

import org.omnifaces.resourcehandler.WebAppManifest;

@ApplicationScoped
public class ManifestJson extends WebAppManifest {

    @Override
    public String getName() {
        return "OmniFaces Showcase";
    }

    @Override
    public String getShortName() {
        return "OFS";
    }

    @Override
    public Collection<ImageResource> getIcons() {
        return asList(ImageResource.of("layout/img/OmniFaces-logo.svg"));
    }

    @Override
    public String getThemeColor() {
        return "#373737";
    }

    @Override
    public String getBackgroundColor() {
        return "#f2f2f2";
    }

}