1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.jxpath.servlet;
17
18 import javax.servlet.ServletContext;
19 import javax.servlet.ServletRequest;
20 import javax.servlet.http.HttpServletRequest;
21 import javax.servlet.http.HttpSession;
22 import javax.servlet.jsp.PageContext;
23 import org.apache.commons.jxpath.JXPathContext;
24 import org.apache.commons.jxpath.JXPathContextFactory;
25 import org.apache.commons.jxpath.JXPathIntrospector;
26
27 /***
28 * Static methods that allocate and cache JXPathContexts bound to PageContext,
29 * ServletRequest, HttpSession and ServletContext.
30 * <p>
31 * The JXPathContext returned by {@link #getPageContext getPageContext()}
32 * provides access to all scopes via the PageContext.findAttribute()
33 * method. Thus, an expression like "foo" will first look for the attribute
34 * named "foo" in the "page" context, then the "request" context, then
35 * the "session" one and finally in the "application" context.
36 * <p>
37 * If you need to limit the attibute lookup to just one scope, you can use the
38 * pre-definded variables "page", "request", "session" and "application".
39 * For example, the expression "$session/foo" extracts the value of the
40 * session attribute named "foo".
41 * <p>
42 * Following are some implementation details. There is a separate JXPathContext
43 * for each of the four scopes. These contexts are chained according to the
44 * nesting of the scopes. So, the parent of the "page" JXPathContext is a
45 * "request" JXPathContext, whose parent is a "session" JXPathContext (that is
46 * if there is a session), whose parent is an "application" context.
47 * <p>
48 * The XPath context node for each context is the corresponding object:
49 * PageContext, ServletRequest, HttpSession or ServletContext. This feature can
50 * be used by servlets. A servlet can use one of the methods declared by this
51 * class and work with a specific JXPathContext for any scope.
52 * <p>
53 * Since JXPath chains lookups for variables and extension functions, variables
54 * and extension function declared in the outer scopes are also available in
55 * the inner scopes.
56 * <p>
57 * Each of the four context declares exactly one variable, the value of which
58 * is the corresponding object: PageContext, etc.
59 * <p>
60 * The "session" variable will be undefined if there is no session for this
61 * servlet. JXPath does not automatically create sessions.
62 *
63 * @author Dmitri Plotnikov
64 * @version $Revision: 1.6 $ $Date: 2004/05/08 15:10:49 $
65 */
66 public final class JXPathServletContexts {
67
68 private static JXPathContextFactory factory;
69
70 static {
71 JXPathIntrospector.registerDynamicClass(
72 PageScopeContext.class,
73 PageScopeContextHandler.class);
74 JXPathIntrospector.registerDynamicClass(
75 PageContext.class,
76 PageContextHandler.class);
77 JXPathIntrospector.registerDynamicClass(
78 ServletContext.class,
79 ServletContextHandler.class);
80 JXPathIntrospector.registerDynamicClass(
81 ServletRequestAndContext.class,
82 ServletRequestHandler.class);
83 JXPathIntrospector.registerDynamicClass(
84 HttpSessionAndServletContext.class,
85 HttpSessionHandler.class);
86 factory = JXPathContextFactory.newInstance();
87 }
88
89 /***
90 * Returns a JXPathContext bound to the "page" scope. Caches that context
91 * within the PageContext itself.
92 */
93 public static JXPathContext getPageContext(PageContext pageContext) {
94 JXPathContext context =
95 (JXPathContext) pageContext.getAttribute(Constants.JXPATH_CONTEXT);
96 if (context == null) {
97 JXPathContext parentContext =
98 getRequestContext(
99 pageContext.getRequest(),
100 pageContext.getServletContext());
101 context = factory.newContext(parentContext, pageContext);
102 context.setVariables(
103 new KeywordVariables(
104 Constants.PAGE_SCOPE,
105 new PageScopeContext(pageContext)));
106 pageContext.setAttribute(Constants.JXPATH_CONTEXT, context);
107 }
108 return context;
109 }
110
111 /***
112 * Returns a JXPathContext bound to the "request" scope. Caches that context
113 * within the request itself.
114 */
115 public static JXPathContext getRequestContext(
116 ServletRequest request,
117 ServletContext servletContext)
118 {
119 JXPathContext context =
120 (JXPathContext) request.getAttribute(Constants.JXPATH_CONTEXT);
121
122
123
124 if (context != null) {
125 ServletRequestAndContext handle =
126 (ServletRequestAndContext) context.getContextBean();
127 if (handle.getServletRequest() == request) {
128 return context;
129 }
130 }
131
132 JXPathContext parentContext = null;
133 if (request instanceof HttpServletRequest) {
134 HttpSession session =
135 ((HttpServletRequest) request).getSession(false);
136 if (session != null) {
137 parentContext = getSessionContext(session, servletContext);
138 }
139 else {
140 parentContext = getApplicationContext(servletContext);
141 }
142 }
143 ServletRequestAndContext handle =
144 new ServletRequestAndContext(request, servletContext);
145 context = factory.newContext(parentContext, handle);
146 context.setVariables(
147 new KeywordVariables(Constants.REQUEST_SCOPE, handle));
148 request.setAttribute(Constants.JXPATH_CONTEXT, context);
149 return context;
150 }
151
152 /***
153 * Returns a JXPathContext bound to the "session" scope. Caches that context
154 * within the session itself.
155 */
156 public static JXPathContext getSessionContext(
157 HttpSession session,
158 ServletContext servletContext)
159 {
160 JXPathContext context =
161 (JXPathContext) session.getAttribute(Constants.JXPATH_CONTEXT);
162 if (context == null) {
163 JXPathContext parentContext = getApplicationContext(servletContext);
164 HttpSessionAndServletContext handle =
165 new HttpSessionAndServletContext(session, servletContext);
166 context = factory.newContext(parentContext, handle);
167 context.setVariables(
168 new KeywordVariables(Constants.SESSION_SCOPE, handle));
169 session.setAttribute(Constants.JXPATH_CONTEXT, context);
170 }
171 return context;
172 }
173
174 /***
175 * Returns a JXPathContext bound to the "application" scope. Caches that
176 * context within the servlet context itself.
177 */
178 public static JXPathContext getApplicationContext(
179 ServletContext servletContext)
180 {
181 JXPathContext context =
182 (JXPathContext) servletContext.getAttribute(
183 Constants.JXPATH_CONTEXT);
184 if (context == null) {
185 context = factory.newContext(null, servletContext);
186 context.setVariables(
187 new KeywordVariables(
188 Constants.APPLICATION_SCOPE,
189 servletContext));
190 servletContext.setAttribute(Constants.JXPATH_CONTEXT, context);
191 }
192 return context;
193 }
194 }