KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hsqldb > Servlet


1 /* Copyright (c) 1995-2000, The Hypersonic SQL Group.
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of the Hypersonic SQL Group nor the names of its
15  * contributors may be used to endorse or promote products derived from this
16  * software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * This software consists of voluntary contributions made by many individuals
31  * on behalf of the Hypersonic SQL Group.
32  *
33  *
34  * For work added by the HSQL Development Group:
35  *
36  * Copyright (c) 2001-2005, The HSQL Development Group
37  * All rights reserved.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions are met:
41  *
42  * Redistributions of source code must retain the above copyright notice, this
43  * list of conditions and the following disclaimer.
44  *
45  * Redistributions in binary form must reproduce the above copyright notice,
46  * this list of conditions and the following disclaimer in the documentation
47  * and/or other materials provided with the distribution.
48  *
49  * Neither the name of the HSQL Development Group nor the names of its
50  * contributors may be used to endorse or promote products derived from this
51  * software without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
54  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
57  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
58  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
59  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
61  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64  */

65
66
67 package org.hsqldb;
68
69 import java.io.DataInputStream JavaDoc;
70 import java.io.IOException JavaDoc;
71 import java.io.PrintWriter JavaDoc;
72
73 import javax.servlet.ServletConfig JavaDoc;
74 import javax.servlet.ServletException JavaDoc;
75 import javax.servlet.ServletOutputStream JavaDoc;
76 import javax.servlet.http.HttpServletRequest JavaDoc;
77 import javax.servlet.http.HttpServletResponse JavaDoc;
78
79 import org.hsqldb.persist.HsqlProperties;
80 import org.hsqldb.rowio.RowInputBinary;
81 import org.hsqldb.rowio.RowOutputBinary;
82
83 // fredt@users 20020130 - patch 475586 by wreissen@users
84
// fredt@users 20020328 - patch 1.7.0 by fredt - error trapping
85
// fredt@users 20030630 - patch 1.7.2 - new protocol, persistent sessions
86
// fredt@users 20041112 - patch by Willian Crick - use web_inf directory
87

88 /**
89  * Servlet can act as an interface between the client and the database for the
90  * the client / server mode of HSQL Database Engine. It uses the HTTP protocol
91  * for communication. This class is not required if the included HSQLDB
92  * Weberver is used on the server host. But if the host is running a J2EE
93  * application server or a servlet container such as Tomcat, the Servlet class
94  * can be hosted on this server / container to serve external requests from
95  * external hosts.<p>
96  * The remote applet / application should
97  * use the normal JDBC interfaces to connect to the URL of this servlet. An
98  * example URL is:
99  * <pre>
100  * jdbc:hsqldb:http://localhost.com:8080/servlet/org.hsqldb.Servlet
101  * </pre>
102  * The database path/name is taken from the servlet engine property:
103  * <pre>
104  * hsqldb.server.database
105  * </pre>
106  * <p>
107  * If the database is deployed in the WEB-INF directory of the servlet container,
108  * the property:
109  * <pre>
110  * hsqldb.server.use_web-inf_path
111  * </pre>
112  * should be set "true" in the web.xml file of the servlet container.
113  * In this case, the database path should begin with a "/".
114  *
115  * From version 1.7.2 JDBC connections via the HTTP protocol are persistent
116  * in the JDBC sense. The JDBC Connection that is established can support
117  * transactions spanning several Statement calls and real PreparedStatement
118  * calls are supported. This class has been rewritten to support the new
119  * features.<p>
120  * (fredt@users)<p>
121  *
122  * Extensively rewritten for HSQLDB.
123  *
124  * @author Thomas Mueller (Hypersonic SQL Group)
125  * @version 1.7.2
126  * @since Hypersonic SQL
127  */

