Source code: com/opencms/template/A_CmsTemplate.java
1 /*
2 * File : $Source: /usr/local/cvs/opencms/src/com/opencms/template/A_CmsTemplate.java,v $
3 * Date : $Date: 2003/03/02 18:43:55 $
4 * Version: $Revision: 1.10 $
5 *
6 * This library is part of OpenCms -
7 * the Open Source Content Mananagement System
8 *
9 * Copyright (C) 2001 The OpenCms Group
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * For further information about OpenCms, please see the
22 * OpenCms Website: http://www.opencms.org
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 */
28
29 package com.opencms.template;
30
31 import com.opencms.boot.I_CmsLogChannels;
32 import com.opencms.core.A_OpenCms;
33 import com.opencms.core.CmsException;
34 import com.opencms.core.I_CmsConstants;
35 import com.opencms.file.CmsFile;
36 import com.opencms.file.CmsObject;
37 import com.opencms.file.CmsRequestContext;
38
39 import java.util.Hashtable;
40
41 import javax.servlet.http.HttpServletRequest;
42
43 /**
44 * Abstract template class. Contains all commonly used methods for handling cache properties.
45 *
46 * @author Alexander Lucas
47 * @version $Revision: 1.10 $ $Date: 2003/03/02 18:43:55 $
48 */
49 public abstract class A_CmsTemplate implements I_CmsConstants, I_CmsTemplate, I_CmsLogChannels {
50
51 /**
52 * Help method to print nice classnames in error messages
53 * @return class name in [ClassName] format
54 */
55 protected String getClassName() {
56 String name = getClass().getName();
57 return "[" + name.substring(name.lastIndexOf(".") + 1) + "] ";
58 }
59
60 /**
61 * Indicates if the results of this class are cacheable in the internal caches.
62 * By default all resources in the online project may be stored in the internal
63 * cache.
64 * <P>
65 * Complex classes that are able to include other subtemplates
66 * have to check the cacheability of their subclasses here!
67 *
68 * @param cms CmsObject Object for accessing system resources
69 * @param templateFile Filename of the template file
70 * @param elementName Element name of this template in our parent template.
71 * @param parameters Hashtable with all template class parameters.
72 * @param templateSelector template section that should be processed.
73 * @return <EM>true</EM> if cacheable, <EM>false</EM> otherwise.
74 */
75 public boolean isCacheable(CmsObject cms, String templateFile, String elementName, Hashtable parameters, String templateSelector) {
76 try {
77 return cms.getRequestContext().currentProject().isOnlineProject();
78 } catch(Exception e) {
79 return false;
80 }
81 }
82
83 /**
84 * Indicates if the results of this class may be cached by private proxy caches (browsers).
85 * <P>
86 * Default conditions are:
87 * <ul>
88 * <li>Resource is cacheable in the internal cache</li>
89 * <li>Caching key only consists of the URL</li>
90 * </ul>
91 * <P>
92 * Complex classes that are able to include other subtemplates
93 * have to check the cacheability of their subclasses here!
94 *
95 * @param cms CmsObject Object for accessing system resources
96 * @param templateFile Filename of the template file
97 * @param elementName Element name of this template in our parent template.
98 * @param parameters Hashtable with all template class parameters.
99 * @param templateSelector template section that should be processed.
100 * @return <EM>true</EM> if cacheable, <EM>false</EM> otherwise.
101 */
102 public boolean isProxyPrivateCacheable(CmsObject cms, String templateFile, String elementName, Hashtable parameters, String templateSelector) {
103 boolean result;
104 try {
105 result = isProxyPublicCacheable(cms, templateFile, elementName, parameters, templateSelector)
106 && cms.getRequestContext().currentUser().equals(cms.anonymousUser());
107 } catch (Exception e) {
108 result = false;
109 }
110 return result;
111 }
112
113 /**
114 * Indicates if the results of this class may be cached by public proxy caches.
115 * <P>
116 * Default conditions are:
117 * <ul>
118 * <li>Resource may be cached by private proxies</li>
119 * <li>Current user is Guest (otherwise privat information may be stored)</li>
120 * </ul>
121 * <P>
122 * Complex classes that are able to include other subtemplates
123 * have to check the cacheability of their subclasses here!
124 *
125 * @param cms CmsObject Object for accessing system resources
126 * @param templateFile Filename of the template file
127 * @param elementName Element name of this template in our parent template.
128 * @param parameters Hashtable with all template class parameters.
129 * @param templateSelector template section that should be processed.
130 * @return <EM>true</EM> if cacheable, <EM>false</EM> otherwise.
131 */
132 public boolean isProxyPublicCacheable(CmsObject cms, String templateFile, String elementName, Hashtable parameters, String templateSelector) {
133 CmsRequestContext reqContext = cms.getRequestContext();
134 String key = (String)getKey(cms, templateFile, parameters, templateSelector);
135 String projId = "" + reqContext.currentProject().getId() + ":";
136 String uri = reqContext.getUri();
137 String uri2 = null;
138 if(uri != null && uri.indexOf("?") > 1) {
139 uri2 = uri.substring(0, uri.indexOf("?"));
140 }
141
142 boolean result = (key.equals(uri) || key.equals(uri2) || key.equals(templateFile)
143 || key.equals(projId + uri) || key.equals(projId + uri2) || key.equals(projId + templateFile));
144 return result;
145 }
146
147 /**
148 * Indicates if the results of this class are "static" and may be exported.
149 * <P>
150 * Default conditions are:
151 * <ul>
152 * <li>Resource may be cached by public proxies</li>
153 * <li>There are no parameters in the URL</li>
154 * <li>The resource's internal flag must not be set</li>
155 * </ul>
156 * <P>
157 * Complex classes that are able to include other subtemplates
158 * have to check the export ability of their subclasses here!
159 *
160 * @param cms CmsObject Object for accessing system resources
161 * @param templateFile Filename of the template file
162 * @param elementName Element name of this template in our parent template.
163 * @param parameters Hashtable with all template class parameters.
164 * @param templateSelector template section that should be processed.
165 * @return <EM>true</EM> if exportable, <EM>false</EM> otherwise.
166 */
167 public boolean isExportable(CmsObject cms, String templateFile, String elementName, Hashtable parameters, String templateSelector) {
168 HttpServletRequest httpReq = (HttpServletRequest)cms.getRequestContext().getRequest().getOriginalRequest();
169 String queryString = "";
170 if(httpReq != null){
171 queryString = httpReq.getQueryString();
172 }
173 boolean result = isProxyPrivateCacheable(cms, templateFile, elementName, parameters, templateSelector)
174 && (queryString == null || "".equals(queryString));
175 try {
176 CmsFile file = cms.readFile(templateFile);
177 result = result && (file.getAccessFlags() & CmsFile.C_ACCESS_INTERNAL_READ) != CmsFile.C_ACCESS_INTERNAL_READ;
178 } catch(Exception e) {
179 result = false;
180 }
181 return result;
182 }
183
184 /**
185 * Indicates if the current template class is able to stream it's results
186 * directly to the response oputput stream.
187 * <P>
188 * Classes must not set this feature, if they might throw special
189 * exception that cause HTTP errors (e.g. 404/Not Found), or if they
190 * might send HTTP redirects.
191 * <p>
192 * If a class sets this feature, it has to check the
193 * isStreaming() property of the RequestContext. If this is set
194 * to <code>true</code> the results must be streamed directly
195 * to the output stream. If it is <code>false</code> the results
196 * must not be streamed.
197 * <P>
198 * Complex classes that are able to include other subtemplates
199 * have to check the streaming ability of their subclasses here!
200 *
201 * @param cms CmsObject Object for accessing system resources
202 * @param templateFile Filename of the template file
203 * @param elementName Element name of this template in our parent template.
204 * @param parameters Hashtable with all template class parameters.
205 * @param templateSelector template section that should be processed.
206 * @return <EM>true</EM> if this class may stream it's results, <EM>false</EM> otherwise.
207 */
208 public boolean isStreamable(CmsObject cms, String templateFile, String elementName, Hashtable parameters, String templateSelector) {
209 return false;
210 }
211
212 /**
213 * Collect caching informations from the current template class.
214 * <P>
215 * Complex classes that are able to include other subtemplates
216 * have to check the streaming ability of their subclasses here!
217 *
218 * @param cms CmsObject Object for accessing system resources
219 * @param templateFile Filename of the template file
220 * @param elementName Element name of this template in our parent template.
221 * @param parameters Hashtable with all template class parameters.
222 * @param templateSelector template section that should be processed.
223 * @return <EM>true</EM> if this class may stream it's results, <EM>false</EM> otherwise.
224 */
225 public CmsCacheDirectives collectCacheDirectives(CmsObject cms, String templateFile, String elementName, Hashtable parameters, String templateSelector) {
226 boolean isCacheable = isCacheable(cms, templateFile, elementName, parameters, templateSelector);
227 boolean isProxyPublicCacheable = isProxyPublicCacheable(cms, templateFile, elementName, parameters, templateSelector);
228 boolean isProxyPrivateCacheable = isProxyPrivateCacheable(cms, templateFile, elementName, parameters, templateSelector);
229 boolean isExportable = isExportable(cms, templateFile, elementName, parameters, templateSelector);
230 boolean isStreamable = isStreamable(cms, templateFile, elementName, parameters, templateSelector);
231 CmsCacheDirectives result = new CmsCacheDirectives(isCacheable, isProxyPrivateCacheable, isProxyPublicCacheable, isExportable, isStreamable);
232 return result;
233 }
234
235 protected void debugPrint(String s, int i) {
236 System.err.print("* " + s);
237 for(int j=0; j<(15-s.length()); j++) {
238 System.err.print(" ");
239 }
240
241 //INT PUB PRV EXP STR
242 System.err.print(" " + ((i & 1) == 1?"X":" ") + " ");
243 System.err.print(" " + ((i & 2) == 2?"X":" ") + " ");
244 System.err.print(" " + ((i & 4) == 4?"X":" ") + " ");
245 System.err.print(" " + ((i & 8) == 8?"X":" ") + " ");
246 System.err.print(" " + ((i & 16) == 16?"X":" ") + " ");
247 }
248
249
250
251 /**
252 * Help method that handles any occuring error by writing
253 * an error message to the OpenCms logfile and throwing a
254 * CmsException of the type "unknown".
255 * @param errorMessage String with the error message to be printed.
256 * @throws CmsException
257 */
258 protected void throwException(String errorMessage) throws CmsException {
259 throwException(errorMessage, CmsException.C_UNKNOWN_EXCEPTION);
260 }
261
262 /**
263 * Help method that handles any occuring error by writing
264 * an error message to the OpenCms logfile and throwing a
265 * CmsException of the given type.
266 * @param errorMessage String with the error message to be printed.
267 * @param type Type of the exception to be thrown.
268 * @throws CmsException
269 */
270 protected void throwException(String errorMessage, int type) throws CmsException {
271 if(I_CmsLogChannels.C_PREPROCESSOR_IS_LOGGING && A_OpenCms.isLogging() ) {
272 A_OpenCms.log(C_OPENCMS_CRITICAL, getClassName() + errorMessage);
273 }
274 throw new CmsException(errorMessage, type);
275 }
276
277 /**
278 * Help method that handles any occuring error by writing
279 * an error message to the OpenCms logfile and re-throwing a
280 * caught exception.
281 * @param errorMessage String with the error message to be printed.
282 * @param e Exception to be re-thrown.
283 * @throws CmsException
284 */
285 protected void throwException(String errorMessage, Exception e) throws CmsException {
286 if(I_CmsLogChannels.C_PREPROCESSOR_IS_LOGGING && A_OpenCms.isLogging() ) {
287 A_OpenCms.log(C_OPENCMS_CRITICAL, getClassName() + errorMessage);
288 A_OpenCms.log(C_OPENCMS_CRITICAL, getClassName() + "Exception: " + e);
289 }
290 if(e instanceof CmsException) {
291 throw (CmsException)e;
292 }
293 else {
294 throw new CmsException(errorMessage, CmsException.C_UNKNOWN_EXCEPTION, e);
295 }
296 }
297 }