KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > flex > CmsFlexRequest


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src/org/opencms/flex/CmsFlexRequest.java,v $
3  * Date : $Date: 2006/03/27 14:52:35 $
4  * Version: $Revision: 1.37 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (c) 2005 Alkacon Software GmbH (http://www.alkacon.com)
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 Alkacon Software GmbH, please see the
22  * company website: http://www.alkacon.com
23  *
24  * For further information about OpenCms, please see the
25  * project website: http://www.opencms.org
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */

31
32 package org.opencms.flex;
33
34 import org.opencms.file.CmsObject;
35 import org.opencms.main.CmsEvent;
36 import org.opencms.main.CmsLog;
37 import org.opencms.main.I_CmsEventListener;
38 import org.opencms.main.OpenCms;
39 import org.opencms.security.CmsRole;
40 import org.opencms.staticexport.CmsLinkManager;
41
42 import java.util.Arrays JavaDoc;
43 import java.util.Collections JavaDoc;
44 import java.util.Enumeration JavaDoc;
45 import java.util.HashMap JavaDoc;
46 import java.util.Iterator JavaDoc;
47 import java.util.List JavaDoc;
48 import java.util.Map JavaDoc;
49 import java.util.Vector JavaDoc;
50
51 import javax.servlet.http.HttpServletRequest JavaDoc;
52 import javax.servlet.http.HttpServletRequestWrapper JavaDoc;
53
54 import org.apache.commons.logging.Log;
55
56 /**
57  * Wrapper class for a HttpServletRequest.<p>
58  *
59  * This class wraps the standard HttpServletRequest so that it's output can be delivered to
60  * the CmsFlexCache.<p>
61  *
62  * @author Alexander Kandzior
63  *
64  * @version $Revision: 1.37 $
65  *
66  * @since 6.0.0
67  */

68 public class CmsFlexRequest extends HttpServletRequestWrapper JavaDoc {
69
70     /** Request parameter for FlexCache commands. */
71     public static final String JavaDoc PARAMETER_FLEX = "_flex";
72
73     /** The log object for this class. */
74     private static final Log LOG = CmsLog.getLog(CmsFlexRequest.class);
75
76     /** Flag to decide if this request can be cached or not. */
77     private boolean m_canCache;
78
79     /** The CmsFlexController for this request. */
80     private CmsFlexController m_controller;
81
82     /** Flag to force a JSP recompile. */
83     private boolean m_doRecompile;
84
85     /** The requested resources element URI in the OpenCms VFS. */
86     private String JavaDoc m_elementUri;
87
88     /** The site root of the requested resource. */
89     private String JavaDoc m_elementUriSiteRoot;
90
91     /** List of all include calls (to prevent an endless inclusion loop). */
92     private List JavaDoc m_includeCalls;
93
94     /** Flag to check if this request is in the online project or not. */
95     private boolean m_isOnline;
96
97     /** The CmsFlexRequestKey for this request. */
98     private CmsFlexRequestKey m_key;
99
100     /** Map of parameters from the original request. */
101     private Map JavaDoc m_parameters;
102
103     /** Stores the request URI after it was once calculated. */
104     private String JavaDoc m_requestUri;
105
106     /** Stores the request URL after it was once calculated. */
107     private StringBuffer JavaDoc m_requestUrl;
108
109     /**
110      * Creates a new CmsFlexRequest wrapper which is most likley the "Top"
111      * request wrapper, i.e. the wrapper that is constructed around the
112      * first "real" (not wrapped) request.<p>
113      *
114      * @param req the request to wrap
115      * @param controller the controller to use
116      */

117     public CmsFlexRequest(HttpServletRequest JavaDoc req, CmsFlexController controller) {
118
119         super(req);
120         m_controller = controller;
121         CmsObject cms = m_controller.getCmsObject();
122         m_elementUri = cms.getSitePath(m_controller.getCmsResource());
123         m_elementUriSiteRoot = cms.getRequestContext().getSiteRoot();
124         m_includeCalls = new Vector JavaDoc();
125         m_parameters = req.getParameterMap();
126         m_isOnline = cms.getRequestContext().currentProject().isOnlineProject();
127         String JavaDoc[] paras = req.getParameterValues(PARAMETER_FLEX);
128         boolean nocachepara = false;
129         boolean dorecompile = false;
130         if (paras != null) {
131             if (cms.hasRole(CmsRole.WORKPLACE_MANAGER)) {
132                 List JavaDoc l = Arrays.asList(paras);
133                 boolean firstCall = controller.isEmptyRequestList();
134                 nocachepara = l.contains("nocache");
135                 dorecompile = l.contains("recompile");
136                 boolean p_on = l.contains("online");
137                 boolean p_off = l.contains("offline");
138                 if (l.contains("purge") && firstCall) {
139                     OpenCms.fireCmsEvent(new CmsEvent(
140                         I_CmsEventListener.EVENT_FLEX_PURGE_JSP_REPOSITORY,
141                         new HashMap JavaDoc(0)));
142                     OpenCms.fireCmsEvent(new CmsEvent(
143                         I_CmsEventListener.EVENT_FLEX_CACHE_CLEAR,
144                         Collections.singletonMap("action", new Integer JavaDoc(CmsFlexCache.CLEAR_ENTRIES))));
145                     dorecompile = false;
146                 } else if ((l.contains("clearcache") || dorecompile) && firstCall) {
147                     if (!(p_on || p_off)) {
148                         OpenCms.fireCmsEvent(new CmsEvent(
149                             I_CmsEventListener.EVENT_FLEX_CACHE_CLEAR,
150                             Collections.singletonMap("action", new Integer JavaDoc(CmsFlexCache.CLEAR_ALL))));
151                     } else {
152                         if (p_on) {
153                             OpenCms.fireCmsEvent(new CmsEvent(
154                                 I_CmsEventListener.EVENT_FLEX_CACHE_CLEAR,
155                                 Collections.singletonMap("action", new Integer JavaDoc(CmsFlexCache.CLEAR_ONLINE_ALL))));
156                         }
157                         if (p_off) {
158                             OpenCms.fireCmsEvent(new CmsEvent(
159                                 I_CmsEventListener.EVENT_FLEX_CACHE_CLEAR,
160                                 Collections.singletonMap("action", new Integer JavaDoc(CmsFlexCache.CLEAR_OFFLINE_ALL))));
161                         }
162                     }
163                 } else if (l.contains("clearvariations") && firstCall) {
164                     if (!(p_on || p_off)) {
165                         OpenCms.fireCmsEvent(new CmsEvent(
166                             I_CmsEventListener.EVENT_FLEX_CACHE_CLEAR,
167                             Collections.singletonMap("action", new Integer JavaDoc(CmsFlexCache.CLEAR_ENTRIES))));
168                     } else {
169                         if (p_on) {
170                             OpenCms.fireCmsEvent(new CmsEvent(
171                                 I_CmsEventListener.EVENT_FLEX_CACHE_CLEAR,
172                                 Collections.singletonMap("action", new Integer JavaDoc(CmsFlexCache.CLEAR_ONLINE_ENTRIES))));
173                         }
174                         if (p_off) {
175                             OpenCms.fireCmsEvent(new CmsEvent(
176                                 I_CmsEventListener.EVENT_FLEX_CACHE_CLEAR,
177                                 Collections.singletonMap("action", new Integer JavaDoc(CmsFlexCache.CLEAR_OFFLINE_ENTRIES))));
178                         }
179                     }
180                 }
181             }
182         }
183         m_canCache = (((m_isOnline || m_controller.getCmsCache().cacheOffline()) && !nocachepara) || dorecompile);
184         m_doRecompile = dorecompile;
185         if (LOG.isDebugEnabled()) {
186             LOG.debug(Messages.get().getBundle().key(Messages.LOG_FLEXREQUEST_CREATED_NEW_REQUEST_1, m_elementUri));
187         }
188     }
189
190     /**
191      * Constructs a new wrapper layer around an (already wrapped) CmsFlexRequest.<p>
192      *
193      * @param req the request to be wrapped
194      * @param controller the controller to use
195      * @param resource the target resource that has been requested
196      */

197     CmsFlexRequest(HttpServletRequest JavaDoc req, CmsFlexController controller, String JavaDoc resource) {
198
199         super(req);
200         m_controller = controller;
201         m_elementUri = CmsLinkManager.getAbsoluteUri(resource, m_controller.getCurrentRequest().getElementUri());
202         m_elementUriSiteRoot = m_controller.getCurrentRequest().m_elementUriSiteRoot;
203         m_isOnline = m_controller.getCurrentRequest().isOnline();
204         m_canCache = m_controller.getCurrentRequest().isCacheable();
205         m_doRecompile = m_controller.getCurrentRequest().isDoRecompile();
206         m_includeCalls = m_controller.getCurrentRequest().getCmsIncludeCalls();
207         m_parameters = req.getParameterMap();
208         if (LOG.isDebugEnabled()) {
209             LOG.debug(Messages.get().getBundle().key(Messages.LOG_FLEXREQUEST_REUSING_FLEX_REQUEST_1, m_elementUri));
210         }
211     }
212
213     /**
214      * Adds the specified Map to the paramters of the request,
215      * added parametes will not overwrite existing parameters in the
216      * request.<p>
217      *
218      * Remember that the value for a parameter name in
219      * a HttpRequest is a String array. If a parameter name already
220      * exists in the HttpRequest, the values will be added to the existing
221      * value array. Multiple occurences of the same value for one
222      * paramter are also possible.<p>
223      *
224      * @param map the map to add
225      * @return the merged map of parameters
226      */

227     public Map JavaDoc addParameterMap(Map JavaDoc map) {
228
229         if (map == null) {
230             return m_parameters;
231         }
232         if ((m_parameters == null) || (m_parameters.size() == 0)) {
233             m_parameters = Collections.unmodifiableMap(map);
234         } else {
235             HashMap JavaDoc parameters = new HashMap JavaDoc();
236             parameters.putAll(m_parameters);
237
238             Iterator JavaDoc it = map.keySet().iterator();
239             while (it.hasNext()) {
240                 String JavaDoc key = (String JavaDoc)it.next();
241                 // Check if the parameter name (key) exists
242
if (parameters.containsKey(key)) {
243
244                     String JavaDoc[] oldValues = (String JavaDoc[])parameters.get(key);
245                     String JavaDoc[] newValues = (String JavaDoc[])map.get(key);
246
247                     String JavaDoc[] mergeValues = new String JavaDoc[oldValues.length + newValues.length];
248                     System.arraycopy(newValues, 0, mergeValues, 0, newValues.length);
249                     System.arraycopy(oldValues, 0, mergeValues, newValues.length, oldValues.length);
250
251                     parameters.put(key, mergeValues);
252                 } else {
253                     // No: Add new value array
254
parameters.put(key, map.get(key));
255                 }
256             }
257             m_parameters = Collections.unmodifiableMap(parameters);
258         }
259
260         return m_parameters;
261     }
262
263     /**
264      * Returns the full element URI site root path to the resource currently processed.<p>
265      *
266      * @return the name of the resource currently processed
267      */

268     public String JavaDoc getElementRootPath() {
269
270         return m_controller.getCmsObject().getRequestContext().addSiteRoot(m_elementUriSiteRoot, m_elementUri);
271     }
272
273     /**
274      * Returns the element URI of the resource currently processed,
275      * relative to the current site root.<p>
276      *
277      * This might be the name of an included resource,
278      * not neccesarily the name the resource requested by the user.
279      *
280      * @return the name of the resource currently processed
281      */

282     public String JavaDoc getElementUri() {
283
284         return m_elementUri;
285     }
286
287     /**
288      * Return the value of the specified request parameter, if any; otherwise,
289      * return <code>null</code>.<p>
290      *
291      * If there is more than one value defined,
292      * return only the first one.<p>
293      *
294      * @param name the name of the desired request parameter
295      * @return the value of the specified request parameter
296      * @see javax.servlet.ServletRequest#getParameter(java.lang.String)
297      */

298     public String JavaDoc getParameter(String JavaDoc name) {
299
300         String JavaDoc[] values = (String JavaDoc[])m_parameters.get(name);
301         if (values != null) {
302             return (values[0]);
303         } else {
304             return (null);
305         }
306     }
307
308     /**
309      * Returns a <code>Map</code> of the parameters of this request.<p>
310      *
311      * Request parameters are extra information sent with the request.
312      * For HTTP servlets, parameters are contained in the query string
313      * or posted form data.<p>
314      *
315      * @return a <code>Map</code> containing parameter names as keys
316      * and parameter values as map values
317      * @see javax.servlet.ServletRequest#getParameterMap()
318      */

319     public Map JavaDoc getParameterMap() {
320
321         return m_parameters;
322     }
323
324     /**
325      * Return the names of all defined request parameters for this request.<p>
326      *
327      * @return the names of all defined request parameters for this request
328      * @see javax.servlet.ServletRequest#getParameterNames()
329      */

330     public Enumeration JavaDoc getParameterNames() {
331
332         Vector JavaDoc v = new Vector JavaDoc();
333         v.addAll(m_parameters.keySet());
334         return (v.elements());
335     }
336
337     /**
338      * Returns the defined values for the specified request parameter, if any;
339      * otherwise, return <code>null</code>.
340      *
341      * @param name Name of the desired request parameter
342      * @return the defined values for the specified request parameter, if any;
343      * <code>null</code> otherwise
344      * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String)
345      */

346     public String JavaDoc[] getParameterValues(String JavaDoc name) {
347
348         return (String JavaDoc[])m_parameters.get(name);
349     }
350
351     /**
352      * Allows requests to be dispatched to internal VFS resources or
353      * external JSP pages, overloads the standard servlet API <code>getRequestDispatcher()</code> method.<p>
354      *
355      * @param target the target for the request dispatcher
356      * @return a special RequestDispatcher that allows access to VFS resources
357      */

358     public javax.servlet.RequestDispatcher JavaDoc getRequestDispatcher(String JavaDoc target) {
359
360         String JavaDoc absolutUri = CmsLinkManager.getAbsoluteUri(target, m_controller.getCurrentRequest().getElementUri());
361         return new CmsFlexRequestDispatcher(
362             m_controller.getTopRequest().getRequestDispatcher(absolutUri),
363             absolutUri,
364             null);
365     }
366
367     /**
368      * Replacement for the standard servlet API getRequestDispatcher() method.<p>
369      *
370      * This variation is used if an external file (probably JSP) is dispached to.
371      * This external file must have a "mirror" version, i.e. a file in the OpenCms VFS
372      * that represents the external file.<p>
373      *
374      * @param vfs_target the OpenCms file that is a "mirror" version of the external file
375      * @param ext_target the external file (outside the OpenCms VFS)
376      * @return the constructed CmsFlexRequestDispatcher
377      */

378     public CmsFlexRequestDispatcher getRequestDispatcherToExternal(String JavaDoc vfs_target, String JavaDoc ext_target) {
379
380         return new CmsFlexRequestDispatcher(
381             m_controller.getTopRequest().getRequestDispatcher(ext_target),
382             CmsLinkManager.getAbsoluteUri(vfs_target, m_controller.getCmsObject().getRequestContext().getUri()),
383             ext_target);
384     }
385
386     /**
387      * Wraps the request URI, overloading the standard API.<p>
388      *
389      * This ensures that any wrapped request will use the "faked"
390      * target parameters. Remember that for the real request,
391      * a mixture of PathInfo and other request information is used to
392      * idenify the target.<p>
393      *
394      * @return a faked URI that will point to the wrapped target in the VFS
395      * @see javax.servlet.http.HttpServletRequest#getRequestURI()
396      */

397     public String JavaDoc getRequestURI() {
398
399         if (m_requestUri != null) {
400             return m_requestUri;
401         }
402         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(128);
403         buf.append(OpenCms.getSystemInfo().getOpenCmsContext());
404         buf.append(getElementUri());
405         m_requestUri = buf.toString();
406         return m_requestUri;
407     }
408
409     /**
410      * Wraps the request URL, overloading the standard API,
411      * the wrapped URL will always point to the currently included VFS resource.<p>
412      *
413      * @return a faked URL that will point to the included target in the VFS
414      * @see javax.servlet.http.HttpServletRequest#getRequestURL()
415      */

416     public StringBuffer JavaDoc getRequestURL() {
417
418         if (m_requestUrl != null) {
419             return m_requestUrl;
420         }
421         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(128);
422         buf.append(getScheme());
423         buf.append("://");
424         buf.append(getServerName());
425         buf.append(":");
426         buf.append(getServerPort());
427         buf.append(getRequestURI());
428         m_requestUrl = buf;
429         return m_requestUrl;
430     }
431
432     /**
433      * Checks if JSPs should always be recompiled.<p>
434      *
435      * This is useful in case directive based includes are used
436      * with &lt;%@ include file="..." %&gt; on a JSP.
437      * Note that this also forces the request not to be cached.<p>
438      *
439      * @return true if JSPs should be recompiled, false otherwise
440      */

441     public boolean isDoRecompile() {
442
443         return m_doRecompile;
444     }
445
446     /**
447      * Indicates that this request belongs to an online project.<p>
448      *
449      * This is required to distinguish between online and offline
450      * resources in the cache. Since the resources have the same name,
451      * a suffix [online] or [offline] is added to distinguish the strings
452      * when building cache keys.
453      * Any resource from a request that isOnline() will be saved with
454      * the [online] suffix and vice versa.<p>
455      *
456      * Resources in the OpenCms workplace are not distinguised between
457      * online and offline but have their own suffix [workplace].
458      * The assumption is that if you do change the workplace, this is
459      * only on true development macines so you can do the cache clearing
460      * manually if required.<p>
461      *
462      * The suffixes are used so that we have a simple String name
463      * for the resources in the cache. This makes it easy to
464      * use a standard HashMap for storage of the resources.<p>
465      *
466      * @return true if an online resource was requested, false otherwise
467      */

468     public boolean isOnline() {
469
470         return m_isOnline;
471     }
472
473     /**
474      * Sets the specified Map as paramter map of the request.<p>
475      *
476      * The map set should be immutable.
477      * This will completly replace the parameter map.
478      * Use this in combination with getParameterMap() and
479      * addParameterMap() in case you want to set the old status
480      * of the parameter map after you have modified it for
481      * a specific operation.<p>
482      *
483      * @param map the map to set
484      */

485     public void setParameterMap(Map JavaDoc map) {
486
487         m_parameters = map;
488     }
489
490     /**
491      * @see java.lang.Object#toString()
492      */

493     public String JavaDoc toString() {
494
495         // return the uri of the element requested for this request, useful in debugging
496
return m_elementUri;
497     }
498
499     /**
500      * Returns the List of include calls which will be passed to the next wrapping layer.<p>
501      *
502      * The set of include calls is maintained to dectect
503      * an endless inclusion loop.<p>
504      *
505      * @return the List of include calls
506      */

507     protected List JavaDoc getCmsIncludeCalls() {
508
509         return m_includeCalls;
510     }
511
512     /**
513      * Adds another include call to this wrapper.<p>
514      *
515      * The set of include calls is maintained to dectect
516      * an endless inclusion loop.<p>
517      *
518      * @param target the target name (absolute OpenCms URI) to add
519      */

520     void addInlucdeCall(String JavaDoc target) {
521
522         m_includeCalls.add(target);
523     }
524
525     /**
526      * Checks if a given target is already included in a top-layer of this
527      * wrapped request.<p>
528      *
529      * The set of include calls is maintained to dectect
530      * an endless inclusion loop.<p>
531      *
532      * @param target the target name (absolute OpenCms URI) to check for
533      * @return true if the target is already included, false otherwise
534      */

535     boolean containsIncludeCall(String JavaDoc target) {
536
537         return m_includeCalls.contains(target);
538     }
539
540     /**
541      * Returns the CmsFlexCacheKey for this request,
542      * the key will be calculated if neccessary.<p>
543      *
544      * @return the CmsFlexCacheKey for this request
545      */

546     CmsFlexRequestKey getCmsCacheKey() {
547
548         // The key for this request is only calculated if actually requested
549
if (m_key == null) {
550             m_key = new CmsFlexRequestKey(this, m_elementUri, m_isOnline);
551         }
552         return m_key;
553     }
554
555     /**
556      * This is needed to decide if this request can be cached or not.<p>
557      *
558      * Using the request to decide if caching is used or not
559      * makes it possible to set caching to false e.g. on a per-user
560      * or per-project basis.<p>
561      *
562      * @return true if the request is cacheable, false otherwise
563      */

564     boolean isCacheable() {
565
566         return m_canCache;
567     }
568
569     /**
570      * Removes an include call from this wrapper.<p>
571      *
572      * The set of include calls is maintained to dectect
573      * an endless inclusion loop.<p>
574      *
575      * @param target the target name (absolute OpenCms URI) to remove
576      */

577     void removeIncludeCall(String JavaDoc target) {
578
579         m_includeCalls.remove(target);
580     }
581 }
582
Popular Tags