1 16 package org.apache.myfaces.renderkit.html; 17 18 import org.apache.myfaces.config.MyfacesConfig; 19 import org.apache.myfaces.renderkit.JSFAttr; 20 import org.apache.myfaces.renderkit.RendererUtils; 21 import org.apache.myfaces.renderkit.html.util.DummyFormResponseWriter; 22 import org.apache.myfaces.renderkit.html.util.DummyFormUtils; 23 import org.apache.myfaces.renderkit.html.util.JavascriptUtils; 24 25 import javax.faces.application.StateManager; 26 import javax.faces.application.ViewHandler; 27 import javax.faces.component.*; 28 import javax.faces.component.html.HtmlCommandLink; 29 import javax.faces.context.FacesContext; 30 import javax.faces.context.ResponseWriter; 31 import javax.faces.event.ActionEvent; 32 import java.io.IOException ; 33 import java.io.UnsupportedEncodingException ; 34 import java.net.URLEncoder ; 35 import java.util.Iterator ; 36 37 100 public abstract class HtmlLinkRendererBase 101 extends HtmlRenderer 102 { 103 104 public static final String URL_STATE_MARKER = "JSF_URL_STATE_MARKER=DUMMY"; 105 public static final int URL_STATE_MARKER_LEN = URL_STATE_MARKER.length(); 106 107 109 public boolean getRendersChildren() 110 { 111 return true; 114 } 115 116 public void decode(FacesContext facesContext, UIComponent component) 117 { 118 super.decode(facesContext, component); 120 if (component instanceof UICommand) 121 { 122 String clientId = component.getClientId(facesContext); 123 String reqValue = (String )facesContext.getExternalContext().getRequestParameterMap().get(HtmlRendererUtils.getHiddenCommandLinkFieldName(HtmlRendererUtils.getFormName(component, facesContext))); 124 if (reqValue != null && reqValue.equals(clientId)) 125 { 126 component.queueEvent(new ActionEvent(component)); 127 } 128 } 129 else if (component instanceof UIOutput) 130 { 131 } 133 else 134 { 135 throw new IllegalArgumentException ("Unsupported component class " + component.getClass().getName()); 136 } 137 } 138 139 140 public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException 141 { 142 super.encodeBegin(facesContext, component); 144 if (component instanceof UICommand) 145 { 146 renderCommandLinkStart(facesContext, component, 147 component.getClientId(facesContext), 148 ((UICommand)component).getValue(), 149 getStyle(facesContext, component), 150 getStyleClass(facesContext, component)); 151 } 152 else if (component instanceof UIOutput) 153 { 154 renderOutputLinkStart(facesContext, (UIOutput)component); 155 } 156 else 157 { 158 throw new IllegalArgumentException ("Unsupported component class " + component.getClass().getName()); 159 } 160 } 161 162 163 166 protected String getStyle(FacesContext facesContext, UIComponent link) 167 { 168 if (link instanceof HtmlCommandLink) 169 { 170 return ((HtmlCommandLink)link).getStyle(); 171 } 172 else 173 { 174 return (String )link.getAttributes().get(HTML.STYLE_ATTR); 175 } 176 } 177 178 181 protected String getStyleClass(FacesContext facesContext, UIComponent link) 182 { 183 if (link instanceof HtmlCommandLink) 184 { 185 return ((HtmlCommandLink)link).getStyleClass(); 186 } 187 else 188 { 189 return (String )link.getAttributes().get(HTML.STYLE_CLASS_ATTR); 190 } 191 } 192 193 public void encodeChildren(FacesContext facesContext, UIComponent component) throws IOException 194 { 195 RendererUtils.renderChildren(facesContext, component); 196 } 197 198 public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException 199 { 200 super.encodeEnd(facesContext, component); renderLinkEnd(facesContext, component); 202 } 203 204 protected void renderCommandLinkStart(FacesContext facesContext, UIComponent component, 205 String clientId, 206 Object value, 207 String style, 208 String styleClass) 209 throws IOException 210 { 211 ResponseWriter writer = facesContext.getResponseWriter(); 212 213 if (JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext())) 214 { 215 renderJavaScriptAnchorStart(facesContext, writer, component, clientId); 216 } 217 else 218 { 219 renderNonJavaScriptAnchorStart(facesContext, writer, component, clientId); 220 } 221 222 writer.writeAttribute(HTML.ID_ATTR, clientId, null); 223 HtmlRendererUtils.renderHTMLAttributes(writer, component, 224 HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_STYLE); 225 HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_ATTR, HTML.STYLE_ATTR, 226 style); 227 HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_CLASS_ATTR, HTML.STYLE_CLASS_ATTR, 228 styleClass); 229 230 if(value != null) 232 { 233 writer.writeText(value.toString(), JSFAttr.VALUE_ATTR); 234 } 235 } 236 237 protected void renderJavaScriptAnchorStart(FacesContext facesContext, 238 ResponseWriter writer, 239 UIComponent component, 240 String clientId) 241 throws IOException 242 { 243 UIComponent parent = component.getParent(); 245 while (parent != null && !(parent instanceof UIForm)) 246 { 247 parent = parent.getParent(); 248 } 249 250 UIForm nestingForm = null; 251 String formName; 252 DummyFormResponseWriter dummyFormResponseWriter; 253 if (parent != null) 254 { 255 nestingForm = (UIForm)parent; 257 formName = nestingForm.getClientId(facesContext); 258 dummyFormResponseWriter = null; 259 } 260 else 261 { 262 formName = DummyFormUtils.DUMMY_FORM_NAME; 264 dummyFormResponseWriter = DummyFormUtils.getDummyFormResponseWriter(facesContext); 265 dummyFormResponseWriter.setWriteDummyForm(true); 266 } 267 268 StringBuffer onClick = new StringBuffer (); 269 270 String commandOnclick; 271 if (component instanceof HtmlCommandLink) 272 { 273 commandOnclick = ((HtmlCommandLink)component).getOnclick(); 274 } 275 else 276 { 277 commandOnclick = (String )component.getAttributes().get(HTML.ONCLICK_ATTR); 278 } 279 if (commandOnclick != null) 280 { 281 onClick.append(commandOnclick); 282 onClick.append(';'); 283 } 284 285 onClick.append(HtmlRendererUtils.getClearHiddenCommandFormParamsFunctionName(formName)).append("();"); 287 288 String jsForm = "document.forms['" + formName + "']"; 289 290 if (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isAutoScroll()) 291 { 292 JavascriptUtils.appendAutoScrollAssignment(onClick, formName); 293 } 294 295 String hiddenFieldName = HtmlRendererUtils.getHiddenCommandLinkFieldName(formName); 297 onClick.append(jsForm); 298 onClick.append(".elements['").append(hiddenFieldName).append("']"); 299 onClick.append(".value='").append(clientId).append("';"); 300 if (nestingForm != null) 301 { 302 HtmlFormRendererBase.addHiddenCommandParameter(nestingForm, hiddenFieldName); 303 } 304 else 305 { 306 dummyFormResponseWriter.addDummyFormParameter(hiddenFieldName); 307 } 308 309 for (Iterator it = component.getChildren().iterator(); it.hasNext(); ) 311 { 312 UIComponent child = (UIComponent)it.next(); 313 if (child instanceof UIParameter) 314 { 315 String name = ((UIParameter)child).getName(); 316 Object value = ((UIParameter)child).getValue(); 317 318 renderLinkParameter(dummyFormResponseWriter, name, value, onClick, jsForm, nestingForm); 319 } 320 } 321 322 String target = ((HtmlCommandLink)component).getTarget(); 324 if (target != null && target.trim().length() > 0) { 325 onClick.append(jsForm); 326 onClick.append(".target='"); 327 onClick.append(target); 328 onClick.append("';"); 329 } 330 331 onClick.append("if("+jsForm+".onsubmit){"+jsForm+".onsubmit();}"); 333 334 onClick.append(jsForm); 336 onClick.append(".submit();return false;"); 338 writer.startElement(HTML.ANCHOR_ELEM, component); 339 writer.writeURIAttribute(HTML.HREF_ATTR, "#", null); 340 writer.writeAttribute(HTML.ONCLICK_ATTR, onClick.toString(), null); 341 } 342 343 344 protected void renderNonJavaScriptAnchorStart(FacesContext facesContext, 345 ResponseWriter writer, 346 UIComponent component, 347 String clientId) 348 throws IOException 349 { 350 ViewHandler viewHandler = facesContext.getApplication().getViewHandler(); 351 String viewId = facesContext.getViewRoot().getViewId(); 352 String path = viewHandler.getActionURL(facesContext, viewId); 353 354 StringBuffer hrefBuf = new StringBuffer (path); 355 356 358 if (path.indexOf('?') == -1) 359 { 360 hrefBuf.append('?'); 361 } 362 else 363 { 364 hrefBuf.append('&'); 365 } 366 String hiddenFieldName = HtmlRendererUtils.getHiddenCommandLinkFieldName(HtmlRendererUtils.getFormName(component, facesContext)); 367 hrefBuf.append(hiddenFieldName); 368 hrefBuf.append('='); 369 hrefBuf.append(clientId); 370 371 if (component.getChildCount() > 0) 372 { 373 addChildParametersToHref(component, hrefBuf, 374 false, writer.getCharacterEncoding()); 376 } 377 378 StateManager stateManager = facesContext.getApplication().getStateManager(); 379 if (stateManager.isSavingStateInClient(facesContext)) 380 { 381 hrefBuf.append("&"); 382 hrefBuf.append(URL_STATE_MARKER); 383 } 384 String href = facesContext.getExternalContext().encodeActionURL(hrefBuf.toString()); 385 writer.startElement(HTML.ANCHOR_ELEM, component); 386 writer.writeURIAttribute(HTML.HREF_ATTR, 387 facesContext.getExternalContext().encodeActionURL(href), 388 null); 389 } 390 391 private void addChildParametersToHref(UIComponent linkComponent, 392 StringBuffer hrefBuf, 393 boolean firstParameter, 394 String charEncoding) 395 throws IOException 396 { 397 for (Iterator it = linkComponent.getChildren().iterator(); it.hasNext(); ) 398 { 399 UIComponent child = (UIComponent)it.next(); 400 if (child instanceof UIParameter) 401 { 402 String name = ((UIParameter)child).getName(); 403 Object value = ((UIParameter)child).getValue(); 404 405 addParameterToHref(name, value, hrefBuf, firstParameter, charEncoding); 406 firstParameter = false; 407 } 408 } 409 } 410 411 protected void renderOutputLinkStart(FacesContext facesContext, UIOutput output) 412 throws IOException 413 { 414 ResponseWriter writer = facesContext.getResponseWriter(); 415 416 String href = RendererUtils.getStringValue(facesContext, output); 418 if (output.getChildCount() > 0) 419 { 420 StringBuffer hrefBuf = new StringBuffer (href); 421 addChildParametersToHref(output, hrefBuf, 422 (href.indexOf('?') == -1), writer.getCharacterEncoding()); 424 href = hrefBuf.toString(); 425 } 426 href = facesContext.getExternalContext().encodeResourceURL(href); 428 writer.startElement(HTML.ANCHOR_ELEM, output); 430 writer.writeAttribute(HTML.ID_ATTR, output.getClientId(facesContext), null); 431 writer.writeURIAttribute(HTML.HREF_ATTR, href, null); 432 HtmlRendererUtils.renderHTMLAttributes(writer, output, HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES); 433 writer.flush(); 434 } 435 436 private void renderLinkParameter(DummyFormResponseWriter dummyFormResponseWriter, 437 String name, 438 Object value, 439 StringBuffer onClick, 440 String jsForm, 441 UIForm nestingForm) 442 { 443 if (name == null) 444 { 445 throw new IllegalArgumentException ("Unnamed parameter value not allowed within command link."); 446 } 447 onClick.append(jsForm); 448 onClick.append(".elements['").append(name).append("']"); 449 String strParamValue = value != null ? value.toString() : ""; onClick.append(".value='").append(strParamValue).append("';"); 452 453 if (nestingForm != null) 454 { 455 HtmlFormRendererBase.addHiddenCommandParameter(nestingForm, name); 457 } 458 else 459 { 460 dummyFormResponseWriter.addDummyFormParameter(name); 461 } 462 } 463 464 private static void addParameterToHref(String name, Object value, StringBuffer hrefBuf, boolean firstParameter, String charEncoding) 465 throws UnsupportedEncodingException 466 { 467 if (name == null) 468 { 469 throw new IllegalArgumentException ("Unnamed parameter value not allowed within command link."); 470 } 471 472 hrefBuf.append(firstParameter ? '?' : '&'); 473 hrefBuf.append(URLEncoder.encode(name, charEncoding)); 474 hrefBuf.append('='); 475 if (value != null) 476 { 477 hrefBuf.append(URLEncoder.encode(value.toString(), charEncoding)); 479 } 480 } 481 482 483 protected void renderLinkEnd(FacesContext facesContext, UIComponent component) 484 throws IOException 485 { 486 ResponseWriter writer = facesContext.getResponseWriter(); 487 writer.writeText("", null); 489 writer.endElement(HTML.ANCHOR_ELEM); 490 } 491 492 493 } 494 | Popular Tags |