001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.jxpath;
018:
019: import org.apache.avalon.framework.component.Component;
020: import org.apache.avalon.framework.context.Contextualizable;
021: import org.apache.avalon.framework.thread.ThreadSafe;
022:
023: import org.apache.cocoon.components.ContextHelper;
024: import org.apache.cocoon.environment.Context;
025: import org.apache.cocoon.environment.Cookie;
026: import org.apache.cocoon.environment.ObjectModelHelper;
027: import org.apache.cocoon.environment.Request;
028: import org.apache.cocoon.environment.Session;
029:
030: import org.apache.commons.jxpath.JXPathContext;
031: import org.apache.commons.jxpath.JXPathContextFactory;
032: import org.apache.commons.jxpath.JXPathIntrospector;
033: import org.apache.commons.jxpath.servlet.Constants;
034: import org.apache.commons.jxpath.servlet.KeywordVariables;
035:
036: import java.io.InputStream;
037: import java.net.MalformedURLException;
038: import java.net.URL;
039: import java.security.Principal;
040: import java.util.Enumeration;
041: import java.util.Locale;
042: import java.util.Map;
043:
044: /**
045: * Component that allocate and cache JXPathContexts bound to VariableContext,
046: * Cocoon Request, Cocoon Session and Cocoon Context.
047: *
048: * <p>
049: * If you need to limit the attibute lookup to just one scope, you can use the
050: * pre-definded variables "request", "session" and "application".
051: * For example, the expression "$session/foo" extracts the value of the
052: * session attribute named "foo".</p>
053: *
054: * <p>
055: * Following are some implementation details.
056: * There is a separate JXPathContext for each of the four scopes. These contexts are chained
057: * according to the nesting of the scopes. So, the parent of the "variable"
058: * JXPathContext is a "request" JXPathContext, whose parent is a "session"
059: * JXPathContext (that is if there is a session), whose parent is an "application"
060: * context.</p>
061: *
062: * <p>
063: * Since JXPath chains lookups for variables and extension functions, variables
064: * and extension function declared in the outer scopes are also available in
065: * the inner scopes.</p>
066: *
067: * <p>
068: * The "session" variable will be undefined if there is no session for this servlet.
069: * JXPath does not automatically create sessions.</p>
070: *
071: * @author <a href="mailto:volker.schmitt@basf-it-services.com">Volker Schmitt</a>
072: * @version $Id: JXPathCocoonContexts.java 433543 2006-08-22 06:22:54Z crossley $
073: */
074: public final class JXPathCocoonContexts implements Component,
075: Contextualizable, ThreadSafe {
076:
077: public static final String ROLE = JXPathCocoonContexts.class
078: .getName();
079:
080: private static final String VARCONTEXT = Constants.JXPATH_CONTEXT
081: + "/VAR";
082:
083: private static JXPathContextFactory factory;
084: private org.apache.avalon.framework.context.Context context;
085:
086: static {
087: factory = JXPathContextFactory.newInstance();
088: JXPathIntrospector.registerDynamicClass(RequestProxy.class,
089: CocoonRequestHandler.class);
090: JXPathIntrospector.registerDynamicClass(SessionProxy.class,
091: CocoonSessionHandler.class);
092: JXPathIntrospector.registerDynamicClass(ContextProxy.class,
093: CocoonContextHandler.class);
094: }
095:
096: public void contextualize(
097: org.apache.avalon.framework.context.Context context) {
098: this .context = context;
099: }
100:
101: public final JXPathContext getVariableContext() {
102: final Map objectModel = ContextHelper
103: .getObjectModel(this .context);
104:
105: Request request = ObjectModelHelper.getRequest(objectModel);
106: JXPathContext context = (JXPathContext) request
107: .getAttribute(VARCONTEXT);
108: if (context == null) {
109: context = factory.newContext(getRequestContext(), null);
110: request.setAttribute(VARCONTEXT, context);
111: }
112: return context;
113: }
114:
115: /**
116: * Returns a JXPathContext bound to the "request" scope.
117: * Caches that context within the request itself.
118: */
119: public final JXPathContext getRequestContext() {
120: final Map objectModel = ContextHelper
121: .getObjectModel(this .context);
122:
123: Request request = ObjectModelHelper.getRequest(objectModel);
124: JXPathContext context = (JXPathContext) request
125: .getAttribute(Constants.JXPATH_CONTEXT);
126: if (context == null) {
127: Context envContext = ObjectModelHelper
128: .getContext(objectModel);
129: JXPathContext parentContext = null;
130:
131: Session session = request.getSession(false);
132: if (session != null) {
133: parentContext = getSessionContext(session, envContext);
134: } else {
135: parentContext = getApplicationContext(envContext);
136: }
137:
138: request = new RequestProxy(request);
139: context = factory.newContext(parentContext, request);
140: context.setVariables(new KeywordVariables(
141: Constants.REQUEST_SCOPE, request));
142: request.setAttribute(Constants.JXPATH_CONTEXT, context);
143: }
144: return context;
145: }
146:
147: /**
148: * Returns a JXPathContext bound to the "session" scope.
149: * Caches that context within the session itself.
150: */
151: public final JXPathContext getSessionContext(Session session,
152: Context envContext) {
153: JXPathContext context = (JXPathContext) session
154: .getAttribute(Constants.JXPATH_CONTEXT);
155: if (context == null) {
156: JXPathContext parentContext = getApplicationContext(envContext);
157: session = new SessionProxy(session);
158: context = factory.newContext(parentContext, session);
159: context.setVariables(new KeywordVariables(
160: Constants.SESSION_SCOPE, session));
161: session.setAttribute(Constants.JXPATH_CONTEXT, context);
162: }
163: return context;
164: }
165:
166: /**
167: * Returns a JXPathContext bound to the "application" scope. Caches that context
168: * within the servlet context itself.
169: */
170: public final JXPathContext getApplicationContext(Context envContext) {
171: JXPathContext context = (JXPathContext) envContext
172: .getAttribute(Constants.JXPATH_CONTEXT);
173: if (context == null) {
174: envContext = new ContextProxy(envContext);
175: context = factory.newContext(null, envContext);
176: context.setVariables(new KeywordVariables(
177: Constants.APPLICATION_SCOPE, envContext));
178: envContext.setAttribute(Constants.JXPATH_CONTEXT, context);
179: }
180: return context;
181: }
182:
183: public static final class RequestProxy implements Request {
184: private Request delegate;
185:
186: public RequestProxy(Request delegate) {
187: this .delegate = delegate;
188: }
189:
190: public Object get(String name) {
191: return this .delegate.get(name);
192: }
193:
194: public Object getAttribute(String name) {
195: return this .delegate.getAttribute(name);
196: }
197:
198: public Enumeration getAttributeNames() {
199: return this .delegate.getAttributeNames();
200: }
201:
202: public String getCharacterEncoding() {
203: return this .delegate.getCharacterEncoding();
204: }
205:
206: public void setCharacterEncoding(String enc)
207: throws java.io.UnsupportedEncodingException {
208: this .delegate.setCharacterEncoding(enc);
209: }
210:
211: public int getContentLength() {
212: return this .delegate.getContentLength();
213: }
214:
215: public String getContentType() {
216: return this .delegate.getContentType();
217: }
218:
219: public String getParameter(String name) {
220: return this .delegate.getParameter(name);
221: }
222:
223: public Enumeration getParameterNames() {
224: return this .delegate.getParameterNames();
225: }
226:
227: public String[] getParameterValues(String name) {
228: return this .delegate.getParameterValues(name);
229: }
230:
231: public String getProtocol() {
232: return this .delegate.getProtocol();
233: }
234:
235: public String getScheme() {
236: return this .delegate.getScheme();
237: }
238:
239: public String getServerName() {
240: return this .delegate.getServerName();
241: }
242:
243: public int getServerPort() {
244: return this .delegate.getServerPort();
245: }
246:
247: public String getRemoteAddr() {
248: return this .delegate.getRemoteAddr();
249: }
250:
251: public String getRemoteHost() {
252: return this .delegate.getRemoteHost();
253: }
254:
255: public void setAttribute(String name, Object o) {
256: this .delegate.setAttribute(name, o);
257: }
258:
259: public void removeAttribute(String name) {
260: this .delegate.removeAttribute(name);
261: }
262:
263: public Locale getLocale() {
264: return this .delegate.getLocale();
265: }
266:
267: public Enumeration getLocales() {
268: return this .delegate.getLocales();
269: }
270:
271: public boolean isSecure() {
272: return this .delegate.isSecure();
273: }
274:
275: public Cookie[] getCookies() {
276: return this .delegate.getCookies();
277: }
278:
279: public Map getCookieMap() {
280: return this .delegate.getCookieMap();
281: }
282:
283: public long getDateHeader(String name) {
284: return this .delegate.getDateHeader(name);
285: }
286:
287: public String getHeader(String name) {
288: return this .delegate.getHeader(name);
289: }
290:
291: public Enumeration getHeaders(String name) {
292: return this .delegate.getHeaders(name);
293: }
294:
295: public Enumeration getHeaderNames() {
296: return this .delegate.getHeaderNames();
297: }
298:
299: public String getMethod() {
300: return this .delegate.getMethod();
301: }
302:
303: public String getPathInfo() {
304: return this .delegate.getPathInfo();
305: }
306:
307: public String getPathTranslated() {
308: return this .delegate.getPathTranslated();
309: }
310:
311: public String getContextPath() {
312: return this .delegate.getContextPath();
313: }
314:
315: public String getQueryString() {
316: return this .delegate.getQueryString();
317: }
318:
319: public String getRemoteUser() {
320: return this .delegate.getRemoteUser();
321: }
322:
323: public String getRequestedSessionId() {
324: return this .delegate.getRequestedSessionId();
325: }
326:
327: public String getRequestURI() {
328: return this .delegate.getRequestURI();
329: }
330:
331: public String getSitemapURI() {
332: return this .delegate.getSitemapURI();
333: }
334:
335: public String getSitemapURIPrefix() {
336: return this .delegate.getSitemapURIPrefix();
337: }
338:
339: public String getServletPath() {
340: return this .delegate.getServletPath();
341: }
342:
343: public Session getSession(boolean create) {
344: return this .delegate.getSession(create);
345: }
346:
347: public Session getSession() {
348: return this .delegate.getSession();
349: }
350:
351: public boolean isRequestedSessionIdValid() {
352: return this .delegate.isRequestedSessionIdValid();
353: }
354:
355: public boolean isRequestedSessionIdFromCookie() {
356: return this .delegate.isRequestedSessionIdFromCookie();
357: }
358:
359: public boolean isRequestedSessionIdFromURL() {
360: return this .delegate.isRequestedSessionIdFromURL();
361: }
362:
363: public Principal getUserPrincipal() {
364: return this .delegate.getUserPrincipal();
365: }
366:
367: public boolean isUserInRole(String role) {
368: return this .delegate.isUserInRole(role);
369: }
370:
371: public String getAuthType() {
372: return this .delegate.getAuthType();
373: }
374: }
375:
376: public class SessionProxy implements Session {
377: private Session delegate;
378:
379: public SessionProxy(Session delegate) {
380: this .delegate = delegate;
381: }
382:
383: public long getCreationTime() {
384: return this .delegate.getCreationTime();
385: }
386:
387: public String getId() {
388: return this .delegate.getId();
389: }
390:
391: public long getLastAccessedTime() {
392: return this .delegate.getLastAccessedTime();
393: }
394:
395: public void setMaxInactiveInterval(int interval) {
396: this .delegate.setMaxInactiveInterval(interval);
397: }
398:
399: public int getMaxInactiveInterval() {
400: return this .delegate.getMaxInactiveInterval();
401: }
402:
403: public Object getAttribute(String name) {
404: return this .delegate.getAttribute(name);
405: }
406:
407: public Enumeration getAttributeNames() {
408: return this .delegate.getAttributeNames();
409: }
410:
411: public void setAttribute(String name, Object value) {
412: this .delegate.setAttribute(name, value);
413: }
414:
415: public void removeAttribute(String name) {
416: this .delegate.removeAttribute(name);
417: }
418:
419: public void invalidate() {
420: this .delegate.invalidate();
421: }
422:
423: public boolean isNew() {
424: return this .delegate.isNew();
425: }
426: }
427:
428: public class ContextProxy implements Context {
429: private Context delegate;
430:
431: public ContextProxy(
432: org.apache.cocoon.environment.Context delegate) {
433: this .delegate = delegate;
434: }
435:
436: public Object getAttribute(String name) {
437: return this .delegate.getAttribute(name);
438: }
439:
440: public void setAttribute(String name, Object value) {
441: this .delegate.setAttribute(name, value);
442: }
443:
444: public void removeAttribute(String name) {
445: this .delegate.removeAttribute(name);
446: }
447:
448: public Enumeration getAttributeNames() {
449: return this .delegate.getAttributeNames();
450: }
451:
452: public URL getResource(String path)
453: throws MalformedURLException {
454: return this .delegate.getResource(path);
455: }
456:
457: public String getRealPath(String path) {
458: return this .delegate.getRealPath(path);
459: }
460:
461: public String getMimeType(String file) {
462: return this .delegate.getMimeType(file);
463: }
464:
465: public String getInitParameter(String name) {
466: return this .delegate.getInitParameter(name);
467: }
468:
469: public InputStream getResourceAsStream(String path) {
470: return this.delegate.getResourceAsStream(path);
471: }
472: }
473: }
|