package net.techreadiness.ui.tags.helpers;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.components.template.TemplateRenderingContext;
import org.apache.struts2.views.java.Attributes;
import org.apache.struts2.views.java.TagSerializer;
import org.apache.struts2.views.java.XHTMLTagSerializer;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
public class StaticResourcesTag extends SimpleTagSupport {
private String additionalCssFiles;
private String additionalJsFiles;
@Override
public void doTag() throws JspException, IOException {
TagSerializer s = new XHTMLTagSerializer();
TemplateRenderingContext renderingContext = new TemplateRenderingContext(null, getJspContext().getOut(), null, null,
null);
s.setup(renderingContext);
ServletContext context = ((PageContext) getJspContext()).getServletContext();
String contextPath = context.getContextPath();
List<String> cssFiles = Lists.newArrayList();
List<String> jsFiles = Lists.newArrayList();
List<String> lessFiles = Lists.newArrayList();
Gson gson = new GsonBuilder().create();
Type mapType = new TypeToken<Map<String, List<String>>>() {
// Define a type for JSON parsing
}.getType();
Map<String, Collection<String>> resourcePack = gson.fromJson(
new InputStreamReader(getClass().getResourceAsStream("/mainResourcePack.json")), mapType);
cssFiles.addAll(getResources("css", resourcePack));
jsFiles.addAll(getResources("js", resourcePack));
lessFiles.addAll(getResources("less", resourcePack));
Attributes cssAttrs = new Attributes();
cssAttrs.add("rel", "stylesheet").add("type", "text/css");
Attributes jsAttrs = new Attributes();
jsAttrs.add("type", "text/javascript");
if (StringUtils.isNotBlank(additionalCssFiles)) {
String[] css = additionalCssFiles.split(" ");
for (int i = 0; i < css.length; i++) {
cssFiles.add(css[i]);
}
}
if (StringUtils.isNotBlank(additionalJsFiles)) {
String[] js = additionalJsFiles.split(" ");
for (int i = 0; i < js.length; i++) {
jsFiles.add(js[i]);
}
}
s.start("script", jsAttrs);
StringBuilder contextBuilder = new StringBuilder(13 + contextPath.length());
contextBuilder.append("var ctx = '");
contextBuilder.append(contextPath);
contextBuilder.append("';");
s.characters(contextBuilder.toString());
s.end("script");
// For development -- these files are heavily cached by the browser, append something (for now)
// so they are retrieved each time.
for (String file : cssFiles) {
StringBuilder sb = new StringBuilder(contextPath.length() + file.length());
sb.append(contextPath);
sb.append(file);
cssAttrs.add("href", sb.toString());
s.start("link", cssAttrs);
}
for (String file : lessFiles) {
String cssFile = file.replace(".less", ".css");
StringBuilder sb = new StringBuilder(contextPath.length() + cssFile.length());
sb.append(contextPath);
sb.append(cssFile);
cssAttrs.add("href", sb.toString());
s.start("link", cssAttrs);
}
for (String file : jsFiles) {
StringBuilder sb = new StringBuilder(contextPath.length() + file.length());
sb.append(contextPath);
sb.append(file);
jsAttrs.add("src", sb.toString());
s.start("script", jsAttrs);
s.end("script");
}
}
private static Collection<String> getResources(String type, Map<String, Collection<String>> map) {
Collection<String> resources = map.get(type);
if (resources == null) {
return Collections.emptySet();
}
return resources;
}
public String getAdditionalJsFiles() {
return additionalJsFiles;
}
public void setAdditionalJsFiles(String additionalJsFiles) {
this.additionalJsFiles = additionalJsFiles;
}
public String getAdditionalCssFiles() {
return additionalCssFiles;
}
public void setAdditionalCssFiles(String additionalCssFiles) {
this.additionalCssFiles = additionalCssFiles;
}
}