001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/syllabus/tags/sakai_2-4-1/syllabus-app/src/java/org/sakaiproject/tool/syllabus/SyllabusFilePickerServlet.java $
003: * $Id: SyllabusFilePickerServlet.java 14709 2006-09-15 15:42:44Z lance@indiana.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2003, 2004, 2005, 2006 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.tool.syllabus;
021:
022: import java.io.IOException;
023: import java.util.Enumeration;
024:
025: import javax.servlet.RequestDispatcher;
026: import javax.servlet.ServletException;
027: import javax.servlet.http.HttpServletRequest;
028: import javax.servlet.http.HttpServletResponse;
029:
030: import org.sakaiproject.jsf.util.JsfTool;
031: import org.sakaiproject.tool.api.ActiveTool;
032: import org.sakaiproject.tool.api.Tool;
033: import org.sakaiproject.tool.api.ToolException;
034: import org.sakaiproject.tool.api.ToolSession;
035: import org.sakaiproject.tool.cover.ActiveToolManager;
036: import org.sakaiproject.tool.cover.SessionManager;
037: import org.sakaiproject.util.Web;
038:
039: /**
040: * @author <a href="mailto:cwen.iupui.edu">Chen Wen</a>
041: * @version $Id: SyllabusFilePickerServlet.java 14709 2006-09-15 15:42:44Z lance@indiana.edu $
042: *
043: */
044: public class SyllabusFilePickerServlet extends JsfTool {
045: private static final String HELPER_EXT = ".helper";
046:
047: private static final String HELPER_SESSION_PREFIX = "session.";
048:
049: protected void dispatch(HttpServletRequest req,
050: HttpServletResponse res) throws ServletException,
051: IOException {
052: // NOTE: this is a simple path dispatching, taking the path as the view id = jsp file name for the view,
053: // with default used if no path and a path prefix as configured.
054: // TODO: need to allow other sorts of dispatching, such as pulling out drill-down ids and making them
055: // available to the JSF
056:
057: // build up the target that will be dispatched to
058: String target = req.getPathInfo();
059:
060: // see if we have a helper request
061: if (sendToHelper(req, res, target)) {
062: return;
063: }
064:
065: // see if we have a resource request - i.e. a path with an extension, and one that is not the JSF_EXT
066: if (isResourceRequest(target)) {
067: // get a dispatcher to the path
068: RequestDispatcher resourceDispatcher = getServletContext()
069: .getRequestDispatcher(target);
070: if (resourceDispatcher != null) {
071: resourceDispatcher.forward(req, res);
072: return;
073: }
074: }
075:
076: if ("Title".equals(req.getParameter("panel"))) {
077: // This allows only one Title JSF for each tool
078: target = "/title.jsf";
079: }
080:
081: else {
082: ToolSession session = SessionManager
083: .getCurrentToolSession();
084:
085: if (target == null || "/".equals(target)) {
086: target = computeDefaultTarget();
087:
088: // make sure it's a valid path
089: if (!target.startsWith("/")) {
090: target = "/" + target;
091: }
092:
093: // now that we've messed with the URL, send a redirect to make it official
094: res.sendRedirect(Web.returnUrl(req, target));
095: return;
096: }
097:
098: // see if we want to change the specifically requested view
099: String newTarget = redirectRequestedTarget(target);
100:
101: // make sure it's a valid path
102: if (!newTarget.startsWith("/")) {
103: newTarget = "/" + newTarget;
104: }
105:
106: if (!newTarget.equals(target)) {
107: // now that we've messed with the URL, send a redirect to make it official
108: res.sendRedirect(Web.returnUrl(req, newTarget));
109: return;
110: }
111: target = newTarget;
112:
113: // store this
114: if (m_defaultToLastView) {
115: session.setAttribute(LAST_VIEW_VISITED, target);
116: }
117: }
118:
119: // add the configured folder root and extension (if missing)
120: target = m_path + target;
121:
122: // add the default JSF extension (if we have no extension)
123: int lastSlash = target.lastIndexOf("/");
124: int lastDot = target.lastIndexOf(".");
125: if (lastDot < 0 || lastDot < lastSlash) {
126: target += JSF_EXT;
127: }
128:
129: // set the information that can be removed from return URLs
130: req.setAttribute(URL_PATH, m_path);
131: req.setAttribute(URL_EXT, ".jsp");
132:
133: // set the sakai request object wrappers to provide the native, not Sakai set up, URL information
134: // - this assures that the FacesServlet can dispatch to the proper view based on the path info
135: req.setAttribute(Tool.NATIVE_URL, Tool.NATIVE_URL);
136:
137: // TODO: Should setting the HTTP headers be moved up to the portal level as well?
138: res.setContentType("text/html; charset=UTF-8");
139: res.addDateHeader("Expires", System.currentTimeMillis()
140: - (1000L * 60L * 60L * 24L * 365L));
141: res.addDateHeader("Last-Modified", System.currentTimeMillis());
142: res
143: .addHeader("Cache-Control",
144: "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0");
145: res.addHeader("Pragma", "no-cache");
146:
147: // dispatch to the target
148: /*M_log.debug("dispatching path: " + req.getPathInfo() + " to: " + target + " context: "
149: + getServletContext().getServletContextName());*/
150: RequestDispatcher dispatcher = getServletContext()
151: .getRequestDispatcher(target);
152: dispatcher.forward(req, res);
153:
154: // restore the request object
155: req.removeAttribute(Tool.NATIVE_URL);
156: req.removeAttribute(URL_PATH);
157: req.removeAttribute(URL_EXT);
158: }
159:
160: protected boolean sendToHelper(HttpServletRequest req,
161: HttpServletResponse res, String target)
162: throws ToolException {
163: String path = req.getPathInfo();
164: if (path == null)
165: path = "/";
166:
167: // 0 parts means the path was just "/", otherwise parts[0] = "", parts[1] = item id, parts[2] if present is "edit"...
168: String[] parts = path.split("/");
169:
170: if (parts.length < 2) {
171: return false;
172: }
173:
174: if (!parts[1].endsWith(HELPER_EXT)) {
175: return false;
176: }
177:
178: ToolSession toolSession = SessionManager
179: .getCurrentToolSession();
180:
181: Enumeration params = req.getParameterNames();
182: while (params.hasMoreElements()) {
183: String paramName = (String) params.nextElement();
184: if (paramName.startsWith(HELPER_SESSION_PREFIX)) {
185: String attributeName = paramName
186: .substring(HELPER_SESSION_PREFIX.length());
187: toolSession.setAttribute(attributeName, req
188: .getParameter(paramName));
189: }
190: }
191:
192: // calc helper id
193: int posEnd = parts[1].lastIndexOf(".");
194:
195: String helperId = target.substring(1, posEnd + 1);
196: ActiveTool helperTool = ActiveToolManager
197: .getActiveTool(helperId);
198:
199: if (toolSession.getAttribute(helperTool.getId()
200: + Tool.HELPER_DONE_URL) == null) {
201: toolSession
202: .setAttribute(helperTool.getId()
203: + Tool.HELPER_DONE_URL, req
204: .getContextPath()
205: + req.getServletPath()
206: + computeDefaultTarget(true));
207: }
208:
209: /*comment out for using the global parameter rather than tool-by-tool setting
210: SessionState state = UsageSessionService.getSessionState(toolSession.getPlacementId());
211: boolean show_other_sites = ServerConfigurationService.getBoolean("syllabus.resources.show_all_collections.helper", true);
212: state.setAttribute("resources.allow_user_to_see_all_sites", (new Boolean(show_other_sites)).toString());
213: state.setAttribute("resources.user_chooses_to_see_other_sites", (new Boolean(show_other_sites)).toString());
214: */
215: String context = req.getContextPath() + req.getServletPath()
216: + Web.makePath(parts, 1, 2);
217: String toolPath = Web.makePath(parts, 2, parts.length);
218: helperTool.help(req, res, context, toolPath);
219:
220: return true; // was handled as helper call
221: }
222:
223: protected String computeDefaultTarget(boolean lastVisited) {
224: // setup for the default view as configured
225: String target = "/" + m_default;
226:
227: // if we are doing lastVisit and there's a last-visited view, for this tool placement / user, use that
228: if (lastVisited) {
229: ToolSession session = SessionManager
230: .getCurrentToolSession();
231: String last = (String) session
232: .getAttribute(LAST_VIEW_VISITED);
233: if (last != null) {
234: target = last;
235: }
236: }
237:
238: return target;
239: }
240: }
|