KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jahia > services > applications > ServletIncludeRequestWrapper


1 //
2
// ____.
3
// __/\ ______| |__/\. _______
4
// __ .____| | \ | +----+ \
5
// _______| /--| | | - \ _ | : - \_________
6
// \\______: :---| : : | : | \________>
7
// |__\---\_____________:______: :____|____:_____\
8
// /_____|
9
//
10
// . . . i n j a h i a w e t r u s t . . .
11
//
12
//
13
//
14

15 package org.jahia.services.applications;
16
17 import java.io.PrintWriter JavaDoc;
18 import java.io.StringWriter JavaDoc;
19 import java.net.MalformedURLException JavaDoc;
20 import java.net.URL JavaDoc;
21 import java.net.URLDecoder JavaDoc;
22 import java.security.Principal JavaDoc;
23 import java.util.Collections JavaDoc;
24 import java.util.Enumeration JavaDoc;
25 import java.util.Hashtable JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Locale JavaDoc;
28 import java.util.Map JavaDoc;
29
30 import javax.servlet.RequestDispatcher JavaDoc;
31 import javax.servlet.ServletContext JavaDoc;
32 import javax.servlet.http.HttpServletRequest JavaDoc;
33 import javax.servlet.http.HttpServletRequestWrapper JavaDoc;
34 import javax.servlet.http.HttpSession JavaDoc;
35
36 import org.apache.log4j.Logger;
37 import org.jahia.exceptions.JahiaException;
38 import org.jahia.exceptions.JahiaSessionExpirationException;
39 import org.jahia.params.ParamBean;
40 import org.jahia.registries.ServicesRegistry;
41 import org.jahia.security.license.LicenseConstants;
42 import org.jahia.services.usermanager.GenericPrincipal;
43 import org.jahia.services.usermanager.JahiaGroup;
44 import org.jahia.services.usermanager.JahiaUser;
45
46 /**
47  * This wrapper around the request object has multiple responsabilities, such as
48  * making sure that the application gets only it's local parameter set, and not
49  * Jahia's.
50  *
51  * @author Serge Huber
52  * @version 1.0
53  * @todo This emulation is not complete, mostly for development time reasons.
54  * @todo We should really split this class into two classes : one with
55  * emulation, one without. It would make a lot of the code much simpler to
56  * maintain.
57  * @todo FIXME It seems that the hasRequestURI() handling is not correct,
58  * notably for the following methods : getParameter* should return a
59  * combination of the original request parameters and the include/forward
60  * parameters, getQueryString() should be concatenated with the original
61  * query (is this correct)
62  */

