
io.dropwizard.bundles.assets.ConfiguredAssetsBundle Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dropwizard-configurable-assets-bundle Show documentation
Show all versions of dropwizard-configurable-assets-bundle Show documentation
An implementation of an AssetBundle for use in Dropwizard that allows user configuration.
package io.dropwizard.bundles.assets;
import com.google.common.base.Charsets;
import com.google.common.cache.CacheBuilderSpec;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import io.dropwizard.ConfiguredBundle;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkArgument;
/**
* An assets bundle (like io.dropwizard.assets.AssetsBundle) that utilizes configuration to provide
* the ability to override how assets are loaded and cached. Specifying an override is useful
* during the development phase to allow assets to be loaded directly out of source directories
* instead of the classpath and to force them to not be cached by the browser or the server. This
* allows developers to edit an asset, save and then immediately refresh the web browser and see the
* updated assets. No compilation or copy steps are necessary.
*/
public class ConfiguredAssetsBundle implements ConfiguredBundle {
private static final Logger LOGGER = LoggerFactory.getLogger(ConfiguredAssetsBundle.class);
private static final String DEFAULT_PATH = "/assets";
public static final CacheBuilderSpec DEFAULT_CACHE_SPEC =
CacheBuilderSpec.parse("maximumSize=100");
private static final String DEFAULT_INDEX_FILE = "index.htm";
private static final String DEFAULT_SERVLET_MAPPING_NAME = "assets";
private final Iterable> resourcePathToUriMappings;
private final CacheBuilderSpec cacheBuilderSpec;
private final String indexFile;
private final String assetsName;
/**
* Creates a new {@link ConfiguredAssetsBundle} which serves up static assets from
* {@code src/main/resources/assets/*} as {@code /assets/*}.
*
* @see ConfiguredAssetsBundle#ConfiguredAssetsBundle(String, String, String, String,
* CacheBuilderSpec)
*/
public ConfiguredAssetsBundle() {
this(DEFAULT_PATH);
}
/**
* Creates a new {@link ConfiguredAssetsBundle} which will configure the service to serve the
* static files located in {@code src/main/resources/${path}} as {@code /${path}}. For example,
* given a {@code path} of {@code "/assets"}, {@code src/main/resources/assets/example.js} would
* be served up from {@code /assets/example.js}.
*
* @param path the classpath and URI root of the static asset files
* @see ConfiguredAssetsBundle#ConfiguredAssetsBundle(String, String, String, String,
* CacheBuilderSpec)
*/
public ConfiguredAssetsBundle(String path) {
this(path, path, DEFAULT_INDEX_FILE, DEFAULT_SERVLET_MAPPING_NAME, DEFAULT_CACHE_SPEC);
}
/**
* Creates a new {@link ConfiguredAssetsBundle} which will configure the service to serve the
* static files located in {@code src/main/resources/${resourcePath}} as {@code /${uriPath}}. For
* example, given a {@code resourcePath} of {@code "/assets"} and a uriPath of {@code "/js"},
* {@code src/main/resources/assets/example.js} would be served up from {@code /js/example.js}.
*
* @param resourcePath the resource path (in the classpath) of the static asset files
* @param uriPath the uri path for the static asset files
* @see ConfiguredAssetsBundle#ConfiguredAssetsBundle(String, String, String, String,
* CacheBuilderSpec)
*/
public ConfiguredAssetsBundle(String resourcePath, String uriPath) {
this(resourcePath, uriPath, DEFAULT_INDEX_FILE, DEFAULT_SERVLET_MAPPING_NAME,
DEFAULT_CACHE_SPEC);
}
/**
* Creates a new AssetsBundle which will configure the service to serve the static files
* located in {@code src/main/resources/${resourcePath}} as {@code /${uriPath}}. If no file name
* is in ${uriPath}, ${indexFile} is appended before serving. For example, given a
* {@code resourcePath} of {@code "/assets"} and a uriPath of {@code "/js"},
* {@code src/main/resources/assets/example.js} would be served up from {@code /js/example.js}.
*
* @param resourcePath the resource path (in the classpath) of the static asset files
* @param uriPath the uri path for the static asset files
* @param indexFile the name of the index file to use
*/
public ConfiguredAssetsBundle(String resourcePath, String uriPath, String indexFile) {
this(resourcePath, uriPath, indexFile, DEFAULT_SERVLET_MAPPING_NAME, DEFAULT_CACHE_SPEC);
}
/**
* Creates a new AssetsBundle which will configure the service to serve the static files
* located in {@code src/main/resources/${resourcePath}} as {@code /${uriPath}}. If no file name
* is in ${uriPath}, ${indexFile} is appended before serving. For example, given a
* {@code resourcePath} of {@code "/assets"} and a uriPath of {@code "/js"},
* {@code src/main/resources/assets/example.js} would be served up from {@code /js/example.js}.
*
* @param resourcePath the resource path (in the classpath) of the static asset files
* @param uriPath the uri path for the static asset files
* @param indexFile the name of the index file to use
* @param assetsName the name of servlet mapping used for this assets bundle
*/
public ConfiguredAssetsBundle(String resourcePath, String uriPath, String indexFile,
String assetsName) {
this(resourcePath, uriPath, indexFile, assetsName, DEFAULT_CACHE_SPEC);
}
/**
* Creates a new {@link ConfiguredAssetsBundle} which serves up static assets from
* {@code src/main/resources/assets/*} as {@code /assets/*}.
*
* @param cacheBuilderSpec the spec for the cache builder
* @see ConfiguredAssetsBundle#ConfiguredAssetsBundle(Map, String, String, CacheBuilderSpec)
*/
public ConfiguredAssetsBundle(CacheBuilderSpec cacheBuilderSpec) {
this(DEFAULT_PATH, DEFAULT_PATH, DEFAULT_INDEX_FILE, DEFAULT_SERVLET_MAPPING_NAME,
cacheBuilderSpec);
}
/**
* Creates a new {@link ConfiguredAssetsBundle} which will configure the service to serve the
* static files located in {@code src/main/resources/${path}} as {@code /${path}}. For example,
* given a {@code path} of {@code "/assets"}, {@code src/main/resources/assets/example.js} would
* be served up from {@code /assets/example.js}.
*
* @param resourcePath the resource path (in the classpath) of the static asset files
* @param cacheBuilderSpec the spec for the cache builder
*/
public ConfiguredAssetsBundle(String resourcePath, CacheBuilderSpec cacheBuilderSpec) {
this(resourcePath, resourcePath, DEFAULT_INDEX_FILE, DEFAULT_SERVLET_MAPPING_NAME,
cacheBuilderSpec);
}
/**
* Creates a new {@link ConfiguredAssetsBundle} which will configure the service to serve the
* static files located in {@code src/main/resources/${resourcePath}} as {@code /${uriPath}}. For
* example, given a {@code resourcePath} of {@code "/assets"} and a uriPath of {@code "/js"},
* {@code src/main/resources/assets/example.js} would be served up from {@code /js/example.js}.
*
* @param resourcePath the resource path (in the classpath) of the static asset files
* @param uriPath the uri path for the static asset files
* @param cacheBuilderSpec the spec for the cache builder
* @see ConfiguredAssetsBundle#ConfiguredAssetsBundle(Map, String, String, CacheBuilderSpec)
*/
public ConfiguredAssetsBundle(String resourcePath, String uriPath,
CacheBuilderSpec cacheBuilderSpec) {
this(resourcePath, uriPath, DEFAULT_INDEX_FILE, DEFAULT_SERVLET_MAPPING_NAME, cacheBuilderSpec);
}
/**
* Creates a new AssetsBundle which will configure the service to serve the static files
* located in {@code src/main/resources/${resourcePath}} as {@code /${uriPath}}. If no file name
* is in ${uriPath}, ${indexFile} is appended before serving. For example, given a
* {@code resourcePath} of {@code "/assets"} and a uriPath of {@code "/js"},
* {@code src/main/resources/assets/example.js} would be served up from {@code /js/example.js}.
*
* @param resourcePath the resource path (in the classpath) of the static asset files
* @param uriPath the uri path for the static asset files
* @param indexFile the name of the index file to use
* @param cacheBuilderSpec the spec for the cache builder
* @see ConfiguredAssetsBundle#ConfiguredAssetsBundle(Map, String, String, CacheBuilderSpec)
*/
public ConfiguredAssetsBundle(String resourcePath, String uriPath, String indexFile,
CacheBuilderSpec cacheBuilderSpec) {
this(resourcePath, uriPath, indexFile, DEFAULT_SERVLET_MAPPING_NAME, cacheBuilderSpec);
}
/**
* Creates a new {@link ConfiguredAssetsBundle} which will configure the service to serve the
* static files located in {@code src/main/resources/${resourcePath}} as {@code /${uriPath}}. For
* example, given a {@code resourcePath} of {@code "/assets"} and a uriPath of {@code "/js"},
* {@code src/main/resources/assets/example.js} would be served up from {@code /js/example.js}.
*
* @param resourcePath the resource path (in the classpath) of the static asset files
* @param cacheBuilderSpec the spec for the cache builder
* @param uriPath the uri path for the static asset files
* @param indexFile the name of the index file to use
* @param assetsName the name of servlet mapping used for this assets bundle
*/
public ConfiguredAssetsBundle(String resourcePath, String uriPath, String indexFile,
String assetsName, CacheBuilderSpec cacheBuilderSpec) {
this(ImmutableMap.builder().put(resourcePath, uriPath).build(), indexFile,
assetsName, cacheBuilderSpec);
}
/**
* Creates a new {@link ConfiguredAssetsBundle} which will configure the service to serve the
* static files located in {@code src/main/resources/${resourcePath}} as {@code /${uriPath}}. For
* example, given a {@code resourcePath} of {@code "/assets"} and a uriPath of {@code "/js"},
* {@code src/main/resources/assets/example.js} would be served up from {@code /js/example.js}.
*
* @param resourcePathToUriMappings a series of mappings from resource paths (in the classpath)
* to the uri path that hosts the resource
* @see ConfiguredAssetsBundle#ConfiguredAssetsBundle(String, String, String, String,
* CacheBuilderSpec)
*/
public ConfiguredAssetsBundle(Map resourcePathToUriMappings) {
this(resourcePathToUriMappings, DEFAULT_INDEX_FILE, DEFAULT_SERVLET_MAPPING_NAME,
DEFAULT_CACHE_SPEC);
}
/**
* Creates a new AssetsBundle which will configure the service to serve the static files
* located in {@code src/main/resources/${resourcePath}} as {@code /${uriPath}}. If no file name
* is in ${uriPath}, ${indexFile} is appended before serving. For example, given a
* {@code resourcePath} of {@code "/assets"} and a uriPath of {@code "/js"},
* {@code src/main/resources/assets/example.js} would be served up from {@code /js/example.js}.
*
* @param resourcePathToUriMappings a series of mappings from resource paths (in the classpath)
* to the uri path that hosts the resource
* @param indexFile the name of the index file to use
*/
public ConfiguredAssetsBundle(Map resourcePathToUriMappings, String indexFile) {
this(resourcePathToUriMappings, indexFile, DEFAULT_SERVLET_MAPPING_NAME, DEFAULT_CACHE_SPEC);
}
/**
* Creates a new AssetsBundle which will configure the service to serve the static files
* located in {@code src/main/resources/${resourcePath}} as {@code /${uriPath}}. If no file name
* is in ${uriPath}, ${indexFile} is appended before serving. For example, given a
* {@code resourcePath} of {@code "/assets"} and a uriPath of {@code "/js"},
* {@code src/main/resources/assets/example.js} would be served up from {@code /js/example.js}.
*
* @param resourcePathToUriMappings a series of mappings from resource paths (in the classpath)
* to the uri path that hosts the resource
* @param indexFile the name of the index file to use
* @param assetsName the name of servlet mapping used for this assets bundle
*/
public ConfiguredAssetsBundle(Map resourcePathToUriMappings, String indexFile,
String assetsName) {
this(resourcePathToUriMappings, indexFile, assetsName, DEFAULT_CACHE_SPEC);
}
/**
* Creates a new {@link ConfiguredAssetsBundle} which will configure the service to serve the
* static files located in {@code src/main/resources/${resourcePath}} as {@code /${uriPath}}. For
* example, given a {@code resourcePath} of {@code "/assets"} and a uriPath of {@code "/js"},
* {@code src/main/resources/assets/example.js} would be served up from {@code /js/example.js}.
*
* @param resourcePathToUriMappings a series of mappings from resource paths (in the classpath)
* to the uri path that hosts the resource
* @param cacheBuilderSpec the spec for the cache builder
* @see ConfiguredAssetsBundle#ConfiguredAssetsBundle(Map, String, String, CacheBuilderSpec)
*/
public ConfiguredAssetsBundle(Map resourcePathToUriMappings,
CacheBuilderSpec cacheBuilderSpec) {
this(resourcePathToUriMappings, DEFAULT_INDEX_FILE, DEFAULT_SERVLET_MAPPING_NAME,
cacheBuilderSpec);
}
/**
* Creates a new AssetsBundle which will configure the service to serve the static files
* located in {@code src/main/resources/${resourcePath}} as {@code /${uriPath}}. If no file name
* is in ${uriPath}, ${indexFile} is appended before serving. For example, given a
* {@code resourcePath} of {@code "/assets"} and a uriPath of {@code "/js"},
* {@code src/main/resources/assets/example.js} would be served up from {@code /js/example.js}.
*
* @param resourcePathToUriMappings a series of mappings from resource paths (in the classpath)
* to the uri path that hosts the resource
* @param indexFile the name of the index file to use
* @param cacheBuilderSpec the spec for the cache builder
* @see ConfiguredAssetsBundle#ConfiguredAssetsBundle(Map, String, String,
* CacheBuilderSpec)
*/
public ConfiguredAssetsBundle(Map resourcePathToUriMappings, String indexFile,
CacheBuilderSpec cacheBuilderSpec) {
this(resourcePathToUriMappings, indexFile, DEFAULT_SERVLET_MAPPING_NAME, cacheBuilderSpec);
}
/**
* Creates a new {@link ConfiguredAssetsBundle} which will configure the service to serve the
* static files located in {@code src/main/resources/${resourcePath}} as {@code /${uriPath}}. For
* example, given a {@code resourcePath} of {@code "/assets"} and a uriPath of {@code "/js"},
* {@code src/main/resources/assets/example.js} would be served up from {@code /js/example.js}.
*
* @param resourcePathToUriMappings a series of mappings from resource paths (in the classpath)
* to the uri path that hosts the resource
* @param cacheBuilderSpec the spec for the cache builder
* @param indexFile the name of the index file to use
* @param assetsName the name of servlet mapping used for this assets bundle
*/
public ConfiguredAssetsBundle(Map resourcePathToUriMappings, String indexFile,
String assetsName, CacheBuilderSpec cacheBuilderSpec) {
for (Map.Entry mapping : resourcePathToUriMappings.entrySet()) {
String resourcePath = mapping.getKey();
checkArgument(resourcePath.startsWith("/"), "%s is not an absolute path", resourcePath);
checkArgument(!"/".equals(resourcePath), "%s is the classpath root", resourcePath);
}
this.resourcePathToUriMappings =
Iterables.unmodifiableIterable(resourcePathToUriMappings.entrySet());
this.cacheBuilderSpec = cacheBuilderSpec;
this.indexFile = indexFile;
this.assetsName = assetsName;
}
@Override
public void initialize(Bootstrap> bootstrap) {
// nothing to do
}
@Override
public void run(AssetsBundleConfiguration bundleConfig, Environment env) throws Exception {
AssetsConfiguration config = bundleConfig.getAssetsConfiguration();
// Let the cache spec from the configuration override the one specified in the code
CacheBuilderSpec spec = (config.getCacheSpec() != null)
? CacheBuilderSpec.parse(config.getCacheSpec())
: cacheBuilderSpec;
Iterable> overrides = config.getOverrides().entrySet();
Iterable> mimeTypes = config.getMimeTypes().entrySet();
Iterable> servletResourcePathToUriMappings;
if (!config.getResourcePathToUriMappings().isEmpty()) {
servletResourcePathToUriMappings = config.getResourcePathToUriMappings().entrySet();
} else {
servletResourcePathToUriMappings = resourcePathToUriMappings;
}
AssetServlet servlet = new AssetServlet(servletResourcePathToUriMappings, indexFile,
Charsets.UTF_8, spec, overrides, mimeTypes);
for (Map.Entry mapping : servletResourcePathToUriMappings) {
String mappingPath = mapping.getValue();
if (!mappingPath.endsWith("/")) {
mappingPath += '/';
}
mappingPath += "*";
servlet.setCacheControlHeader(config.getCacheControlHeader());
LOGGER.info("Registering ConfiguredAssetBundle with name: {} for path {}", assetsName,
mappingPath);
env.servlets().addServlet(assetsName, servlet).addMapping(mappingPath);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy