1 16 package org.apache.cocoon.faces.taglib; 17 18 import org.apache.avalon.framework.parameters.Parameters; 19 20 import org.apache.cocoon.environment.ObjectModelHelper; 21 import org.apache.cocoon.environment.Request; 22 import org.apache.cocoon.environment.SourceResolver; 23 import org.apache.cocoon.taglib.Tag; 24 import org.apache.cocoon.taglib.XMLProducerTagSupport; 25 26 import org.apache.cocoon.faces.FacesUtils; 27 import org.apache.cocoon.faces.renderkit.XMLResponseWriter; 28 import org.apache.commons.lang.BooleanUtils; 29 import org.xml.sax.Attributes ; 30 import org.xml.sax.SAXException ; 31 32 import javax.faces.application.Application; 33 import javax.faces.component.UIComponent; 34 import javax.faces.context.FacesContext; 35 import javax.faces.context.ResponseWriter; 36 import javax.faces.el.ValueBinding; 37 import java.io.IOException ; 38 import java.util.ArrayList ; 39 import java.util.Iterator ; 40 import java.util.List ; 41 import java.util.Map ; 42 43 46 public abstract class UIComponentTag extends XMLProducerTagSupport { 47 48 private static final String CREATED_COMPONENTS = "javax.faces.webapp.COMPONENT_IDS"; 49 private static final String CREATED_FACETS = "javax.faces.webapp.FACET_NAMES"; 50 51 55 private String id; 56 private String binding; 57 private String rendered; 58 59 63 private FacesContext context; 64 private UIComponent component; 65 66 private boolean created; 67 private List createdComponents; 68 private List createdFacets; 69 70 74 protected final FacesContext getFacesContext() { 75 return this.context; 76 } 77 78 protected final Application getApplication() { 79 return getFacesContext().getApplication(); 80 } 81 82 protected final UIComponent getComponentInstance() { 83 return this.component; 84 } 85 86 protected final boolean getCreated() { 87 return this.created; 88 } 89 90 protected final ValueBinding createValueBinding(String valueRef) { 91 return getApplication().createValueBinding(valueRef); 92 } 93 94 protected final Object evaluate(String value) { 95 if (FacesUtils.isExpression(value)) { 96 return createValueBinding(value).getValue(getFacesContext()); 97 } 98 99 return value; 100 } 101 102 protected final boolean evaluateBoolean(String value) { 103 if (FacesUtils.isExpression(value)) { 104 Boolean obj = (Boolean ) createValueBinding(value).getValue(getFacesContext()); 105 return obj.booleanValue(); 106 } 107 108 return BooleanUtils.toBoolean(value); 109 } 110 111 protected final int evaluateInteger(String value) { 112 if (FacesUtils.isExpression(value)) { 113 Number obj = (Number ) createValueBinding(value).getValue(getFacesContext()); 114 return obj.intValue(); 115 } 116 117 return Integer.parseInt(value); 118 } 119 120 protected final long evaluateLong(String value) { 121 if (FacesUtils.isExpression(value)) { 122 Number obj = (Number ) createValueBinding(value).getValue(getFacesContext()); 123 return obj.longValue(); 124 } 125 126 return Long.parseLong(value); 127 } 128 129 protected final double evaluateDouble(String value) { 130 if (FacesUtils.isExpression(value)) { 131 Number obj = (Number ) createValueBinding(value).getValue(getFacesContext()); 132 return obj.doubleValue(); 133 } 134 135 return Double.parseDouble(value); 136 } 137 138 142 public void setup(SourceResolver resolver, Map objectModel, Parameters parameters) 143 throws SAXException , IOException { 144 super.setup(resolver, objectModel, parameters); 145 146 this.context = FacesUtils.getFacesContext(this, objectModel); 148 149 ResponseWriter writer = this.context.getResponseWriter(); 151 if (writer == null) { 152 Request request = ObjectModelHelper.getRequest(objectModel); 154 writer = new XMLResponseWriter(this.xmlConsumer, null, request.getCharacterEncoding()); 155 this.context.setResponseWriter(writer); 156 } 157 } 158 159 public int doStartTag(String namespaceURI, String localName, String qName, Attributes attrs) 160 throws SAXException { 161 final UIComponentTag parentTag = findParent(); 162 163 this.component = findComponent(parentTag); 164 165 try { 166 if (!isSuppressed()) { 167 if (!this.component.getRendersChildren()) { 168 encodeBegin(); 169 getFacesContext().getResponseWriter().flush(); 170 } 171 } 172 } catch (IOException e) { 173 throw new SAXException ("Exception in doStartTag", e); 174 } 175 176 return getDoStartValue(); 177 } 178 179 public int doEndTag(String namespaceURI, String localName, String qName) 180 throws SAXException { 181 removeOldChildren(); 182 removeOldFacets(); 183 try { 184 if (!isSuppressed()) { 185 if (this.component.getRendersChildren()) { 186 encodeBegin(); 187 encodeChildren(); 188 } 189 encodeEnd(); 190 getFacesContext().getResponseWriter().flush(); 191 } 192 } catch (IOException e) { 193 throw new SAXException ("Exception in doEndTag", e); 194 } 195 196 return getDoEndValue(); 197 } 198 199 200 204 public void recycle() { 205 super.recycle(); 206 207 this.component = null; 208 this.context = null; 209 210 this.id = null; 211 this.binding = null; 212 this.created = false; 213 this.rendered = null; 214 215 this.createdComponents = null; 216 this.createdFacets = null; 217 } 218 219 220 224 protected abstract String getComponentType(); 225 226 protected abstract String getRendererType(); 227 228 protected int getDoEndValue() { 229 return Tag.EVAL_PAGE; 230 } 231 232 protected int getDoStartValue() { 233 return Tag.EVAL_BODY; 234 } 235 236 protected void encodeBegin() throws IOException { 237 this.component.encodeBegin(this.context); 238 } 239 240 protected void encodeChildren() throws IOException { 241 this.component.encodeChildren(this.context); 242 } 243 244 protected void encodeEnd() throws IOException { 245 this.component.encodeEnd(this.context); 246 } 247 248 protected void setProperties(UIComponent component) { 249 if (this.rendered != null) { 250 if (FacesUtils.isExpression(this.rendered)) { 251 ValueBinding vb = createValueBinding(this.rendered); 252 component.setValueBinding("rendered", vb); 253 } else { 254 component.setRendered(BooleanUtils.toBoolean(this.rendered)); 255 } 256 } 257 258 if (getRendererType() != null) { 259 component.setRendererType(getRendererType()); 260 } 261 } 262 263 protected final void setProperty(UIComponent component, String name, String value) { 264 if (value != null) { 265 if (FacesUtils.isExpression(value)) { 266 ValueBinding vb = createValueBinding(value); 267 component.setValueBinding(name, vb); 268 } else { 269 component.getAttributes().put(name, value); 270 } 271 } 272 } 273 274 protected final void setBooleanProperty(UIComponent component, String name, String value) { 275 if (value != null) { 276 if (FacesUtils.isExpression(value)) { 277 ValueBinding vb = createValueBinding(value); 278 component.setValueBinding(name, vb); 279 } else { 280 component.getAttributes().put(name, BooleanUtils.toBooleanObject(value)); 281 } 282 } 283 } 284 285 protected final void setIntegerProperty(UIComponent component, String name, String value) { 286 if (value != null) { 287 if (FacesUtils.isExpression(value)) { 288 ValueBinding vb = createValueBinding(value); 289 component.setValueBinding(name, vb); 290 } else { 291 component.getAttributes().put(name, new Integer (value)); 292 } 293 } 294 } 295 296 297 301 private UIComponentTag findParent() { 302 Tag parent = this; 303 do { 304 parent = parent.getParent(); 305 } while (parent != null && !(parent instanceof UIComponentTag)); 306 307 return (UIComponentTag) parent; 308 } 309 310 313 private UIComponent findComponent(UIComponentTag parentTag) { 314 if (parentTag == null) { 316 UIComponent root = getFacesContext().getViewRoot(); 317 setProperties(root); 318 if (this.id != null) { 319 root.setId(this.id); 320 } 321 return root; 322 } 323 324 String id = createId(); 325 326 String facet = getFacetName(); 328 if (facet != null) { 329 return createFacet(parentTag, facet, id); 330 } 331 332 return createChild(parentTag, id); 334 } 335 336 339 private String getFacetName() { 340 final Tag parentTag = getParent(); 341 if (parentTag instanceof FacetTag) { 342 return ((FacetTag) parentTag).getName(); 343 } 344 345 return null; 346 } 347 348 private boolean isSuppressed() { 349 if (getFacetName() != null) { 350 return true; 351 } 352 353 if (!this.component.isRendered()) { 354 return true; 355 } 356 357 for (UIComponent component = this.component.getParent(); component != null; component = component.getParent()) { 358 if (!component.isRendered()) { 359 return true; 360 } 361 362 if (component.getRendersChildren()) { 363 return true; 364 } 365 } 366 367 return false; 368 } 369 370 private void addChild(UIComponent child) { 371 if (createdComponents == null) { 372 createdComponents = new ArrayList (); 373 } 374 createdComponents.add(child.getId()); 375 } 376 377 private void addFacet(String name) { 378 if (createdFacets == null) { 379 createdFacets = new ArrayList (); 380 } 381 createdFacets.add(name); 382 } 383 384 private UIComponent createComponent(String id) { 385 UIComponent component; 386 Application application = context.getApplication(); 387 if (this.binding != null) { 388 ValueBinding vb = application.createValueBinding(this.binding); 389 component = application.createComponent(vb, context, getComponentType()); 390 component.setValueBinding("binding", vb); 391 } else { 392 component = application.createComponent(getComponentType()); 393 } 394 component.setId(id); 395 this.created = true; 396 397 setProperties(component); 398 return component; 399 } 400 401 private UIComponent createChild(UIComponentTag parentTag, String id) { 402 final UIComponent parent = parentTag.getComponentInstance(); 403 UIComponent component = FacesUtils.getChild(parent, id); 404 if (component == null) { 405 component = createComponent(id); 406 parent.getChildren().add(component); 407 } 408 409 parentTag.addChild(component); 410 return component; 411 } 412 413 private UIComponent createFacet(UIComponentTag parentTag, String name, String id) { 414 final UIComponent parent = parentTag.getComponentInstance(); 415 UIComponent component = (UIComponent) parent.getFacets().get(name); 416 if (component == null) { 417 component = createComponent(id); 418 parent.getFacets().put(name, component); 419 } 420 421 parentTag.addFacet(name); 422 return component; 423 } 424 425 private String createId() { 426 if (this.id == null) { 427 return getFacesContext().getViewRoot().createUniqueId(); 428 } 429 430 return this.id; 431 } 432 433 private void removeOldChildren() { 434 List oldList = (List ) component.getAttributes().remove(CREATED_COMPONENTS); 435 if (oldList != null) { 436 if (createdComponents != null) { 437 for (Iterator olds = oldList.iterator(); olds.hasNext();) { 438 String old = (String ) olds.next(); 439 if (!createdComponents.contains(old)) { 440 FacesUtils.removeChild(component, old); 441 } 442 } 443 } else { 444 for (Iterator i = oldList.iterator(); i.hasNext();) { 445 FacesUtils.removeChild(component, (String ) i.next()); 446 } 447 } 448 } 449 450 if (createdComponents != null) { 451 component.getAttributes().put(CREATED_COMPONENTS, createdComponents); 452 createdComponents = null; 453 } 454 } 455 456 private void removeOldFacets() { 457 List oldList = (List ) component.getAttributes().remove(CREATED_FACETS); 458 if (oldList != null) { 459 if (createdFacets != null) { 460 for (Iterator olds = oldList.iterator(); olds.hasNext();) { 461 String old = (String ) olds.next(); 462 if (!createdFacets.contains(old)) { 463 component.getFacets().remove(old); 464 } 465 } 466 } else { 467 for (Iterator olds = oldList.iterator(); olds.hasNext(); ) { 468 String old = (String ) olds.next(); 469 component.getFacets().remove(old); 470 } 471 } 472 } 473 474 if (createdFacets != null) { 475 component.getAttributes().put(CREATED_FACETS, createdFacets); 476 createdFacets = null; 477 } 478 } 479 480 481 485 public String getId() { 486 return this.id; 487 } 488 489 public void setId(String id) { 490 this.id = id; 491 } 492 493 public String getBinding() { 494 return this.binding; 495 } 496 497 public void setBinding(String binding) { 498 if (!FacesUtils.isExpression(binding)) { 499 throw new IllegalArgumentException ("Binding value must be an expression"); 500 } 501 502 this.binding = binding; 503 } 504 505 public String getRendered() { 506 return this.rendered; 507 } 508 509 public void setRendered(String rendered) { 510 this.rendered = rendered; 511 } 512 } 513 | Popular Tags |