package frostillicus.xsp.controller; import javax.faces.application.ViewHandler; import javax.faces.component.UIViewRoot; import javax.faces.context.FacesContext; import javax.faces.el.MethodBinding; import javax.faces.event.PhaseEvent; import frostillicus.xsp.util.FrameworkUtils; import com.ibm.commons.util.StringUtil; import com.ibm.xsp.component.UIViewRootEx; import org.openntf.domino.*; import java.util.*; /** * @since 1.0 */ public class ControllingViewHandler extends com.ibm.xsp.application.ViewHandlerExImpl { public static final String BEAN_NAME = "controller"; public ControllingViewHandler(final ViewHandler delegate) { super(delegate); } @SuppressWarnings("unchecked") @Override public UIViewRoot createView(final FacesContext context, final String pageName) { // Page name is in the format "/home" String truePageName = pageName; String pageClassName = pageName.substring(1); if(pageClassName.contains(".xsp")) { pageClassName = FrameworkUtils.strLeft(pageClassName, ".xsp"); } if(pageClassName.equalsIgnoreCase("$$OpenDominoDocument")) { // Handle the virtual document page. There may be a better way to do this, but this will do for now Database database = FrameworkUtils.getDatabase(); Map<String, String> param = (Map<String, String>)resolveVariable(context, "param"); String documentId = param.get("documentId"); if(StringUtil.isNotEmpty(documentId)) { Document doc = database.getDocumentByUNID(param.get("documentId")); if(doc == null) { // Could be a Note ID doc = database.getDocumentByID(documentId); } if(doc != null) { String formName = doc.getItemValueString("Form"); // Now that we have the form, look for the XPageAlt Form form = database.getForm(formName); String formURL = form.getURL(); String formUNID = FrameworkUtils.strRightBack(FrameworkUtils.strLeftBack(formURL, "?Open"), "/"); Document formDoc = database.getDocumentByUNID(formUNID); String xpageAlt = formDoc.getItemValueString("$XPageAlt"); if(StringUtil.isEmpty(xpageAlt)) { pageClassName = formName; } else { pageClassName = FrameworkUtils.strLeftBack(xpageAlt, ".xsp"); } truePageName = "/" + pageClassName; } } } Class<? extends XPageController> controllerClass = null; try { controllerClass = (Class<? extends XPageController>)Class.forName("controller." + pageClassName, true, context.getContextClassLoader()); } catch(ClassNotFoundException cnfe) { controllerClass = BasicXPageController.class; } UIViewRootEx root = null; try { XPageController pageController = controllerClass.newInstance(); Map<String, Object> requestScope = (Map<String, Object>)resolveVariable(context, "requestScope"); requestScope.put(BEAN_NAME, pageController); root = (UIViewRootEx)super.createView(FacesContext.getCurrentInstance(), truePageName); root.getViewMap().put(BEAN_NAME, pageController); requestScope.remove(BEAN_NAME); if(root.getBeforeRenderResponse() == null) { MethodBinding beforeRenderResponse = context.getApplication().createMethodBinding("#{" + BEAN_NAME + ".beforeRenderResponse}", new Class[] { PhaseEvent.class }); root.setBeforeRenderResponse(beforeRenderResponse); } if(root.getAfterRenderResponse() == null) { MethodBinding afterRenderResponse = context.getApplication().createMethodBinding("#{" + BEAN_NAME + ".afterRenderResponse}", new Class[] { PhaseEvent.class }); root.setAfterRenderResponse(afterRenderResponse); } if(root.getAfterRestoreView() == null) { MethodBinding afterRestoreView = context.getApplication().createMethodBinding("#{" + BEAN_NAME + ".afterRestoreView}", new Class[] { PhaseEvent.class }); root.setAfterRestoreView(afterRestoreView); } } catch(Exception e) { e.printStackTrace(); root = (UIViewRootEx)super.createView(context, truePageName); } return root; } private static Object resolveVariable(final FacesContext context, final String varName) { return context.getApplication().getVariableResolver().resolveVariable(context, varName); } }