blob: 57b57ebe3a9e66108b1d50b9eb33d7472b3950f8 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cocoon.jxpath;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.cocoon.components.ContextHelper;
import org.apache.cocoon.environment.Context;
import org.apache.cocoon.environment.Cookie;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Session;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.JXPathContextFactory;
import org.apache.commons.jxpath.JXPathIntrospector;
import org.apache.commons.jxpath.servlet.Constants;
import org.apache.commons.jxpath.servlet.KeywordVariables;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.Principal;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
/**
* Component that allocate and cache JXPathContexts bound to VariableContext,
* Cocoon Request, Cocoon Session and Cocoon Context.
*
* <p>
* If you need to limit the attibute lookup to just one scope, you can use the
* pre-definded variables "request", "session" and "application".
* For example, the expression "$session/foo" extracts the value of the
* session attribute named "foo".</p>
*
* <p>
* Following are some implementation details.
* There is a separate JXPathContext for each of the four scopes. These contexts are chained
* according to the nesting of the scopes. So, the parent of the "variable"
* JXPathContext is a "request" JXPathContext, whose parent is a "session"
* JXPathContext (that is if there is a session), whose parent is an "application"
* context.</p>
*
* <p>
* Since JXPath chains lookups for variables and extension functions, variables
* and extension function declared in the outer scopes are also available in
* the inner scopes.</p>
*
* <p>
* The "session" variable will be undefined if there is no session for this servlet.
* JXPath does not automatically create sessions.</p>
*
* @author <a href="mailto:volker.schmitt@basf-it-services.com">Volker Schmitt</a>
* @version $Id$
*/
public final class JXPathCocoonContexts implements Component, Contextualizable, ThreadSafe {
public static final String ROLE = JXPathCocoonContexts.class.getName();
private static final String VARCONTEXT = Constants.JXPATH_CONTEXT + "/VAR";
private static JXPathContextFactory factory;
private org.apache.avalon.framework.context.Context context;
static {
factory = JXPathContextFactory.newInstance();
JXPathIntrospector.registerDynamicClass(RequestProxy.class, CocoonRequestHandler.class);
JXPathIntrospector.registerDynamicClass(SessionProxy.class, CocoonSessionHandler.class);
JXPathIntrospector.registerDynamicClass(ContextProxy.class, CocoonContextHandler.class);
}
public void contextualize(org.apache.avalon.framework.context.Context context) {
this.context = context;
}
public final JXPathContext getVariableContext() {
final Map objectModel = ContextHelper.getObjectModel(this.context);
Request request = ObjectModelHelper.getRequest(objectModel);
JXPathContext context = (JXPathContext) request.getAttribute(VARCONTEXT);
if (context == null) {
context = factory.newContext(getRequestContext(), null);
request.setAttribute(VARCONTEXT, context);
}
return context;
}
/**
* Returns a JXPathContext bound to the "request" scope.
* Caches that context within the request itself.
*/
public final JXPathContext getRequestContext() {
final Map objectModel = ContextHelper.getObjectModel(this.context);
Request request = ObjectModelHelper.getRequest(objectModel);
JXPathContext context = (JXPathContext) request.getAttribute(Constants.JXPATH_CONTEXT);
if (context == null) {
Context envContext = ObjectModelHelper.getContext(objectModel);
JXPathContext parentContext = null;
Session session = request.getSession(false);
if (session != null) {
parentContext = getSessionContext(session, envContext);
} else {
parentContext = getApplicationContext(envContext);
}
request = new RequestProxy(request);
context = factory.newContext(parentContext, request);
context.setVariables(new KeywordVariables(Constants.REQUEST_SCOPE, request));
request.setAttribute(Constants.JXPATH_CONTEXT, context);
}
return context;
}
/**
* Returns a JXPathContext bound to the "session" scope.
* Caches that context within the session itself.
*/
public final JXPathContext getSessionContext(Session session, Context envContext) {
JXPathContext context = (JXPathContext) session.getAttribute(Constants.JXPATH_CONTEXT);
if (context == null) {
JXPathContext parentContext = getApplicationContext(envContext);
session = new SessionProxy(session);
context = factory.newContext(parentContext, session);
context.setVariables(new KeywordVariables(Constants.SESSION_SCOPE, session));
session.setAttribute(Constants.JXPATH_CONTEXT, context);
}
return context;
}
/**
* Returns a JXPathContext bound to the "application" scope. Caches that context
* within the servlet context itself.
*/
public final JXPathContext getApplicationContext(Context envContext) {
JXPathContext context = (JXPathContext) envContext.getAttribute(Constants.JXPATH_CONTEXT);
if (context == null) {
envContext = new ContextProxy(envContext);
context = factory.newContext(null, envContext);
context.setVariables(new KeywordVariables(Constants.APPLICATION_SCOPE, envContext));
envContext.setAttribute(Constants.JXPATH_CONTEXT, context);
}
return context;
}
public static final class RequestProxy implements Request {
private Request delegate;
public RequestProxy (Request delegate) {
this.delegate = delegate;
}
public Object get(String name) {
return this.delegate.get(name);
}
public Object getAttribute(String name) {
return this.delegate.getAttribute(name);
}
public Enumeration getAttributeNames() {
return this.delegate.getAttributeNames();
}
public String getCharacterEncoding() {
return this.delegate.getCharacterEncoding();
}
public void setCharacterEncoding(String enc)
throws java.io.UnsupportedEncodingException {
this.delegate.setCharacterEncoding(enc);
}
public int getContentLength() {
return this.delegate.getContentLength();
}
public String getContentType() {
return this.delegate.getContentType();
}
public String getParameter(String name) {
return this.delegate.getParameter(name);
}
public Enumeration getParameterNames() {
return this.delegate.getParameterNames();
}
public String[] getParameterValues(String name) {
return this.delegate.getParameterValues(name);
}
public String getProtocol() {
return this.delegate.getProtocol();
}
public String getScheme() {
return this.delegate.getScheme();
}
public String getServerName() {
return this.delegate.getServerName();
}
public int getServerPort() {
return this.delegate.getServerPort();
}
public String getRemoteAddr() {
return this.delegate.getRemoteAddr();
}
public String getRemoteHost() {
return this.delegate.getRemoteHost();
}
public void setAttribute(String name, Object o) {
this.delegate.setAttribute(name, o);
}
public void removeAttribute(String name) {
this.delegate.removeAttribute(name);
}
public Locale getLocale() {
return this.delegate.getLocale();
}
public Enumeration getLocales() {
return this.delegate.getLocales();
}
public boolean isSecure() {
return this.delegate.isSecure();
}
public Cookie[] getCookies() {
return this.delegate.getCookies();
}
public Map getCookieMap() {
return this.delegate.getCookieMap();
}
public long getDateHeader(String name) {
return this.delegate.getDateHeader(name);
}
public String getHeader(String name) {
return this.delegate.getHeader(name);
}
public Enumeration getHeaders(String name) {
return this.delegate.getHeaders(name);
}
public Enumeration getHeaderNames() {
return this.delegate.getHeaderNames();
}
public String getMethod() {
return this.delegate.getMethod();
}
public String getPathInfo() {
return this.delegate.getPathInfo();
}
public String getPathTranslated() {
return this.delegate.getPathTranslated();
}
public String getContextPath() {
return this.delegate.getContextPath();
}
public String getQueryString() {
return this.delegate.getQueryString();
}
public String getRemoteUser() {
return this.delegate.getRemoteUser();
}
public String getRequestedSessionId() {
return this.delegate.getRequestedSessionId();
}
public String getRequestURI() {
return this.delegate.getRequestURI();
}
public String getSitemapURI() {
return this.delegate.getSitemapURI();
}
public String getSitemapURIPrefix() {
return this.delegate.getSitemapURIPrefix();
}
public String getServletPath() {
return this.delegate.getServletPath();
}
public Session getSession(boolean create) {
return this.delegate.getSession(create);
}
public Session getSession() {
return this.delegate.getSession();
}
public Session getCocoonSession(boolean create) {
return this.getSession(create);
}
public Session getCocoonSession() {
return this.getSession(true);
}
public boolean isRequestedSessionIdValid() {
return this.delegate.isRequestedSessionIdValid();
}
public boolean isRequestedSessionIdFromCookie() {
return this.delegate.isRequestedSessionIdFromCookie();
}
public boolean isRequestedSessionIdFromURL() {
return this.delegate.isRequestedSessionIdFromURL();
}
public Principal getUserPrincipal() {
return this.delegate.getUserPrincipal();
}
public boolean isUserInRole(String role) {
return this.delegate.isUserInRole(role);
}
public String getAuthType() {
return this.delegate.getAuthType();
}
}
public class SessionProxy implements Session {
private Session delegate;
public SessionProxy(Session delegate) {
this.delegate = delegate;
}
public long getCreationTime() {
return this.delegate.getCreationTime();
}
public String getId() {
return this.delegate.getId();
}
public long getLastAccessedTime() {
return this.delegate.getLastAccessedTime();
}
public void setMaxInactiveInterval(int interval) {
this.delegate.setMaxInactiveInterval(interval);
}
public int getMaxInactiveInterval() {
return this.delegate.getMaxInactiveInterval();
}
public Object getAttribute(String name) {
return this.delegate.getAttribute(name);
}
public Enumeration getAttributeNames() {
return this.delegate.getAttributeNames();
}
public void setAttribute(String name, Object value) {
this.delegate.setAttribute(name, value);
}
public void removeAttribute(String name) {
this.delegate.removeAttribute(name);
}
public void invalidate() {
this.delegate.invalidate();
}
public boolean isNew() {
return this.delegate.isNew();
}
}
public class ContextProxy implements Context {
private Context delegate;
public ContextProxy(org.apache.cocoon.environment.Context delegate) {
this.delegate = delegate;
}
public Object getAttribute(String name) {
return this.delegate.getAttribute(name);
}
public void setAttribute(String name, Object value) {
this.delegate.setAttribute(name, value);
}
public void removeAttribute(String name) {
this.delegate.removeAttribute(name);
}
public Enumeration getAttributeNames() {
return this.delegate.getAttributeNames();
}
public URL getResource(String path) throws MalformedURLException {
return this.delegate.getResource(path);
}
public String getRealPath(String path) {
return this.delegate.getRealPath(path);
}
public String getMimeType(String file) {
return this.delegate.getMimeType(file);
}
public String getInitParameter(String name) {
return this.delegate.getInitParameter(name);
}
public InputStream getResourceAsStream(String path) {
return this.delegate.getResourceAsStream(path);
}
}
}