001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/jsf/tags/sakai_2-4-1/app/src/java/org/sakaiproject/jsf/app/SakaiViewHandler.java $
003: * $Id: SakaiViewHandler.java 9278 2006-05-10 23:29:21Z ray@media.berkeley.edu $
004: **********************************************************************************
005: *
006: * Copyright (c) 2003, 2004, 2005 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.jsf.app;
021:
022: import java.io.IOException;
023: import java.util.Locale;
024:
025: import javax.faces.FacesException;
026: import javax.faces.application.ViewHandler;
027: import javax.faces.component.UIViewRoot;
028: import javax.faces.context.FacesContext;
029: import javax.servlet.http.HttpServletRequest;
030:
031: import org.apache.commons.logging.Log;
032: import org.apache.commons.logging.LogFactory;
033: import org.sakaiproject.tool.api.Tool;
034: import org.sakaiproject.util.Web;
035:
036: /**
037: * <p>
038: * SakaiViewHandler extends the basic ViewHandler functionality for getActionURL(). getActionURL() is extended ...
039: *
040: * @author University of Michigan, Sakai Software Development Team
041: * @version $Revision: 9278 $
042: */
043: public class SakaiViewHandler extends ViewHandler {
044: // TODO: Note, these two values must match those in jsf-tool's JsfTool
045:
046: /** Request attribute we set to help the return URL know what path we add (does not need to be in the URL. */
047: public static final String URL_PATH = "sakai.jsf.tool.URL.path";
048:
049: /** Request attribute we set to help the return URL know what extension we (or jsf) add (does not need to be in the URL. */
050: public static final String URL_EXT = "sakai.jsf.tool.URL.ext";
051:
052: /** Our log (commons). */
053: private static Log M_log = LogFactory
054: .getLog(SakaiViewHandler.class);
055:
056: /** The wrapped ViewHandler. */
057: private ViewHandler m_wrapped = null;
058:
059: private SakaiViewHandler() {
060: }
061:
062: public SakaiViewHandler(ViewHandler wrapped) {
063: m_wrapped = wrapped;
064: }
065:
066: public String getActionURL(FacesContext context, String viewId) {
067: HttpServletRequest req = (HttpServletRequest) context
068: .getExternalContext().getRequest();
069:
070: if (req.getAttribute(URL_EXT) == null) {
071: // If the request didn't go through JsfTool (the JSF is accessed directly from its webapp,
072: // not as a Sakai tool), then don't do Sakai's special action URL handling.
073: return m_wrapped.getActionURL(context, viewId);
074: }
075:
076: // get the path that got us here (from the tool's point of view)
077: String path = viewId;
078:
079: // modify the path to remove things that were added by Sakai navigation to get here (prefix path, suffix extension)
080: String prefix = (String) req.getAttribute(URL_PATH);
081: if ((prefix != null) && path.startsWith(prefix))
082: path = path.substring(prefix.length());
083:
084: String ext = (String) req.getAttribute(URL_EXT);
085: if ((ext != null) && path.endsWith(ext))
086: path = path.substring(0, path.length() - ext.length());
087:
088: // make sure the URL processing uses the Sakai, not Native the request object so we can get at the URL information setup by the invoker
089: req.removeAttribute(Tool.NATIVE_URL);
090:
091: // form our return URL
092: String rv = Web.returnUrl(req, path);
093:
094: // restore (if needed)
095: req.setAttribute(Tool.NATIVE_URL, Tool.NATIVE_URL);
096:
097: M_log.debug("action url for view: " + viewId + " = " + rv);
098:
099: return rv;
100: }
101:
102: /** Methods delegated to default ViewHandler */
103:
104: public Locale calculateLocale(FacesContext arg0) {
105: return m_wrapped.calculateLocale(arg0);
106: }
107:
108: public String calculateRenderKitId(FacesContext arg0) {
109: return m_wrapped.calculateRenderKitId(arg0);
110: }
111:
112: public UIViewRoot createView(FacesContext arg0, String arg1) {
113: UIViewRoot root = m_wrapped.createView(arg0, arg1);
114:
115: if (root != null) {
116: // restore messages
117: MessageSaver.restoreMessages(arg0);
118: }
119:
120: return root;
121: }
122:
123: public String getResourceURL(FacesContext arg0, String arg1) {
124: return m_wrapped.getResourceURL(arg0, arg1);
125: }
126:
127: public void renderView(FacesContext arg0, UIViewRoot arg1)
128: throws IOException, FacesException {
129: m_wrapped.renderView(arg0, arg1);
130: }
131:
132: public UIViewRoot restoreView(FacesContext arg0, String arg1) {
133: UIViewRoot root = m_wrapped.restoreView(arg0, arg1);
134:
135: if (root != null) {
136: // restore messages
137: MessageSaver.restoreMessages(arg0);
138: }
139:
140: return root;
141: }
142:
143: public void writeState(FacesContext arg0) throws IOException {
144: m_wrapped.writeState(arg0);
145: }
146: }
|