Python Server Pages: Part 2
by Kirby W. Angell

Listing One
public class PSPServlet extends HttpServlet {
  PyObject m_cgEngine = null;
  static {
    // Initialize the JPython interpreter
    PSP.interp.exec( "import sys" );
    // Put our installation directory at the beginning of the JPython
    // search path.  That means our modules get loaded before anything else,
    // keeping us away from any nasty module colisions.
    PSP.interp.set( "PSPSearchPath", Py.java2py(PSP.pspRoot) );
    PSP.interp.exec( "sys.path = [PSPSearchPath] + sys.path" );
    // Load up the JPython based code generator module used by PSP
    PyObject cg = __builtin__.__import__( new PyString("cg") );
    PyObject cgVersion = cg.__getattr__( "Version" );

    // Create an instance of the code generator that we can use
    String cachedir = PSP.pspRoot + "cache";
    PyObject engineClass = cg.__getattr__( "cgEngine" );
    PyObject engine = engineClass.__call__( Py.java2py(cachedir) );
    PSP.codeGenerator = engine;
  }
  public void service(ServletRequest req, ServletResponse res)
    throws ServletException, IOException {
    String psp = ((HttpServletRequest)req).getServletPath();
    // Get an application object to satisify this request.
    PSPAppContext ac = getApplication( (HttpServletRequest)req );
    ac.processPage(
        psp, (HttpServletRequest)req,
      (HttpServletResponse)res );
  } // service
  synchronized PSPAppContext getApplication( HttpServletRequest req ) {
    String psp = req.getServletPath();
    psp = psp.replace( '/', File.separatorChar );
        psp = psp.replace( '\\', File.separatorChar );
    // Get application name
    File pspFile = new File( psp );
    String appName = pspFile.getParent();

    PSPAppContext app = (PSPAppContext) PSP.getApp( appName );
    if ( app == null )
        return loadApplication( appName, req );
    else
        return app;
  } // getApplication
  PSPAppContext loadApplication( String name, HttpServletRequest req ) {
    File pspFile = new File( name );
    String appName = name;
    // Look for a global script file indicating the
    // base directory of an application.
    while ( appName != null ) {
        String globalScript = req.getRealPath(
            appName + File.separatorChar + PSP.GLOBAL_SCRIPT);
            File f = new File(globalScript);
        if ( f.exists() )
            break;
        pspFile = new File( appName);
        appName = pspFile.getParent();
    } // while
    if ( appName == null )
        appName = new String( "" + File.separatorChar);
    PSPAppContext app = (PSPAppContext) PSP.getApp( appName );
    if ( app == null ) {
      app = new PSPAppContext(
        (PyStringMap)PSP.interp.getLocals(), tr, appName );
      PSP.addApp( appName, app );
    }
    // If we didn't find this application in the same
    // directory where we started
    if ( !appName.equals(name) ) {
      // Put this application object in the cache
      // under the directory name where we finally found it.
      PSP.addApp( name, app );
    }
    return app;
  } // loadApplication
}

Listing Two
public class PSP {
   static PythonInterpreter interp = new PythonInterpreter();
   static PyObject codeGenerator = null;
   static Hashtable apps = new Hashtable(); // Cache for Application Contexts
   static String pspRoot = findRoot();
   static final String GLOBAL_SCRIPT = "global.psa";

  // finds the directory where psp is installed
  public static String findRoot() {
      String root;
      // If find psp.jar in class.path
      String classpath = System.getProperty("java.class.path");
      if (classpath == null) return null;
      int jpy = classpath.toLowerCase().indexOf("psp.jar");
      if (jpy == -1) {
          return null;
      }
      int start = classpath.lastIndexOf(java.io.File.pathSeparator, jpy)+1;
      return classpath.substring(start, jpy);
  } // findRoot
  // adds a new application context to the cache
  static public synchronized void addApp( String name, PSPAppContext app ) {
    apps.put( name, app );
  }
  // gets a cached application context from the cache
    static public synchronized PSPAppContext getApp( String name ) {
    return (PSPAppContext)apps.get( name );
  }
  // clears the application cache for the servlet
  static public synchronized void clearCache( boolean newValue ) {
    apps = new Hashtable();
    System.gc();
  }
  // returns a python dictionary with statistics for the loaded apps
  static public synchronized PyDictionary getAppStats() {
     Hashtable ht = new Hashtable( apps.size() );
    Enumeration e = apps.elements();
    while ( e.hasMoreElements() ) {
        PSPAppContext app = (PSPAppContext)e.nextElement();
        Hashtable htPages = new Hashtable( app.g_scripts.size() );
       Enumeration scripts = app.g_scripts.keys();
            Enumeration dates = app.g_dates.elements();
      while ( scripts.hasMoreElements() ) {
        PyString script = new PyString( (String)scripts.nextElement() );
        PyLong date = new PyLong( ((Long)dates.nextElement()).longValue() );
                htPages.put( script, date );
      } // While
      ht.put( Py.java2py(app.g_appName), new PyDictionary(htPages) );
    } // while
    return new PyDictionary( ht );
  } // getAppStats
  // generate a PyDictionary containing HTTP cookies
  static public PyDictionary makeCookies( Cookie[] cookies ) {
    if ( cookies == null )
        return new PyDictionary();
    Hashtable ht = new Hashtable( cookies.length );
    for( int i = 0; i < cookies.length; i++ ) {
        Cookie cookie = cookies[i];
      ht.put( Py.java2py( cookie.getName() ),
        Py.java2py( cookie ) );
    } // for
    return new PyDictionary( ht );
  } // makeCookies
}

Listing Three
import org.python.util.PythonInterpreter;
import org.python.core.*;

public class SimpleEmbedded {
    public static void main(String []args) throws PyException {
        PythonInterpreter interp = new PythonInterpreter();

        System.out.println("Hello, brave new world");
        interp.exec("import sys");
        interp.exec("print sys");

        interp.set("a", new PyInteger(42));
        interp.exec("print a");
        interp.exec("x = 2+2");
        PyObject x = interp.get("x");

        System.out.println("x: "+x);
        System.out.println("Goodbye, cruel world");
    }
}




1


