KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > web > servlet > view > AbstractCachingViewResolver


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

16
17 package org.springframework.web.servlet.view;
18
19 import java.util.HashMap JavaDoc;
20 import java.util.Locale JavaDoc;
21 import java.util.Map JavaDoc;
22
23 import org.springframework.web.context.support.WebApplicationObjectSupport;
24 import org.springframework.web.servlet.View;
25 import org.springframework.web.servlet.ViewResolver;
26
27 /**
28  * Convenient base class for {@link org.springframework.web.servlet.ViewResolver}
29  * implementations. Caches {@link org.springframework.web.servlet.View} objects
30  * once resolved: This means that view resolution won't be a performance problem,
31  * no matter how costly initial view retrieval is.
32  *
33  * <p>Subclasses need to implement the {@link #loadView} template method,
34  * building the View object for a specific view name and locale.
35  *
36  * @author Rod Johnson
37  * @author Juergen Hoeller
38  * @see #loadView
39  */

40 public abstract class AbstractCachingViewResolver extends WebApplicationObjectSupport implements ViewResolver {
41
42     /** Whether we should cache views, once resolved */
43     private boolean cache = true;
44
45     /** View name --> View instance */
46     private final Map JavaDoc viewCache = new HashMap JavaDoc();
47
48
49     /**
50      * Enable or disable caching.
51      * <p>Default is "true": caching is enabled.
52      * Disable this only for debugging and development.
53      * <p><b>Warning: Disabling caching can severely impact performance.</b>
54      */

55     public void setCache(boolean cache) {
56         this.cache = cache;
57     }
58
59     /**
60      * Return if caching is enabled.
61      */

62     public boolean isCache() {
63         return cache;
64     }
65
66
67     public View resolveViewName(String JavaDoc viewName, Locale JavaDoc locale) throws Exception JavaDoc {
68         if (!isCache()) {
69             logger.warn("View caching is SWITCHED OFF -- DEVELOPMENT SETTING ONLY: This can severely impair performance");
70             return createView(viewName, locale);
71         }
72         else {
73             Object JavaDoc cacheKey = getCacheKey(viewName, locale);
74             synchronized (this.viewCache) {
75                 View view = (View) this.viewCache.get(cacheKey);
76                 if (view == null) {
77                     // Ask the subclass to create the View object.
78
view = createView(viewName, locale);
79                     this.viewCache.put(cacheKey, view);
80                     if (logger.isDebugEnabled()) {
81                         logger.debug("Cached view [" + cacheKey + "]");
82                     }
83                 }
84                 return view;
85             }
86         }
87     }
88
89     /**
90      * Return the cache key for the given view name and the given locale.
91      * <p>Default is a String consisting of view name and locale suffix.
92      * Can be overridden in subclasses.
93      * <p>Needs to respect the locale in general, as a different locale can
94      * lead to a different view resource.
95      */

96     protected Object JavaDoc getCacheKey(String JavaDoc viewName, Locale JavaDoc locale) {
97         return viewName + "_" + locale;
98     }
99
100     /**
101      * Provides functionality to clear the cache for a certain view.
102      * <p>This can be handy in case developer are able to modify views
103      * (e.g. Velocity templates) at runtime after which you'd need to
104      * clear the cache for the specified view.
105      * @param viewName the view name for which the cached view object
106      * (if any) needs to be removed
107      * @param locale the locale for which the view object should be removed
108      */

109     public void removeFromCache(String JavaDoc viewName, Locale JavaDoc locale) {
110         if (!this.cache) {
111             logger.warn("View caching is SWITCHED OFF -- removal not necessary");
112         }
113         else {
114             Object JavaDoc cacheKey = getCacheKey(viewName, locale);
115             Object JavaDoc cachedView = null;
116             synchronized (this.viewCache) {
117                 cachedView = this.viewCache.remove(cacheKey);
118             }
119             if (cachedView == null) {
120                 // Some debug output might be useful...
121
if (logger.isDebugEnabled()) {
122                     logger.debug("No cached instance for view '" + cacheKey + "' was found");
123                 }
124             }
125             else {
126                 if (logger.isDebugEnabled()) {
127                     logger.debug("Cache for view " + cacheKey + " has been cleared");
128                 }
129             }
130         }
131     }
132
133     /**
134      * Clear the entire view cache, removing all cached view objects.
135      * Subsequent resolve calls will lead to recreation of demanded view objects.
136      */

137     public void clearCache() {
138         logger.debug("Clearing entire view cache");
139         synchronized (this.viewCache) {
140             this.viewCache.clear();
141         }
142     }
143
144
145     /**
146      * Create the actual View object.
147      * <p>The default implementation delegates to {@link #loadView}.
148      * This can be overridden to resolve certain view names in a special fashion,
149      * before delegating to the actual <code>loadView</code> implementation
150      * provided by the subclass.
151      * @param viewName the name of the view to retrieve
152      * @param locale the Locale to retrieve the view for
153      * @return the View instance, or <code>null</code> if not found
154      * (optional, to allow for ViewResolver chaining)
155      * @throws Exception if the view couldn't be resolved
156      * @see #loadView
157      */

158     protected View createView(String JavaDoc viewName, Locale JavaDoc locale) throws Exception JavaDoc {
159         return loadView(viewName, locale);
160     }
161
162     /**
163      * Subclasses must implement this method, building a View object
164      * for the specified view. The returned View objects will be
165      * cached by this ViewResolver base class.
166      * <p>Subclasses are not forced to support internationalization:
167      * A subclass that doesn't may simply ignore the locale parameter.
168      * @param viewName the name of the view to retrieve
169      * @param locale the Locale to retrieve the view for
170      * @return the View instance, or <code>null</code> if not found
171      * (optional, to allow for ViewResolver chaining)
172      * @throws Exception if the view couldn't be resolved
173      * @see #resolveViewName
174      */

175     protected abstract View loadView(String JavaDoc viewName, Locale JavaDoc locale) throws Exception JavaDoc;
176
177 }
178
Popular Tags