1 18 package org.alfresco.web.app; 19 20 import java.util.Stack ; 21 22 import javax.faces.application.NavigationHandler; 23 import javax.faces.application.ViewHandler; 24 import javax.faces.component.UIViewRoot; 25 import javax.faces.context.FacesContext; 26 27 import org.alfresco.config.Config; 28 import org.alfresco.config.ConfigService; 29 import org.alfresco.web.bean.NavigationBean; 30 import org.alfresco.web.bean.repository.Node; 31 import org.alfresco.web.config.NavigationConfigElement; 32 import org.alfresco.web.config.NavigationElementReader; 33 import org.alfresco.web.config.NavigationResult; 34 import org.apache.commons.logging.Log; 35 import org.apache.commons.logging.LogFactory; 36 import org.springframework.web.jsf.FacesContextUtils; 37 38 41 public class AlfrescoNavigationHandler extends NavigationHandler 42 { 43 public final static String DIALOG_SEPARATOR = ":"; 44 public final static String DIALOG_PREXIX = "dialog" + DIALOG_SEPARATOR; 45 public final static String CLOSE_DIALOG_OUTCOME = DIALOG_PREXIX + "close"; 46 47 private final static Log logger = LogFactory.getLog(AlfrescoNavigationHandler.class); 48 private final static String VIEW_STACK = "_alfViewStack"; 49 50 private NavigationHandler origHandler; 52 53 58 public AlfrescoNavigationHandler(NavigationHandler origHandler) 59 { 60 super(); 61 this.origHandler = origHandler; 62 } 63 64 67 @Override 68 @SuppressWarnings ("unchecked") 69 public void handleNavigation(FacesContext context, String fromAction, String outcome) 70 { 71 if (logger.isDebugEnabled()) 72 logger.debug("handleNavigation (fromAction=" + fromAction + ", outcome=" + outcome + ")"); 73 74 boolean useOriginalNavHandler = true; 75 boolean closingDialog = false; 76 String viewId = context.getViewRoot().getViewId(); 77 78 if (logger.isDebugEnabled()) 79 logger.debug("Current view id: " + viewId); 80 81 if (outcome != null && outcome.startsWith(DIALOG_PREXIX)) 83 { 84 closingDialog = outcome.startsWith(CLOSE_DIALOG_OUTCOME); 86 87 outcome = outcome.substring(DIALOG_PREXIX.length()); 89 90 if (closingDialog) 91 { 92 if (getViewStack(context).empty() == false) 96 { 97 String newViewId = (String )getViewStack(context).pop(); 98 99 int idx = outcome.indexOf(DIALOG_SEPARATOR); 101 if (idx == -1) 102 { 103 if (logger.isDebugEnabled()) 105 logger.debug("Closing dialog, going back to view id: " + newViewId); 106 107 goToView(context, newViewId); 108 } 109 else 110 { 111 outcome = outcome.substring(idx+1, outcome.length()); 113 114 getViewStack(context).clear(); 117 118 if (logger.isDebugEnabled()) 119 logger.debug("Closing dialog with an overridden outcome of '" + outcome + "'"); 120 121 this.origHandler.handleNavigation(context, fromAction, outcome); 122 } 123 } 124 else 125 { 126 if (logger.isWarnEnabled()) 129 { 130 logger.warn("Attempting to close a dialog with an empty view stack, returning null outcome"); 131 } 132 133 this.origHandler.handleNavigation(context, fromAction, null); 134 } 135 } 136 else 137 { 138 143 148 if (getViewStack(context).empty() || 149 viewId.equals(getViewStack(context).peek()) == false) 150 { 151 getViewStack(context).push(viewId); 152 153 if (logger.isDebugEnabled()) 154 logger.debug("Pushed current view to stack: " + viewId); 155 } 156 else 157 { 158 if (getViewStack(context).empty() == false && logger.isDebugEnabled()) 159 { 160 logger.debug("current view is already top the view stack!"); 161 } 162 } 163 } 164 165 if (logger.isDebugEnabled()) 166 logger.debug("view stack: " + getViewStack(context)); 167 } 168 169 if (closingDialog == false) 170 { 171 NavigationBean navBean = (NavigationBean)context.getExternalContext(). 172 getSessionMap().get("NavigationBean"); 173 174 if (navBean != null && navBean.getDispatchContextNode() != null) 176 { 177 Node node = navBean.getDispatchContextNode(); 178 179 if (logger.isDebugEnabled()) 180 logger.debug("Found node with type '" + node.getType().toString() + 181 "' in dispatch context"); 182 183 ConfigService configSvc = Application.getConfigService(context); 185 Config nodeConfig = configSvc.getConfig(node); 186 NavigationConfigElement navigationCfg = (NavigationConfigElement)nodeConfig. 187 getConfigElement(NavigationElementReader.ELEMENT_NAVIGATION); 188 189 if (navigationCfg != null) 190 { 191 NavigationResult navResult = navigationCfg.getOverride(viewId, outcome); 193 194 if (navResult != null) 195 { 196 if (logger.isDebugEnabled()) 197 logger.debug("Found navigation config: " + navResult); 198 199 if (navResult.isOutcome()) 200 { 201 outcome = navResult.getResult(); 202 } 203 else 204 { 205 String newViewId = navResult.getResult(); 206 207 if (newViewId.equals(viewId) == false) 208 { 209 useOriginalNavHandler = false; 210 211 if (logger.isDebugEnabled()) 212 logger.debug("Dispatching to new view id: " + newViewId); 213 214 goToView(context, newViewId); 215 } 216 else 217 { 218 if (logger.isDebugEnabled()) 219 logger.debug("New view id is the same as the current one so setting outcome to null"); 220 221 outcome = null; 222 } 223 } 224 } 225 else if (logger.isDebugEnabled()) 226 { 227 logger.debug("No override configuration found for current view or outcome"); 228 } 229 } 230 else if (logger.isDebugEnabled()) 231 { 232 logger.debug("No navigation configuration found for node"); 233 } 234 235 navBean.resetDispatchContext(); 237 } 238 else if (logger.isDebugEnabled()) 239 { 240 logger.debug("No dispatch context found"); 241 } 242 243 if (useOriginalNavHandler) 245 { 246 if (logger.isDebugEnabled()) 247 logger.debug("Passing outcome '" + outcome + "' to original navigation handler"); 248 249 this.origHandler.handleNavigation(context, fromAction, outcome); 250 } 251 } 252 } 253 254 260 private void goToView(FacesContext context, String viewId) 261 { 262 ViewHandler viewHandler = context.getApplication().getViewHandler(); 263 UIViewRoot viewRoot = viewHandler.createView(context, viewId); 264 viewRoot.setViewId(viewId); 265 context.setViewRoot(viewRoot); 266 context.renderResponse(); 267 } 268 269 276 @SuppressWarnings ("unchecked") 277 private Stack getViewStack(FacesContext context) 278 { 279 Stack viewStack = (Stack )context.getExternalContext().getSessionMap().get(VIEW_STACK); 280 281 if (viewStack == null) 282 { 283 viewStack = new Stack (); 284 context.getExternalContext().getSessionMap().put(VIEW_STACK, viewStack); 285 } 286 287 return viewStack; 288 } 289 } 290 | Popular Tags |