org.duelengine.duel.CDNLinkInterceptor Maven / Gradle / Ivy
package org.duelengine.duel;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CDNLinkInterceptor implements LinkInterceptor {
private static final Logger log = LoggerFactory.getLogger(CDNLinkInterceptor.class);
protected final boolean isDevMode;
protected final String cdnHost;
private final Map cdnMap;
/**
* @param cdnHost the CDN server hostname (e.g., "cdn.example.com")
* @param cdnMap a mapping of paths to their compacted form (e.g., "/foo.js" => "/foo.min.js")
* @param isDevMode uses normal paths unless compacted form has a dev form (e.g., "/foo.js" => "/foo.min.js" => "/foo.test.js", else "/foo.js")
* @throws URISyntaxException
*/
public CDNLinkInterceptor(String cdnHost, ResourceBundle cdnBundle, boolean isDevMode)
throws URISyntaxException {
this(cdnHost, bundleAsMap(cdnBundle, isDevMode), isDevMode);
}
/**
* @param cdnHost the CDN server hostname (e.g., "cdn.example.com")
* @param cdnMap a mapping of paths to their compacted form (e.g., "/foo.js" => "/foo.min.js")
* @param isDevMode uses normal paths unless compacted form has a dev form (e.g., "/foo.js" => "/foo.min.js" => "/foo.test.js", else "/foo.js")
* @throws URISyntaxException
*/
public CDNLinkInterceptor(String cdnHost, Map cdnMap, boolean isDevMode)
throws URISyntaxException {
if (cdnMap == null) {
cdnMap = Collections.emptyMap();
}
this.isDevMode = isDevMode;
this.cdnMap = cdnMap;
// use URI class to check for proper host syntax
this.cdnHost = formatURL(cdnHost);
log.info("cdnHost="+cdnHost);
log.info("isDevMode="+isDevMode);
}
private static String formatURL(String path) {
path = path == null ? "" : path.trim();
if (path.isEmpty() || path.equals("/")) {
return "";
}
if (!path.startsWith(".")) {
try {
int index = path.indexOf('/');
if (index < 0) {
path = new URI("http", path, null, null).getRawSchemeSpecificPart();
} else {
path = new URI("http", path.substring(0, index), path.substring(index), null).getRawSchemeSpecificPart();
}
} catch (URISyntaxException ex) {
log.error(ex.getMessage(), ex);
}
if (!path.startsWith("/")) {
path = "//"+path;
}
}
if (path.endsWith("/")) {
path = path.substring(0, path.length()-1);
}
return path;
}
public String transformURL(String url) {
// query and hash
String suffix = "";
int query = url.indexOf('?');
if (query >= 0) {
suffix += url.substring(query);
url = url.substring(0, query);
}
int hash = url.indexOf('#');
if (hash >= 0) {
suffix += url.substring(hash);
url = url.substring(0, hash);
}
if (!cdnMap.containsKey(url)) {
return url + suffix;
}
// lookup CDN resource
String cdnURL = cdnMap.get(url);
if (isDevMode) {
if (!cdnMap.containsKey(cdnURL)) {
// scripts & stylesheets served directly
return url + suffix;
}
// merge files serve generated placeholder
cdnURL = cdnMap.get(cdnURL);
}
// CDN resources are compacted and optionally served from a different root
return cdnHost + cdnURL + suffix;
}
/**
* Converts ResourceBundle to a Map
* @param cdnBundle
* @return
*/
protected static Map bundleAsMap(final ResourceBundle bundle, boolean isDevMode) {
if (bundle == null) {
return null;
}
if (!isDevMode) {
// dump key-value pairs into simple map
Set keys = bundle.keySet();
Map map = new HashMap(keys.size());
for (String key : keys) {
map.put(key, bundle.getString(key));
}
return map;
}
// wrap bundle with an adaptor to allow dynamic reloading of bundle
return new Map() {
@Override
public void clear() {}
@Override
public boolean containsKey(Object arg0) {
return bundle.containsKey((String)arg0);
}
@Override
public boolean containsValue(Object arg0) { return false; }
@Override
public Set> entrySet() { return null; }
@Override
public String get(Object arg0) {
return (String)bundle.getObject((String)arg0);
}
@Override
public boolean isEmpty() { return false; }
@Override
public Set keySet() { return null; }
@Override
public String put(String arg0, String arg1) { return null; }
@Override
public void putAll(Map extends String, ? extends String> arg0) {}
@Override
public String remove(Object arg0) { return null; }
@Override
public int size() { return 0; }
@Override
public Collection values() { return null; }
};
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy