Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/roller/presentation/velocity/DataSourceResourceLoader.java


1   package org.roller.presentation.velocity; 
2   
3   
4   /*
5    * The Apache Software License, Version 1.1
6    *
7    * Copyright (c) 2001 The Apache Software Foundation.  All rights
8    * reserved.
9    *
10   * Redistribution and use in source and binary forms, with or without
11   * modification, are permitted provided that the following conditions
12   * are met:
13   *
14   * 1. Redistributions of source code must retain the above copyright
15   *    notice, this list of conditions and the following disclaimer.
16   *
17   * 2. Redistributions in binary form must reproduce the above copyright
18   *    notice, this list of conditions and the following disclaimer in
19   *    the documentation and/or other materials provided with the
20   *    distribution.
21   *
22   * 3. The end-user documentation included with the redistribution, if
23   *    any, must include the following acknowlegement:
24   *       "This product includes software developed by the
25   *        Apache Software Foundation (http://www.apache.org/)."
26   *    Alternately, this acknowlegement may appear in the software itself,
27   *    if and wherever such third-party acknowlegements normally appear.
28   *
29   * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
30   *    Foundation" must not be used to endorse or promote products derived
31   *    from this software without prior written permission. For written
32   *    permission, please contact apache@apache.org.
33   *
34   * 5. Products derived from this software may not be called "Apache"
35   *    nor may "Apache" appear in their names without prior written
36   *    permission of the Apache Group.
37   *
38   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
39   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
42   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
44   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
45   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
47   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
48   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49   * SUCH DAMAGE.
50   * ====================================================================
51   *
52   * This software consists of voluntary contributions made by many
53   * individuals on behalf of the Apache Software Foundation.  For more
54   * information on the Apache Software Foundation, please see
55   * <http://www.apache.org/>.
56   */
57  
58  import java.io.InputStream;
59  import java.io.BufferedInputStream;
60  import java.util.Map;
61  import java.util.Hashtable;
62  
63  import java.sql.*;
64  import javax.sql.DataSource;
65  import javax.naming.InitialContext;
66  
67  import org.apache.velocity.runtime.Runtime;
68  import org.apache.velocity.runtime.resource.Resource;
69  
70  import org.apache.velocity.exception.ResourceNotFoundException;
71  
72  import org.apache.commons.collections.ExtendedProperties;
73  
74  import org.apache.velocity.runtime.resource.loader.*;
75  
76  /**
77   * This is a simple template file loader that loads templates
78   * from a DataSource instead of plain files.
79   * 
80   * It can be configured with a datasource name, a table name,
81   * id column (name), content column (the template body) and a
82   * timestamp column (for last modification info).
83   * <br />
84   * <br />
85   * Example configuration snippet for velocity.properties:
86   * <br />
87   * <br />
88   * resource.loader.1.public.name = DataSource <br />
89   * resource.loader.1.description = Velocity DataSource Resource Loader <br /> 
90   * resource.loader.1.class = org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader <br />
91   * resource.loader.1.resource.datasource = jdbc/SomeDS <br />
92   * resource.loader.1.resource.table = template_table <br />
93   * resource.loader.1.resource.keycolumn = template_id <br />
94   * resource.loader.1.resource.templatecolumn = template_definition <br />
95   * resource.loader.1.resource.timestampcolumn = template_timestamp <br />
96   * resource.loader.1.cache = false <br />
97   * resource.loader.1.modificationCheckInterval = 60<br />
98   *
99   * @author <a href="mailto:david.kinnvall@alertir.com">David Kinnvall</a>
100  * @author <a href="mailto:paulo.gaspar@krankikom.de">Paulo Gaspar</a>
101  * @version $Id: DataSourceResourceLoader.java,v 1.2 2002/08/09 17:21:42 mraible Exp $
102  */
103 public class DataSourceResourceLoader extends ResourceLoader
104 {
105      private String dataSourceName;
106      private String tableName;
107      private String keyColumn;
108      private String templateColumn;
109      private String timestampColumn;
110      private InitialContext ctx;
111      private DataSource dataSource;
112 
113      public void init( ExtendedProperties configuration)
114      {
115          dataSourceName  = configuration.getString("resource.datasource");
116          tableName       = configuration.getString("resource.table");
117          keyColumn       = configuration.getString("resource.keycolumn");
118          templateColumn  = configuration.getString("resource.templatecolumn");
119          timestampColumn = configuration.getString("resource.timestampcolumn");
120          
121          System.err.println("Resources Loaded From: " + dataSourceName + "/" + tableName);
122          System.err.println( "Resource Loader using columns: " + keyColumn + ", "
123                        + templateColumn + " and " + timestampColumn);
124          System.err.println("Resource Loader Initalized.");
125 
126          /*Runtime.info("Resources Loaded From: " + dataSourceName + "/" + tableName);
127          Runtime.info( "Resource Loader using columns: " + keyColumn + ", "
128                        + templateColumn + " and " + timestampColumn);
129          Runtime.info("Resource Loader Initalized.");*/
130      }
131 
132      public boolean isSourceModified(Resource resource)
133      {
134          return (resource.getLastModified() != 
135                  readLastModified(resource, "checking timestamp"));
136      }
137 
138      public long getLastModified(Resource resource)
139      {
140          return readLastModified(resource, "getting timestamp");
141      }
142 
143      /**
144       * Get an InputStream so that the Runtime can build a
145       * template with it.
146       *
147       *  @param name name of template
148       *  @return InputStream containing template
149       */
150      public synchronized InputStream getResourceStream( String name )
151          throws ResourceNotFoundException
152      {
153          if (name == null || name.length() == 0)
154          {
155              throw new ResourceNotFoundException ("Need to specify a template name!");
156          }
157 
158          try
159          {   
160              Connection conn = openDbConnection();
161              
162              try
163              {   
164                  ResultSet rs = readData(conn, templateColumn, name);
165                  
166                  try
167                  {   
168                      if (rs.next())
169                      {
170                          return new
171                              BufferedInputStream(rs.getAsciiStream(templateColumn));
172                      }
173                      else
174                      {
175                          String msg = "DataSourceResourceLoader Error: cannot find resource " 
176                              + name;
177                          Runtime.error(msg );
178 
179                          throw new ResourceNotFoundException (msg);
180                      }
181                  }
182                  finally
183                  {   
184                      rs.close();
185                  }
186              }
187              finally
188              {   
189                  closeDbConnection(conn);
190              }
191          }
192          catch(Exception e)
193          {   
194              String msg =  "DataSourceResourceLoader Error: database problem trying to load resource "
195                  + name + ": " + e.toString();
196 
197              Runtime.error( msg );
198 
199              throw new ResourceNotFoundException (msg);
200                          
201          }
202  
203      }
204 
205     /**
206      *  Fetches the last modification time of the resource
207      *
208      *  @param resource Resource object we are finding timestamp of
209      *  @param i_operation string for logging, indicating caller's intention
210      *
211      *  @return timestamp as long
212      */
213      private long readLastModified(Resource resource, String i_operation)
214      {
215          /*
216           *  get the template name from the resource
217           */
218 
219          String name = resource.getName();
220          try
221          {   
222              Connection conn = openDbConnection();
223              
224              try
225              {   
226                  ResultSet rs = readData(conn, timestampColumn, name);
227                  try
228                  {   
229                      if (rs.next())
230                      {
231                          return rs.getLong(timestampColumn);
232                      }
233                      else
234                      {
235                          Runtime.error("DataSourceResourceLoader Error: while " 
236                                        + i_operation 
237                                        + " could not find resource " + name);
238                      }
239                  }
240                  finally
241                  {   
242                      rs.close();
243                  }
244              }
245              finally
246              {   
247                  closeDbConnection(conn);
248              }
249          }
250          catch(Exception e)
251          {   
252              Runtime.error( "DataSourceResourceLoader Error: error while " 
253                  + i_operation + " when trying to load resource "
254                  + name + ": " + e.toString() );
255          }
256          return 0;
257      }
258 
259     /**
260      *   gets connection to the datasource specified through the configuration
261      *  parameters.
262      *
263      *  @return connection
264      */
265      private Connection openDbConnection()
266          throws Exception
267     {
268          if(ctx == null)
269          {
270              ctx = new InitialContext();
271          }
272          
273          if(dataSource == null)
274          {
275              dataSource = (DataSource)ctx.lookup(dataSourceName);
276          }
277 
278          return dataSource.getConnection();
279      }
280 
281     /**
282      *  Closes connection to the datasource 
283      */
284      private void closeDbConnection(Connection conn)
285      {  
286          try 
287          {
288              conn.close();
289          } 
290          catch (Exception e) 
291          {
292              Runtime.info(
293                  "DataSourceResourceLoader Quirk: problem when closing connection: " 
294                  + e.toString());
295          }
296      }
297 
298     /**
299      *  Reads the data from the datasource.  It simply does the following query :
300      *  <br />
301      *   SELECT <i>columnNames</i> FROM <i>tableName</i> WHERE <i>keyColumn</i>
302      *      = '<i>templateName</i>'
303      *  <br />
304      *  where <i>keyColumn</i> is a class member set in init()
305      *
306      *  @param conn connection to datasource
307      *  @param columnNames columns to fetch from datasource
308      *  @param templateName name of template to fetch
309      *  @return result set from query
310      */
311      private ResultSet readData(Connection conn, String columnNames, String templateName)
312          throws SQLException
313      {   
314          Statement stmt = conn.createStatement();
315          
316          String sql = "SELECT " + columnNames
317                       + " FROM " + tableName
318                       + " WHERE " + keyColumn + " = '" + templateName + "'";
319 
320          return stmt.executeQuery(sql);
321      }
322 }
323 
324 
325 
326