***** ControllingViewHandler Java class ***** package frostillicus.controller; import javax.faces.application.ViewHandler; import javax.faces.component.UIViewRoot; import javax.faces.context.FacesContext; import javax.servlet.http.HttpServletRequest; import org.openntf.domino.Database; import org.openntf.domino.utils.Factory; import uk.co.intec.util.IntecUtils; import com.ibm.xsp.component.UIViewRootEx; import com.ibm.xsp.designer.context.XSPContext; import com.ibm.xsp.extlib.util.ExtLibUtil; /** * Core class handling which controller class to use * */ public class ControllingViewHandler extends com.ibm.xsp.application.ViewHandlerExImpl { private static enum AnonymousPageNames { INDEX("/index.xsp"), ERROR("/Error.xsp"); private final String value_; private AnonymousPageNames(String name) { value_ = name; } public String getValue() { return value_; } } public ControllingViewHandler(ViewHandler arg0) { super(arg0); } /* * Extended to get page name from Form if page includes $$OpenDominoDocument or XPage. Looks to controller package and adds it to ViewScope. * Adds beforeRenderResponse, afterRenderResponse, and afterRestoreView methods. Also sets pageTitle property * * (non-Javadoc) * @see com.ibm.xsp.application.ViewHandlerEx#createView(javax.faces.context.FacesContext, java.lang.String) */ @SuppressWarnings("unchecked") @Override public UIViewRoot createView(FacesContext context, String pageName) { // Page name is in the format "/Home" // Uncomment this bit if documents should have anonymous access. It will check for $$OpenDocument as the page name, // in which case get the relevant page name from the underlying Form using an in-built XPpages function /*if (pageClassName.equalsIgnoreCase("$$OpenDominoDocument")) { // Handle the virtual document page. There may be a better way to do this, but this will do for now try { Map<String, String> param = (Map<String, String>) ExtLibUtil.resolveVariable(FacesContext .getCurrentInstance(), "param"); Database database = AppUtils.getAppDb(); Document doc = database.getDocumentByUNID(param.get("documentId")); if (doc == null) { try { doc = database.getDocumentByID(param.get("documentId")); } catch (Throwable te) { // Just couldn't get doc } } if (doc != null) { pageName = DominoUtils.getXPagesForDocument(doc); } } catch (Exception e) { IntecUtils.handleException(e); } }*/ if (!pageName.contains(".xsp")) { pageName = pageName + ".xsp"; } if (!pageName.startsWith("/")) { pageName = "/" + pageName; } boolean allowContinue = false; if (!Factory.getSession().getEffectiveUserName().equalsIgnoreCase("anonymous")) { allowContinue = true; } else { for (AnonymousPageNames page : AnonymousPageNames.values()) { if (page.getValue().equalsIgnoreCase(pageName)) { allowContinue = true; break; } } } if (!allowContinue) { XSPContext xspContext = (XSPContext) IntecUtils.resolveVariable("context"); try { Database currDb = Factory.getSession().getCurrentDatabase(); HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest(); String url = request.getRequestURL().toString() + "?" + request.getQueryString(); // Next line is an example of redirecting within the NSF - easy because it's done within XPages runtime . Amend XPage name as required // xspContext.redirectToPage("login.xsp?open&redirectTo=" + java.net.URLEncoder.encode(url, "UTF-8")); // The following is an example of redirecting outside the current NSF - more difficult because we can't redirect until Render Response // So redirect to Error page in this NSF, then sniff for ResdirectToLogin requestScope in beforeRenderResponse to redirect // AMEND THIS NEXT LINE IF NOT USING ODA String dbName = currDb.getFileName(); // Build this URL as required String fullUrl = url.substring(0, url.indexOf(dbName)) + dbName + "/login.xsp?open&redirectTo=" + java.net.URLEncoder.encode(url, "UTF-8"); ExtLibUtil.getRequestScope().put("RedirectToLogin", fullUrl); pageName = "/Error.xsp"; } catch (Throwable t) { if (t instanceof com.ibm.xsp.acl.RedirectSignal) { // Don't log redirections } else { t.printStackTrace(); } xspContext.redirectToHome(); } } UIViewRootEx root = null; root = (UIViewRootEx) super.createView(context, pageName); return root; } } ***** Registering the ControllingViewHandler in faces-config ***** <application> <view-handler>frostillicus.controller.ControllingViewHandler</view-handler> </application> ***** beforeRenderResponse code for Error page ***** <xp:this.beforeRenderResponse><![CDATA[#{javascript:if (requestScope.containsKey("RedirectToLogin")) { print(requestScope.get("RedirectToLogin")); facesContext.getExternalContext().redirect(requestScope.get("RedirectToLogin")); }}]]></xp:this.beforeRenderResponse>