<%@ page language="java" %> <%@ page import="com.maff.forum.*,com.maff.forum.jsp.*" %> <%@ page session="false" %> Slots - Software Reality <%@ include file="/include/body.txt" %> <%@ include file="/design/table-top.txt" %> <%@ include file="/design/title.txt" %> <%@ include file="/include/navbar.txt" %> <%@ include file="/include/storytable-top.txt" %> Slots Web Framework <%@ include file="/include/storytable-mid.txt" %>

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

 

<%@ include file="/include/storytable-bot.txt" %> <%-- navbar2 --%> <%@ include file="/design/table-bot.txt" %>