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

Quick Search    Search Deep

Source code: echopoint/template/SwitchedDataSource.java


1   package echopoint.template;
2   /* 
3    * This file is part of the Echo Point Project.  This project is a collection
4    * of Components that have extended the Echo Web Application Framework.
5    *
6    * EchoPoint is free software; you can redistribute it and/or modify
7    * it under the terms of the GNU Lesser General Public License as published by
8    * the Free Software Foundation; either version 2 of the License, or
9    * (at your option) any later version.
10   *
11   * EchoPoint is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public License
17   * along with Echo Point; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   */
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.io.Reader;
24  import java.io.UnsupportedEncodingException;
25  import java.net.URL;
26  
27  import javax.servlet.ServletContext;
28  
29  import nextapp.echo.EchoInstance;
30  import nextapp.echoservlet.ServerContext;
31  
32  import echopoint.util.URLKit;
33  
34  
35  /**
36   * <code>SwitchedDataSource</code> allows you to use a
37   * 3 step strategy for finding HTML template data.  
38   * <p>
39   * Step 1:<p>
40   * This class will first look for the existence of a file and if it 
41   * exists then it will use it as the template data source.  The file
42   * name is defined as <code>fileDirectoryPrefix</code> + <code>fileOrResourceName</code>  
43   * <p>
44   * Step 2:<p>
45   * Faling that, if you provide an EchoInstance, it will retrieve the
46   * javax.servlet.ServletContext from the instance and attempt to 
47   * load it using <code>javax.servlet.ServletContext.getResource(java.lang.String)</code>
48   * and the <code>fileOrResourceName</code>.  This step allows you to 
49   * access resources in your web application that are not under a 
50   * class path directory.
51   * <p>
52   * Step 3:<p>
53   * If ServletContext.getResource() fails or the EchoIntance is null, it will then 
54   * attempt to load the template data as a class resource 
55   * via Class.getResource(java.lang.String).
56   * <p>
57   * This class is useful when moving between development and production.
58   * For example, in development your templates may reside in your 
59   * web project source directory (probably under source control).  
60   * <p>
61   * Then when you move to production, they will reside as class resources
62   * under the web application servlet context root directory or 
63   * WEB-INF/classes directory of your web application.  
64   * <p>
65   * This class will allow for easier template changes during development 
66   * and testing and then use class loading in production.  
67   * <p>
68   * You would use this class something like this :
69   * <blockquote><pre>
70   * ds = new SwitchedDataSource(
71   *       "/java/myproject/finance/src",
72   *       "/com/bankwest/templates/login.html",
73   *       getEchoInstance());
74   * 
75   * template.setTemplate(ds);
76   * </pre></blockquote>
77   * 
78   * In the above example the <code>SwitchedDataSource</code> will 
79   * first look for the template data as a File in :
80   * <blockquote><pre>
81   * "/java/myproject/finance/src/com/bankwest/templates/login.html"
82   * </pre></blockquote>
83   * Then if this file cant be found it will load the template data as 
84   * a ServletContext resource using the name :
85   * <blockquote><pre>
86   * "/com/bankwest/templates/login.html"
87   * </pre></blockquote>
88   * Finally if this files it will load the template data as
89   * a Class resource using the name :
90   * <blockquote><pre>
91   * "/com/bankwest/templates/login.html"
92   * </pre></blockquote>
93   * 
94   * @see echopoint.util.URLKit#locate(String, String, EchoInstance, Class)
95   */
96  public class SwitchedDataSource implements DataSource {
97    
98    private CachedFileDataSource cachedDS;
99    
100   /**
101    * Constructs a <code>SwitchedDataSource</code> that 
102    * locates the template data using the following strategy :
103    * <p>
104    * Step 1 : Looks for a file called 'fileDirectoryPrefix + fileOrResourceName'
105    * <p> 
106    * Step 2 : failing that, it will a Class.getResource(fileOrResourceName)     
107    * 
108    * @param fileDirectoryPrefix     - the directory prefix to use when looking
109    *                   initially for the File.  May be null.
110    * @param fileOrResourceName   - the file or class resource name to use.
111    * 
112    * @throws IOException
113    * @throws UnsupportedEncodingException
114    * 
115    * @see Class#getResource(java.lang.String)
116    * @see echopoint.util.URLKit#locate(String, String, EchoInstance, Class)
117    */
118   public SwitchedDataSource(String fileDirectoryPrefix, String fileOrResourceName) throws IOException {
119     this(fileDirectoryPrefix,fileOrResourceName,null,AbstractDataSource.DEFAULT_ENCODING, SwitchedDataSource.class);
120   }
121 
122 
123   /**
124    * Constructs a <code>SwitchedDataSource</code> that 
125    * locates the template data using the following strategy :
126    * <p>
127    * Step 1 : Looks for a file called 'fileDirectoryPrefix + fileOrResourceName'
128    * <p> 
129    * Step 2 : failing that, it uses the EchoInstance to locate the URL 
130    *       via ServletContext.getResource(fileOrResourceName), if the
131    *       EchoInstance is not null.
132    * <p> 
133    * Step 3 : failing that, it will a Class.getResource(fileOrResourceName)     
134    * 
135    * @param fileDirectoryPrefix     - the directory prefix to use when looking
136    *                   initially for the File.  May be null.
137    * @param fileOrResourceName   - the file or class resource name to use.
138    * @param echoInstance      - the EchoInstance to retreive the ServletContext from.  This 
139    *                   can be null, in which case ServletContext resource loading
140    *                        will not be used.
141    * 
142    * @throws IOException
143    * @throws UnsupportedEncodingException
144    * 
145    * @see Class#getResource(java.lang.String)
146    * @see echopoint.util.URLKit#locate(String, String, EchoInstance, Class)
147    */
148   public SwitchedDataSource(String fileDirectoryPrefix, String fileOrResourceName, EchoInstance echoInstance) throws IOException {
149     this(fileDirectoryPrefix,fileOrResourceName,echoInstance,AbstractDataSource.DEFAULT_ENCODING, SwitchedDataSource.class);
150   }
151 
152   /**
153    * Constructs a <code>SwitchedDataSource</code> that 
154    * locates the template data using the following strategy :
155    * <p>
156    * Step 1 : Looks for a file called 'fileDirectoryPrefix + fileOrResourceName'
157    * <p> 
158    * Step 2 : failing that, it uses the EchoInstance to locate the URL 
159    *       via ServletContext.getResource(fileOrResourceName), if the
160    *       EchoInstance is not null.
161    * <p> 
162    * Step 3 : failing that, it will a Class.getResource(fileOrResourceName)     
163    * 
164    * @param fileDirectoryPrefix     - the directory prefix to use when looking
165    *                   initially for the File.  May be null.
166    * @param fileOrResourceName   - the file or class resource name to use.
167    * @param encoding        - the character encoding to use when reading the data
168    * 
169    * @throws IOException
170    * @throws UnsupportedEncodingException
171    * 
172    * @see Class#getResource(java.lang.String)
173    * @see echopoint.util.URLKit#locate(String, String, EchoInstance, Class)
174    */
175   public SwitchedDataSource(String fileDirectoryPrefix, String fileOrResourceName, String encoding) throws IOException, UnsupportedEncodingException {
176     this(fileDirectoryPrefix, fileOrResourceName, null, encoding, SwitchedDataSource.class);
177   }
178 
179 
180   /**
181    * Constructs a <code>SwitchedDataSource</code> that 
182    * locates the template data using the following strategy :
183    * <p>
184    * Step 1 : Looks for a file called 'fileDirectoryPrefix + fileOrResourceName'
185    * <p> 
186    * Step 2 : failing that, it uses the EchoInstance to locate the URL 
187    *       via ServletContext.getResource(fileOrResourceName), if the
188    *       EchoInstance is not null.
189    * <p> 
190    * Step 3 : failing that, it will a Class.getResource(fileOrResourceName)     
191    * 
192    * @param fileDirectoryPrefix     - the directory prefix to use when looking
193    *                   initially for the File.  May be null.
194    * @param fileOrResourceName   - the file or class resource name to use.
195    * @param echoInstance      - the EchoInstance to retreive the ServletContext from.  This 
196    *                   can be null, in which case ServletContext resource loading
197    *                        will not be used.
198    * @param encoding        - the character encoding to use when reading the data
199    * @param resourceClass     - the class to use when loading the resource data via
200    *                   Class.getResource(java.lang.String)
201    * 
202    * @throws IOException
203    * @throws UnsupportedEncodingException
204    * 
205    * @see Class#getResource(java.lang.String)
206    * @see echopoint.util.URLKit#locate(String, String, EchoInstance, Class)
207    */
208   public SwitchedDataSource(String fileDirectoryPrefix, String fileOrResourceName, EchoInstance echoInstance, String encoding, Class resourceClass) throws IOException, UnsupportedEncodingException {
209     if (fileOrResourceName == null && fileDirectoryPrefix == null)
210       throw new IllegalArgumentException(" The SwitchedDataSource fileDirectoryPrefix or the fileOrResourceName must be non null!");
211 
212     if (resourceClass == null)
213       resourceClass = SwitchedDataSource.class;
214 
215     cachedDS = null;
216     String fileName = fileOrResourceName;
217     if (fileDirectoryPrefix != null)
218       fileName = fileDirectoryPrefix + fileOrResourceName;
219 
220     //
221     // So that the DataSource lastModified time is still valid
222     // for files we use the File invocation if the file exists, otherwise
223     // we move onto standard URLKit processing    
224     File file = new File(fileName);
225     if (file.exists()) {
226       cachedDS  = new CachedFileDataSource(file,CachedFileDataSource.CACHED_SIZE_LIMIT,encoding);
227       cachedDS.lastModified();
228     }
229     //
230     // Try the ServletContext and get the real file path.  That way
231     // last modified processing will still work!
232     if (cachedDS == null && echoInstance != null) {
233       ServerContext echoServerC = (ServerContext) echoInstance.getAttribute(ServerContext.ATTRIBUTE_NAME);
234       if (echoServerC != null) {
235         ServletContext sc = echoServerC.getServletConfig().getServletContext();
236         String realFileName = sc.getRealPath(fileOrResourceName);
237         file = new File(realFileName);
238         if (file.exists()) {
239           cachedDS  = new CachedFileDataSource(file,CachedFileDataSource.CACHED_SIZE_LIMIT,encoding);
240           cachedDS.lastModified();
241         }
242       }
243     }
244     
245     //
246     // File isnt any good lets try the URLKit way!
247     if (cachedDS == null) {
248       URL url = URLKit.locate(fileDirectoryPrefix,fileOrResourceName,echoInstance,resourceClass);
249       if (url == null)
250         throw new IllegalArgumentException("The SwitchedDataSource class resource could not be loaded : '" + fileOrResourceName + "' nor could the file : '" + fileName + "'");
251       cachedDS = new CachedFileDataSource(url,encoding);
252     } 
253   }
254 
255   /**
256    * @see echopoint.template.DataSource#getCanonicalName()
257    */
258   public String getCanonicalName() {
259     return cachedDS.getCanonicalName();
260   }
261 
262   /**
263    * @see echopoint.template.DataSource#getCharacterEncoding()
264    */
265   public String getCharacterEncoding() {
266     return cachedDS.getCharacterEncoding();
267   }
268 
269   /**
270    * @see echopoint.template.DataSource#getInputReader()
271    */
272   public Reader getInputReader() throws IOException {
273     return cachedDS.getInputReader();
274   }
275 
276   /**
277    * @see echopoint.template.DataSource#lastModified()
278    */
279   public long lastModified() {
280     return cachedDS.lastModified();
281   }
282 
283 }