63
64 public class ServletIncludeRequestWrapper extends HttpServletRequestWrapper JavaDoc {
65
66     private static Logger logger = Logger.getLogger(ServletIncludeRequestWrapper.class);
67
68     private String JavaDoc emulatedContextPath;
69     private URL JavaDoc emulatedURL;
70     private String JavaDoc emulatedMethod;
71     private Map JavaDoc parameters = new Hashtable JavaDoc();
72     private boolean parsed = false;
73     private HttpSessionWrapper sessionWrapper;
74     private PersistantServletRequest appRequest;
75     private final ParamBean jahiaParams;
76     private String JavaDoc contextIdentifier; // an application is instantied only
77

78     private String JavaDoc emulatedServletPath = "";
79     private String JavaDoc emulatedPathInfo = "";
80     private String JavaDoc initialRequestURI = ""; // used to detect forward between servlet
81
//private String jSessionId = "";
82

83     private boolean applicationCacheOn = true;
84     private long applicationCacheExpirationDelay = -1;
85     private boolean inheritJahiaSessionAttributes = false;
86     private boolean hideRequestParameter = false;
87
88     /**
89      * This constructor creates a new emulated request object by substituting
90      * Jahia's URL with the application's URL. This way the application will
91      * have the impression it is executing itself normally within it's context.
92      * It remains to be seen if it seems reasonable to undertake the full
93      * emulation of this object, or if only parts will suffice (let's hope so !)
94      * A good test of this emulation would be to run Jahia within Jahia.
95      *
96      * @param httpServletRequest
97      * Jahia's original request object
98      * @param emulURL
99      * The new URL to be substituted with Jahia's.
100      * @param emulContextPath
101      * The path of the emulated context
102      * @param emulMethod
103      * the method (GET, POST, etc...) that the wrapper emulates
104      * @param applicationRequest
105      * Application request used for internal string keys elements
106      * @param contextID
107      * identifier containing the string that represents the context
108      * ID of the running application (usually the fieldID)
109      * @param jParams
110      * Jahia's param bean object
111      */

112     public ServletIncludeRequestWrapper(HttpServletRequest JavaDoc httpServletRequest,
113             String JavaDoc emulURL, String JavaDoc emulContextPath, String JavaDoc emulMethod,
114             PersistantServletRequest applicationRequest, String JavaDoc contextID,
115             boolean fullScreenActivated, boolean inheritJahiaSessionAttr,
116             ParamBean jParams) {
117         super(httpServletRequest);
118         initialRequestURI = super.getRequestURI();
119         emulatedContextPath = emulContextPath;
120         emulatedMethod = emulMethod;
121         appRequest = applicationRequest;
122         jahiaParams = jParams;
123         contextIdentifier = contextID;
124         this.inheritJahiaSessionAttributes = inheritJahiaSessionAttr;
125         parsed = false;
126         // here we should add code that will decode the Jahia parameters and construct
127
// the emulated request body <--
128

129         //set origanal request
130
setAttribute("originalRequest", getRequest());
131         try {
132
133             String JavaDoc URLPort;
134             if (jahiaParams.getRealRequest().getServerPort() == 80) {
135                 URLPort = "";
136             } else {
137                 Integer JavaDoc conv = new Integer JavaDoc(jahiaParams.getRealRequest()
138                     .getServerPort());
139                 URLPort = ":" + conv.toString();
140             }
141
142             URL JavaDoc contextURL = new URL JavaDoc(jahiaParams
143                 .getRealRequest().getScheme()
144                     + "://"
145                     + jahiaParams.getRealRequest().getServerName()
146                     + URLPort + "/");
147             /*
148             // STRUTS ISSUE :
149             // Struts use Servlet Action with extension,
150             // i.e /strutsApp/myAction.do
151             // so we have to give the emulated URL , the appearance of an URL instead of a file
152             if ( appRequest.getServletMappingPattern().startsWith("*.")
153                  && emulURL.endsWith(appRequest.getServletMappingPattern().substring(2)) ){
154                 emulURL += "?jahiastrutsaction=true";
155                 appRequest.setURL(emulURL);
156             }
157              */

158             emulatedURL = new URL JavaDoc(contextURL, emulURL);
159
160             httpServletRequest.setAttribute("org.portletapi.portal", "true");
161             /** @todo Add a security check before enabling this attribute */
162             httpServletRequest.setAttribute("org.portletapi.contextid",
163                 contextID);
164             if (fullScreenActivated) {
165                 httpServletRequest.setAttribute("org.portletapi.fullscreen",
166                     "true");
167             } else {
168                 httpServletRequest.setAttribute("org.portletapi.fullscreen",
169                     "false");
170             }
171             httpServletRequest.setAttribute("org.jahia.sitekey", jParams
172                 .getSiteKey());
173             httpServletRequest.setAttribute("org.jahia.siteurl", jParams
174                 .getSiteURL());
175             httpServletRequest.setAttribute("org.jahia.siteid", Integer
176                 .toString(jParams.getSiteID()));
177             httpServletRequest.setAttribute("org.jahia.pageid", Integer
178                 .toString(jParams.getPageID()));
179             httpServletRequest.setAttribute("org.jahia.operationmode", jParams
180                 .getOperationMode());
181             // can be used by the application to perform some license check
182
/**
183              * @todo FIXME this is here in case some legacy applications still
184              * use this, but should be removed !
185              */

186             httpServletRequest.setAttribute("org.jahia.license.licenseType",
187                 new Integer JavaDoc(LicenseConstants.PROJODA_LICENSE_TYPE));
188
189             this.hideRequestParameter = (!applicationRequest.getUniqueIDStr()
190                 .equalsIgnoreCase(
191                     jParams.getRealRequest().getParameter("appid")));
192
193             parseParameters(httpServletRequest);
194             parseEmulatedURL(URLDecode(emulURL));
195         } catch (MalformedURLException JavaDoc mue) {
196             logger.debug("Malformed URL", mue);
197             emulatedURL = null;
198         } catch (JahiaException je) {
199             logger
200                 .debug("JahiaException in constructor of request wrapper", je);
201             emulatedURL = null;
202         }
203         logger.debug("emulatedURL value : [" + emulatedURL + "]");
204         logger
205             .debug("super.requestURI value : [" + super.getRequestURI() + "]");
206         logger.debug("initial requestURI value : [" + initialRequestURI + "]");
207
208     }
209
210     // --------------------------------------------------------------------------
211
/**
212      * Returns true if the initial requestURI and the value returned by
213      * super.getRequestURI() is different. If true, this means a servlet include
214      * or forward has been performed. When true, any emulated value should be
215      * ignored and the value returned by wrapped methods like getServletPath(),
216      * getPathInfo(), getRequestURI(), getRequestURL() should be the real value ! (
217      * calling super.getServletPath(), super.getPathInfo(), ... )
218      *
219      * @author Khue Nguyen
220      */

221     public boolean hasRequestURIChanged() {
222         // return ( super.getContentLength() != this.initiaContentLength );
223
/*
224         if ( this.emulatedURL != null &&
225              !super.getRequestURI().equals(initialRequestURI) ){
226             logger.debug("Request URI Has changed ! emulatedURI=" + initialRequestURI + ", super.getRequestURI()=" + super.getRequestURI());
227             if ( this.emulatedURL != null ){
228               logger.debug(",emulatedURL=" + this.emulatedURL.toString());
229             }
230             if (super.getRequestURL() != null ){
231               logger.debug(", super.getRequestURL()=" + super.getRequestURL() + "\n");
232             }
233
234             // reparse the emulated url
235             updateEmulatedValues();
236             return true;
237         }*/

238
239         if (!super.getRequestURI().equals(initialRequestURI)) {
240             if (logger.isDebugEnabled()){
241                 logger.debug("Request URI Has changed ! emulatedURI="
242                     + initialRequestURI + ", super.getRequestURI()="
243                     + super.getRequestURI());
244                 if (this.emulatedURL != null) {
245                     logger.debug(",emulatedURL=" + this.emulatedURL.toString());
246                 }
247                 if (super.getRequestURL() != null) {
248                     logger.debug(", super.getRequestURL()=" + super.getRequestURL()
249                         + "\n");
250                 } else {
251                     logger.debug(", super.getRequestURL()=null\n");
252                 }
253             }
254             /*
255       logger.debug(RequestDispatcherWrapper.INCLUDE_REQUEST_URI + "=" + getAttribute("javax.servlet.include.request_uri") + ", super.getRequestURI()=" + super.getRequestURI());
256       logger.debug(RequestDispatcherWrapper.INCLUDE_CONTEXT_PATH + "=" + getAttribute("javax.servlet.include.context_path") + ", super.getContextPath()=" + super.getContextPath());
257       logger.debug(RequestDispatcherWrapper.INCLUDE_SERVLET_PATH + "=" + getAttribute("javax.servlet.include.servlet_path") + ", super.getServletPath()=" + super.getServletPath());
258       logger.debug(RequestDispatcherWrapper.INCLUDE_PATH_INFO + "=" + getAttribute("javax.servlet.include.path_info") + ", super.getPathInfo()=" + super.getPathInfo());
259       logger.debug(RequestDispatcherWrapper.INCLUDE_QUERY_STRING + "=" + getAttribute("javax.servlet.include.query_string") + ", super.getQueryString()=" + super.getQueryString());
260              */

261
262             this.initialRequestURI = super.getRequestURI();
263             if (this.appRequest != null) {
264                 // reparse the emulated url
265
updateEmulatedValues();
266                 this.parsed = false;
267                 this.hideRequestParameter = false;
268                 parseParameters(this);
269             }
270             return true;
271         }
272
273         return false;
274     }
275
276     private void updateEmulatedValues() {
277         try {
278             String JavaDoc URLPort;
279             if (getServerPort() == 80) {
280                 URLPort = "";
281             } else {
282                 Integer JavaDoc conv = new Integer JavaDoc(getServerPort());
283                 URLPort = ":" + conv.toString();
284             }
285
286             StringBuffer JavaDoc newRequestURL = new StringBuffer JavaDoc(super.getRequestURI());
287             String JavaDoc queryString = (String JavaDoc) getAttribute(RequestDispatcherWrapper.INCLUDE_QUERY_STRING);
288             if (queryString == null) {
289                 queryString = (String JavaDoc) getAttribute(RequestDispatcherWrapper.FORWARD_QUERY_STRING);
290             }
291             if (queryString == null) {
292                 queryString = super.getQueryString();
293             }
294
295             if (queryString != null && !"".equals(queryString.trim())) {
296                 newRequestURL.append("?");
297                 newRequestURL.append(queryString);
298             }
299
300             URL JavaDoc contextURL = new URL JavaDoc(getScheme() + "://"
301                     + getServerName() + URLPort + "/");
302             emulatedURL = new URL JavaDoc(contextURL, newRequestURL.toString());
303             parseEmulatedURL(newRequestURL.toString());
304
305             if (queryString != null) {
306                 // Parse any parameters specified in the query string
307
logger.info("Parsing query string [" + queryString + "]");
308                 if (parameters == null) {
309                     parameters = new Hashtable JavaDoc();
310                 }
311
312                 parseStringParameters(parameters, queryString,
313                     getCharacterEncoding(), false);
314             }
315             // this.parsed = false;
316
// parseParameters((HttpServletRequest)getRequest());
317
} catch (Throwable JavaDoc t) {
318             logger.debug("Error updating emulated values", t);
319         }
320     }
321
322     // --------------------------------------------------------------------------
323
/**
324      * Parses the emulated URL using servlet mapping to correctly emulate
325      * Servlet Path, Path Info...
326      *
327      * @author Khue Nguyen
328      */

329     private void parseEmulatedURL(String JavaDoc url) throws JahiaException {
330         if (url == null) {
331             String JavaDoc errMsg = "App emulated URL is null !";
332             throw new JahiaException(errMsg, errMsg,
333                 JahiaException.ERROR_SEVERITY, JahiaException.APPLICATION_ERROR);
334         }
335
336         int pos = url.indexOf(appRequest.getContext());
337         if (pos == -1) {
338             String JavaDoc errMsg = "App emulated URL doesn't contains the application context path !";
339             throw new JahiaException(errMsg, errMsg,
340                 JahiaException.ERROR_SEVERITY, JahiaException.APPLICATION_ERROR);
341         }
342
343         String JavaDoc path = url.substring(pos + appRequest.getContext().length());
344         int pos2 = path.indexOf("?");
345
346         // Servlet mapping check
347
String JavaDoc servletMappingPattern = appRequest.getServletMappingPattern();
348         if (servletMappingPattern != null) {
349             if (servletMappingPattern.equals("/")) {
350                 // default servlet
351
this.emulatedServletPath = "";
352                 this.emulatedPathInfo = "";
353             } else if (servletMappingPattern.startsWith("/")
354                     && servletMappingPattern.endsWith("/*")) {
355                 // path mapping
356
this.emulatedServletPath = servletMappingPattern.substring(0,
357                     servletMappingPattern.length() - 2);
358
359                 if (pos2 == -1) {
360                     this.emulatedPathInfo = path;
361                 } else {
362                     this.emulatedPathInfo = path.substring(0, pos2);
363                 }
364
365                 // FIXME NK:
366
// considere an url = /myforum/folder1/myforum/dir2/index.jsp
367
// then path = /folder1/myforum/dir2/index.jsp ( we removed the app context
368
// We remove only the servlet path part only if it start at pos 0 !!!!
369
if (this.emulatedPathInfo.startsWith(this.emulatedServletPath)) {
370                     this.emulatedPathInfo = this.emulatedPathInfo
371                         .substring(this.emulatedServletPath.length());
372                 }
373
374             } else if (servletMappingPattern.startsWith("*.")) {
375                 // extension mapping
376
int pathSepPos = path.lastIndexOf("/");
377                 int pos3 = -1;
378                 if (pathSepPos != -1) {
379                     pos3 = path.indexOf(servletMappingPattern.substring(1),
380                         pathSepPos);
381                 } else {
382                     pos3 = path.indexOf(servletMappingPattern.substring(1));
383                 }
384                 if (pos3 != -1) {
385                     this.emulatedServletPath = path.substring(0, pos3
386                             + servletMappingPattern.length() - 1);
387                     if (pos2 == -1) {
388                         this.emulatedPathInfo = path;
389                     } else {
390                         this.emulatedPathInfo = path.substring(0, pos2);
391                     }
392                     if (this.emulatedPathInfo
393                         .startsWith(this.emulatedServletPath)) {
394                         this.emulatedPathInfo = this.emulatedPathInfo
395                             .substring(this.emulatedServletPath.length());
396                     }
397                 }
398             } else if (!servletMappingPattern.equals("")) {
399                 // exact mapping
400
this.emulatedServletPath = servletMappingPattern;
401                 pos = path.indexOf(this.emulatedServletPath);
402                 if (pos2 == -1) {
403                     this.emulatedPathInfo = path;
404                 } else {
405                     this.emulatedPathInfo = path.substring(0, pos2);
406                 }
407                 if (this.emulatedPathInfo.startsWith(this.emulatedServletPath)) {
408                     this.emulatedPathInfo = this.emulatedPathInfo
409                         .substring(this.emulatedServletPath.length());
410                 }
411             } else {
412                 if (appRequest.getWebAppType() == PersistantServletRequest.JSP_TYPE) {
413                     // we got a welcome file
414
if (pos2 == -1) {
415                         this.emulatedServletPath = path;
416                     } else {
417                         this.emulatedServletPath = path.substring(0, pos2);
418                     }
419                     this.emulatedPathInfo = "";
420                 }
421             }
422         } else {
423             this.emulatedServletPath = "";
424             this.emulatedPathInfo = "";
425         }
426
427         if (this.emulatedPathInfo != null) {
428             // let's remove the session ID from the parameters if it was
429
// attached.
430
int sessionIDPos = this.emulatedPathInfo
431                 .lastIndexOf(";jsessionid=");
432             if (sessionIDPos != -1) {
433                 //this.jSessionId = this.emulatedPathInfo.substring(sessionIDPos);
434
this.emulatedPathInfo = this.emulatedPathInfo.substring(0,
435                     sessionIDPos);
436                 logger.debug("Removed session ID marker from end of path info");
437             }
438         }
439
440         if (logger.isDebugEnabled()) {
441             logger.debug("url = [" + url + "]");
442             logger.debug("emulated servlet path = [" + this.emulatedServletPath
443                     + "]");
444             logger
445                 .debug("emulated path info = [" + this.emulatedPathInfo + "]");
446             logger.debug("super.requestURI value : [" + super.getRequestURI()
447                     + "]");
448             logger.debug("initial requestURI value : [" + initialRequestURI
449                     + "]");
450         }
451     }
452
453     /**
454      * This is a version of the wrapper for dispatcher's that don't need to
455      * emulate URLs but need Jahia Params
456      *
457      * @param httpServletRequest
458      * Jahia's original request object
459      */

460     public ServletIncludeRequestWrapper(HttpServletRequest JavaDoc httpServletRequest,
461             ParamBean jParams) {
462         super(httpServletRequest);
463         emulatedContextPath = super.getContextPath();
464         emulatedMethod = null;
465         emulatedURL = null;
466         jahiaParams = jParams;
467     }
468
469     public String JavaDoc getRemoteUser() {
470         if (emulatedURL != null) {
471             JahiaUser user = jahiaParams.getUser();
472             if (user != null) {
473                 // Hollis , cos getName return the user key and not the user login name
474
// return user.getName();
475
return user.getUsername();
476             } else {
477                 return "";
478             }
479         } else {
480             return super.getRemoteUser();
481         }
482     }
483
484     /**
485      * @author NK
486      */

487     public Principal JavaDoc getUserPrincipal() {
488         if (emulatedURL != null) {
489             JahiaUser user = jahiaParams.getUser();
490
491             if (user != null) {
492
493                 GenericPrincipal gPrincipal = new GenericPrincipal(user);
494                 return gPrincipal;
495
496             } else {
497                 return null;
498             }
499
500         } else {
501             return super.getUserPrincipal();
502         }
503     }
504
505     /*
506     public java.security.Principal getUserPrincipal() {
507         if (emulatedURL != null) {
508             JahiaUser user = jahiaParams.getUser();
509             return user;
510         } else {
511             return super.getUserPrincipal();
512         }
513     }
514      */

515
516     public RequestDispatcher JavaDoc getRequestDispatcher(String JavaDoc path) {
517         logger.debug("path = [" + path + "]");
518         if (emulatedURL != null) {
519             ServletContext JavaDoc dispatchedContext = jahiaParams.getContext()
520                 .getContext(emulatedContextPath);
521             if (dispatchedContext == null) {
522                 logger.debug("Error getting request context "
523                         + emulatedContextPath + " for app "
524                         + appRequest.getName());
525                 return null;
526             }
527
528             // Now let's retrieve that context's dispatcher object.
529
RequestDispatcher JavaDoc sessionDispatcher = dispatchedContext
530                 .getRequestDispatcher(path);
531             return sessionDispatcher;
532         } else {
533             return super.getRequestDispatcher(path);
534         }
535     }
536
537     public boolean isUserInRole(String JavaDoc role) {
538         // This method maps servlet roles on Jahia's groups
539
if (emulatedURL != null) {
540             if (jahiaParams == null) {
541                 logger.debug("Jahia Params is null, exiting immediately...");
542                 return false;
543             }
544             JahiaUser user = jahiaParams.getUser();
545             if (user != null) {
546                 if (appRequest == null) {
547                     logger
548                         .debug("Null application request object, exiting isUserInRole...");
549                     return false;
550                 }
551                 if (appRequest.getApplicationBean() == null) {
552                     logger
553                         .debug("Null application bean object, exiting isUserInRole...");
554                     return false;
555                 }
556                 // Hollis all apps groups roles are a group with siteID=0
557
JahiaGroup roleGroup = ServicesRegistry.getInstance()
558                     .getJahiaGroupManagerService().lookupGroup(
559                         0,
560                         appRequest.getApplicationBean().getID() + "_"
561                                 + contextIdentifier + "_" + role);
562                 if (roleGroup != null) {
563                     if (roleGroup.isMember(user) == true) {
564                         logger.debug("User [" + user.getUsername()
565                                 + "] is a member of role ["
566                                 + roleGroup.getName() + "]");
567                         return true; // user is indeed member of role (aka
568
// group)
569
} else {
570                         logger.debug("User [" + user.getUsername()
571                                 + "] is NOT a member of role ["
572                                 + roleGroup.getName() + "]");
573                         return false; // user is not member of role (=group)
574
}
575                 } else {
576                     logger.debug("Role ["
577                             + appRequest.getApplicationBean().getID() + "_"
578                             + contextIdentifier + "_" + role
579                             + "] not found in Jahia's groups!");
580                     return false; // the role (aka group) does not exist
581
}
582             } else {
583                 logger.debug("No user logged, ignoring call !");
584                 return false;
585             }
586         } else {
587             // default servlet behavior
588
logger.debug("Using servlet API standard call...");
589             return super.isUserInRole(role);
590         }
591     }
592
593     public void setContextPath(String JavaDoc newPath) {
594         logger.debug("setContextPath(" + newPath + ")");
595         // emulatedContextPath = newPath;
596
}
597
598     public String JavaDoc getContextPath() {
599         String JavaDoc contextPath = super.getContextPath();
600         if (emulatedURL != null) {
601             if (hasRequestURIChanged()) {
602                 return contextPath;
603             }
604         }
605         logger.debug(" super.getContextPath=[" + contextPath + "]");
606         logger.debug("emulatedContextPath = [" + emulatedContextPath + "]");
607         return emulatedContextPath;
608     }
609
610     private static String JavaDoc decode(String JavaDoc value, String JavaDoc encoding,
611             boolean urlParameters) {
612         if (value != null
613                 && (value.indexOf('%') >= 0 || value.indexOf('+') >= 0)) {
614             try {
615                 if (urlParameters)
616                     value = URLDecode(value);
617                 else
618                     value = URLDecoder.decode(value, encoding);
619             } catch (Throwable JavaDoc t) {
620                 logger.debug("Error during decoding", t);
621             }
622         }
623         return value;
624     }
625
626     /**
627      * Removes all the attributes specified in the data string for the map
628      * passed in parameter.
629      * <p>
630      * <strong>IMPLEMENTATION NOTE</strong>: URL decoding is performed
631      * individually on the parsed name and value elements, rather than on the
632      * entire query string ahead of time, to properly deal with the case where
633      * the name or value includes an encoded "=" or "&" character that would
634      * otherwise be interpreted as a delimiter.
635      *
636      * @param map
637      * Map that accumulates the resulting parameters
638      * @param data
639      * Input string containing request parameters
640      * @param urlParameters
641      * true if we're parsing parameters on the URL
642      * @exception IllegalArgumentException
643      * if the data is malformed
644      */

645     public static void removeStringParameters(Map JavaDoc map, String JavaDoc data,
646             String JavaDoc encoding, boolean urlParameters) {
647         if (data == null || data.length() == 0)
648             return;
649
650         // logger.debug("Parsing string [" + data + "]");
651

652         // Initialize the variables we will require
653
StringParser parser = new StringParser(data);
654         boolean first = true;
655         int nameStart = 0;
656         int nameEnd = 0;
657         int valueStart = 0;
658         int valueEnd = 0;
659         String JavaDoc name = null;
660         String JavaDoc value = null;
661
662         // Loop through the "name=value" entries in the input data
663
while (true) {
664             // Extract the name and value components
665
if (first)
666                 first = false;
667             else
668                 parser.advance();
669
670             nameStart = parser.getIndex();
671             nameEnd = parser.findChar('=');
672             parser.advance();
673             valueStart = parser.getIndex();
674             valueEnd = parser.findChar('&');
675             name = parser.extract(nameStart, nameEnd);
676             value = parser.extract(valueStart, valueEnd);
677
678             // A zero-length name means we are done
679
if (name.length() < 1)
680                 break;
681
682             // Decode the name and value if required
683
name = decode(name, encoding, urlParameters);
684             value = decode(value, encoding, urlParameters);
685
686             // logger.debug("removeParameters. Removing key [" + name + "]");
687
map.remove(name);
688         }
689     }
690
691     /**
692      * Append request parameters from the specified String to the specified Map.
693      * It is presumed that the specified Map is not accessed from any other
694      * thread, so no synchronization is performed.
695      * <p>
696      * <strong>IMPLEMENTATION NOTE</strong>: URL decoding is performed
697      * individually on the parsed name and value elements, rather than on the
698      * entire query string ahead of time, to properly deal with the case where
699      * the name or value includes an encoded "=" or "&" character that would
700      * otherwise be interpreted as a delimiter.
701      *
702      * @param map
703      * Map that accumulates the resulting parameters
704      * @param data
705      * Input string containing request parameters
706      * @param encoding
707      * character encoding of the request parameter string
708      * @param urlParameters
709      * true if we're parsing parameters on the URL
710      * @exception IllegalArgumentException
711      * if the data is malformed
712      */

713     public static void parseStringParameters(Map JavaDoc map, String JavaDoc data,
714             String JavaDoc encoding, boolean urlParameters) {
715
716         if ((data == null) || (data.length() < 1))
717             return;
718
719         // logger.debug( "Parsing string [" + data + "]");
720

721         // Initialize the variables we will require
722
StringParser parser = new StringParser(data);
723         boolean first = true;
724         int nameStart = 0;
725         int nameEnd = 0;
726         int valueStart = 0;
727         int valueEnd = 0;
728         String JavaDoc name = null;
729         String JavaDoc value = null;
730
731         // Loop through the "name=value" entries in the input data
732
while (true) {
733             // Extract the name and value components
734
if (first)
735                 first = false;
736             else
737                 parser.advance();
738             nameStart = parser.getIndex();
739             nameEnd = parser.findChar('=');
740             parser.advance();
741             valueStart = parser.getIndex();
742             valueEnd = parser.findChar('&');
743             name = parser.extract(nameStart, nameEnd);
744             value = parser.extract(valueStart, valueEnd);
745
746             // A zero-length name means we are done
747
if (name.length() < 1)
748                 break;
749
750             // Decode the name and value if required
751
// Decode the name and value if required
752
name = decode(name, encoding, urlParameters);
753             value = decode(value, encoding, urlParameters);
754
755             // Create or update the array of values for this name
756
// logger.debug("parseParameters. Storing key [" + name + "]");
757
map.put(name, value);
758         }
759     }
760
761     /**
762      * Parse the parameters of this request, if it has not already occurred. If
763      * parameters are present in both the query string and the request content,
764      * they are merged.
765      *
766      * @param originalRequest
767      * the non emulated original request
768      */

769     protected void parseParameters(HttpServletRequest JavaDoc originalRequest) {
770
771         // logger.debug("Parsing parameters...");
772

773         if (parsed)
774             return;
775
776         Map JavaDoc results = parameters;
777         if (results == null)
778             results = new Hashtable JavaDoc();
779
780         // we can't do the following because getParameterMap is not implemented in all
781
// servlet containers yet. :((((
782
// results = copyMap(originalRequest.getParameterMap());
783
// so in the meantime we do the following junk...
784

785         if (!this.hideRequestParameter) {
786             Enumeration JavaDoc paramNames = originalRequest.getParameterNames();
787             while (paramNames.hasMoreElements()) {
788                 String JavaDoc paramName = (String JavaDoc) paramNames.nextElement();
789                 results.put(paramName, originalRequest
790                     .getParameterValues(paramName));
791             }
792         }
793
794         // logger.debug("Parsing query string [" +
795
// originalRequest.getQueryString()
796
// + "] and removing it's parameters");
797
String JavaDoc encoding = originalRequest.getCharacterEncoding();
798         removeStringParameters(results, originalRequest.getQueryString(),
799             encoding, true);
800
801         // Parse any parameters specified in the query string
802
String JavaDoc queryString = emulatedURL.getQuery();
803         // logger.debug("Parsing query string [" + queryString + "]");
804
if (queryString != null && queryString.length() != 0) {
805             try {
806                 parseStringParameters(results, queryString, encoding, true);
807             } catch (Throwable JavaDoc t) {
808                 logger.debug("Error parsing URL parameters !");
809             }
810         }
811
812         // logger.debug("Printing out full set of parameter keys...");
813
// Hashtable results2 = (Hashtable)results;
814
// Enumeration resultKeys = results2.keys();
815
// while (resultKeys.hasMoreElements())
816
// {
817
// String nextKey = (String)resultKeys.nextElement();
818
// logger.debug("Parameter keys [" + nextKey + "] defined");
819
// }
820
// logger.debug("...done printing parameter keys !");
821

822         parsed = true;
823         parameters = results;
824     }
825
826     /**
827      * Decode and return the specified URL-encoded String.
828      *
829      * @param str
830      * The url-encoded string
831      * @returns the string containing the decoded URL
832      * @exception IllegalArgumentException
833      * if a '%' character is not followed by a valid 2-digit
834      * hexadecimal number
835      */

836     public static String JavaDoc URLDecode(String JavaDoc str) throws IllegalArgumentException JavaDoc {
837
838         if (str == null)
839             return (null);
840
841         StringBuffer JavaDoc dec = new StringBuffer JavaDoc();
842         int pos = 0;
843         int len = str.length();
844         dec.ensureCapacity(str.length());
845
846         while (pos < len) {
847             int lookahead; // Look-ahead position
848

849             // Look ahead to the next URLencoded metacharacter, if any
850
for (lookahead = pos; lookahead < len; lookahead++) {
851                 char ch = str.charAt(lookahead);
852                 if ((ch == '+') || (ch == '%'))
853                     break;
854             }
855
856             // If there were non-metacharacters, copy them as a block
857
if (lookahead > pos) {
858                 dec.append(str.substring(pos, lookahead));
859                 pos = lookahead;
860             }
861
862             // Shortcut out if we are at the end of the string
863
if (pos >= len)
864                 break;
865
866             // Process the next metacharacter
867
char meta = str.charAt(pos);
868             if (meta == '+') {
869                 dec.append(' ');
870                 pos++;
871             } else if (meta == '%') {
872                 try {
873                     dec.append((char) Integer.parseInt(str.substring(pos + 1,
874                         pos + 3), 16));
875                 } catch (NumberFormatException JavaDoc e) {
876                     throw new IllegalArgumentException JavaDoc("Invalid hexadecimal '"
877                             + str.substring(pos + 1, pos + 3)
878                             + " in URLencoded string");
879                 } catch (StringIndexOutOfBoundsException JavaDoc e) {
880                     throw new IllegalArgumentException JavaDoc(
881                         "Invalid unescaped '%' in URLcoded string");
882                 }
883                 pos += 3;
884             }
885         }
886         return (dec.toString());
887
888     }
889
890     public String JavaDoc getRequestURI() {
891
892         String JavaDoc requestURI = super.getRequestURI();
893         logger.debug(" super.getRequestURI()=[" + requestURI + "]");
894
895         if (emulatedURL != null) {
896             if (hasRequestURIChanged()) {
897                 return requestURI;
898             }
899
900             String JavaDoc requestURL = getContextPath();
901             if (appRequest.getWebAppType() == PersistantServletRequest.SERVLET_TYPE) {
902                 if (this.emulatedServletPath.length() > 0) {
903                     if (!this.emulatedServletPath.startsWith("/")) {
904                         requestURL += "/";
905                     }
906                     requestURL += this.emulatedServletPath;
907                 }
908                 requestURL += this.emulatedPathInfo;
909             } else {
910                 if (!appRequest.getservletsrc().startsWith("/")) {
911                     requestURL += "/";
912                 }
913                 requestURL += appRequest.getservletsrc();
914             }
915             // requestURL += this.jSessionId;
916

917             logger.debug("emulated requestURI = [" + requestURL + "]");
918             // return getContextPath()+ "/" + appRequest.getServletName();
919
return requestURL;
920         } else {
921             return super.getRequestURI();
922         }
923     }
924
925     public StringBuffer JavaDoc getRequestURL() {
926         StringBuffer JavaDoc requestURL = super.getRequestURL();
927         String JavaDoc reqURL = "";
928         if (requestURL != null) {
929             reqURL = requestURL.toString();
930         }
931         String JavaDoc emulURL = "";
932         if (emulatedURL != null) {
933             emulURL = emulatedURL.toString();
934         }
935         logger.debug(" super.getRequestURL()=[" + reqURL + "], emulatedURL="
936                 + emulURL);
937
938         if (emulatedURL != null) {
939             if (hasRequestURIChanged()) {
940                 return requestURL;
941             }
942             /*
943              * logger.debug("emulated requestURL = [" + super.getRequestURL() +
944              * "]"); return super.getRequestURL();
945              */

946             logger.debug("emulated requestURL = [" + emulatedURL + "]");
947             return new StringBuffer JavaDoc(emulatedURL.toString());
948         } else {
949             return super.getRequestURL();
950         }
951     }
952
953     public String JavaDoc getServletPath() {
954         String JavaDoc servletPath = super.getServletPath();
955         String JavaDoc pathInfo = super.getPathInfo();
956         logger.debug("super.getServletPath()=[" + servletPath + "]");
957         logger
958             .debug("emulated servlet path [" + this.emulatedServletPath + "]");
959         logger.debug("while super.getPathInfo()=[" + pathInfo + "]");
960
961         if (emulatedURL != null) {
962
963             if (hasRequestURIChanged()) {
964                 logger
965                     .debug("Request URI has changed, returning super.getServletPath=["
966                             + servletPath + "]");
967                 return servletPath;
968                 // emulatedServletPath = serverPath;
969
}
970
971             /*
972              * logger.debug("getServletPath() = [" + appRequest.getName() +
973              * "]");
974              */

975             if (servletPath.endsWith(".jsp")) {
976                 /**
977                  * @todo remove this hack that was introduced to make internal
978                  * app redirection to JSP work. Must find a better way to
979                  * detect this. This will fail if we try to redirect to a
980                  * JSP directly (or maybe it works but not guaranteed.
981                  */

982                 logger.debug("JSP servlet path (" + servletPath
983                         + ") detected, returning server path...");
984
985                 this.emulatedServletPath = servletPath;
986                 if (super.getPathInfo() != null) {
987                     this.emulatedPathInfo = super.getPathInfo();
988                 } else {
989                     this.emulatedPathInfo = "";
990                 }
991
992                 if (super.getMethod() != null) {
993                     this.emulatedMethod = super.getMethod();
994                 } else {
995                     this.emulatedMethod = "";
996                 }
997                 return servletPath;
998             }
999
1000            logger.debug("emulated servlet path [" + this.emulatedServletPath
1001                    + "]");
1002            return this.emulatedServletPath;
1003        }
1004
1005        return super.getServletPath();
1006
1007    }
1008
1009    public String JavaDoc getQueryString() {
1010        String JavaDoc queryString = super.getQueryString();
1011        logger.debug("super.getQueryString()=[" + queryString + "]");
1012        if (emulatedURL != null) {
1013            if (hasRequestURIChanged()) {
1014                return queryString;
1015            }
1016
1017            logger.debug("getQueryString() = [" + emulatedURL.getQuery() + "]");
1018            return emulatedURL.getQuery();
1019        } else {
1020            return super.getQueryString();
1021        }
1022    }
1023
1024    public String JavaDoc getPathTranslated() {
1025        if (emulatedURL != null) {
1026            logger.debug("getPathTranslated() = [" + super.getPathTranslated()
1027                    + "]");
1028            return super.getPathTranslated();
1029        } else {
1030            return super.getPathTranslated();
1031        }
1032    }
1033
1034    public Locale JavaDoc getLocale() {
1035        Locale JavaDoc loc;
1036        if (emulatedURL != null || jahiaParams != null)
1037            loc = jahiaParams.getLocale();
1038        else
1039            loc = super.getLocale();
1040        logger.debug("getLocale() = [" + loc + "]");
1041        return loc;
1042    }
1043
1044    public Enumeration JavaDoc getLocales() {
1045        if (emulatedURL != null) {
1046            List JavaDoc locales;
1047            try {
1048                locales = jahiaParams.getLocales();
1049            } catch (Throwable JavaDoc ex) {
1050                logger.debug("error getting locales", ex);
1051                locales = Collections.singletonList(Locale.getDefault());
1052            }
1053            logger.debug("getLocale() = [" + locales + "]");
1054            return Collections.enumeration(locales);
1055        } else {
1056            logger.debug("getLocale() = [" + super.getLocales() + "]");
1057            return super.getLocales();
1058        }
1059    }
1060
1061    public String JavaDoc getPathInfo() {
1062        String JavaDoc pathInfo = super.getPathInfo();
1063        logger.debug("super.getPathInfo()=[" + pathInfo + "]");
1064
1065        if (emulatedURL == null) {
1066            logger.debug("getPathInfo() = [" + pathInfo + "]");
1067            return pathInfo;
1068        } else {
1069            if (hasRequestURIChanged()) {
1070                return pathInfo;
1071            }
1072            logger.debug("getPathInfo() emulated pathInfo = ["
1073                    + this.emulatedPathInfo + "]");
1074            return this.emulatedPathInfo;
1075        }
1076    }
1077
1078    public String JavaDoc getParameter(String JavaDoc name) {
1079        // logger.debug("RequestWrapper.Entering getParameter("+name+")...");
1080
if (emulatedURL != null && !hasRequestURIChanged()) {
1081            if (parameters == null) {
1082                // logger.debug("Error : parameter Object not found !");
1083
}
1084
1085            Object JavaDoc objValue = parameters.get(name);
1086            if (objValue == null) {
1087                // logger.debug("Warning : parameter ["+name+"] not found !");
1088
return null;
1089            }
1090            Class JavaDoc classValue = objValue.getClass();
1091
1092            if (classValue.isArray()) {
1093
1094                String JavaDoc[] value = (String JavaDoc[]) parameters.get(name);
1095                if (value == null) {
1096                    return null;
1097                } else {
1098                    // logger.debug("Array detected. Parameter = " +
1099
// value.toString());
1100
}
1101
1102                // logger.debug("Array detected. Result = [" + value[0] + "]");
1103
return value[0];
1104            } else {
1105                String JavaDoc value = (String JavaDoc) objValue;
1106                // logger.debug("String detected. Result = [" + value + "]");
1107
return value;
1108            }
1109        } else {
1110            // logger.debug("Result from parent = [" + super.getParameter(name)
1111
// + "]");
1112
return super.getParameter(name);
1113        }
1114    }
1115
1116    public Enumeration JavaDoc getParameterNames() {
1117        // logger.debug("started");
1118
if (emulatedURL != null && !hasRequestURIChanged()) {
1119            return new Hashtable JavaDoc(parameters).keys();
1120        } else {
1121            return super.getParameterNames();
1122        }
1123    }
1124
1125    public String JavaDoc[] getParameterValues(String JavaDoc name) {
1126        logger.debug("getParameterValues(" + name + ")");
1127        if (emulatedURL != null && !hasRequestURIChanged()) {
1128
1129            Object JavaDoc objValue = parameters.get(name);
1130            if (objValue == null) {
1131                // logger.debug("Warning : parameter ["+name+"] not found !");
1132
return null;
1133            }
1134            Class JavaDoc classValue = objValue.getClass();
1135
1136            if (classValue.isArray()) {
1137
1138                String JavaDoc[] value = (String JavaDoc[]) parameters.get(name);
1139                return value;
1140            } else {
1141                String JavaDoc value = (String JavaDoc) objValue;
1142                // logger.debug("String detected. Result = [" + value + "]");
1143
String JavaDoc[] valueArray = { value };
1144                return valueArray;
1145            }
1146
1147            /*
1148            String[] x = (String[]) parameters.get(name);
1149            logger.debug( "getParameterValues("+name+") : values :[" + x[0] + "]");
1150            return x;
1151             */

1152        } else {
1153            return super.getParameterValues(name);
1154        }
1155    }
1156
1157    public Map JavaDoc getParameterMap() {
1158        if (emulatedURL != null && !hasRequestURIChanged()) {
1159            logger.debug("getParameterMap()");
1160            return Collections.unmodifiableMap(parameters);
1161        } else {
1162            return super.getParameterMap();
1163        }
1164    }
1165
1166    public void setAttribute(String JavaDoc name, Object JavaDoc o) {
1167        if (o != null) {
1168            // logger.debug( "setAttribute(" + name + "," + o.toString() + ")");
1169
if (name.equals("javax.servlet.jsp.jspException")) {
1170                // let's print out the exception...
1171
StringWriter JavaDoc sw = new StringWriter JavaDoc();
1172                PrintWriter JavaDoc pw = new PrintWriter JavaDoc(sw);
1173                Throwable JavaDoc t = (Throwable JavaDoc) o;
1174                t.printStackTrace(pw);
1175                logger.debug("Exception : " + sw.toString());
1176            }
1177        }
1178        String JavaDoc objValue = "null";
1179        if (o != null) {
1180            objValue = objValue.toString();
1181        }
1182        logger.debug("setAttribute(" + name + ", " + objValue + ")");
1183
1184        if (emulatedURL != null) {
1185            // Note : we used to have here some code to deactivate setting
1186
// of include parameters, but this was resolved by using a NamedDispatcher
1187
// that doesn't set these. These caused problems with Tomcat's implementation
1188
// of JSP dispatching that checked for the include attributes.
1189
if ("org.jahia.portletapi.CacheExpirationDelay".equals(name)) {
1190                Long JavaDoc delay = (Long JavaDoc) o;
1191                applicationCacheExpirationDelay = delay.longValue();
1192                if (applicationCacheExpirationDelay == 0) {
1193                    applicationCacheOn = false;
1194                }
1195            } else {
1196                super.setAttribute(name, o);
1197            }
1198        } else {
1199            super.setAttribute(name, o);
1200        }
1201
1202    }
1203
1204    public void removeAttribute(String JavaDoc name) {
1205        logger.debug("removeAttribute(" + name + ")");
1206        super.removeAttribute(name);
1207    }
1208
1209    public Object JavaDoc getAttribute(String JavaDoc name) {
1210        logger.debug("getAttribute(" + name + ")");
1211        if (super.getAttribute(name) == null) {
1212            if ("org.portletapi.userlist".equals(name)) {
1213                super.setAttribute("org.portletapi.userlist", appRequest
1214                    .getAppContextUsers());
1215            }
1216        }
1217        return super.getAttribute(name);
1218    }
1219
1220    public HttpSession JavaDoc getSession(boolean create) {
1221        if (emulatedURL != null) {
1222            // logger.debug( "getEmulatedSession");
1223
if (sessionWrapper == null) {
1224                try {
1225                    sessionWrapper = new HttpSessionWrapper(jahiaParams
1226                        .getSession(create), appRequest.getApplicationBean()
1227                        .getName(), contextIdentifier,
1228                        inheritJahiaSessionAttributes);
1229                } catch (JahiaSessionExpirationException ex) {
1230                    logger.debug("Session exception, create=" + create, ex);
1231                    return null;
1232                }
1233
1234            }
1235            return sessionWrapper;
1236        } else {
1237            // logger.debug ("getSession");
1238
return super.getSession(create);
1239        }
1240    }
1241
1242    public HttpSession JavaDoc getSession() {
1243        return getSession(true);
1244    }
1245
1246    public String JavaDoc getMethod() {
1247        if (emulatedURL != null) {
1248            return emulatedMethod;
1249        } else {
1250            return super.getMethod();
1251        }
1252    }
1253
1254    public PersistantServletRequest getPersistantServletRequest() {
1255        return this.appRequest;
1256    }
1257
1258    public boolean isApplicationCacheOn() {
1259        return applicationCacheOn;
1260    }
1261
1262    public long getApplicationCacheExpirationDelay() {
1263        return applicationCacheExpirationDelay;
1264    }
1265
1266} // end ServletIncludeRequestWrapper
1267
Popular Tags