128 public class Servlet extends javax.servlet.http.HttpServlet JavaDoc {
129
130     private static final int BUFFER_SIZE = 256;
131     private String JavaDoc dbType;
132     private String JavaDoc dbPath;
133     private String JavaDoc errorStr;
134     private RowOutputBinary rowOut;
135     private RowInputBinary rowIn;
136     private int iQueries;
137
138     /**
139      * Method declaration
140      *
141      *
142      * @param config
143      */

144     public void init(ServletConfig JavaDoc config) {
145
146         try {
147             super.init(config);
148
149             rowOut = new RowOutputBinary(BUFFER_SIZE);
150             rowIn = new RowInputBinary(rowOut);
151         } catch (ServletException JavaDoc e) {
152             log(e.toString());
153         }
154
155         String JavaDoc dbStr = getInitParameter("hsqldb.server.database");
156
157         if (dbStr == null) {
158             dbStr = ".";
159         }
160
161 // begin WEB-INF patch */
162
String JavaDoc useWebInfStr =
163             getInitParameter("hsqldb.server.use_web-inf_path");
164
165         if (!dbStr.equals(".") && "true".equalsIgnoreCase(useWebInfStr)) {
166             dbStr = getServletContext().getRealPath("/") + "WEB-INF" + dbStr;
167         }
168
169 // end WEB-INF patch
170
HsqlProperties dbURL = DatabaseURL.parseURL(dbStr, false);
171
172         log("Database filename = " + dbStr);
173
174         if (dbURL == null) {
175             errorStr = "Bad Database name";
176         } else {
177             dbPath = dbURL.getProperty("database");
178             dbType = dbURL.getProperty("connection_type");
179
180             try {
181
182 // loosecannon1@users 1.7.2 patch properties on the JDBC URL
183
DatabaseManager.getDatabase(dbType, dbPath, dbURL);
184             } catch (HsqlException e) {
185                 errorStr = e.getMessage();
186             }
187         }
188
189         log(errorStr);
190         log("Initialization completed.");
191     }
192
193     private static long lModified = 0;
194
195     /**
196      * Method declaration
197      *
198      *
199      * @param req
200      *
201      * @return
202      */

203     protected long getLastModified(HttpServletRequest JavaDoc req) {
204
205         // this is made so that the cache of the http server is not used
206
// maybe there is some other way
207
return lModified++;
208     }
209
210     /**
211      * Method declaration
212      *
213      *
214      * @param request
215      * @param response
216      *
217      * @throws IOException
218      * @throws ServletException
219      */

220     public void doGet(HttpServletRequest JavaDoc request,
221                       HttpServletResponse JavaDoc response)
222                       throws IOException JavaDoc, ServletException JavaDoc {
223
224         String JavaDoc query = request.getQueryString();
225
226         if ((query == null) || (query.length() == 0)) {
227             response.setContentType("text/html");
228
229 // fredt@users 20020130 - patch 1.7.0 by fredt
230
// to avoid caching on the browser
231
response.setHeader("Pragma", "no-cache");
232
233             PrintWriter JavaDoc out = response.getWriter();
234
235             out.println(
236                 "<html><head><title>HSQL Database Engine Servlet</title>");
237             out.println("</head><body><h1>HSQL Database Engine Servlet</h1>");
238             out.println("The servlet is running.<p>");
239
240             if (errorStr == null) {
241                 out.println("The database is also running.<p>");
242                 out.println("Database name: " + dbType + dbPath + "<p>");
243                 out.println("Queries processed: " + iQueries + "<p>");
244             } else {
245                 out.println("<h2>The database is not running!</h2>");
246                 out.println("The error message is:<p>");
247                 out.println(errorStr);
248             }
249
250             out.println("</body></html>");
251         }
252     }
253
254     /**
255      * Method declaration
256      *
257      *
258      * @param request
259      * @param response
260      *
261      * @throws IOException
262      * @throws ServletException
263      */

264     public void doPost(HttpServletRequest JavaDoc request,
265                        HttpServletResponse JavaDoc response)
266                        throws IOException JavaDoc, ServletException JavaDoc {
267
268         synchronized (this) {
269             DataInputStream JavaDoc inStream = null;
270             ServletOutputStream JavaDoc outStream = null;
271
272             try {
273
274                 // fredt@users - the servlet container, Resin does not return all
275
// the bytes with one call to input.read(b,0,len) when len > 8192
276
// bytes, the loop in the Result.read() method handles this
277
inStream = new DataInputStream JavaDoc(request.getInputStream());
278
279                 Result resultIn = Result.read(rowIn, inStream);
280                 Result resultOut;
281
282                 if (resultIn.mode == ResultConstants.SQLCONNECT) {
283                     try {
284                         Session session = DatabaseManager.newSession(dbType,
285                             dbPath, resultIn.getMainString(),
286                             resultIn.getSubString(), null);
287
288                         resultOut = new Result(ResultConstants.UPDATECOUNT);
289                         resultOut.sessionID = session.getId();
290                     } catch (HsqlException e) {
291                         resultOut = new Result(e, null);
292                     }
293                 } else {
294                     int dbId = resultIn.databaseID;
295                     int sessionId = resultIn.sessionID;
296                     Session session = DatabaseManager.getSession(dbId,
297                         sessionId);
298
299                     resultOut = session.execute(resultIn);
300                 }
301
302                 rowOut.reset();
303                 resultOut.write(rowOut);
304
305                 //
306
response.setContentType("application/octet-stream");
307                 response.setContentLength(rowOut.size());
308
309                 //
310
outStream = response.getOutputStream();
311
312                 outStream.write(rowOut.getOutputStream().getBuffer(), 0,
313                                 rowOut.getOutputStream().size());
314
315                 iQueries++;
316             } catch (HsqlException e) {}
317             finally {
318                 if (outStream != null) {
319                     outStream.close();
320                 }
321
322                 if (inStream != null) {
323                     inStream.close();
324                 }
325             }
326         }
327
328         // Trace.printSystemOut("Queries processed: "+iQueries+" \n");
329
}
330 }
331
Popular Tags