View Javadoc

1   /*
2    * $Source: /usr/cvsroot/melati/melati/src/main/java/org/melati/servlet/JspServlet.java,v $
3    * $Revision: 1.15 $
4    *
5    * Copyright (C) 2003 Tim Pizey
6    *
7    * Part of Melati (http://melati.org), a framework for the rapid
8    * development of clean, maintainable web applications.
9    *
10   * Melati is free software; Permission is granted to copy, distribute
11   * and/or modify this software under the terms either:
12   *
13   * a) the GNU General Public License as published by the Free Software
14   *    Foundation; either version 2 of the License, or (at your option)
15   *    any later version,
16   *
17   *    or
18   *
19   * b) any version of the Melati Software License, as published
20   *    at http://melati.org
21   *
22   * You should have received a copy of the GNU General Public License and
23   * the Melati Software License along with this program;
24   * if not, write to the Free Software Foundation, Inc.,
25   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
26   * GNU General Public License and visit http://melati.org to obtain the
27   * Melati Software License.
28   *
29   * Feel free to contact the Developers of Melati (http://melati.org),
30   * if you would like to work out a different arrangement than the options
31   * outlined here.  It is our intention to allow Melati to be used by as
32   * wide an audience as possible.
33   *
34   * This program is distributed in the hope that it will be useful,
35   * but WITHOUT ANY WARRANTY; without even the implied warranty of
36   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37   * GNU General Public License for more details.
38   *
39   * Contact details for copyright holder:
40   *
41   *     Tim Pizey <timp At paneris.org>
42   */
43  package org.melati.servlet;
44  
45  import java.io.IOException;
46  
47  import javax.servlet.ServletConfig;
48  import javax.servlet.ServletException;
49  import javax.servlet.http.HttpServlet;
50  import javax.servlet.http.HttpServletRequest;
51  import javax.servlet.http.HttpServletResponse;
52  import javax.servlet.jsp.HttpJspPage;
53  
54  import org.melati.Melati;
55  import org.melati.PoemContext;
56  import org.melati.MelatiConfig;
57  import org.melati.poem.AccessToken;
58  import org.melati.poem.Database;
59  import org.melati.poem.PoemTask;
60  import org.melati.util.DatabaseInitException;
61  import org.melati.poem.util.StringUtils;
62  
63  /**
64   * This is a TOY and does not represent the proper way to use Melati as Melati
65   * was designed with a template engine in mind.
66   * 
67   * To use extend this class.
68   * 
69   * @author timp At paneris.org
70   *  
71   */
72  public abstract class JspServlet extends HttpServlet implements HttpJspPage {
73  
74    /**
75     * Eclipse generated.
76     */
77    private static final long serialVersionUID = 9018372044518826369L;
78    
79    static MelatiConfig melatiConfig;
80  
81    /**
82     * Initialise Melati.
83     * 
84     * @param config a <code>ServletConfig</code>
85     * @throws ServletException is anything goes wrong
86     */
87    public void init(ServletConfig config) throws ServletException {
88      super.init(config);
89       melatiConfig = getMelatiConfig();
90      jspInit();
91      _jspInit();
92    }
93  
94    /**
95     * Override this to tailor your configuration.
96     * 
97     * @return a configured MelatiConfig
98     */
99    protected MelatiConfig getMelatiConfig() {
100     MelatiConfig m = new MelatiConfig();
101     return m;
102   }
103 
104   /**
105    * {@inheritDoc}
106    * @see javax.servlet.jsp.JspPage#jspInit()
107    */
108   public void jspInit() {
109   }
110 
111   /**
112    * Do nothing.
113    */
114   public void _jspInit() {
115   }
116 
117   /**
118    * {@inheritDoc}
119    * @see javax.servlet.Servlet#getServletInfo()
120    */
121   public String getServletInfo() {
122     return "org.wafer.weblog.melati.jsp.JspServlet - " + "timp@paneris.org - "
123         + "21/10/2003";
124   }
125 
126   /**
127    * {@inheritDoc}
128    * @see javax.servlet.Servlet#destroy()
129    */
130   public final void destroy() {
131     jspDestroy();
132     _jspDestroy();
133   }
134 
135   /**
136    * {@inheritDoc}
137    * @see javax.servlet.jsp.JspPage#jspDestroy()
138    */
139   public void jspDestroy() {
140   }
141 
142   protected void _jspDestroy() {
143   }
144 
145   /**
146    * This method is overridden by the code generated from the .jsp file.
147    * {@inheritDoc}
148    * @see javax.servlet.jsp.HttpJspPage#_jspService(javax.servlet.http.HttpServletRequest,
149    *      javax.servlet.http.HttpServletResponse)
150    */
151   public abstract void _jspService(HttpServletRequest request,
152       HttpServletResponse response) throws ServletException, IOException;
153 
154   /**
155    * Run the generated code within a database session. Poem requires that any
156    * access to the db be associated with a user. We just supply it with the
157    * superuser to bypass Melati's access handling.
158    * 
159    * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest,
160    *      javax.servlet.http.HttpServletResponse)
161    */
162   public final void service(final HttpServletRequest request,
163       final HttpServletResponse response) throws ServletException {
164     final Melati melati;
165     melati = new Melati(melatiConfig, request, response);
166     PoemContext pc = getPoemContext();
167     try {
168       melati.setPoemContext(pc);
169     } catch (DatabaseInitException e) {
170       e.printStackTrace(System.err);
171       throw new ServletException(e.toString());
172     }
173 
174     Database db = melati.getDatabase();
175     db.inSession(AccessToken.root, new PoemTask() {
176       public void run() {
177         // Uncomment to use Melati's access handling
178         // melatiConfig.getAccessHandler().establishUser(melati);
179         try {
180           _jspService(request, response);
181         } catch (Exception e) {
182           Throwable cause = e.getCause();
183           if (cause != null) {
184             cause.printStackTrace(System.err);
185             throw new RuntimeException(cause.getMessage());
186           }
187           e.printStackTrace(System.err);
188           throw new RuntimeException(e.toString() + " : " + e.getMessage());
189         }
190       }
191     });
192   }
193 
194   /**
195    * Override this to supply a PoemContext with at least a database field
196    * filled. <code>
197    *    protected PoemContext getPoemContext() {
198    *     return getPoemContext("mydatabase");
199    *    }
200    * </code>
201    * 
202    * @return a new context
203    */
204   protected PoemContext getPoemContext() {
205     return new PoemContext();
206   }
207 
208   protected PoemContext getPoemContext(String logicalDatabase) {
209     PoemContext it = new PoemContext();
210     it.setLogicalDatabase(logicalDatabase);
211     return it;
212   }
213   
214   protected PoemContext getPoemContext(String logicalDatabase,
215       String pathInfo) throws PathInfoException {
216     PoemContext it = getPoemContext(logicalDatabase);
217     String[] pathInfoParts = StringUtils.split(pathInfo, '/');
218     if (pathInfoParts.length > 0) {
219       if (pathInfoParts.length == 1)
220         it.setMethod(pathInfoParts[0]);
221       if (pathInfoParts.length == 2) {
222         it.setTable(pathInfoParts[0]);
223         it.setMethod(pathInfoParts[1]);
224       }
225       if (pathInfoParts.length >= 3) {
226         it.setTable(pathInfoParts[0]);
227         try {
228           it.setTroid(new Integer(pathInfoParts[1]));
229         } catch (NumberFormatException e) {
230           throw new PathInfoException(pathInfo, e);
231         }
232         it.setMethod(pathInfoParts[2]);
233       }
234     }
235     return it;
236   }
237 
238 }
239