001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/portal/tags/sakai_2-4-1/portal-impl/impl/src/java/org/sakaiproject/portal/charon/handlers/SiteHandler.java $
003: * $Id: SiteHandler.java 29144 2007-04-19 01:13:03Z ajpoland@iupui.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2003, 2004, 2005, 2006, 2007 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.portal.charon.handlers;
021:
022: import java.io.IOException;
023: import java.util.ArrayList;
024: import java.util.List;
025: import java.util.Map;
026:
027: import javax.servlet.http.HttpServletRequest;
028: import javax.servlet.http.HttpServletResponse;
029:
030: import org.apache.commons.logging.Log;
031: import org.apache.commons.logging.LogFactory;
032: import org.sakaiproject.component.cover.ServerConfigurationService;
033: import org.sakaiproject.entity.api.ResourceProperties;
034: import org.sakaiproject.exception.IdUnusedException;
035: import org.sakaiproject.exception.PermissionException;
036: import org.sakaiproject.portal.api.Portal;
037: import org.sakaiproject.portal.api.PortalHandlerException;
038: import org.sakaiproject.portal.api.PortalRenderContext;
039: import org.sakaiproject.portal.api.StoredState;
040: import org.sakaiproject.portal.util.PortalSiteHelper;
041: import org.sakaiproject.site.api.Site;
042: import org.sakaiproject.site.api.SitePage;
043: import org.sakaiproject.site.cover.SiteService;
044: import org.sakaiproject.tool.api.Session;
045: import org.sakaiproject.tool.api.ToolException;
046: import org.sakaiproject.user.api.Preferences;
047: import org.sakaiproject.user.api.UserNotDefinedException;
048: import org.sakaiproject.user.cover.PreferencesService;
049: import org.sakaiproject.user.cover.UserDirectoryService;
050: import org.sakaiproject.util.Web;
051:
052: /**
053: *
054: * @author ieb
055: * @since Sakai 2.4
056: * @version $Rev: 29144 $
057: *
058: */
059: public class SiteHandler extends WorksiteHandler {
060:
061: private static final String INCLUDE_SITE_NAV = "include-site-nav";
062:
063: private static final String INCLUDE_LOGO = "include-logo";
064:
065: private static final String INCLUDE_TABS = "include-tabs";
066:
067: private static final Log log = LogFactory.getLog(SiteHandler.class);
068:
069: private PortalSiteHelper siteHelper = new PortalSiteHelper();
070:
071: public SiteHandler() {
072: urlFragment = "site";
073: }
074:
075: @Override
076: public int doGet(String[] parts, HttpServletRequest req,
077: HttpServletResponse res, Session session)
078: throws PortalHandlerException {
079: if ((parts.length >= 2) && (parts[1].equals("site"))) {
080: try {
081: // recognize an optional page/pageid
082: String pageId = null;
083: if ((parts.length == 5) && (parts[3].equals("page"))) {
084: pageId = parts[4];
085: }
086:
087: // site might be specified
088: String siteId = null;
089: if (parts.length >= 3) {
090: siteId = parts[2];
091: }
092:
093: doSite(req, res, session, siteId, pageId, req
094: .getContextPath()
095: + req.getServletPath());
096: return END;
097: } catch (Exception ex) {
098: throw new PortalHandlerException(ex);
099: }
100: } else {
101: return NEXT;
102: }
103: }
104:
105: public void doSite(HttpServletRequest req, HttpServletResponse res,
106: Session session, String siteId, String pageId,
107: String toolContextPath) throws ToolException, IOException {
108: // default site if not set
109: if (siteId == null) {
110: if (session.getUserId() == null) {
111: siteId = ServerConfigurationService.getGatewaySiteId();
112: } else {
113: siteId = SiteService.getUserSiteId(session.getUserId());
114: }
115: }
116:
117: // if no page id, see if there was a last page visited for this site
118: if (pageId == null) {
119: pageId = (String) session
120: .getAttribute(Portal.ATTR_SITE_PAGE + siteId);
121: }
122:
123: // find the site, for visiting
124: Site site = null;
125: try {
126: site = siteHelper.getSiteVisit(siteId);
127: } catch (IdUnusedException e) {
128: portal.doError(req, res, session, Portal.ERROR_SITE);
129: return;
130: } catch (PermissionException e) {
131: // if not logged in, give them a chance
132: if (session.getUserId() == null) {
133: StoredState ss = portalService.newStoredState(
134: "directtool", "tool");
135: ss.setRequest(req);
136: ss.setToolContextPath(toolContextPath);
137: portalService.setStoredState(ss);
138: portal.doLogin(req, res, session, req.getPathInfo(),
139: false);
140: } else {
141: portal.doError(req, res, session, Portal.ERROR_SITE);
142: }
143: return;
144: }
145:
146: // find the page, or use the first page if pageId not found
147: SitePage page = site.getPage(pageId);
148: if (page == null) {
149: // List pages = site.getOrderedPages();
150: List pages = siteHelper.getPermittedPagesInOrder(site);
151: if (!pages.isEmpty()) {
152: page = (SitePage) pages.get(0);
153: }
154: }
155: if (page == null) {
156: portal.doError(req, res, session, Portal.ERROR_SITE);
157: return;
158: }
159:
160: // store the last page visited
161: session.setAttribute(Portal.ATTR_SITE_PAGE + siteId, page
162: .getId());
163:
164: // form a context sensitive title
165: String title = ServerConfigurationService
166: .getString("ui.service")
167: + " : " + site.getTitle() + " : " + page.getTitle();
168:
169: // start the response
170: String siteType = portal.calcSiteType(siteId);
171: PortalRenderContext rcontext = portal.startPageContext(
172: siteType, title, site.getSkin(), req);
173:
174: // the 'full' top area
175: includeSiteNav(rcontext, req, session, siteId);
176:
177: includeWorksite(rcontext, res, req, session, site, page,
178: toolContextPath, "site");
179:
180: portal.includeBottom(rcontext);
181:
182: // end the response
183: portal.sendResponse(rcontext, res, "site", null);
184: StoredState ss = portalService.getStoredState();
185: if (ss != null
186: && toolContextPath.equals(ss.getToolContextPath())) {
187: // This request is the destination of the request
188: portalService.setStoredState(null);
189: }
190: }
191:
192: protected void includeSiteNav(PortalRenderContext rcontext,
193: HttpServletRequest req, Session session, String siteId) {
194: if (rcontext.uses(INCLUDE_SITE_NAV)) {
195:
196: boolean loggedIn = session.getUserId() != null;
197: boolean topLogin = ServerConfigurationService.getBoolean(
198: "top.login", true);
199:
200: String siteNavUrl = null;
201: int height = 0;
202: String siteNavClass = null;
203:
204: if (loggedIn) {
205: siteNavUrl = Web.returnUrl(req, "/site_tabs/"
206: + Web.escapeUrl(siteId));
207: height = 104;
208: siteNavClass = "sitenav-max";
209: } else {
210: siteNavUrl = Web.returnUrl(req, "/nav_login/"
211: + Web.escapeUrl(siteId));
212: height = 80;
213: siteNavClass = "sitenav-log";
214: }
215:
216: String accessibilityURL = ServerConfigurationService
217: .getString("accessibility.url");
218: rcontext
219: .put(
220: "siteNavHasAccessibilityURL",
221: Boolean
222: .valueOf((accessibilityURL != null && accessibilityURL != "")));
223: rcontext.put("siteNavAccessibilityURL", accessibilityURL);
224: // rcontext.put("siteNavSitAccessability",
225: // Web.escapeHtml(rb.getString("sit_accessibility")));
226: // rcontext.put("siteNavSitJumpContent",
227: // Web.escapeHtml(rb.getString("sit_jumpcontent")));
228: // rcontext.put("siteNavSitJumpTools",
229: // Web.escapeHtml(rb.getString("sit_jumptools")));
230: // rcontext.put("siteNavSitJumpWorksite",
231: // Web.escapeHtml(rb.getString("sit_jumpworksite")));
232:
233: rcontext.put("siteNavLoggedIn", Boolean.valueOf(loggedIn));
234:
235: try {
236: if (loggedIn) {
237: includeLogo(rcontext, req, session, siteId);
238: includeTabs(rcontext, req, session, siteId, "site",
239: false);
240: } else {
241: includeLogo(rcontext, req, session, siteId);
242: if (siteHelper.doGatewaySiteList())
243: includeTabs(rcontext, req, session, siteId,
244: "site", false);
245: }
246: } catch (Exception any) {
247: }
248: }
249: }
250:
251: public void includeLogo(PortalRenderContext rcontext,
252: HttpServletRequest req, Session session, String siteId)
253: throws IOException {
254: if (rcontext.uses(INCLUDE_LOGO)) {
255:
256: String skin = getSiteSkin(siteId);
257:
258: if (skin == null) {
259: skin = ServerConfigurationService
260: .getString("skin.default");
261: }
262: String skinRepo = ServerConfigurationService
263: .getString("skin.repo");
264: rcontext.put("logoSkin", skin);
265: rcontext.put("logoSkinRepo", skinRepo);
266: String siteType = portal.calcSiteType(siteId);
267: String cssClass = (siteType != null) ? siteType
268: : "undeterminedSiteType";
269: rcontext.put("logoSiteType", siteType);
270: rcontext.put("logoSiteClass", cssClass);
271: portal.includeLogin(rcontext, req, session);
272: }
273: }
274:
275: private String getSiteSkin(String siteId) {
276: // First, try to get the skin the default way
277: String skin = SiteService.getSiteSkin(siteId);
278: // If this fails, try to get the real site id if the site is a user site
279: if (skin == null && SiteService.isUserSite(siteId)) {
280: try {
281: String userId = SiteService.getSiteUserId(siteId);
282: String alternateSiteId = SiteService
283: .getUserSiteId(userId);
284: skin = SiteService.getSiteSkin(alternateSiteId);
285: } catch (Exception e) {
286: // Ignore
287: }
288: }
289: return skin;
290: }
291:
292: public void includeTabs(PortalRenderContext rcontext,
293: HttpServletRequest req, Session session, String siteId,
294: String prefix, boolean addLogout) throws IOException {
295:
296: if (rcontext.uses(INCLUDE_TABS)) {
297:
298: // for skinning
299: String siteType = portal.calcSiteType(siteId);
300: String origPrefix = prefix;
301:
302: // If we have turned on auto-state reset on navigation, we generate
303: // the "site-reset" "worksite-reset" and "gallery-reset" urls
304: if ("true".equals(ServerConfigurationService
305: .getString(Portal.CONFIG_AUTO_RESET))) {
306: prefix = prefix + "-reset";
307: }
308:
309: boolean loggedIn = session.getUserId() != null;
310: // Get the user's My WorkSpace and its ID
311: Site myWorkspaceSite = siteHelper.getMyWorkspace(session);
312: String myWorkspaceSiteId = null;
313: if (myWorkspaceSite != null) {
314: myWorkspaceSiteId = siteHelper
315: .getSiteEffectiveId(myWorkspaceSite);
316: }
317:
318: int prefTabs = 4;
319: int tabsToDisplay = prefTabs;
320:
321: // Get the list of sites in the right order,
322: // My WorkSpace will be the first in the list
323: List<Site> mySites = siteHelper.getAllSites(req, session,
324: true);
325: if (!loggedIn) {
326: prefTabs = ServerConfigurationService.getInt(
327: "gatewaySiteListDisplayCount", prefTabs);
328: } else {
329: Preferences prefs = PreferencesService
330: .getPreferences(session.getUserId());
331: ResourceProperties props = prefs
332: .getProperties("sakai:portal:sitenav");
333: try {
334: prefTabs = (int) props.getLongProperty("tabs");
335: } catch (Exception any) {
336: }
337: }
338:
339: // Note that if there are exactly one more site
340: // than tabs allowed - simply put the site on
341: // instead of a dropdown with one site
342: List<Site> moreSites = new ArrayList<Site>();
343: if (mySites.size() > (tabsToDisplay + 1)) {
344: // Check to see if the selected site is in the first
345: // "tabsToDisplay" tabs
346: boolean found = false;
347: for (int i = 0; i < tabsToDisplay && i < mySites.size(); i++) {
348: Site site = mySites.get(i);
349: String effectiveId = siteHelper
350: .getSiteEffectiveId(site);
351: if (site.getId().equals(siteId)
352: || effectiveId.equals(siteId))
353: found = true;
354: }
355:
356: // Save space for the current site
357: if (!found)
358: tabsToDisplay = tabsToDisplay - 1;
359: if (tabsToDisplay < 2)
360: tabsToDisplay = 2;
361:
362: // Create the list of "additional sites"- but do not
363: // include the currently selected set in the list
364: Site currentSelectedSite = null;
365:
366: int remove = mySites.size() - tabsToDisplay;
367: for (int i = 0; i < remove; i++) {
368: // We add the site the the drop-down
369: // unless it it the current site in which case
370: // we retain it for later
371: Site site = mySites.get(tabsToDisplay);
372: mySites.remove(tabsToDisplay);
373:
374: String effectiveId = siteHelper
375: .getSiteEffectiveId(site);
376: if (site.getId().equals(siteId)
377: || effectiveId.equals(siteId)) {
378: currentSelectedSite = site;
379: } else {
380: moreSites.add(site);
381: }
382: }
383:
384: // check to see if we need to re-add the current site
385: if (currentSelectedSite != null) {
386: mySites.add(currentSelectedSite);
387: }
388: }
389:
390: String cssClass = (siteType != null) ? "siteNavWrap "
391: + siteType : "siteNavWrap";
392:
393: rcontext.put("tabsCssClass", cssClass);
394:
395: List<Map> l = portal
396: .convertSitesToMaps(
397: req,
398: mySites,
399: prefix,
400: siteId,
401: myWorkspaceSiteId,
402: /* includeSummary */false, /* expandSite */
403: false,
404: /* resetTools */"true"
405: .equals(ServerConfigurationService
406: .getString(Portal.CONFIG_AUTO_RESET)),
407: /* doPages */true, /* toolContextPath */
408: null, loggedIn);
409:
410: rcontext.put("tabsSites", l);
411:
412: rcontext.put("tabsMoreSitesShow", Boolean.valueOf(moreSites
413: .size() > 0));
414:
415: // more dropdown
416: if (moreSites.size() > 0) {
417: List<Map> m = portal
418: .convertSitesToMaps(
419: req,
420: moreSites,
421: prefix,
422: siteId,
423: myWorkspaceSiteId,
424: /* includeSummary */false, /* expandSite */
425: false,
426: /* resetTools */"true"
427: .equals(ServerConfigurationService
428: .getString(Portal.CONFIG_AUTO_RESET)),
429: /* doPages */true, /* toolContextPath */
430: null, loggedIn);
431:
432: rcontext.put("tabsMoreSites", m);
433: }
434:
435: rcontext.put("tabsAddLogout", Boolean.valueOf(addLogout));
436: if (addLogout) {
437: String logoutUrl = Web.serverUrl(req)
438: + ServerConfigurationService
439: .getString("portalPath")
440: + "/logout_gallery";
441: rcontext.put("tabsLogoutUrl", logoutUrl);
442: // rcontext.put("tabsSitLog",
443: // Web.escapeHtml(rb.getString("sit_log")));
444: }
445: }
446: }
447:
448: }
|