mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Next phase of forums functionality
Simple dialog framework implementation git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2056 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
package org.alfresco.web.app;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import javax.faces.application.NavigationHandler;
|
||||
import javax.faces.application.ViewHandler;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
@@ -38,7 +40,12 @@ import org.springframework.web.jsf.FacesContextUtils;
|
||||
*/
|
||||
public class AlfrescoNavigationHandler extends NavigationHandler
|
||||
{
|
||||
public final static String DIALOG_SEPARATOR = ":";
|
||||
public final static String DIALOG_PREXIX = "dialog" + DIALOG_SEPARATOR;
|
||||
public final static String CLOSE_DIALOG_OUTCOME = DIALOG_PREXIX + "close";
|
||||
|
||||
private final static Log logger = LogFactory.getLog(AlfrescoNavigationHandler.class);
|
||||
private final static String VIEW_STACK = "_alfViewStack";
|
||||
|
||||
// The original navigation handler
|
||||
private NavigationHandler origHandler;
|
||||
@@ -58,102 +65,228 @@ public class AlfrescoNavigationHandler extends NavigationHandler
|
||||
* @see javax.faces.application.NavigationHandler#handleNavigation(javax.faces.context.FacesContext, java.lang.String, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void handleNavigation(FacesContext context, String fromAction, String outcome)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("handleNavigation (fromAction=" + fromAction + ", outcome=" + outcome + ")");
|
||||
|
||||
boolean useOriginalNavHandler = true;
|
||||
String finalOutcome = outcome;
|
||||
boolean closingDialog = false;
|
||||
String viewId = context.getViewRoot().getViewId();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Current view id: " + viewId);
|
||||
|
||||
NavigationBean navBean = (NavigationBean)context.getExternalContext().
|
||||
getSessionMap().get("NavigationBean");
|
||||
|
||||
// only continue if we have some dispatching context
|
||||
if (navBean != null && navBean.getDispatchContextNode() != null)
|
||||
// determine if we are dealing with a dialog
|
||||
if (outcome != null && outcome.startsWith(DIALOG_PREXIX))
|
||||
{
|
||||
Node node = navBean.getDispatchContextNode();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Found node in dispatch context: " + node);
|
||||
// determine whether it's being closed or opened
|
||||
closingDialog = outcome.startsWith(CLOSE_DIALOG_OUTCOME);
|
||||
|
||||
// remove the dialog prefix
|
||||
outcome = outcome.substring(DIALOG_PREXIX.length());
|
||||
|
||||
// see if there is any navigation config for the node type
|
||||
ConfigService configSvc = (ConfigService)FacesContextUtils.getRequiredWebApplicationContext(
|
||||
context).getBean(Application.BEAN_CONFIG_SERVICE);
|
||||
|
||||
Config nodeConfig = configSvc.getConfig(node);
|
||||
NavigationConfigElement navigationCfg = (NavigationConfigElement)nodeConfig.
|
||||
getConfigElement(NavigationElementReader.ELEMENT_NAVIGATION);
|
||||
|
||||
if (navigationCfg != null)
|
||||
if (closingDialog)
|
||||
{
|
||||
// see if there is config for the current view state
|
||||
NavigationResult navResult = navigationCfg.getOverride(viewId, outcome);
|
||||
|
||||
if (navResult != null)
|
||||
// if we are closing the dialog take the view off the
|
||||
// top of the stack then decide whether to use the view
|
||||
// or any overridden outcome that may be present
|
||||
if (getViewStack(context).empty() == false)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Found navigation config: " + navResult);
|
||||
|
||||
if (navResult.isOutcome())
|
||||
String newViewId = (String)getViewStack(context).pop();
|
||||
|
||||
// is there an overiddent outcome?
|
||||
int idx = outcome.indexOf(DIALOG_SEPARATOR);
|
||||
if (idx == -1)
|
||||
{
|
||||
finalOutcome = navResult.getResult();
|
||||
// there isn't an overidden outcome so go back to the previous view
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Closing dialog, going back to view id: " + newViewId);
|
||||
|
||||
goToView(context, newViewId);
|
||||
}
|
||||
else
|
||||
{
|
||||
String newViewId = navResult.getResult();
|
||||
// there is an overidden outcome so extract it
|
||||
outcome = outcome.substring(idx+1, outcome.length());
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Closing dialog with an overridden outcome of '" + outcome + "'");
|
||||
|
||||
if (newViewId.equals(viewId) == false)
|
||||
this.origHandler.handleNavigation(context, fromAction, outcome);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are trying to close a dialog when one hasn't been opened!
|
||||
// log a warning and return a null outcome to stay on the same page
|
||||
if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("Attempting to close a dialog with an empty view stack, returning 'browse' outcome");
|
||||
}
|
||||
|
||||
// TODO: change this back to returning null outcome as that
|
||||
// will highlight any areas we have neglected to launch
|
||||
// in a dilaog, for backwards compatibility for the short
|
||||
// term return 'browse' outcome.
|
||||
|
||||
this.origHandler.handleNavigation(context, fromAction, "browse");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we are opening a dialog push the current view id
|
||||
// on to the stack, but only if it is different than the
|
||||
// current view at the top (you can't launch a dialog from
|
||||
// the same page 2 times in a row!)
|
||||
|
||||
// TODO: This wouldn't happen if we could be sure a dialog is
|
||||
// ALWAYS exited properly, look into a way of ensuring
|
||||
// dialogs get closed if a user navigates away from the page,
|
||||
// would a PhaseListener help in any way??
|
||||
|
||||
if (getViewStack(context).empty() ||
|
||||
viewId.equals(getViewStack(context).peek()) == false)
|
||||
{
|
||||
getViewStack(context).push(viewId);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Pushed current view to stack: " + viewId);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (getViewStack(context).empty() == false && logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("current view is already top the view stack!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("view stack: " + getViewStack(context));
|
||||
}
|
||||
|
||||
if (closingDialog == false)
|
||||
{
|
||||
NavigationBean navBean = (NavigationBean)context.getExternalContext().
|
||||
getSessionMap().get("NavigationBean");
|
||||
|
||||
// only continue if we have some dispatching context
|
||||
if (navBean != null && navBean.getDispatchContextNode() != null)
|
||||
{
|
||||
Node node = navBean.getDispatchContextNode();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Found node with type '" + node.getType().toString() +
|
||||
"' in dispatch context");
|
||||
|
||||
// see if there is any navigation config for the node type
|
||||
ConfigService configSvc = (ConfigService)FacesContextUtils.getRequiredWebApplicationContext(
|
||||
context).getBean(Application.BEAN_CONFIG_SERVICE);
|
||||
|
||||
Config nodeConfig = configSvc.getConfig(node);
|
||||
NavigationConfigElement navigationCfg = (NavigationConfigElement)nodeConfig.
|
||||
getConfigElement(NavigationElementReader.ELEMENT_NAVIGATION);
|
||||
|
||||
if (navigationCfg != null)
|
||||
{
|
||||
// see if there is config for the current view state
|
||||
NavigationResult navResult = navigationCfg.getOverride(viewId, outcome);
|
||||
|
||||
if (navResult != null)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Found navigation config: " + navResult);
|
||||
|
||||
if (navResult.isOutcome())
|
||||
{
|
||||
useOriginalNavHandler = false;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Dispatching to new view id: " + newViewId);
|
||||
|
||||
ViewHandler viewHandler = context.getApplication().getViewHandler();
|
||||
UIViewRoot viewRoot = viewHandler.createView(context, newViewId);
|
||||
viewRoot.setViewId(newViewId);
|
||||
context.setViewRoot(viewRoot);
|
||||
context.renderResponse();
|
||||
outcome = navResult.getResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("New view id is the same as the current one so setting outcome to null");
|
||||
String newViewId = navResult.getResult();
|
||||
|
||||
finalOutcome = null;
|
||||
if (newViewId.equals(viewId) == false)
|
||||
{
|
||||
useOriginalNavHandler = false;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Dispatching to new view id: " + newViewId);
|
||||
|
||||
goToView(context, newViewId);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("New view id is the same as the current one so setting outcome to null");
|
||||
|
||||
outcome = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("No override configuration found for current view or outcome");
|
||||
}
|
||||
}
|
||||
else if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("No override configuration found for current view or outcome");
|
||||
logger.debug("No navigation configuration found for node");
|
||||
}
|
||||
|
||||
// reset the dispatch context
|
||||
navBean.resetDispatchContext();
|
||||
}
|
||||
else if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("No navigation configuration found for node");
|
||||
logger.debug("No dispatch context found");
|
||||
}
|
||||
|
||||
// reset the dispatch context
|
||||
navBean.resetDispatchContext();
|
||||
}
|
||||
else if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("No dispatch context found");
|
||||
}
|
||||
|
||||
// do the appropriate navigation handling
|
||||
if (useOriginalNavHandler)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Passing outcome '" + finalOutcome + "' to original navigation handler");
|
||||
|
||||
this.origHandler.handleNavigation(context, fromAction, finalOutcome);
|
||||
// do the appropriate navigation handling
|
||||
if (useOriginalNavHandler)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Passing outcome '" + outcome + "' to original navigation handler");
|
||||
|
||||
this.origHandler.handleNavigation(context, fromAction, outcome);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches to the given view id
|
||||
*
|
||||
* @param context Faces context
|
||||
* @param viewId The view id to go to
|
||||
*/
|
||||
private void goToView(FacesContext context, String viewId)
|
||||
{
|
||||
ViewHandler viewHandler = context.getApplication().getViewHandler();
|
||||
UIViewRoot viewRoot = viewHandler.createView(context, viewId);
|
||||
viewRoot.setViewId(viewId);
|
||||
context.setViewRoot(viewRoot);
|
||||
context.renderResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the view stack for the current user.
|
||||
*
|
||||
* @param context FacesContext
|
||||
* @return A Stack representing the views that have launched dialogs in
|
||||
* the users session, will never be null
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private Stack getViewStack(FacesContext context)
|
||||
{
|
||||
Stack viewStack = (Stack)context.getExternalContext().getSessionMap().get(VIEW_STACK);
|
||||
|
||||
if (viewStack == null)
|
||||
{
|
||||
viewStack = new Stack();
|
||||
context.getExternalContext().getSessionMap().put(VIEW_STACK, viewStack);
|
||||
}
|
||||
|
||||
return viewStack;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user