KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > velocity > runtime > resource > loader > DataSourceResourceLoader


1 package org.apache.velocity.runtime.resource.loader;
2
3 /*
4  * Copyright 2001-2002,2004 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 import java.io.InputStream JavaDoc;
20 import java.io.BufferedInputStream JavaDoc;
21 import java.util.Hashtable JavaDoc;
22
23 import javax.sql.DataSource JavaDoc;
24 import javax.naming.InitialContext JavaDoc;
25
26 import org.apache.velocity.runtime.Runtime;
27 import org.apache.velocity.runtime.resource.Resource;
28
29 import org.apache.velocity.exception.ResourceNotFoundException;
30
31 import org.apache.commons.collections.ExtendedProperties;
32 import java.sql.Connection JavaDoc;
33 import java.sql.ResultSet JavaDoc;
34 import java.sql.Statement JavaDoc;
35 import java.sql.SQLException JavaDoc;
36
37 /**
38  * This is a simple template file loader that loads templates
39  * from a DataSource instead of plain files.
40  *
41  * It can be configured with a datasource name, a table name,
42  * id column (name), content column (the template body) and a
43  * datetime column (for last modification info).
44  * <br>
45  * <br>
46  * Example configuration snippet for velocity.properties:
47  * <br>
48  * <br>
49  * resource.loader = file, ds <br>
50  * <br>
51  * ds.resource.loader.public.name = DataSource <br>
52  * ds.resource.loader.description = Velocity DataSource Resource Loader <br>
53  * ds.resource.loader.class = org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader <br>
54  * ds.resource.loader.resource.datasource = java:comp/env/jdbc/Velocity <br>
55  * ds.resource.loader.resource.table = tb_velocity_template <br>
56  * ds.resource.loader.resource.keycolumn = id_template <br>
57  * ds.resource.loader.resource.templatecolumn = template_definition <br>
58  * ds.resource.loader.resource.timestampcolumn = template_timestamp <br>
59  * ds.resource.loader.cache = false <br>
60  * ds.resource.loader.modificationCheckInterval = 60 <br>
61  * <br>
62  * Example WEB-INF/web.xml: <br>
63  * <br>
64  * <resource-ref> <br>
65  * <description>Velocity template DataSource</description> <br>
66  * <res-ref-name>jdbc/Velocity</res-ref-name> <br>
67  * <res-type>javax.sql.DataSource</res-type> <br>
68  * <res-auth>Container</res-auth> <br>
69  * </resource-ref> <br>
70  * <br>
71  * <br>
72  * and Tomcat 4 server.xml file: <br>
73  * [...] <br>
74  * <Context path="/exampleVelocity" docBase="exampleVelocity" debug="0"> <br>
75  * [...] <br>
76  * <ResourceParams name="jdbc/Velocity"> <br>
77  * <parameter> <br>
78  * <name>driverClassName</name> <br>
79  * <value>org.hsql.jdbcDriver</value> <br>
80  * </parameter> <br>
81  * <parameter> <br>
82  * <name>driverName</name> <br>
83  * <value>jdbc:HypersonicSQL:database</value> <br>
84  * </parameter> <br>
85  * <parameter> <br>
86  * <name>user</name> <br>
87  * <value>database_username</value> <br>
88  * </parameter> <br>
89  * <parameter> <br>
90  * <name>password</name> <br>
91  * <value>database_password</value> <br>
92  * </parameter> <br>
93  * </ResourceParams> <br>
94  * [...] <br>
95  * </Context> <br>
96  * [...] <br>
97  * <br>
98  * Example sql script:<br>
99  * CREATE TABLE tb_velocity_template ( <br>
100  * id_template varchar (40) NOT NULL , <br>
101  * template_definition text (16) NOT NULL , <br>
102  * template_timestamp datetime NOT NULL <br>
103  * ) <br>
104  *
105  * @author <a HREF="mailto:david.kinnvall@alertir.com">David Kinnvall</a>
106  * @author <a HREF="mailto:paulo.gaspar@krankikom.de">Paulo Gaspar</a>
107  * @author <a HREF="mailto:lachiewicz@plusnet.pl">Sylwester Lachiewicz</a>
108  * @version $Id: DataSourceResourceLoader.java,v 1.8.8.1 2004/03/03 23:23:02 geirm Exp $
109  */

