0001: /**********************************************************************************
0002: * $URL: https://source.sakaiproject.org/svn/portal/tags/sakai_2-4-1/portal-impl/impl/src/java/org/sakaiproject/portal/charon/SkinnableCharonPortal.java $
0003: * $Id: SkinnableCharonPortal.java 29143 2007-04-19 01:10:38Z ajpoland@iupui.edu $
0004: ***********************************************************************************
0005: *
0006: * Copyright (c) 2005, 2006 The Sakai Foundation.
0007: *
0008: * Licensed under the Educational Community License, Version 1.0 (the "License");
0009: * you may not use this file except in compliance with the License.
0010: * You may obtain a copy of the License at
0011: *
0012: * http://www.opensource.org/licenses/ecl1.php
0013: *
0014: * Unless required by applicable law or agreed to in writing, software
0015: * distributed under the License is distributed on an "AS IS" BASIS,
0016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: * See the License for the specific language governing permissions and
0018: * limitations under the License.
0019: *
0020: **********************************************************************************/package org.sakaiproject.portal.charon;
0021:
0022: import java.io.IOException;
0023: import java.io.PrintWriter;
0024: import java.util.ArrayList;
0025: import java.util.Enumeration;
0026: import java.util.HashMap;
0027: import java.util.Iterator;
0028: import java.util.List;
0029: import java.util.Map;
0030: import java.util.Properties;
0031:
0032: import javax.servlet.ServletConfig;
0033: import javax.servlet.ServletException;
0034: import javax.servlet.http.HttpServlet;
0035: import javax.servlet.http.HttpServletRequest;
0036: import javax.servlet.http.HttpServletResponse;
0037:
0038: import org.apache.commons.logging.Log;
0039: import org.apache.commons.logging.LogFactory;
0040: import org.sakaiproject.authz.cover.SecurityService;
0041: import org.sakaiproject.component.cover.ServerConfigurationService;
0042: import org.sakaiproject.exception.IdUnusedException;
0043: import org.sakaiproject.exception.PermissionException;
0044: import org.sakaiproject.portal.api.Portal;
0045: import org.sakaiproject.portal.api.PortalHandler;
0046: import org.sakaiproject.portal.api.PortalRenderContext;
0047: import org.sakaiproject.portal.api.PortalRenderEngine;
0048: import org.sakaiproject.portal.api.PortalService;
0049: import org.sakaiproject.portal.api.StoredState;
0050: import org.sakaiproject.portal.charon.handlers.AtomHandler;
0051: import org.sakaiproject.portal.charon.handlers.DirectToolHandler;
0052: import org.sakaiproject.portal.charon.handlers.ErrorDoneHandler;
0053: import org.sakaiproject.portal.charon.handlers.ErrorReportHandler;
0054: import org.sakaiproject.portal.charon.handlers.GalleryHandler;
0055: import org.sakaiproject.portal.charon.handlers.GalleryResetHandler;
0056: import org.sakaiproject.portal.charon.handlers.HelpHandler;
0057: import org.sakaiproject.portal.charon.handlers.LoginGalleryHandler;
0058: import org.sakaiproject.portal.charon.handlers.LoginHandler;
0059: import org.sakaiproject.portal.charon.handlers.LogoutGalleryHandler;
0060: import org.sakaiproject.portal.charon.handlers.LogoutHandler;
0061: import org.sakaiproject.portal.charon.handlers.NavLoginGalleryHandler;
0062: import org.sakaiproject.portal.charon.handlers.NavLoginHandler;
0063: import org.sakaiproject.portal.charon.handlers.OpmlHandler;
0064: import org.sakaiproject.portal.charon.handlers.PDAHandler;
0065: import org.sakaiproject.portal.charon.handlers.PageHandler;
0066: import org.sakaiproject.portal.charon.handlers.PresenceHandler;
0067: import org.sakaiproject.portal.charon.handlers.ReLoginHandler;
0068: import org.sakaiproject.portal.charon.handlers.RssHandler;
0069: import org.sakaiproject.portal.charon.handlers.SiteHandler;
0070: import org.sakaiproject.portal.charon.handlers.SiteResetHandler;
0071: import org.sakaiproject.portal.charon.handlers.StaticScriptsHandler;
0072: import org.sakaiproject.portal.charon.handlers.StaticStylesHandler;
0073: import org.sakaiproject.portal.charon.handlers.ToolHandler;
0074: import org.sakaiproject.portal.charon.handlers.ToolResetHandler;
0075: import org.sakaiproject.portal.charon.handlers.WorksiteHandler;
0076: import org.sakaiproject.portal.charon.handlers.WorksiteResetHandler;
0077: import org.sakaiproject.portal.charon.handlers.XLoginHandler;
0078: import org.sakaiproject.portal.render.api.RenderResult;
0079: import org.sakaiproject.portal.render.cover.ToolRenderService;
0080: import org.sakaiproject.portal.util.ErrorReporter;
0081: import org.sakaiproject.portal.util.PortalSiteHelper;
0082: import org.sakaiproject.portal.util.ToolURLManagerImpl;
0083: import org.sakaiproject.site.api.Site;
0084: import org.sakaiproject.site.api.SitePage;
0085: import org.sakaiproject.site.api.ToolConfiguration;
0086: import org.sakaiproject.site.cover.SiteService;
0087: import org.sakaiproject.thread_local.cover.ThreadLocalManager;
0088: import org.sakaiproject.tool.api.ActiveTool;
0089: import org.sakaiproject.tool.api.Placement;
0090: import org.sakaiproject.tool.api.Session;
0091: import org.sakaiproject.tool.api.Tool;
0092: import org.sakaiproject.tool.api.ToolException;
0093: import org.sakaiproject.tool.api.ToolSession;
0094: import org.sakaiproject.tool.api.ToolURL;
0095: import org.sakaiproject.tool.cover.ActiveToolManager;
0096: import org.sakaiproject.tool.cover.SessionManager;
0097: import org.sakaiproject.tool.cover.ToolManager;
0098: import org.sakaiproject.user.api.UserNotDefinedException;
0099: import org.sakaiproject.user.cover.UserDirectoryService;
0100: import org.sakaiproject.util.BasicAuth;
0101: import org.sakaiproject.util.ResourceLoader;
0102: import org.sakaiproject.util.StringUtil;
0103: import org.sakaiproject.util.Web;
0104:
0105: /**
0106: * <p/> Charon is the Sakai Site based portal.
0107: * </p>
0108: *
0109: * @since Sakai 2.4
0110: * @version $Rev: 29143 $
0111: *
0112: */
0113: public class SkinnableCharonPortal extends HttpServlet implements
0114: Portal {
0115: /**
0116: * Our log (commons).
0117: */
0118: private static Log M_log = LogFactory
0119: .getLog(SkinnableCharonPortal.class);
0120:
0121: /**
0122: * messages.
0123: */
0124: private static ResourceLoader rloader = new ResourceLoader(
0125: "sitenav");
0126:
0127: /**
0128: * Parameter value to indicate to look up a tool ID within a site
0129: */
0130: protected static final String PARAM_SAKAI_SITE = "sakai.site";
0131:
0132: private BasicAuth basicAuth = null;
0133:
0134: private boolean enableDirect = false;
0135:
0136: private PortalService portalService;
0137:
0138: private static final String PADDING = " ";
0139:
0140: private static final String INCLUDE_BOTTOM = "include-bottom";
0141:
0142: private static final String INCLUDE_LOGIN = "include-login";
0143:
0144: private static final String INCLUDE_TITLE = "include-title";
0145:
0146: private PortalSiteHelper siteHelper = new PortalSiteHelper();
0147:
0148: // private HashMap<String, PortalHandler> handlerMap = new HashMap<String,
0149: // PortalHandler>();
0150:
0151: private GalleryHandler galleryHandler;
0152:
0153: private WorksiteHandler worksiteHandler;
0154:
0155: private SiteHandler siteHandler;
0156:
0157: private String portalContext;
0158:
0159: public String getPortalContext() {
0160: return portalContext;
0161: }
0162:
0163: /**
0164: * Shutdown the servlet.
0165: */
0166: public void destroy() {
0167: M_log.info("destroy()");
0168: portalService.removePortal(this );
0169:
0170: super .destroy();
0171: }
0172:
0173: public void doError(HttpServletRequest req,
0174: HttpServletResponse res, Session session, int mode)
0175: throws ToolException, IOException {
0176: if (ThreadLocalManager.get(ATTR_ERROR) == null) {
0177: ThreadLocalManager.set(ATTR_ERROR, ATTR_ERROR);
0178:
0179: // send to the error site
0180: switch (mode) {
0181: case ERROR_SITE: {
0182: siteHandler.doSite(req, res, session, "!error", null,
0183: req.getContextPath() + req.getServletPath());
0184: break;
0185: }
0186: case ERROR_GALLERY: {
0187: galleryHandler.doGallery(req, res, session, "!error",
0188: null, req.getContextPath()
0189: + req.getServletPath());
0190: break;
0191: }
0192: case ERROR_WORKSITE: {
0193: worksiteHandler.doWorksite(req, res, session, "!error",
0194: null, req.getContextPath()
0195: + req.getServletPath());
0196: break;
0197: }
0198: }
0199: return;
0200: }
0201:
0202: // error and we cannot use the error site...
0203:
0204: // form a context sensitive title
0205: String title = ServerConfigurationService
0206: .getString("ui.service")
0207: + " : Portal";
0208:
0209: // start the response
0210: PortalRenderContext rcontext = startPageContext("", title,
0211: null, req);
0212:
0213: showSession(rcontext, true);
0214:
0215: showSnoop(rcontext, true, getServletConfig(), req);
0216:
0217: sendResponse(rcontext, res, "error", null);
0218: }
0219:
0220: private void showSnoop(PortalRenderContext rcontext, boolean b,
0221: ServletConfig servletConfig, HttpServletRequest req) {
0222: Enumeration e = null;
0223:
0224: rcontext.put("snoopRequest", req.toString());
0225:
0226: if (servletConfig != null) {
0227: Map<String, Object> m = new HashMap<String, Object>();
0228: e = servletConfig.getInitParameterNames();
0229:
0230: if (e != null) {
0231: boolean first = true;
0232: while (e.hasMoreElements()) {
0233: String param = (String) e.nextElement();
0234: m.put(param, servletConfig.getInitParameter(param));
0235: }
0236: }
0237: rcontext.put("snoopServletConfigParams", m);
0238: }
0239: rcontext.put("snoopRequest", req);
0240:
0241: e = req.getHeaderNames();
0242: if (e.hasMoreElements()) {
0243: Map<String, Object> m = new HashMap<String, Object>();
0244: while (e.hasMoreElements()) {
0245: String name = (String) e.nextElement();
0246: m.put(name, req.getHeader(name));
0247: }
0248: rcontext.put("snoopRequestHeaders", m);
0249: }
0250:
0251: e = req.getParameterNames();
0252: if (e.hasMoreElements()) {
0253: Map<String, Object> m = new HashMap<String, Object>();
0254: while (e.hasMoreElements()) {
0255: String name = (String) e.nextElement();
0256: m.put(name, req.getParameter(name));
0257: }
0258: rcontext.put("snoopRequestParamsSingle", m);
0259: }
0260:
0261: e = req.getParameterNames();
0262: if (e.hasMoreElements()) {
0263: Map<String, Object> m = new HashMap<String, Object>();
0264: while (e.hasMoreElements()) {
0265: String name = (String) e.nextElement();
0266: String[] vals = (String[]) req.getParameterValues(name);
0267: StringBuilder sb = new StringBuilder();
0268: if (vals != null) {
0269: sb.append(vals[0]);
0270: for (int i = 1; i < vals.length; i++)
0271: sb.append(" ").append(vals[i]);
0272: }
0273: m.put(name, sb.toString());
0274: }
0275: rcontext.put("snoopRequestParamsMulti", m);
0276: }
0277:
0278: e = req.getAttributeNames();
0279: if (e.hasMoreElements()) {
0280: Map<String, Object> m = new HashMap<String, Object>();
0281: while (e.hasMoreElements()) {
0282: String name = (String) e.nextElement();
0283: m.put(name, req.getAttribute(name));
0284:
0285: }
0286: rcontext.put("snoopRequestAttr", m);
0287: }
0288: }
0289:
0290: protected void doThrowableError(HttpServletRequest req,
0291: HttpServletResponse res, Throwable t) {
0292: ErrorReporter err = new ErrorReporter();
0293: err.report(req, res, t);
0294: }
0295:
0296: /*
0297: * Produce a portlet like view with the navigation all at the top with
0298: * implicit reset
0299: */
0300: public PortalRenderContext includePortal(HttpServletRequest req,
0301: HttpServletResponse res, Session session, String siteId,
0302: String toolId, String toolContextPath, String prefix,
0303: boolean doPages, boolean resetTools,
0304: boolean includeSummary, boolean expandSite)
0305: throws ToolException, IOException {
0306:
0307: String errorMessage = null;
0308:
0309: // find the site, for visiting
0310: Site site = null;
0311: try {
0312: site = siteHelper.getSiteVisit(siteId);
0313: } catch (IdUnusedException e) {
0314: errorMessage = "Unable to find site: " + siteId;
0315: siteId = null;
0316: toolId = null;
0317: } catch (PermissionException e) {
0318: if (session.getUserId() == null) {
0319: errorMessage = "No permission for anynymous user to view site: "
0320: + siteId;
0321: } else {
0322: errorMessage = "No permission to view site: " + siteId;
0323: }
0324: siteId = null;
0325: toolId = null; // Tool needs the site and needs it to be visitable
0326: }
0327:
0328: // Get the Tool Placement
0329: ToolConfiguration placement = null;
0330: if (site != null && toolId != null) {
0331: placement = SiteService.findTool(toolId);
0332: if (placement == null) {
0333: errorMessage = "Unable to find tool placement "
0334: + toolId;
0335: toolId = null;
0336: }
0337:
0338: boolean this Tool = siteHelper.allowTool(site, placement);
0339: // System.out.println(" Allow Tool Display -" +
0340: // placement.getTitle() + " retval = " + thisTool);
0341: if (!this Tool) {
0342: errorMessage = "No permission to view tool placement "
0343: + toolId;
0344: toolId = null;
0345: placement = null;
0346: }
0347: }
0348:
0349: // Get the user's My WorkSpace and its ID
0350: Site myWorkspaceSite = siteHelper.getMyWorkspace(session);
0351: String myWorkspaceSiteId = null;
0352: if (myWorkspaceSite != null) {
0353: myWorkspaceSiteId = myWorkspaceSite.getId();
0354: }
0355:
0356: // form a context sensitive title
0357: String title = ServerConfigurationService
0358: .getString("ui.service");
0359: if (site != null) {
0360: title = title + ":" + site.getTitle();
0361: if (placement != null)
0362: title = title + " : " + placement.getTitle();
0363: }
0364:
0365: // start the response
0366: String siteType = null;
0367: String siteSkin = null;
0368: if (site != null) {
0369: siteType = calcSiteType(siteId);
0370: siteSkin = site.getSkin();
0371: }
0372:
0373: PortalRenderContext rcontext = startPageContext(siteType,
0374: title, siteSkin, req);
0375:
0376: // Make the top Url where the "top" url is
0377: String portalTopUrl = Web.serverUrl(req)
0378: + ServerConfigurationService.getString("portalPath")
0379: + "/";
0380: if (prefix != null)
0381: portalTopUrl = portalTopUrl + prefix + "/";
0382:
0383: rcontext.put("portalTopUrl", portalTopUrl);
0384: rcontext.put("loggedIn", Boolean
0385: .valueOf(session.getUserId() != null));
0386:
0387: if (placement != null) {
0388: Map m = includeTool(res, req, placement);
0389: if (m != null)
0390: rcontext.put("currentPlacement", m);
0391: }
0392:
0393: boolean loggedIn = session.getUserId() != null;
0394:
0395: if (site != null) {
0396: Map m = convertSiteToMap(req, site, prefix, siteId,
0397: myWorkspaceSiteId, includeSummary,
0398: /* expandSite */true, resetTools, doPages,
0399: toolContextPath, loggedIn);
0400: if (m != null)
0401: rcontext.put("currentSite", m);
0402: }
0403:
0404: List mySites = siteHelper.getAllSites(req, session, true);
0405: List l = convertSitesToMaps(req, mySites, prefix, siteId,
0406: myWorkspaceSiteId, includeSummary, expandSite,
0407: resetTools, doPages, toolContextPath, loggedIn);
0408: rcontext.put("allSites", l);
0409:
0410: includeLogin(rcontext, req, session);
0411: includeBottom(rcontext);
0412:
0413: return rcontext;
0414: }
0415:
0416: public boolean isPortletPlacement(Placement placement) {
0417: if (placement == null)
0418: return false;
0419: Properties toolProps = placement.getTool().getFinalConfig();
0420: if (toolProps == null)
0421: return false;
0422: String portletContext = toolProps
0423: .getProperty(PortalService.TOOL_PORTLET_CONTEXT_PATH);
0424: return (portletContext != null);
0425: }
0426:
0427: public Map includeTool(HttpServletResponse res,
0428: HttpServletRequest req, ToolConfiguration placement)
0429: throws IOException {
0430:
0431: // find the tool registered for this
0432: ActiveTool tool = ActiveToolManager.getActiveTool(placement
0433: .getToolId());
0434: if (tool == null) {
0435: // doError(req, res, session);
0436: return null;
0437: }
0438:
0439: // Get the Site - we could change the API call in the future to
0440: // pass site in, but that would break portals that extend Charon
0441: // so for now we simply look this up here.
0442: String siteId = placement.getSiteId();
0443: Site site = null;
0444: try {
0445: site = SiteService.getSiteVisit(siteId);
0446: } catch (IdUnusedException e) {
0447: site = null;
0448: } catch (PermissionException e) {
0449: site = null;
0450: }
0451:
0452: // FIXME: This does not look absolutely right,
0453: // this appears to say, reset all tools on the page since there
0454: // is no filtering of the tool that is bing reset, surely there
0455: // should be a check which tool is being reset, rather than all
0456: // tools on the page.
0457: // let the tool do some the work (include) (see note above)
0458:
0459: String toolUrl = ServerConfigurationService.getToolUrl() + "/"
0460: + Web.escapeUrl(placement.getId()) + "/";
0461: String titleString = Web.escapeHtml(placement.getTitle());
0462:
0463: // Reset the tool state if requested
0464: if ("true".equals(req.getParameter(portalService
0465: .getResetStateParam()))
0466: || "true".equals(portalService.getResetState())) {
0467: Session s = SessionManager.getCurrentSession();
0468: ToolSession ts = s.getToolSession(placement.getId());
0469: ts.clearAttributes();
0470: }
0471:
0472: // emit title information
0473:
0474: // for the reset button
0475: boolean showResetButton = !"false".equals(placement.getConfig()
0476: .getProperty(Portal.TOOLCONFIG_SHOW_RESET_BUTTON));
0477:
0478: String resetActionUrl = PortalStringUtil.replaceFirst(toolUrl,
0479: "/tool/", "/tool-reset/")
0480: + "?panel=Main";
0481:
0482: // Reset is different for Portlets
0483: if (isPortletPlacement(placement)) {
0484: resetActionUrl = Web.serverUrl(req)
0485: + ServerConfigurationService
0486: .getString("portalPath")
0487: + req.getPathInfo() + "?sakai.state.reset=true";
0488: }
0489:
0490: // for the help button
0491: // get the help document ID from the tool config (tool registration
0492: // usually).
0493: // The help document ID defaults to the tool ID
0494: boolean helpEnabledGlobally = ServerConfigurationService
0495: .getBoolean("display.help.icon", true);
0496: boolean helpEnabledInTool = !"false".equals(placement
0497: .getConfig().getProperty(
0498: Portal.TOOLCONFIG_SHOW_HELP_BUTTON));
0499: boolean showHelpButton = helpEnabledGlobally
0500: && helpEnabledInTool;
0501:
0502: String helpActionUrl = "";
0503: if (showHelpButton) {
0504: String helpDocUrl = placement.getConfig().getProperty(
0505: Portal.TOOLCONFIG_HELP_DOCUMENT_URL);
0506: String helpDocId = placement.getConfig().getProperty(
0507: Portal.TOOLCONFIG_HELP_DOCUMENT_ID);
0508: if (helpDocUrl != null && helpDocUrl.length() > 0) {
0509: helpActionUrl = helpDocUrl;
0510: } else {
0511: if (helpDocId == null || helpDocId.length() == 0) {
0512: helpDocId = tool.getId();
0513: }
0514: helpActionUrl = ServerConfigurationService
0515: .getHelpUrl(helpDocId);
0516: }
0517: }
0518:
0519: Map<String, Object> toolMap = new HashMap<String, Object>();
0520: RenderResult result = ToolRenderService.render(placement, req,
0521: res, getServletContext());
0522:
0523: if (result.getJSR168HelpUrl() != null) {
0524: toolMap.put("toolJSR168Help", Web.serverUrl(req)
0525: + result.getJSR168HelpUrl());
0526: }
0527:
0528: // Must have site.upd to see the Edit button
0529: if (result.getJSR168EditUrl() != null && site != null) {
0530: if (SecurityService.unlock(SiteService.SECURE_UPDATE_SITE,
0531: site.getReference())) {
0532: toolMap.put("toolJSR168Edit", Web.serverUrl(req)
0533: + result.getJSR168EditUrl());
0534: }
0535: }
0536:
0537: toolMap.put("toolRenderResult", result);
0538: toolMap.put("hasRenderResult", Boolean.valueOf(true));
0539: toolMap.put("toolUrl", toolUrl);
0540: if (isPortletPlacement(placement)) {
0541: toolMap.put("toolPlacementIDJS", "_self");
0542: } else {
0543: toolMap.put("toolPlacementIDJS", Web
0544: .escapeJavascript("Main" + placement.getId()));
0545: }
0546: toolMap.put("toolResetActionUrl", resetActionUrl);
0547: toolMap.put("toolTitle", titleString);
0548: toolMap.put("toolShowResetButton", Boolean
0549: .valueOf(showResetButton));
0550: toolMap.put("toolShowHelpButton", Boolean
0551: .valueOf(showHelpButton));
0552: toolMap.put("toolHelpActionUrl", helpActionUrl);
0553: return toolMap;
0554: }
0555:
0556: public List<Map> convertSitesToMaps(HttpServletRequest req,
0557: List mySites, String prefix, String currentSiteId,
0558: String myWorkspaceSiteId, boolean includeSummary,
0559: boolean expandSite, boolean resetTools, boolean doPages,
0560: String toolContextPath, boolean loggedIn) {
0561: List<Map> l = new ArrayList<Map>();
0562: boolean motdDone = false;
0563: for (Iterator i = mySites.iterator(); i.hasNext();) {
0564: Site s = (Site) i.next();
0565:
0566: // The first site is the current site
0567: if (currentSiteId == null)
0568: currentSiteId = s.getId();
0569:
0570: Map m = convertSiteToMap(req, s, prefix, currentSiteId,
0571: myWorkspaceSiteId, includeSummary, expandSite,
0572: resetTools, doPages, toolContextPath, loggedIn);
0573:
0574: if (includeSummary && m.get("rssDescription") == null) {
0575: if (!motdDone) {
0576: siteHelper.summarizeTool(m, s, "sakai.motd");
0577: motdDone = true;
0578: } else {
0579: siteHelper.summarizeTool(m, s,
0580: "sakai.announcements");
0581: }
0582:
0583: }
0584: l.add(m);
0585: }
0586: return l;
0587: }
0588:
0589: public Map convertSiteToMap(HttpServletRequest req, Site s,
0590: String prefix, String currentSiteId,
0591: String myWorkspaceSiteId, boolean includeSummary,
0592: boolean expandSite, boolean resetTools, boolean doPages,
0593: String toolContextPath, boolean loggedIn) {
0594: if (s == null)
0595: return null;
0596: Map<String, Object> m = new HashMap<String, Object>();
0597:
0598: // In case the effective is different than the actual site
0599: String effectiveSite = siteHelper.getSiteEffectiveId(s);
0600: m.put("isCurrentSite", Boolean.valueOf(currentSiteId != null
0601: && (s.getId().equals(currentSiteId) || effectiveSite
0602: .equals(currentSiteId))));
0603: m
0604: .put(
0605: "isMyWorkspace",
0606: Boolean
0607: .valueOf(myWorkspaceSiteId != null
0608: && (s.getId().equals(
0609: myWorkspaceSiteId) || effectiveSite
0610: .equals(myWorkspaceSiteId))));
0611: m.put("siteTitle", Web.escapeHtml(s.getTitle()));
0612: m.put("siteDescription", Web.escapeHtml(s.getDescription()));
0613: String siteUrl = Web.serverUrl(req)
0614: + ServerConfigurationService.getString("portalPath")
0615: + "/";
0616: if (prefix != null)
0617: siteUrl = siteUrl + prefix + "/";
0618: siteUrl = siteUrl
0619: + Web.escapeUrl(siteHelper.getSiteEffectiveId(s));
0620: m.put("siteUrl", siteUrl);
0621:
0622: if (includeSummary) {
0623: siteHelper.summarizeTool(m, s, "sakai.announce");
0624: }
0625: if (expandSite) {
0626: Map pageMap = pageListToMap(req, loggedIn, s, /* SitePage */
0627: null, toolContextPath, prefix, doPages, resetTools,
0628: includeSummary);
0629: m.put("sitePages", pageMap);
0630: }
0631:
0632: return m;
0633: }
0634:
0635: /**
0636: * Respond to navigation / access requests.
0637: *
0638: * @param req
0639: * The servlet request.
0640: * @param res
0641: * The servlet response.
0642: * @throws javax.servlet.ServletException.
0643: * @throws java.io.IOException.
0644: */
0645: protected void doGet(HttpServletRequest req, HttpServletResponse res)
0646: throws ServletException, IOException {
0647:
0648: int stat = PortalHandler.NEXT;
0649: try {
0650: basicAuth.doLogin(req);
0651: if (!ToolRenderService.preprocess(req, res,
0652: getServletContext())) {
0653: return;
0654: }
0655:
0656: // Check to see if the pre-process step has redirected us - if so,
0657: // our work is done here - we will likely come back again to finish
0658: // our
0659: // work.
0660: if (res.isCommitted()) {
0661: return;
0662: }
0663:
0664: // get the Sakai session
0665: Session session = SessionManager.getCurrentSession();
0666:
0667: // recognize what to do from the path
0668: String option = req.getPathInfo();
0669:
0670: // if missing, set it to home or gateway
0671: if ((option == null) || ("/".equals(option))) {
0672: if (session.getUserId() == null) {
0673: option = "/site/"
0674: + ServerConfigurationService
0675: .getGatewaySiteId();
0676: } else {
0677: option = "/site/"
0678: + SiteService.getUserSiteId(session
0679: .getUserId());
0680: }
0681: }
0682:
0683: // get the parts (the first will be "")
0684: String[] parts = option.split("/");
0685:
0686: Map<String, PortalHandler> handlerMap = portalService
0687: .getHandlerMap(this );
0688: PortalHandler ph = handlerMap.get(parts[1]);
0689: if (ph != null) {
0690: stat = ph.doGet(parts, req, res, session);
0691: if (res.isCommitted()) {
0692: if (stat != PortalHandler.RESET_DONE) {
0693: portalService.setResetState(null);
0694: }
0695: return;
0696: }
0697: }
0698: if (stat == PortalHandler.NEXT) {
0699:
0700: List<PortalHandler> urlHandlers;
0701: for (Iterator<PortalHandler> i = handlerMap.values()
0702: .iterator(); i.hasNext();) {
0703: ph = i.next();
0704: stat = ph.doGet(parts, req, res, session);
0705: if (res.isCommitted()) {
0706: if (stat != PortalHandler.RESET_DONE) {
0707: portalService.setResetState(null);
0708: }
0709: return;
0710: }
0711: // this should be
0712: if (stat != PortalHandler.NEXT) {
0713: break;
0714: }
0715: }
0716: }
0717: if (stat == PortalHandler.NEXT) {
0718: doError(req, res, session, Portal.ERROR_SITE);
0719: }
0720:
0721: } catch (Throwable t) {
0722: doThrowableError(req, res, t);
0723: }
0724:
0725: // Make sure to clear any reset State at the end of the request unless
0726: // we *just* set it
0727: if (stat != PortalHandler.RESET_DONE) {
0728: portalService.setResetState(null);
0729: }
0730: }
0731:
0732: public void doLogin(HttpServletRequest req,
0733: HttpServletResponse res, Session session,
0734: String returnPath, boolean skipContainer)
0735: throws ToolException {
0736: try {
0737: if (basicAuth.doAuth(req, res)) {
0738: // System.err.println("BASIC Auth Request Sent to the Browser
0739: // ");
0740: return;
0741: }
0742: } catch (IOException ioex) {
0743: throw new ToolException(ioex);
0744:
0745: }
0746:
0747: // setup for the helper if needed (Note: in session, not tool session,
0748: // special for Login helper)
0749: // Note: always set this if we are passed in a return path... a blank
0750: // return path is valid... to clean up from
0751: // possible abandened previous login attempt -ggolden
0752: if (returnPath != null) {
0753: // where to go after
0754: session.setAttribute(Tool.HELPER_DONE_URL, Web.returnUrl(
0755: req, returnPath));
0756: }
0757:
0758: ActiveTool tool = ActiveToolManager
0759: .getActiveTool("sakai.login");
0760:
0761: // to skip container auth for this one, forcing things to be handled
0762: // internaly, set the "extreme" login path
0763: String loginPath = (skipContainer ? "/xlogin" : "/relogin");
0764:
0765: String context = req.getContextPath() + req.getServletPath()
0766: + loginPath;
0767: tool.help(req, res, context, loginPath);
0768: }
0769:
0770: /**
0771: * Process a logout
0772: *
0773: * @param req
0774: * Request object
0775: * @param res
0776: * Response object
0777: * @param session
0778: * Current session
0779: * @param returnPath
0780: * if not null, the path to use for the end-user browser redirect
0781: * after the logout is complete. Leave null to use the configured
0782: * logged out URL.
0783: * @throws IOException
0784: */
0785: public void doLogout(HttpServletRequest req,
0786: HttpServletResponse res, Session session, String returnPath)
0787: throws ToolException {
0788: // where to go after
0789: if (returnPath == null) {
0790: // if no path, use the configured logged out URL
0791: String loggedOutUrl = ServerConfigurationService
0792: .getLoggedOutUrl();
0793: session.setAttribute(Tool.HELPER_DONE_URL, loggedOutUrl);
0794: } else {
0795: // if we have a path, use a return based on the request and this
0796: // path
0797: // Note: this is currently used only as "/gallery"
0798: // - we should really add a
0799: // ServerConfigurationService.getGalleryLoggedOutUrl()
0800: // and change the returnPath to a normal/gallery indicator -ggolden
0801: String loggedOutUrl = Web.returnUrl(req, returnPath);
0802: session.setAttribute(Tool.HELPER_DONE_URL, loggedOutUrl);
0803: }
0804:
0805: ActiveTool tool = ActiveToolManager
0806: .getActiveTool("sakai.login");
0807: String context = req.getContextPath() + req.getServletPath()
0808: + "/logout";
0809: tool.help(req, res, context, "/logout");
0810: }
0811:
0812: public PortalRenderContext startPageContext(String siteType,
0813: String title, String skin, HttpServletRequest request) {
0814: PortalRenderEngine rengine = portalService.getRenderEngine(
0815: portalContext, request);
0816: PortalRenderContext rcontext = rengine
0817: .newRenderContext(request);
0818:
0819: if (skin == null) {
0820: skin = ServerConfigurationService.getString("skin.default");
0821: }
0822: String skinRepo = ServerConfigurationService
0823: .getString("skin.repo");
0824:
0825: rcontext.put("pageSkinRepo", skinRepo);
0826: rcontext.put("pageSkin", skin);
0827: rcontext.put("pageTitle", Web.escapeHtml(title));
0828: rcontext.put("pageScriptPath", getScriptPath());
0829: rcontext.put("pageTop", Boolean.valueOf(true));
0830: rcontext.put("rloader", rloader);
0831: // rcontext.put("sitHelp", Web.escapeHtml(rb.getString("sit_help")));
0832: // rcontext.put("sitReset", Web.escapeHtml(rb.getString("sit_reset")));
0833:
0834: if (siteType != null && siteType.length() > 0) {
0835: siteType = "class=\"" + siteType + "\"";
0836: } else {
0837: siteType = "";
0838: }
0839: rcontext.put("pageSiteType", siteType);
0840: rcontext.put("toolParamResetState", portalService
0841: .getResetStateParam());
0842:
0843: return rcontext;
0844: }
0845:
0846: /**
0847: * Respond to data posting requests.
0848: *
0849: * @param req
0850: * The servlet request.
0851: * @param res
0852: * The servlet response.
0853: * @throws ServletException
0854: * @throws IOException
0855: */
0856: protected void doPost(HttpServletRequest req,
0857: HttpServletResponse res) throws ServletException,
0858: IOException {
0859: int stat = PortalHandler.NEXT;
0860: try {
0861: basicAuth.doLogin(req);
0862: if (!ToolRenderService.preprocess(req, res,
0863: getServletContext())) {
0864: // System.err.println("POST FAILED, REDIRECT ?");
0865: return;
0866: }
0867:
0868: // Check to see if the pre-process step has redirected us - if so,
0869: // our work is done here - we will likely come back again to finish
0870: // our
0871: // work. T
0872:
0873: if (res.isCommitted()) {
0874: return;
0875: }
0876:
0877: // get the Sakai session
0878: Session session = SessionManager.getCurrentSession();
0879:
0880: // recognize what to do from the path
0881: String option = req.getPathInfo();
0882:
0883: // if missing, we have a stray post
0884: if ((option == null) || ("/".equals(option))) {
0885: doError(req, res, session, ERROR_SITE);
0886: return;
0887: }
0888:
0889: // get the parts (the first will be "")
0890: String[] parts = option.split("/");
0891:
0892: Map<String, PortalHandler> handlerMap = portalService
0893: .getHandlerMap(this );
0894:
0895: PortalHandler ph = handlerMap.get(parts[1]);
0896: if (ph != null) {
0897: stat = ph.doPost(parts, req, res, session);
0898: if (res.isCommitted()) {
0899: return;
0900: }
0901: }
0902: if (stat == PortalHandler.NEXT) {
0903:
0904: List<PortalHandler> urlHandlers;
0905: for (Iterator<PortalHandler> i = handlerMap.values()
0906: .iterator(); i.hasNext();) {
0907: ph = i.next();
0908: stat = ph.doPost(parts, req, res, session);
0909: if (res.isCommitted()) {
0910: return;
0911: }
0912: // this should be
0913: if (stat != PortalHandler.NEXT) {
0914: break;
0915: }
0916:
0917: }
0918: }
0919: if (stat == PortalHandler.NEXT) {
0920: doError(req, res, session, Portal.ERROR_SITE);
0921: }
0922:
0923: } catch (Throwable t) {
0924: doThrowableError(req, res, t);
0925: }
0926: }
0927:
0928: /*
0929: * Checks to see which form of tool or page placement we have. The normal
0930: * placement is a GUID. However when the parameter sakai.site is added to
0931: * the request, the placement can be of the form sakai.resources. This
0932: * routine determines which form of the placement id, and if this is the
0933: * second type, performs the lookup and returns the GUID of the placement.
0934: * If we cannot resolve the placement, we simply return the passed in
0935: * placement ID. If we cannot visit the site, we send the user to login
0936: * processing and return null to the caller.
0937: */
0938:
0939: public String getPlacement(HttpServletRequest req,
0940: HttpServletResponse res, Session session,
0941: String placementId, boolean doPage) throws ToolException {
0942: String siteId = req.getParameter(PARAM_SAKAI_SITE);
0943: if (siteId == null)
0944: return placementId; // Standard placement
0945:
0946: // find the site, for visiting
0947: // Sites like the !gateway site allow visits by anonymous
0948: Site site = null;
0949: try {
0950: site = SiteService.getSiteVisit(siteId);
0951: } catch (IdUnusedException e) {
0952: return placementId; // cannot resolve placement
0953: } catch (PermissionException e) {
0954: // If we are not logged in, try again after we log in, otherwise
0955: // punt
0956: if (session.getUserId() == null) {
0957: doLogin(req, res, session, req.getPathInfo()
0958: + "?sakai.site=" + res.encodeURL(siteId), false);
0959: return null;
0960: }
0961: return placementId; // cannot resolve placement
0962: }
0963:
0964: if (site == null)
0965: return placementId;
0966: ToolConfiguration toolConfig = site
0967: .getToolForCommonId(placementId);
0968: if (toolConfig == null)
0969: return placementId;
0970:
0971: if (doPage) {
0972: return toolConfig.getPageId();
0973: } else {
0974: return toolConfig.getId();
0975: }
0976:
0977: }
0978:
0979: public void setupForward(HttpServletRequest req,
0980: HttpServletResponse res, Placement p, String skin)
0981: throws ToolException {
0982: // setup html information that the tool might need (skin, body on load,
0983: // js includes, etc).
0984: if (skin == null || skin.length() == 0)
0985: skin = ServerConfigurationService.getString("skin.default");
0986: String skinRepo = ServerConfigurationService
0987: .getString("skin.repo");
0988: String headCssToolBase = "<link href=\""
0989: + skinRepo
0990: + "/tool_base.css\" type=\"text/css\" rel=\"stylesheet\" media=\"all\" />\n";
0991: String headCssToolSkin = "<link href=\""
0992: + skinRepo
0993: + "/"
0994: + skin
0995: + "/tool.css\" type=\"text/css\" rel=\"stylesheet\" media=\"all\" />\n";
0996: String headCss = headCssToolBase + headCssToolSkin;
0997: String headJs = "<script type=\"text/javascript\" language=\"JavaScript\" src=\"/library/js/headscripts.js\"></script>\n";
0998: String head = headCss + headJs;
0999: StringBuilder bodyonload = new StringBuilder();
1000: if (p != null) {
1001: String element = Web.escapeJavascript("Main" + p.getId());
1002: bodyonload.append("setMainFrameHeight('" + element + "');");
1003: }
1004: bodyonload.append("setFocus(focus_path);");
1005:
1006: // to force all non-legacy tools to use the standard css
1007: // to help in transition (needs corresponding entry in properties)
1008: // if
1009: // ("true".equals(ServerConfigurationService.getString("skin.force")))
1010: // {
1011: // headJs = headJs + headCss;
1012: // }
1013:
1014: req.setAttribute("sakai.html.head", head);
1015: req.setAttribute("sakai.html.head.css", headCss);
1016: req.setAttribute("sakai.html.head.css.base", headCssToolBase);
1017: req.setAttribute("sakai.html.head.css.skin", headCssToolSkin);
1018: req.setAttribute("sakai.html.head.js", headJs);
1019: req.setAttribute("sakai.html.body.onload", bodyonload
1020: .toString());
1021:
1022: portalService.getRenderEngine(portalContext, req).setupForward(
1023: req, res, p, skin);
1024: }
1025:
1026: /**
1027: * Forward to the tool - but first setup JavaScript/CSS etc that the tool
1028: * will render
1029: */
1030: public void forwardTool(ActiveTool tool, HttpServletRequest req,
1031: HttpServletResponse res, Placement p, String skin,
1032: String toolContextPath, String toolPathInfo)
1033: throws ToolException {
1034:
1035: // if there is a stored request state, and path, extract that from the
1036: // session and reinstance it
1037:
1038: // let the tool do the the work (forward)
1039: if (enableDirect) {
1040: StoredState ss = portalService.getStoredState();
1041: if (ss == null
1042: || !toolContextPath.equals(ss.getToolContextPath())) {
1043: setupForward(req, res, p, skin);
1044: req.setAttribute(ToolURL.MANAGER,
1045: new ToolURLManagerImpl(res));
1046: tool
1047: .forward(req, res, p, toolContextPath,
1048: toolPathInfo);
1049: } else {
1050: M_log.debug("Restoring StoredState [" + ss + "]");
1051: HttpServletRequest sreq = ss.getRequest(req);
1052: Placement splacement = ss.getPlacement();
1053: String stoolContext = ss.getToolContextPath();
1054: String stoolPathInfo = ss.getToolPathInfo();
1055: ActiveTool stool = ActiveToolManager.getActiveTool(p
1056: .getToolId());
1057: String sskin = ss.getSkin();
1058: setupForward(sreq, res, splacement, sskin);
1059: req.setAttribute(ToolURL.MANAGER,
1060: new ToolURLManagerImpl(res));
1061: stool.forward(sreq, res, splacement, stoolContext,
1062: stoolPathInfo);
1063: // this is correct as we have checked the context path of the
1064: // tool
1065: portalService.setStoredState(null);
1066: }
1067: } else {
1068: setupForward(req, res, p, skin);
1069: req.setAttribute(ToolURL.MANAGER, new ToolURLManagerImpl(
1070: res));
1071: tool.forward(req, res, p, toolContextPath, toolPathInfo);
1072: }
1073:
1074: }
1075:
1076: public void forwardPortal(ActiveTool tool, HttpServletRequest req,
1077: HttpServletResponse res, ToolConfiguration p, String skin,
1078: String toolContextPath, String toolPathInfo)
1079: throws ToolException, IOException {
1080:
1081: // if there is a stored request state, and path, extract that from the
1082: // session and reinstance it
1083:
1084: // generate the forward to the tool page placement
1085: String portalPlacementUrl = "/portal" + getPortalPageUrl(p);
1086: res.sendRedirect(portalPlacementUrl);
1087: return;
1088:
1089: }
1090:
1091: public String getPortalPageUrl(ToolConfiguration p) {
1092: return "/site/" + p.getSiteId() + "/page/" + p.getPageId();
1093: }
1094:
1095: protected String getScriptPath() {
1096: return "/library/js/";
1097: }
1098:
1099: /**
1100: * Access the Servlet's information display.
1101: *
1102: * @return servlet information.
1103: */
1104: public String getServletInfo() {
1105: return "Sakai Charon Portal";
1106: }
1107:
1108: public void includeBottom(PortalRenderContext rcontext) {
1109: if (rcontext.uses(INCLUDE_BOTTOM)) {
1110: String copyright = ServerConfigurationService
1111: .getString("bottom.copyrighttext");
1112: String service = ServerConfigurationService.getString(
1113: "ui.service", "Sakai");
1114: String serviceVersion = ServerConfigurationService
1115: .getString("version.service", "?");
1116: String sakaiVersion = ServerConfigurationService.getString(
1117: "version.sakai", "?");
1118: String server = ServerConfigurationService.getServerId();
1119: String[] bottomNav = ServerConfigurationService
1120: .getStrings("bottomnav");
1121: String[] poweredByUrl = ServerConfigurationService
1122: .getStrings("powered.url");
1123: String[] poweredByImage = ServerConfigurationService
1124: .getStrings("powered.img");
1125: String[] poweredByAltText = ServerConfigurationService
1126: .getStrings("powered.alt");
1127:
1128: {
1129: List<Object> l = new ArrayList<Object>();
1130: if ((bottomNav != null) && (bottomNav.length > 0)) {
1131: for (int i = 0; i < bottomNav.length; i++) {
1132: l.add(bottomNav[i]);
1133: }
1134: }
1135: rcontext.put("bottomNav", l);
1136: }
1137:
1138: // rcontext.put("bottomNavSitNewWindow",
1139: // Web.escapeHtml(rb.getString("site_newwindow")));
1140:
1141: if ((poweredByUrl != null) && (poweredByImage != null)
1142: && (poweredByAltText != null)
1143: && (poweredByUrl.length == poweredByImage.length)
1144: && (poweredByUrl.length == poweredByAltText.length)) {
1145: {
1146: List<Object> l = new ArrayList<Object>();
1147: for (int i = 0; i < poweredByUrl.length; i++) {
1148: Map<String, Object> m = new HashMap<String, Object>();
1149: m.put("poweredByUrl", poweredByUrl[i]);
1150: m.put("poweredByImage", poweredByImage[i]);
1151: m.put("poweredByAltText", poweredByAltText[i]);
1152: l.add(m);
1153: }
1154: rcontext.put("bottomNavPoweredBy", l);
1155:
1156: }
1157: } else {
1158: List<Object> l = new ArrayList<Object>();
1159: Map<String, Object> m = new HashMap<String, Object>();
1160: m.put("poweredByUrl", "http://sakaiproject.org");
1161: m.put("poweredByImage",
1162: "/library/image/sakai_powered.gif");
1163: m.put("poweredByAltText", "Powered by Sakai");
1164: l.add(m);
1165: rcontext.put("bottomNavPoweredBy", l);
1166: }
1167:
1168: rcontext.put("bottomNavService", service);
1169: rcontext.put("bottomNavCopyright", copyright);
1170: rcontext.put("bottomNavServiceVersion", serviceVersion);
1171: rcontext.put("bottomNavSakaiVersion", sakaiVersion);
1172: rcontext.put("bottomNavServer", server);
1173: }
1174: }
1175:
1176: public void includeLogin(PortalRenderContext rcontext,
1177: HttpServletRequest req, Session session) {
1178: if (rcontext.uses(INCLUDE_LOGIN)) {
1179:
1180: // for the main login/out link
1181: String logInOutUrl = Web.serverUrl(req);
1182: String message = null;
1183: String image1 = null;
1184:
1185: // for a possible second link
1186: String logInOutUrl2 = null;
1187: String message2 = null;
1188: String image2 = null;
1189:
1190: // check for the top.login (where the login fields are present
1191: // instead
1192: // of a login link, but ignore it if container.login is set
1193: boolean topLogin = Boolean.TRUE.toString()
1194: .equalsIgnoreCase(
1195: ServerConfigurationService
1196: .getString("top.login"));
1197: boolean containerLogin = Boolean.TRUE.toString()
1198: .equalsIgnoreCase(
1199: ServerConfigurationService
1200: .getString("container.login"));
1201: if (containerLogin)
1202: topLogin = false;
1203:
1204: // if not logged in they get login
1205: if (session.getUserId() == null) {
1206: // we don't need any of this if we are doing top login
1207: if (!topLogin) {
1208: logInOutUrl += ServerConfigurationService
1209: .getString("portalPath")
1210: + "/login";
1211:
1212: // let the login url be overridden by configuration
1213: String overrideLoginUrl = StringUtil
1214: .trimToNull(ServerConfigurationService
1215: .getString("login.url"));
1216: if (overrideLoginUrl != null)
1217: logInOutUrl = overrideLoginUrl;
1218:
1219: // check for a login text override
1220: message = StringUtil
1221: .trimToNull(ServerConfigurationService
1222: .getString("login.text"));
1223: if (message == null)
1224: message = rloader.getString("log.login");
1225:
1226: // check for an image for the login
1227: image1 = StringUtil
1228: .trimToNull(ServerConfigurationService
1229: .getString("login.icon"));
1230:
1231: // check for a possible second, xlogin link
1232: if (Boolean.TRUE.toString().equalsIgnoreCase(
1233: ServerConfigurationService
1234: .getString("xlogin.enabled"))) {
1235: // get the text and image as configured
1236: message2 = StringUtil
1237: .trimToNull(ServerConfigurationService
1238: .getString("xlogin.text"));
1239: image2 = StringUtil
1240: .trimToNull(ServerConfigurationService
1241: .getString("xlogin.icon"));
1242: logInOutUrl2 = ServerConfigurationService
1243: .getString("portalPath")
1244: + "/xlogin";
1245: }
1246: }
1247: }
1248:
1249: // if logged in they get logout
1250: else {
1251: logInOutUrl += ServerConfigurationService
1252: .getString("portalPath")
1253: + "/logout";
1254:
1255: // check for a logout text override
1256: message = StringUtil
1257: .trimToNull(ServerConfigurationService
1258: .getString("logout.text"));
1259: if (message == null)
1260: message = rloader.getString("sit_log");
1261:
1262: // check for an image for the logout
1263: image1 = StringUtil
1264: .trimToNull(ServerConfigurationService
1265: .getString("logout.icon"));
1266:
1267: // since we are doing logout, cancel top.login
1268: topLogin = false;
1269: }
1270: rcontext.put("loginTopLogin", Boolean.valueOf(topLogin));
1271:
1272: if (!topLogin) {
1273:
1274: rcontext.put("loginLogInOutUrl", logInOutUrl);
1275: rcontext.put("loginMessage", message);
1276: rcontext.put("loginImage1", image1);
1277: rcontext.put("image1HasImage1", Boolean
1278: .valueOf(image1 != null));
1279: rcontext.put("loginLogInOutUrl2", logInOutUrl2);
1280: rcontext.put("loginHasLogInOutUrl2", Boolean
1281: .valueOf(logInOutUrl2 != null));
1282: rcontext.put("loginMessage2", message2);
1283: rcontext.put("loginImage2", image2);
1284: rcontext.put("image1HasImage2", Boolean
1285: .valueOf(image2 != null));
1286: // put out the links version
1287:
1288: // else put out the fields that will send to the login interface
1289: } else {
1290: // find the login tool
1291: Tool loginTool = ToolManager.getTool("sakai.login");
1292: String eidWording = null;
1293: String pwWording = null;
1294: eidWording = StringUtil.trimToNull(rloader
1295: .getString("log.userid"));
1296: pwWording = StringUtil.trimToNull(rloader
1297: .getString("log.pass"));
1298:
1299: if (eidWording == null)
1300: eidWording = "eid";
1301: if (pwWording == null)
1302: pwWording = "pw";
1303: String loginWording = rloader.getString("log.login");
1304:
1305: rcontext.put("loginPortalPath",
1306: ServerConfigurationService
1307: .getString("portalPath"));
1308: rcontext.put("loginEidWording", eidWording);
1309: rcontext.put("loginPwWording", pwWording);
1310: rcontext.put("loginWording", loginWording);
1311:
1312: // setup for the redirect after login
1313: session.setAttribute(Tool.HELPER_DONE_URL,
1314: ServerConfigurationService.getPortalUrl());
1315: }
1316: }
1317: }
1318:
1319: // TODO: Refactor code in other functions to use this code rather than doing
1320: // it inline
1321: /*
1322: * Produce a page and/or a tool list doPage = true is best for the
1323: * tabs-based portal and for RSS - these think in terms of pages doPage =
1324: * false is best for the portlet-style - it unrolls all of the tools unless
1325: * a page is marked as a popup. If the page is a popup - it is left a page
1326: * and marked as such. restTools = true - generate resetting tool URLs.
1327: */
1328:
1329: protected Map pageListToMap(HttpServletRequest req,
1330: boolean loggedIn, Site site, SitePage page,
1331: String toolContextPath, String portalPrefix,
1332: boolean doPages, boolean resetTools, boolean includeSummary) {
1333:
1334: Map<String, Object> theMap = new HashMap<String, Object>();
1335:
1336: String pageUrl = Web.returnUrl(req, "/" + portalPrefix + "/"
1337: + Web.escapeUrl(siteHelper.getSiteEffectiveId(site))
1338: + "/page/");
1339: String toolUrl = Web.returnUrl(req, "/" + portalPrefix + "/"
1340: + Web.escapeUrl(siteHelper.getSiteEffectiveId(site)));
1341: if (resetTools) {
1342: toolUrl = toolUrl + "/tool-reset/";
1343: } else {
1344: toolUrl = toolUrl + "/tool/";
1345: }
1346:
1347: String pagePopupUrl = Web.returnUrl(req, "/page/");
1348: boolean showHelp = ServerConfigurationService.getBoolean(
1349: "display.help.menu", true);
1350: String iconUrl = site.getIconUrlFull();
1351: boolean published = site.isPublished();
1352: String type = site.getType();
1353:
1354: theMap.put("pageNavPublished", Boolean.valueOf(published));
1355: theMap.put("pageNavType", type);
1356: theMap.put("pageNavIconUrl", iconUrl);
1357: // theMap.put("pageNavSitToolsHead",
1358: // Web.escapeHtml(rb.getString("sit_toolshead")));
1359:
1360: // order the pages based on their tools and the tool order for the
1361: // site type
1362: // List pages = site.getOrderedPages();
1363: List pages = siteHelper.getPermittedPagesInOrder(site);
1364:
1365: List<Map> l = new ArrayList<Map>();
1366:
1367: for (Iterator i = pages.iterator(); i.hasNext();) {
1368:
1369: SitePage p = (SitePage) i.next();
1370: // check if current user has permission to see page
1371: // we will draw page button if it have permission to see at least
1372: List pTools = p.getTools();
1373: String toolsOnPage = null;
1374:
1375: boolean current = (page != null
1376: && p.getId().equals(page.getId()) && !p.isPopUp());
1377: String pagerefUrl = pageUrl + Web.escapeUrl(p.getId());
1378:
1379: if (doPages || p.isPopUp()) {
1380: Map<String, Object> m = new HashMap<String, Object>();
1381: m.put("isPage", Boolean.valueOf(true));
1382: m.put("current", Boolean.valueOf(current));
1383: m.put("ispopup", Boolean.valueOf(p.isPopUp()));
1384: m.put("pagePopupUrl", pagePopupUrl);
1385: m.put("pageTitle", Web.escapeHtml(p.getTitle()));
1386: m
1387: .put("jsPageTitle", Web.escapeJavascript(p
1388: .getTitle()));
1389: m.put("pageId", Web.escapeUrl(p.getId()));
1390: m.put("jsPageId", Web.escapeJavascript(p.getId()));
1391: m.put("pageRefUrl", pagerefUrl);
1392: if (toolsOnPage != null)
1393: m.put("toolsOnPage", toolsOnPage);
1394: if (includeSummary)
1395: siteHelper.summarizePage(m, site, p);
1396: l.add(m);
1397: continue;
1398: }
1399:
1400: // Loop through the tools again and Unroll the tools
1401: Iterator iPt = pTools.iterator();
1402:
1403: while (iPt.hasNext()) {
1404: ToolConfiguration placement = (ToolConfiguration) iPt
1405: .next();
1406:
1407: String toolrefUrl = toolUrl
1408: + Web.escapeUrl(placement.getId());
1409:
1410: Map<String, Object> m = new HashMap<String, Object>();
1411: m.put("isPage", Boolean.valueOf(false));
1412: m.put("toolId", Web.escapeUrl(placement.getId()));
1413: m.put("jsToolId", Web.escapeJavascript(placement
1414: .getId()));
1415: m.put("toolRegistryId", placement.getToolId());
1416: m
1417: .put("toolTitle", Web.escapeHtml(placement
1418: .getTitle()));
1419: m.put("jsToolTitle", Web.escapeJavascript(placement
1420: .getTitle()));
1421: m.put("toolrefUrl", toolrefUrl);
1422: l.add(m);
1423: }
1424:
1425: }
1426: theMap.put("pageNavTools", l);
1427:
1428: String helpUrl = ServerConfigurationService.getHelpUrl(null);
1429: theMap.put("pageNavShowHelp", Boolean.valueOf(showHelp));
1430: theMap.put("pageNavHelpUrl", helpUrl);
1431:
1432: // theMap.put("pageNavSitContentshead",
1433: // Web.escapeHtml(rb.getString("sit_contentshead")));
1434:
1435: // Handle Presense
1436: boolean showPresence = ServerConfigurationService.getBoolean(
1437: "display.users.present", true);
1438: String presenceUrl = Web.returnUrl(req, "/presence/"
1439: + Web.escapeUrl(site.getId()));
1440:
1441: // theMap.put("pageNavSitPresenceTitle",
1442: // Web.escapeHtml(rb.getString("sit_presencetitle")));
1443: // theMap.put("pageNavSitPresenceFrameTitle",
1444: // Web.escapeHtml(rb.getString("sit_presenceiframetit")));
1445: theMap.put("pageNavShowPresenceLoggedIn", Boolean
1446: .valueOf(showPresence && loggedIn));
1447: theMap.put("pageNavPresenceUrl", presenceUrl);
1448:
1449: return theMap;
1450: }
1451:
1452: public void includeWorksite(PortalRenderContext rcontext,
1453: HttpServletResponse res, HttpServletRequest req,
1454: Session session, Site site, SitePage page,
1455: String toolContextPath, String portalPrefix)
1456: throws IOException {
1457: worksiteHandler.includeWorksite(rcontext, res, req, session,
1458: site, page, toolContextPath, portalPrefix);
1459: }
1460:
1461: /**
1462: * Initialize the servlet.
1463: *
1464: * @param config
1465: * The servlet config.
1466: * @throws ServletException
1467: */
1468: public void init(ServletConfig config) throws ServletException {
1469: super .init(config);
1470:
1471: portalContext = config.getInitParameter("portal.context");
1472: if (portalContext == null || portalContext.length() == 0) {
1473: portalContext = DEFAULT_PORTAL_CONTEXT;
1474: }
1475: portalService = org.sakaiproject.portal.api.cover.PortalService
1476: .getInstance();
1477: M_log.info("init()");
1478:
1479: basicAuth = new BasicAuth();
1480: basicAuth.init();
1481:
1482: enableDirect = portalService.isEnableDirect();
1483: // do this before adding handlers to prevent handlers registering 2
1484: // times.
1485: // if the handlers were already there they will be re-registered,
1486: // but when they are added again, they will be replaced.
1487: // warning messages will appear, but the end state will be the same.
1488: portalService.addPortal(this );
1489:
1490: galleryHandler = new GalleryHandler();
1491: worksiteHandler = new WorksiteHandler();
1492: siteHandler = new SiteHandler();
1493:
1494: addHandler(siteHandler);
1495: addHandler(new SiteResetHandler());
1496:
1497: addHandler(new ToolHandler());
1498: addHandler(new ToolResetHandler());
1499: addHandler(new PageHandler());
1500: addHandler(worksiteHandler);
1501: addHandler(new WorksiteResetHandler());
1502: addHandler(new RssHandler());
1503: addHandler(new PDAHandler());
1504: addHandler(new AtomHandler());
1505: addHandler(new OpmlHandler());
1506: addHandler(galleryHandler);
1507: addHandler(new GalleryResetHandler());
1508: addHandler(new NavLoginHandler());
1509: addHandler(new NavLoginGalleryHandler());
1510: addHandler(new PresenceHandler());
1511: addHandler(new HelpHandler());
1512: addHandler(new ReLoginHandler());
1513: addHandler(new LoginHandler());
1514: addHandler(new XLoginHandler());
1515: addHandler(new LoginGalleryHandler());
1516: addHandler(new LogoutHandler());
1517: addHandler(new LogoutGalleryHandler());
1518: addHandler(new ErrorDoneHandler());
1519: addHandler(new ErrorReportHandler());
1520: addHandler(new StaticStylesHandler());
1521: addHandler(new StaticScriptsHandler());
1522: addHandler(new DirectToolHandler());
1523:
1524: }
1525:
1526: /**
1527: * Register a handler for a URL stub
1528: *
1529: * @param handler
1530: */
1531: private void addHandler(PortalHandler handler) {
1532: portalService.addHandler(this , handler);
1533: }
1534:
1535: private void removeHandler(String urlFragment) {
1536: portalService.removeHandler(this , urlFragment);
1537: }
1538:
1539: /**
1540: * Send the POST request to login
1541: *
1542: * @param req
1543: * @param res
1544: * @param session
1545: * @throws IOException
1546: */
1547: protected void postLogin(HttpServletRequest req,
1548: HttpServletResponse res, Session session, String loginPath)
1549: throws ToolException {
1550: ActiveTool tool = ActiveToolManager
1551: .getActiveTool("sakai.login");
1552: String context = req.getContextPath() + req.getServletPath()
1553: + "/" + loginPath;
1554: tool.help(req, res, context, "/" + loginPath);
1555: }
1556:
1557: /**
1558: * Output some session information
1559: *
1560: * @param rcontext
1561: * The print writer
1562: * @param html
1563: * If true, output in HTML, else in text.
1564: */
1565: protected void showSession(PortalRenderContext rcontext,
1566: boolean html) {
1567: // get the current user session information
1568: Session s = SessionManager.getCurrentSession();
1569: rcontext.put("sessionSession", s);
1570: ToolSession ts = SessionManager.getCurrentToolSession();
1571: rcontext.put("sessionToolSession", ts);
1572: }
1573:
1574: public void sendResponse(PortalRenderContext rcontext,
1575: HttpServletResponse res, String template, String contentType)
1576: throws IOException {
1577: // headers
1578: if (contentType == null) {
1579: res.setContentType("text/html; charset=UTF-8");
1580: } else {
1581: res.setContentType(contentType);
1582: }
1583: res.addDateHeader("Expires", System.currentTimeMillis()
1584: - (1000L * 60L * 60L * 24L * 365L));
1585: res.addDateHeader("Last-Modified", System.currentTimeMillis());
1586: res
1587: .addHeader("Cache-Control",
1588: "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0");
1589: res.addHeader("Pragma", "no-cache");
1590:
1591: // get the writer
1592: PrintWriter out = res.getWriter();
1593:
1594: try {
1595: PortalRenderEngine rengine = rcontext.getRenderEngine();
1596: rengine.render(template, rcontext, out);
1597: } catch (Exception e) {
1598: throw new RuntimeException("Failed to render template ", e);
1599: }
1600:
1601: }
1602:
1603: /**
1604: * Returns the type ("course", "project", "workspace", "mySpecialSiteType",
1605: * etc) of the given site; special handling of returning "workspace" for
1606: * user workspace sites. This method is tightly coupled to site skinning.
1607: */
1608: public String calcSiteType(String siteId) {
1609: String siteType = null;
1610: if (siteId != null && siteId.length() != 0) {
1611: if (SiteService.isUserSite(siteId)) {
1612: siteType = "workspace";
1613: } else {
1614: try {
1615: siteType = SiteService.getSite(siteId).getType();
1616: } catch (IdUnusedException ex) {
1617: // ignore, the site wasn't found
1618: }
1619: }
1620: }
1621:
1622: if (siteType != null && siteType.trim().length() == 0)
1623: siteType = null;
1624: return siteType;
1625: }
1626:
1627: private void logXEntry() {
1628: Exception e = new Exception();
1629: StackTraceElement se = e.getStackTrace()[1];
1630: M_log.info("Log marker " + se.getMethodName() + ":"
1631: + se.getFileName() + ":" + se.getLineNumber());
1632: }
1633:
1634: /**
1635: * Check for any just expired sessions and redirect
1636: *
1637: * @return true if we redirected, false if not
1638: */
1639: public boolean redirectIfLoggedOut(HttpServletResponse res)
1640: throws IOException {
1641: // if we are in a newly created session where we had an invalid
1642: // (presumed timed out) session in the request,
1643: // send script to cause a sakai top level redirect
1644: if (ThreadLocalManager
1645: .get(SessionManager.CURRENT_INVALID_SESSION) != null) {
1646: String loggedOutUrl = ServerConfigurationService
1647: .getLoggedOutUrl();
1648: sendPortalRedirect(res, loggedOutUrl);
1649: return true;
1650: }
1651:
1652: return false;
1653: }
1654:
1655: /**
1656: * Send a redirect so our Portal window ends up at the url, via javascript.
1657: *
1658: * @param url
1659: * The redirect url
1660: */
1661: protected void sendPortalRedirect(HttpServletResponse res,
1662: String url) throws IOException {
1663: PortalRenderContext rcontext = startPageContext("", null, null,
1664: null);
1665: rcontext.put("redirectUrl", url);
1666: sendResponse(rcontext, res, "portal-redirect", null);
1667: }
1668:
1669: /**
1670: * Compute the string that will identify the user site for this user - use
1671: * the EID if possible
1672: *
1673: * @param userId
1674: * The user id
1675: * @return The site "ID" but based on the user EID
1676: */
1677: public String getUserEidBasedSiteId(String userId) {
1678: try {
1679: // use the user EID
1680: String eid = UserDirectoryService.getUserEid(userId);
1681: return SiteService.getUserSiteId(eid);
1682: } catch (UserNotDefinedException e) {
1683: M_log
1684: .warn("getUserEidBasedSiteId: user id not found for eid: "
1685: + userId);
1686: return SiteService.getUserSiteId(userId);
1687: }
1688: }
1689:
1690: }
|