KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > python > util > PyServlet


1
2 package org.python.util;
3
4 import java.io.*;
5 import java.util.*;
6 import javax.servlet.*;
7 import javax.servlet.http.*;
8 import org.python.core.*;
9
10
11 /**
12  * This servlet is used to re-serve JPython servlets. It stores
13  * bytecode for JPython servlets and re-uses it if the underlying .py
14  * file has not changed.
15  * <p>
16  * Many people have been involved with this class:
17  * <ul>
18  * <li>Chris Gokey
19  * <li>David Syer
20  * <li>Finn Bock
21  * </ul>
22  * If somebody is missing from this list, let us know.
23  * <p>
24  *
25  * e.g. http://localhost:8080/test/hello.py
26  * <pre>
27  *
28  * from javax.servlet.http import HttpServlet
29  * class hello(HttpServlet):
30  * def doGet(self, req, res):
31  * res.setContentType("text/html");
32  * out = res.getOutputStream()
33  * print >>out, "<html>"
34  * print >>out, "<head><title>Hello World, How are we?</title></head>"
35  * print >>out, "<body>Hello World, how are we?"
36  * print >>out, "</body>"
37  * print >>out, "</html>"
38  * out.close()
39  * return
40  * </pre>
41  *
42  * in web.xml for the PyServlet context:
43  * <pre>
44  * &lt;web-app>
45  * &lt;servlet>
46  * &lt;servlet-name>PyServlet&lt;/servlet-name>
47  * &lt;servlet-class>org.python.util.PyServlet&lt;/servlet-class>
48  * &lt;init-param>
49  * &lt;param-name>python.home&lt;/param-name>
50  * &lt;param-value>/usr/home/jython-2.1&lt;/param-value>
51  * &lt;/init-param>
52  * &lt;/servlet>
53  * &lt;servlet-mapping>
54  * &lt;servlet-name>PyServlet&lt;/servlet-name>
55  * &lt;url-pattern>*.py&lt;/url-pattern>
56  * &lt;/servlet-mapping>
57  * &lt;/web-app>
58  *
59  * </pre>
60  */

61
62 public class PyServlet extends HttpServlet {
63     private PythonInterpreter interp;
64     private Hashtable cache = new Hashtable();
65     private String JavaDoc rootPath;
66
67
68     public void init() {
69         rootPath = getServletContext().getRealPath("/");
70         if (!rootPath.endsWith(File.separator))
71             rootPath += File.separator;
72
73         Properties props = new Properties();
74
75         // Context parameters
76
ServletContext context = getServletContext();
77         Enumeration e = context.getInitParameterNames();
78         while (e.hasMoreElements()) {
79             String JavaDoc name = (String JavaDoc) e.nextElement();
80             props.put(name, context.getInitParameter(name));
81         }
82
83         // Config parameters
84
e = getInitParameterNames();
85         while (e.hasMoreElements()) {
86             String JavaDoc name = (String JavaDoc) e.nextElement();
87             props.put(name, getInitParameter(name));
88         }
89
90         if (props.getProperty("python.home") == null &&
91                                 System.getProperty("python.home") == null) {
92             props.put("python.home", rootPath + "WEB-INF" +
93                                              File.separator + "lib");
94         }
95
96         PythonInterpreter.initialize(System.getProperties(), props,
97                                      new String JavaDoc[0]);
98         reset();
99
100         PySystemState sys = Py.getSystemState();
101         sys.add_package("javax.servlet");
102         sys.add_package("javax.servlet.http");
103         sys.add_package("javax.servlet.jsp");
104         sys.add_package("javax.servlet.jsp.tagext");
105
106         sys.add_classdir(rootPath + "WEB-INF" +
107                           File.separator + "classes");
108
109         sys.add_extdir(rootPath + "WEB-INF" + File.separator + "lib", true);
110     }
111
112     /**
113      * Implementation of the HttpServlet main method.
114      * @param req the request parameter.
115      * @param res the response parameter.
116      * @exception ServletException
117      * @exception IOException
118      */

119     public void service(ServletRequest req, ServletResponse res)
120         throws ServletException, IOException
121     {
122         req.setAttribute("pyservlet", this);
123
124         String JavaDoc spath = (String JavaDoc)req.getAttribute(
125                                     "javax.servlet.include.servlet_path");
126         if (spath == null) {
127             spath = ((HttpServletRequest) req).getServletPath();
128             if (spath == null || spath.length() == 0) {
129                 // Servlet 2.1 puts the path of an extension-matched
130
// servlet in PathInfo.
131
spath = ((HttpServletRequest) req).getPathInfo();
132             }
133         }
134         String JavaDoc rpath = getServletContext().getRealPath(spath);
135
136         interp.set("__file__", rpath);
137
138         HttpServlet servlet = getServlet(rpath);
139         if (servlet != null)
140             servlet.service(req, res);
141         else
142             throw new ServletException("No python servlet found at:" + spath);
143     }
144
145     public void reset() {
146         destroyCache();
147         interp = new PythonInterpreter(null, new PySystemState());
148         cache.clear();
149         PySystemState sys = Py.getSystemState();
150         sys.path.append(new PyString(rootPath));
151
152         String JavaDoc modulesDir = rootPath + "WEB-INF" +
153                             File.separator + "jython";
154         sys.path.append(new PyString(modulesDir));
155     }
156
157     private synchronized HttpServlet getServlet(String JavaDoc path)
158         throws ServletException, IOException
159     {
160         CacheEntry entry = (CacheEntry) cache.get(path);
161         if (entry == null)
162             return loadServlet(path);
163         File file = new File(path);
164         if (file.lastModified() > entry.date)
165             return loadServlet(path);
166         return entry.servlet;
167     }
168
169     private HttpServlet loadServlet(String JavaDoc path)
170         throws ServletException, IOException
171     {
172         HttpServlet servlet = null;
173         File file = new File(path);
174
175         // Extract servlet name from path (strip ".../" and ".py")
176
int start = path.lastIndexOf(File.separator);
177         if (start < 0)
178             start = 0;
179         else
180             start++;
181         int end = path.lastIndexOf('.');
182         if ((end < 0) || (end <= start))
183             end = path.length();
184         String JavaDoc name = path.substring(start, end);
185
186         try {
187             interp.execfile(path);
188             PyObject cls = interp.get(name);
189             if (cls == null)
190                 throw new ServletException("No callable (class or function) "+
191                                        "named " + name + " in " + path);
192
193             PyObject pyServlet = cls.__call__();
194             Object JavaDoc o = pyServlet.__tojava__(HttpServlet.class);
195             if (o == Py.NoConversion)
196                 throw new ServletException("The value from " + name +
197                                        "must extend HttpServlet");
198             servlet = (HttpServlet)o;
199             servlet.init(getServletConfig());
200
201         } catch (PyException e) {
202             throw new ServletException("Could not create "+
203                                        "Jython servlet" + e.toString());
204         }
205         CacheEntry entry = new CacheEntry(servlet, file.lastModified());
206         cache.put(path, entry);
207         return servlet;
208     }
209
210     public void destroy() {
211         destroyCache();
212     }
213
214     private void destroyCache() {
215         for (Enumeration e = cache.elements(); e.hasMoreElements(); ) {
216             CacheEntry entry = (CacheEntry) e.nextElement();
217             entry.servlet.destroy();
218         }
219     }
220
221 }
222
223 class CacheEntry {
224     public long date;
225     public HttpServlet servlet;
226
227     CacheEntry(HttpServlet servlet, long date) {
228         this.servlet= servlet;
229         this.date = date;
230     }
231 }
232
Popular Tags