All Downloads are FREE. Search and download functionalities are using the official Maven repository.

playn.appcachelinker.AppCacheLinker Maven / Gradle / Ivy

There is a newer version: 2.0.8
Show newest version
/**
 * Copyright 2011 The PlayN Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package playn.appcachelinker;

import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;

import com.google.gwt.core.ext.LinkerContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.linker.Artifact;
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.EmittedArtifact;
import com.google.gwt.core.linker.CrossSiteIframeLinker;

/**
 * A linker for public path resources in the application cache. To use:
 *
 * 
    *
  1. Add {@code manifest="YOURMODULENAME/appcache.nocache.manifest"} to the * {@code } tag in your main html file. E.g., * {@code }
  2. * *
  3. Add a mime-mapping to your web.xml file: *
    {@code 
     * manifest
     * text/cache-manifest
     * 
     * }
    *
  4. *
* *

On every compile, this linker will regenerate the appcache.nocache.manifest file with files * from the public path of your module. * *

This linker has some default behavior with respect to which files will be included in the * manifest, which can be modified by overriding {@link #accept}. * *

To add additional static files to the manifest, override {@link #staticCachedFiles}. * *

Note: This linker currently extends {@link CrossSiteIframeLinker}. For better JavaScript * debugging, this should be changed to extend {@link * com.google.gwt.core.linker.DirectInstallLinker} instead once * http://code.google.com/p/chromium/issues/detail?id=87005 has been fixed. */ public class AppCacheLinker extends CrossSiteIframeLinker { private static final HashSet DEFAULT_EXTENSION_WHITELIST = new HashSet( Arrays.asList(new String[] { // .wav files explicitly excluded, since HTML games use .mp3 "js", "html", "jpg", "jpeg", "png", "gif", "mp3", "ogg", "mov", "avi", "wmv", "webm", "css", "json", "flv", "swf",})); private static final String MANIFEST = "appcache.nocache.manifest"; @Override public String getDescription() { return "AppCacheLinker"; } /* * Standard linker that also outputs a manifest file based on the public * resources */ @Override public ArtifactSet link(TreeLogger logger, LinkerContext context, ArtifactSet artifacts) throws UnableToCompleteException { ArtifactSet toReturn = super.link(logger, context, artifacts); // Create the general cache-manifest resource for the landing page: toReturn.add(emitLandingPageCacheManifest(context, logger, toReturn, staticCachedFiles())); return toReturn; } /** * Determines whether our not the given should be included in the app cache * manifest. Subclasses may override this method in order to filter out * specific file patterns. * * @param path the path of the resource being considered * @return true if the file should be included in the manifest */ protected boolean accept(String path) { // GWT Development Mode files if (path.equals("hosted.html") || path.endsWith(".devmode.js")) { return false; } // Default or welcome file if (path.equals("/")) { return true; } // Whitelisted file extension int pos = path.lastIndexOf('.'); if (pos != -1) { String extension = path.substring(pos + 1); if (DEFAULT_EXTENSION_WHITELIST.contains(extension)) { return true; } } // Not included by default return false; } /** * Creates the cache-manifest resource specific for the landing page. */ private Artifact emitLandingPageCacheManifest(LinkerContext context, TreeLogger logger, ArtifactSet artifacts, String[] staticFiles) throws UnableToCompleteException { // Create a string of cacheable resources StringBuilder publicSourcesSb = new StringBuilder(); StringBuilder publicStaticSourcesSb = new StringBuilder(); // Iterate over all emitted artifacts, and collect all cacheable artifacts for (@SuppressWarnings("rawtypes") Artifact artifact : artifacts) { if (artifact instanceof EmittedArtifact) { EmittedArtifact ea = (EmittedArtifact) artifact; String path = "/" + context.getModuleFunctionName() + "/" + ea.getPartialPath(); if (accept(path)) { publicSourcesSb.append(path + "\n"); } } } // Iterate over all static files if (staticFiles != null) { for (String staticFile : staticFiles) { if (accept(staticFile)) { publicStaticSourcesSb.append(staticFile + "\n"); } } } // build cache list StringBuilder sb = new StringBuilder(); sb.append("CACHE MANIFEST\n"); sb.append("# Unique id #" + (new Date()).getTime() + "." + Math.random() + "\n"); // we have to generate this unique id because the resources can change but // the hashed cache.html files can remain the same. sb.append("# Note: must change this every time for cache to invalidate\n"); sb.append("\n"); sb.append("CACHE:\n"); sb.append(publicSourcesSb.toString()); sb.append("# Static cached files\n"); sb.append(publicStaticSourcesSb.toString()); sb.append("\n\n"); sb.append("# All other resources require the user to be online.\n"); sb.append("NETWORK:\n"); sb.append("*\n"); logger.log(TreeLogger.DEBUG, "Make sure you have the following" + " attribute added to your landing page's tag: "); // Create the manifest as a new artifact and return it: return emitString(logger, sb.toString(), MANIFEST); } /** * Override this method to force the linker to include additional files in the * manifest. * * @return array of additional files to include in the manifest. */ protected String[] staticCachedFiles() { return null; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy