Slots Source Code
<< Slots Central
SlotServlet.java
package com.felstar.slots;
import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
/**
*
* @author Dino Fancellu, felstar.com
* @version
*/
public class SlotServlet extends HttpServlet {
/** Initializes the servlet.
*/
public void init(ServletConfig config) throws ServletException {
super.init(config);
ServletContext context=config.getServletContext();
String realpath=context.getRealPath(slot_config);
slotsConfig=new File(realpath);
if (!slotsConfig.exists())
{
System.out.println("** Config file does not exist at "+realpath);
}
}
/** Destroys the servlet.
*/
public void destroy() {
}
final String slot_config= "/WEB-INF/slots-config.properties";
File slotsConfig=null;
long lastModified=0;
Properties properties=new Properties();
String defaultbase=null;
Hashtable cache=new Hashtable(16);
protected void loadProperties() throws IOException {
if (lastModified>=slotsConfig.lastModified()) return;
synchronized (this)
{
if (lastModified>=slotsConfig.lastModified()) return;
InputStream is=new FileInputStream(slotsConfig);
properties.clear();
properties.load(is);
is.close();
defaultbase=properties.getProperty("default");
cache.clear();
lastModified=slotsConfig.lastModified();
}
}
/*
* Given an entry, base or url, resolves a map of slot entries,
* using base and url inhertance
*
**/
protected LinkedHashMap resolveEntry(String entryname) {
String entry=properties.getProperty(entryname);
//System.out.print(entryname+"=");
//System.out.println(entry);
// if its am invalid base, i.e. no definition
if (entry==null&&!entryname.startsWith("/")) {
throw new IllegalArgumentException("Invalid base, not defined: "+entryname);
}
String originalEntryname=entryname;
// if we haven"t found an entry for complete path, we check parents, up to root
// this lets us define slots for entire directories, recursively.
while (entry==null) {
int lastslash=entryname.lastIndexOf("/");
if (lastslash==-1) {
break;
}
entryname=entryname.substring(0,lastslash);
if (entryname==null||entryname.length()==0) {
break;
}
entry=properties.getProperty(entryname);
}
LinkedHashMap map=parseLine(entry);
if (entry!=null)
{
map.put("entry", "\""+entry+"\"");
}
String base=(String)map.get("base");
//cache.put(base,map);
//System.out.println(" Putting "+base+" "+map);
if (base!=null&&base.startsWith("/")&&!entryname.startsWith("/")) {
return map;
}
LinkedHashMap map2=resolveEntry(base);
map.remove("base");
map2.putAll(map);
return map2;
}
/**
* Takes a line of CSV slot entries and returns a map
* If no base defined, we use the default base
*
* @param line
* @return
*/
protected LinkedHashMap parseLine(String line) {
LinkedHashMap map=new LinkedHashMap();
if (line!=null) {
String vals[]=line.split(",");
for (int x=0;x<vals.length;x++) {
String slot=vals[x];
String[] bits=slot.split("=");
String attr=bits[0];
String attrfile=bits[1];
map.put(attr,attrfile);
}
}
String base=(String)map.get("base");
if (base==null) {
map.put("base",defaultbase);
}
return map;
}
/** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
* @param request servlet request
* @param response servlet response
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String pathinfo=null;
// this request may be for an included resource, don"t want to use parent pathinfo,
// else we"d end up in an infinite loop!
pathinfo = (String)request.getAttribute("javax.servlet.include.path_info");
if (pathinfo==null)
{
pathinfo=request.getPathInfo();
}
//System.out.println("pathinfo="+pathinfo);
String servletPath=request.getServletPath();
//System.out.println("servletPath="+servletPath);
if (pathinfo==null) {
pathinfo=servletPath;
// being served by the *.slot mapping, turn it into a jsp
// remember, this "jsp" can in fact point to a servlet
if (pathinfo.endsWith(".slot")) {
pathinfo=pathinfo.replaceAll("\\.slot", "\\.jsp");
}
}
if (pathinfo!=null&&pathinfo.indexOf(".")==-1) {
out.println("Broken, directory browsing not allowed");
return;
}
loadProperties();
if (properties.size()<1)
{
System.out.println("** Config file empty");
return;
}
LinkedHashMap entryMap=(LinkedHashMap)cache.get(pathinfo);
if (entryMap!=null)
{
// System.out.println(" Cache hit "+pathinfo);
}
else
{
entryMap=resolveEntry(pathinfo);
cache.put(pathinfo,entryMap);
}
SlotWrapper wrapper=new SlotWrapper(response);
// hard wire in /slot path for servlet, slots_root is only used for .jsp refs,
// not needed for .slot refs, can"t use getServletPath(), as it won"t be valid
// when called for .slot
request.setAttribute("slots_root", request.getContextPath()+"/slot");
Iterator keys=entryMap.keySet().iterator();
while (keys.hasNext()) {
String attr=(String)keys.next();
if ("base".equals(attr)) {
continue;
}
String attrfile=(String)entryMap.get(attr);
String st=null;
// we replace with the context path of this webapp, useful for client side references, e.g. css
String filtered=attrfile.replaceAll("/\\$WEBROOT", request.getContextPath());
if (filtered.startsWith("\"")) {
st=filtered.replaceAll("\"", "");
}
else {
st=wrapper.include(request,filtered);
}
request.setAttribute("slots_"+attr, st);
}
// if we haven"t overriden content then take it from pathinfo
if (!entryMap.containsKey("content")) {
String st=wrapper.include(request,pathinfo);
request.setAttribute("slots_content", st);
}
String basefile=(String)entryMap.get("base");
RequestDispatcher disp=request.getRequestDispatcher(basefile);
disp.forward(request,response);
out.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
<< Slots Central
<< Software Reality Front Page
|