KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > jsp > PageManager


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.jsp;
31
32 import com.caucho.config.j2ee.InjectIntrospector;
33 import com.caucho.java.JavaCompiler;
34 import com.caucho.jsp.cfg.JspPropertyGroup;
35 import com.caucho.loader.Environment;
36 import com.caucho.log.Log;
37 import com.caucho.server.util.CauchoSystem;
38 import com.caucho.server.webapp.WebApp;
39 import com.caucho.util.Alarm;
40 import com.caucho.util.CacheListener;
41 import com.caucho.util.LruCache;
42 import com.caucho.vfs.MemoryPath;
43 import com.caucho.vfs.Path;
44 import com.caucho.vfs.PersistentDependency;
45
46 import javax.servlet.http.HttpServletRequest JavaDoc;
47 import javax.servlet.http.HttpServletResponse JavaDoc;
48 import java.io.FileNotFoundException JavaDoc;
49 import java.util.ArrayList JavaDoc;
50 import java.util.Iterator JavaDoc;
51 import java.util.logging.Level JavaDoc;
52 import java.util.logging.Logger JavaDoc;
53
54 /**
55  * Parent template manager for both JspManager and XtpManager. PageManager
56  * is responsible for caching pages until the underlying files change.
57  */

58 abstract public class PageManager {
59   private final static Logger JavaDoc log = Log.open(PageManager.class);
60   
61   static final long ACCESS_INTERVAL = 60000L;
62
63   protected WebApp _webApp;
64   private Path _classDir;
65   private long _updateInterval = 1000;
66   private boolean _isAdapter;
67   private boolean _omitInitLog;
68   private int _pageCacheMax = 256;
69   private LruCache<String JavaDoc,Entry> _cache;
70
71   // true if the manager should detect page changes and automatically recompile
72
protected boolean _autoCompile = true;
73
74   /**
75    * Create a new PageManager
76    *
77    * @param context the servlet webApp.
78    */

79   PageManager()
80   {
81   }
82
83   void initWebApp(WebApp webApp)
84   {
85     _webApp = webApp;
86
87     _classDir = CauchoSystem.getWorkPath();
88
89     long interval = Environment.getDependencyCheckInterval();
90   
91     JspPropertyGroup jspPropertyGroup = _webApp.getJsp();
92
93     if (jspPropertyGroup != null) {
94       _autoCompile = jspPropertyGroup.isAutoCompile();
95
96       if (jspPropertyGroup.getJspMax() > 0)
97     _pageCacheMax = jspPropertyGroup.getJspMax();
98
99       if (jspPropertyGroup.getDependencyCheckInterval() != Long.MIN_VALUE)
100     interval = jspPropertyGroup.getDependencyCheckInterval();
101     }
102
103     if (interval < 0)
104       interval = Integer.MAX_VALUE / 2;
105     
106     _updateInterval = interval;
107   }
108
109   void setPageCacheMax(int max)
110   {
111     _pageCacheMax = max;
112   }
113
114   public Path getClassDir()
115   {
116     if (_classDir != null)
117       return _classDir;
118     else {
119       Path appDir = _webApp.getAppDir();
120
121       if (appDir instanceof MemoryPath) {
122         String JavaDoc workPathName = ("./" + _webApp.getURL());
123         Path path = CauchoSystem.getWorkPath().lookup(workPathName);
124
125         return path;
126       }
127       else
128         return appDir.lookup("WEB-INF/work");
129     }
130   }
131
132   public Path getAppDir()
133   {
134     return _webApp.getAppDir();
135   }
136
137   /**
138    * Returns the CauchoWebApp for the manager.
139    */

140   WebApp getWebApp()
141   {
142     return _webApp;
143   }
144   
145    /**
146     * Compiles and returns the page at the given path and uri. The uri
147     * is needed for jsp:include, etc. in the JSP pages.
148     *
149     * @param path Path to the page.
150     * @param uri uri of the page.
151     *
152     * @return the compiled JSP (or XTP) page.
153     */

154   public Page getPage(String JavaDoc uri, Path path)
155     throws Exception JavaDoc
156   {
157     return getPage(uri, uri, path, null);
158   }
159   
160    /**
161     * Compiles and returns the page at the given path and uri. The uri
162     * is needed for jsp:include, etc. in the JSP pages.
163     *
164     * @param path Path to the page.
165     * @param uri uri of the page.
166     *
167     * @return the compiled JSP (or XTP) page.
168     */

169   public Page getPage(String JavaDoc uri, String JavaDoc pageURI, Path path)
170     throws Exception JavaDoc
171   {
172     return getPage(uri, pageURI, path, null);
173   }
174   
175    /**
176     * Compiles and returns the page at the given path and uri. The uri
177     * is needed for jsp:include, etc. in the JSP pages.
178     *
179     * @param uri uri of the page.
180     * @param uri uri of the page.
181     * @param path Path to the page.
182     *
183     * @return the compiled JSP (or XTP) page.
184     */

185   public Page getPage(String JavaDoc uri, String JavaDoc pageURI, Path path,
186               ArrayList JavaDoc<PersistentDependency> dependList)
187     throws Exception JavaDoc
188   {
189     LruCache<String JavaDoc,Entry> cache = _cache;
190
191     if (cache == null) {
192       initPageManager();
193       
194       synchronized (this) {
195     if (_cache == null)
196       _cache = new LruCache<String JavaDoc,Entry>(_pageCacheMax);
197     cache = _cache;
198       }
199     }
200
201     Entry entry = null;
202
203     synchronized (cache) {
204       entry = cache.get(uri);
205
206       if (entry == null) {
207     entry = new Entry(uri);
208     cache.put(uri, entry);
209       }
210     }
211
212     synchronized (entry) {
213       Page page = entry.getPage();
214
215       if (page != null && ! page.cauchoIsModified())
216         return page;
217       else if (page != null && ! page.isDead()) {
218         try {
219           page.destroy();
220         } catch (Exception JavaDoc e) {
221           log.log(Level.FINE, e.toString(), e);
222         }
223       }
224
225       if (log.isLoggable(Level.FINE)) {
226         log.fine("uri:" + uri +
227                  "(cp:" + getWebApp().getContextPath() +
228                  ",app:" + getWebApp().getAppDir() +
229                  ") -> " + path);
230       }
231      
232       Path appDir = getWebApp().getAppDir();
233
234       String JavaDoc rawClassName = pageURI;
235
236       if (path.getPath().startsWith(appDir.getPath()))
237     rawClassName = path.getPath().substring(appDir.getPath().length());
238
239       String JavaDoc className = JavaCompiler.mangleName("jsp/" + rawClassName);
240
241       page = createPage(path, pageURI, className, dependList);
242
243       if (page == null)
244         throw new FileNotFoundException JavaDoc(pageURI);
245
246       if (_autoCompile == false)
247         page._caucho_setNeverModified(true);
248
249       page._caucho_setUpdateInterval(_updateInterval);
250
251       try {
252     InjectIntrospector.configure(page);
253       } catch (Throwable JavaDoc e) {
254     throw new RuntimeException JavaDoc(e);
255       }
256
257       entry.setPage(page);
258
259       return page;
260     }
261   }
262
263   protected void initPageManager()
264   {
265   }
266   
267   /**
268    * Implementation-specific method to create the actual page. JspManager
269    * and XtpManager define this for their specific needs.
270    */

271   abstract Page createPage(Path path, String JavaDoc uri, String JavaDoc className,
272                ArrayList JavaDoc<PersistentDependency> dependList)
273     throws Exception JavaDoc;
274
275   void killPage(HttpServletRequest JavaDoc request,
276                 HttpServletResponse JavaDoc response,
277                 Page page)
278   {
279   }
280
281   /**
282    * Clean up the pages when the server shuts down.
283    */

284   void destroy()
285   {
286     LruCache<String JavaDoc,Entry> cache = _cache;
287     _cache = null;
288
289     if (cache == null)
290       return;
291     
292     synchronized (cache) {
293       Iterator JavaDoc<Entry> iter = cache.values();
294
295       while (iter.hasNext()) {
296         Entry entry = iter.next();
297
298         Page page = entry != null ? entry.getPage() : null;
299
300         try {
301           if (page != null && ! page.isDead()) {
302             page.destroy();
303       }
304         } catch (Exception JavaDoc e) {
305           log.log(Level.WARNING, e.toString(), e);
306         }
307       }
308     }
309   }
310   
311   class Entry implements CacheListener {
312     private String JavaDoc _key;
313     Page _page;
314     
315     private long _lastAccessTime;
316  
317     Entry(String JavaDoc key)
318     {
319       _key = key;
320     }
321
322     void setPage(Page page)
323     {
324       _page = page;
325       
326       if (page != null)
327     page._caucho_setEntry(this);
328     }
329     
330     Page getPage()
331     {
332       return _page;
333     }
334
335     public void accessPage()
336     {
337       long now = Alarm.getCurrentTime();
338
339       if (now < _lastAccessTime + ACCESS_INTERVAL)
340     return;
341
342       _lastAccessTime = now;
343
344       if (_cache != null)
345     _cache.get(_key);
346     }
347
348     public void removeEvent()
349     {
350       Page page = _page;
351       _page = null;
352       
353       if (page != null && ! page.isDead()) {
354         if (log.isLoggable(Level.FINE))
355           log.fine("dropping page " + page);
356         
357     page.setDead();
358         page.destroy();
359       }
360     }
361   }
362 }
363
Popular Tags