1 16 package org.apache.myfaces.application; 17 18 import java.io.IOException ; 19 import java.util.ArrayList ; 20 import java.util.Collection ; 21 import java.util.Collections ; 22 import java.util.Comparator ; 23 import java.util.HashMap ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 import java.util.Map ; 27 28 import javax.faces.FacesException; 29 import javax.faces.application.NavigationHandler; 30 import javax.faces.application.ViewHandler; 31 import javax.faces.component.UIViewRoot; 32 import javax.faces.context.ExternalContext; 33 import javax.faces.context.FacesContext; 34 import javax.servlet.http.HttpServletRequest ; 35 36 import org.apache.commons.logging.Log; 37 import org.apache.commons.logging.LogFactory; 38 import org.apache.myfaces.config.RuntimeConfig; 39 import org.apache.myfaces.config.element.NavigationCase; 40 import org.apache.myfaces.config.element.NavigationRule; 41 import org.apache.myfaces.portlet.PortletUtil; 42 import org.apache.myfaces.util.HashMapUtils; 43 44 90 public class NavigationHandlerImpl 91 extends NavigationHandler 92 { 93 private static final Log log = LogFactory.getLog(NavigationHandlerImpl.class); 94 95 private static final String ASTERISK = "*"; 96 97 private Map _navigationCases = null; 98 private List _wildcardKeys = new ArrayList (); 99 100 public NavigationHandlerImpl() 101 { 102 if (log.isTraceEnabled()) log.trace("New NavigationHandler instance created"); 103 } 104 105 public void handleNavigation(FacesContext facesContext, String fromAction, String outcome) 106 { 107 if (outcome == null) 108 { 109 return; 111 } 112 113 String viewId = facesContext.getViewRoot().getViewId(); 114 Map casesMap = getNavigationCases(facesContext); 115 NavigationCase navigationCase = null; 116 117 List casesList = (List )casesMap.get(viewId); 118 if (casesList != null) 119 { 120 navigationCase = calcMatchingNavigationCase(casesList, fromAction, outcome); 122 } 123 124 if (navigationCase == null) 125 { 126 List keys = getSortedWildcardKeys(); 128 for (int i = 0, size = keys.size(); i < size; i++) 129 { 130 String fromViewId = (String )keys.get(i); 131 if (fromViewId.length() > 2) 132 { 133 String prefix = fromViewId.substring(0, fromViewId.length() - 2); 134 if (viewId.startsWith(prefix)) 135 { 136 casesList = (List )casesMap.get(fromViewId); 137 if (casesList != null) 138 { 139 navigationCase = calcMatchingNavigationCase(casesList, fromAction, outcome); 140 if (navigationCase != null) break; 141 } 142 } 143 } 144 else 145 { 146 casesList = (List )casesMap.get(fromViewId); 147 if (casesList != null) 148 { 149 navigationCase = calcMatchingNavigationCase(casesList, fromAction, outcome); 150 if (navigationCase != null) break; 151 } 152 } 153 } 154 } 155 156 if (navigationCase != null) 157 { 158 if (log.isTraceEnabled()) 159 { 160 log.trace("handleNavigation fromAction=" + fromAction + " outcome=" + outcome + 161 " toViewId =" + navigationCase.getToViewId() + 162 " redirect=" + navigationCase.isRedirect()); 163 } 164 if (navigationCase.isRedirect() && 165 (!PortletUtil.isPortletRequest(facesContext))) 166 { ExternalContext externalContext = facesContext.getExternalContext(); 168 ViewHandler viewHandler = facesContext.getApplication().getViewHandler(); 169 String redirectPath = viewHandler.getActionURL(facesContext, navigationCase.getToViewId()); 170 Object req = externalContext.getRequest(); 171 if (req instanceof HttpServletRequest ) 172 { 173 String queryString = ((HttpServletRequest )req).getQueryString(); 174 if (queryString != null) 175 { 176 if (redirectPath.indexOf('?') == -1) 177 { 178 redirectPath = redirectPath + '?' + queryString; 179 } 180 else 181 { 182 redirectPath = redirectPath + '&' + queryString; 183 } 184 } 185 } 186 187 try 188 { 189 externalContext.redirect(externalContext.encodeActionURL(redirectPath)); 190 } 191 catch (IOException e) 192 { 193 throw new FacesException(e.getMessage(), e); 194 } 195 facesContext.responseComplete(); 196 } 197 else 198 { 199 ViewHandler viewHandler = facesContext.getApplication().getViewHandler(); 200 UIViewRoot viewRoot = viewHandler.createView(facesContext, navigationCase.getToViewId()); 202 facesContext.setViewRoot(viewRoot); 203 facesContext.renderResponse(); 204 } 205 } 206 else 207 { 208 if (log.isTraceEnabled()) 210 { 211 log.trace("handleNavigation fromAction=" + fromAction + " outcome=" + outcome + 212 " no matching navigation-case found, staying on current ViewRoot"); 213 } 214 } 215 } 216 217 private NavigationCase calcMatchingNavigationCase(List casesList, String actionRef, String outcome) 218 { 219 for (int i = 0, size = casesList.size(); i < size; i++) 220 { 221 NavigationCase caze = (NavigationCase)casesList.get(i); 222 String cazeOutcome = caze.getFromOutcome(); 223 String cazeActionRef = caze.getFromAction(); 224 if ((cazeOutcome == null || cazeOutcome.equals(outcome)) && 225 (cazeActionRef == null || cazeActionRef.equals(actionRef))) 226 { 227 return caze; 228 } 229 } 230 return null; 231 } 232 233 private List getSortedWildcardKeys() 234 { 235 return _wildcardKeys; 236 } 237 238 private Map getNavigationCases(FacesContext facesContext) 239 { 240 if (_navigationCases == null) 241 { 242 synchronized(this) 243 { 244 if (_navigationCases == null) 245 { 246 ExternalContext externalContext = facesContext.getExternalContext(); 247 RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(externalContext); 248 249 Collection rules = runtimeConfig.getNavigationRules(); 250 int rulesSize = rules.size(); 251 Map cases = new HashMap (HashMapUtils.calcCapacity(rulesSize)); 252 List wildcardKeys = new ArrayList (); 253 254 for (Iterator iterator = rules.iterator(); iterator.hasNext();) 255 { 256 NavigationRule rule = (NavigationRule) iterator.next(); 257 String fromViewId = rule.getFromViewId(); 258 259 if (fromViewId == null) 261 { 262 fromViewId = ASTERISK; 263 } 264 else 265 { 266 fromViewId = fromViewId.trim(); 267 } 268 269 List list = (List ) cases.get(fromViewId); 270 if (list == null) 271 { 272 list = new ArrayList (rule.getNavigationCases()); 273 cases.put(fromViewId, list); 274 if (fromViewId.endsWith(ASTERISK)) 275 { 276 wildcardKeys.add(fromViewId); 277 } 278 } else { 279 list.addAll(rule.getNavigationCases()); 280 } 281 282 } 283 Collections.sort(wildcardKeys, new KeyComparator()); 284 285 synchronized (cases) 286 { 287 _navigationCases = cases; 292 _wildcardKeys = wildcardKeys; 293 } 294 } 295 } 296 } 297 return _navigationCases; 298 } 299 300 private static final class KeyComparator 301 implements Comparator 302 { 303 public int compare(Object o1, Object o2) 304 { 305 return -(((String )o1).compareTo((String )o2)); 306 } 307 } 308 } 309 | Popular Tags |