4

I am trying to build a offline gwt app using HTML5 cache manifest and local storage, but to do that, i need to build the manifest file listing all the GWT generated files, right? Can i do this during the compile process or is it better to do this in a shell script?

Julio Faerman
  • 13,228
  • 9
  • 57
  • 75

3 Answers3

5

This should be done using a Linker, so that your resources are automatically added to the manifest at compile time. I know there exists an HTML5 cache manifest linker, since the GWT team has mentioned it a few times, but I don't know where the source is.

The closest alternative (and probably a good starting point for writing an HTML5 linker) is the Gears offline linker. Gears' offline manifests are pretty similar to HTML5's, so it's probably a matter of changing a few lines to make it work.

There's also an informative video about using GWT linkers to have your app take advantage of HTML5 Web Workers.

Jason Hall
  • 20,632
  • 4
  • 50
  • 57
2

I just had to do this other day at work. Like the previous answer says, you just need to add a linker. Here's an example of one that creates a manifest file for the Safari user agent based on a template file.

// Specify the LinkerOrder as Post... this does not replace the regular GWT linker and runs after it.
@LinkerOrder(LinkerOrder.Order.POST)
public class GwtAppCacheLinker extends AbstractLinker {
  public String getDescription() {
    return "to create an HTML5 application cache manifest JSP template.";
  }

  public ArtifactSet link(TreeLogger logger, LinkerContext context, ArtifactSet artifacts) throws UnableToCompleteException {
    ArtifactSet newArtifacts = new ArtifactSet(artifacts);
    // search through each of the compilation results to find the one for Safari. Then 
    // generate application cache for that file
    for (CompilationResult compilationResult : artifacts.find(CompilationResult.class)) {
      // Only emit the safari version
      for (SelectionProperty property : context.getProperties()) {
        if (property.getName().equals("user.agent")) {
          String value = property.tryGetValue();
          // we only care about the Safari user agent in this case
          if (value != null && value.equals("safari")) {
            newArtifacts.add(createCache(logger, context, compilationResult));
            break;
          }
        }
      }
    }

    return newArtifacts;
  }

  private SyntheticArtifact createCache(TreeLogger logger, LinkerContext context, CompilationResult result)
      throws UnableToCompleteException {
    try {
      logger.log(TreeLogger.Type.INFO, "Using the Safari user agent for the manifest file.");
      // load a template JSP file into a string. This contains all of the files that we want in our cache
      // manifest and a placeholder for the GWT javascript file, which will replace with the actual file next
      String manifest = IOUtils.toString(getClass().getResourceAsStream("cache.template.manifest"));
      // replace the placeholder with the real file name
      manifest = manifest.replace("$SAFARI_HTML_FILE_CHECKSUM$", result.getStrongName());
      // return the Artifact named as the file we want to call it
      return emitString(logger, manifest, "cache.manifest.");
    } catch (IOException e) {
      logger.log(TreeLogger.ERROR, "Couldn't read cache manifest template.", e);
      throw new UnableToCompleteException();
    }
  }
}
Pete Aykroyd
  • 123
  • 7
1

Use the gwt2go library's GWT Application Manifest generator to do precisely that. That was easy. :)

Joseph Lust
  • 19,340
  • 7
  • 85
  • 83