110 public class DataSourceResourceLoader extends ResourceLoader
111 {
112      private String JavaDoc dataSourceName;
113      private String JavaDoc tableName;
114      private String JavaDoc keyColumn;
115      private String JavaDoc templateColumn;
116      private String JavaDoc timestampColumn;
117      private InitialContext JavaDoc ctx;
118      private DataSource JavaDoc dataSource;
119
120      public void init( ExtendedProperties configuration)
121      {
122          dataSourceName = configuration.getString("resource.datasource");
123          tableName = configuration.getString("resource.table");
124          keyColumn = configuration.getString("resource.keycolumn");
125          templateColumn = configuration.getString("resource.templatecolumn");
126          timestampColumn = configuration.getString("resource.timestampcolumn");
127
128          Runtime.info("Resources Loaded From: " + dataSourceName + "/" + tableName);
129          Runtime.info( "Resource Loader using columns: " + keyColumn + ", "
130                        + templateColumn + " and " + timestampColumn);
131          Runtime.info("Resource Loader Initalized.");
132      }
133
134      public boolean isSourceModified(Resource resource)
135      {
136          return (resource.getLastModified() !=
137                  readLastModified(resource, "checking timestamp"));
138      }
139
140      public long getLastModified(Resource resource)
141      {
142          return readLastModified(resource, "getting timestamp");
143      }
144
145      /**
146       * Get an InputStream so that the Runtime can build a
147       * template with it.
148       *
149       * @param name name of template
150       * @return InputStream containing template
151       */

152      public synchronized InputStream JavaDoc getResourceStream( String JavaDoc name )
153          throws ResourceNotFoundException
154      {
155          if (name == null || name.length() == 0)
156          {
157              throw new ResourceNotFoundException ("Need to specify a template name!");
158          }
159
160          try
161          {
162              Connection JavaDoc conn = openDbConnection();
163
164              try
165              {
166                  ResultSet JavaDoc rs = readData(conn, templateColumn, name);
167
168                  try
169                  {
170                      if (rs.next())
171                      {
172                          return new
173                              BufferedInputStream JavaDoc(rs.getAsciiStream(templateColumn));
174                      }
175                      else
176                      {
177                          String JavaDoc msg = "DataSourceResourceLoader Error: cannot find resource "
178                              + name;
179                          Runtime.error(msg );
180
181                          throw new ResourceNotFoundException (msg);
182                      }
183                  }
184                  finally
185                  {
186                      rs.close();
187                  }
188              }
189              finally
190              {
191                  closeDbConnection(conn);
192              }
193          }
194          catch(Exception JavaDoc e)
195          {
196              String JavaDoc msg = "DataSourceResourceLoader Error: database problem trying to load resource "
197                  + name + ": " + e.toString();
198
199              Runtime.error( msg );
200
201              throw new ResourceNotFoundException (msg);
202
203          }
204
205      }
206
207     /**
208      * Fetches the last modification time of the resource
209      *
210      * @param resource Resource object we are finding timestamp of
211      * @param i_operation string for logging, indicating caller's intention
212      *
213      * @return timestamp as long
214      */

215      private long readLastModified(Resource resource, String JavaDoc i_operation)
216      {
217          /*
218           * get the template name from the resource
219           */

220
221          String JavaDoc name = resource.getName();
222          try
223          {
224              Connection JavaDoc conn = openDbConnection();
225
226              try
227              {
228                  ResultSet JavaDoc rs = readData(conn, timestampColumn, name);
229                  try
230                  {
231                      if (rs.next())
232                      {
233                          return rs.getTimestamp(timestampColumn).getTime();
234                      }
235                      else
236                      {
237                          Runtime.error("DataSourceResourceLoader Error: while "
238                                        + i_operation
239                                        + " could not find resource " + name);
240                      }
241                  }
242                  finally
243                  {
244                      rs.close();
245                  }
246              }
247              finally
248              {
249                  closeDbConnection(conn);
250              }
251          }
252          catch(Exception JavaDoc e)
253          {
254              Runtime.error( "DataSourceResourceLoader Error: error while "
255                  + i_operation + " when trying to load resource "
256                  + name + ": " + e.toString() );
257          }
258          return 0;
259      }
260
261     /**
262      * gets connection to the datasource specified through the configuration
263      * parameters.
264      *
265      * @return connection
266      */

267      private Connection JavaDoc openDbConnection()
268          throws Exception JavaDoc
269     {
270          if(ctx == null)
271          {
272              ctx = new InitialContext JavaDoc();
273          }
274
275          if(dataSource == null)
276          {
277              dataSource = (DataSource JavaDoc)ctx.lookup(dataSourceName);
278          }
279
280          return dataSource.getConnection();
281      }
282
283     /**
284      * Closes connection to the datasource
285      */

286      private void closeDbConnection(Connection JavaDoc conn)
287      {
288          try
289          {
290              conn.close();
291          }
292          catch (Exception JavaDoc e)
293          {
294              Runtime.info(
295                  "DataSourceResourceLoader Quirk: problem when closing connection: "
296                  + e.toString());
297          }
298      }
299
300     /**
301      * Reads the data from the datasource. It simply does the following query :
302      * <br>
303      * SELECT <i>columnNames</i> FROM <i>tableName</i> WHERE <i>keyColumn</i>
304      * = '<i>templateName</i>'
305      * <br>
306      * where <i>keyColumn</i> is a class member set in init()
307      *
308      * @param conn connection to datasource
309      * @param columnNames columns to fetch from datasource
310      * @param templateName name of template to fetch
311      * @return result set from query
312      */

313      private ResultSet JavaDoc readData(Connection JavaDoc conn, String JavaDoc columnNames, String JavaDoc templateName)
314          throws SQLException JavaDoc
315      {
316          Statement JavaDoc stmt = conn.createStatement();
317
318          String JavaDoc sql = "SELECT " + columnNames
319                       + " FROM " + tableName
320                       + " WHERE " + keyColumn + " = '" + templateName + "'";
321
322          return stmt.executeQuery(sql);
323      }
324 }
325
Popular Tags