/*
* Copyright 2008 Jeff Dwyer
*
* 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 com.apress.progwt.server.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* Based on code from fvisticot
* http://code.google.com/p/gwt-google-apis/issues/detail?id=6
*
*
*/
public class GearsManifestFilter implements Filter {
public static final String EXTENSIONS = "extensions";
public static final String MANIFEST_VERSION = "manifestVersion";
public enum Browser {
OPERA("opera", "'opera'],"), SAFARI("safari", "'safari'],"), GECKO1_8(
"gecko1_8", "'gecko1_8'],"), GECKO("gecko", "'gecko'],"), IE6(
"ie6", "'ie6'],");
private String name;
private String pattern;
private String cacheFileName;
private Browser(String name, String pattern) {
this.name = name;
this.pattern = pattern;
}
public String getName() {
return name;
}
public String getPattern() {
return pattern;
}
public String getCacheFileName() {
return cacheFileName;
}
public void createCacheFileName(StringBuffer noCacheStringBuffer) {
String noCacheString = noCacheStringBuffer.toString();
int beginIndex = noCacheString.indexOf(getPattern())
+ getPattern().length() + 1;
int endIndex = noCacheString.indexOf("'", beginIndex);
String filename = noCacheString.substring(beginIndex,
endIndex);
this.cacheFileName = filename;
}
}
protected String _extensions;
protected String _manifestVersion = "1.0";
protected Map<Browser, String> _manifestMap = new HashMap<Browser, String>();
public static class GearRegexpFilenameFilter implements
FilenameFilter {
private String _regexpFilter;
private Pattern _regexpPattern;
GearRegexpFilenameFilter(String regexpFilter) {
_regexpFilter = regexpFilter;
_regexpPattern = Pattern.compile(_regexpFilter);
}
public boolean accept(File dir, String name) {
if ((name.indexOf(".cache.") == -1)
&& (name.indexOf("-xs.nocache.") == -1)) {
Matcher matcher = _regexpPattern.matcher(name);
return matcher.find();
} else
return false;
}
}
public static class GearResourcesExplorer {
List<String> _result = new ArrayList<String>();
public GearResourcesExplorer() {
}
public List<String> list(File directory, FilenameFilter filter,
boolean recursive, boolean root) {
if (recursive) {
File[] dirs = directory.listFiles(new FileFilter() {
public boolean accept(File pathname) {
if (pathname.isDirectory())
return true;
return false;
}
});
for (int i = 0; i < dirs.length; i++)
list(dirs[i], filter, recursive, false);
}
String[] res = directory.list(filter);
for (int i = 0; i < res.length; i++) {
if (root) {
_result.add(res[i]);
} else {
_result.add(directory.getName() + File.separator
+ res[i]);
}
}
return _result;
}
}
public GearsManifestFilter() {
}
public void init(FilterConfig filterConfig) {
_extensions = filterConfig.getInitParameter(EXTENSIONS);
_manifestVersion = filterConfig
.getInitParameter(MANIFEST_VERSION);
System.out.println("Extensions: " + _extensions);
String realPath = filterConfig.getServletContext().getRealPath(
"/");
System.out.println("Path:" + realPath);
File dir = new File(realPath);
List<String> resourceFilenames = new GearResourcesExplorer()
.list(dir, new GearRegexpFilenameFilter(_extensions),
true, true);
for (int i = 0; i < resourceFilenames.size(); i++) {
System.out.println("File: " + resourceFilenames.get(i));
}
FilenameFilter noCacheFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
if (name.endsWith(".nocache.js")
&& !name.endsWith("-xs.nocache.js"))
return true;
return false;
}
};
String[] noCacheFilenames = dir.list(noCacheFilter);
if (noCacheFilenames.length != 1) {
System.out.println("Error !!");
} else {
getResourcesAccordingUserAgent(realPath + noCacheFilenames[0]);
}
_manifestMap
.put(Browser.SAFARI, createManifest(Browser.SAFARI
.getCacheFileName(), _manifestVersion,
resourceFilenames));
_manifestMap
.put(Browser.GECKO, createManifest(Browser.GECKO
.getCacheFileName(), _manifestVersion,
resourceFilenames));
_manifestMap.put(Browser.GECKO1_8, createManifest(
Browser.GECKO1_8.getCacheFileName(), _manifestVersion,
resourceFilenames));
_manifestMap
.put(Browser.OPERA, createManifest(Browser.OPERA
.getCacheFileName(), _manifestVersion,
resourceFilenames));
_manifestMap
.put(Browser.IE6, createManifest(Browser.IE6
.getCacheFileName(), _manifestVersion,
resourceFilenames));
}
protected void getResourcesAccordingUserAgent(String noCacheFilename) {
System.out.println(noCacheFilename);
BufferedReader in = null;
StringBuffer buffer = new StringBuffer();
try {
in = new BufferedReader(new FileReader(noCacheFilename));
String currentLine;
while ((currentLine = in.readLine()) != null) {
buffer.append(currentLine);
}
in.close();
} catch (IOException e) {
System.out.println("Error");
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Browser.OPERA.createCacheFileName(buffer);
Browser.GECKO.createCacheFileName(buffer);
Browser.GECKO1_8.createCacheFileName(buffer);
Browser.SAFARI.createCacheFileName(buffer);
Browser.IE6.createCacheFileName(buffer);
// System.out.println("OperaFilename: " + _operaCacheFilename);
// System.out.println("GeckoFilename: " + _geckoCacheFilename);
// System.out.println("Gecko1_8Filename: " +
// _gecko1_8CacheFilename);
// System.out.println("SafariFilename: " + _safariCacheFilename);
// System.out.println("IE6Filename: " + _ie6CacheFilename);
}
protected String createManifest(String userAgentHash, String version,
List resourceFilenames) {
StringBuffer manifestBuffer = new StringBuffer("{\n");
manifestBuffer.append("\"betaManifestVersion\": 1,\n");
manifestBuffer.append("\"version\": \"");
manifestBuffer.append(version);
manifestBuffer.append("\",\n");
manifestBuffer.append("\"entries\": [\n");
manifestBuffer.append("{ \"url\": \"");
manifestBuffer.append(userAgentHash + ".cache.js\"");
manifestBuffer.append("},\n");
manifestBuffer.append("{ \"url\": \"");
manifestBuffer.append(userAgentHash + ".cache.html\"");
manifestBuffer.append("},\n");
for (int i = 0; i < resourceFilenames.size() - 1; i++) {
manifestBuffer.append("{ \"url\": \"");
manifestBuffer.append(resourceFilenames.get(i));
manifestBuffer.append("\"},\n");
}
manifestBuffer.append("{ \"url\": \"");
manifestBuffer.append(resourceFilenames.get(resourceFilenames
.size() - 1));
manifestBuffer.append("\"}\n");
manifestBuffer.append("]\n");
manifestBuffer.append("}\n");
System.out.println("Manifest: " + manifestBuffer.toString());
return manifestBuffer.toString();
}
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = ((HttpServletRequest) servletRequest);
String userAgentString = request.getHeader("user-agent");
System.out.println("UserAgent: " + userAgentString);
String userAgent = getUserAgent(userAgentString);
ServletOutputStream out = servletResponse.getOutputStream();
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setContentType("application/jsonrequest");
out.println((String) _manifestMap.get(userAgent));
}
protected String getUserAgent(String userAgentString) {
if (userAgentString.indexOf("IE6") != -1
|| userAgentString.indexOf("MSIE 7") != -1) {
System.out.println("IE6 or more detected");
return Browser.IE6.name;
} else if (userAgentString.indexOf("MOZILLA") != -1) {
System.out.println("MOZILLA detected");
return Browser.GECKO.name;
} else if (userAgentString.indexOf("MOZILLA") != -1) {
System.out.println("MOZILLA detected");
return Browser.IE6.name;
}
return Browser.SAFARI.name;
}
public void destroy() {
}
public void test() {
File dir = new File("c:\\apache-ant-1.7.0");
GearResourcesExplorer gearFilename = new GearResourcesExplorer();
List res = gearFilename.list(dir, new GearRegexpFilenameFilter(
".xml|.xsl"), true, true);
for (int i = 0; i < res.size(); i++)
System.out.println("Selected file: " + res.get(i));
}
public static void main(String[] args) {
GearsManifestFilter gearM = new GearsManifestFilter();
gearM.test();
}
}