1 16 package org.apache.myfaces.custom.tree2; 17 18 import javax.faces.component.UIComponentBase; 19 import javax.faces.component.NamingContainer; 20 import javax.faces.component.UIComponent; 21 import javax.faces.component.EditableValueHolder; 22 import javax.faces.context.FacesContext; 23 import javax.faces.event.AbortProcessingException; 24 import javax.faces.event.FacesEvent; 25 import javax.faces.event.PhaseId; 26 import javax.faces.event.FacesListener; 27 import javax.faces.el.ValueBinding; 28 import javax.faces.application.FacesMessage; 29 30 import java.io.Serializable ; 31 import java.io.IOException ; 32 import java.util.Iterator ; 33 import java.util.Map ; 34 import java.util.HashMap ; 35 import java.util.List ; 36 37 38 49 public class UITreeData extends UIComponentBase implements NamingContainer 50 { 51 52 public static final String COMPONENT_TYPE = "org.apache.myfaces.Tree2"; 53 public static final String COMPONENT_FAMILY = "org.apache.myfaces.HtmlTree2"; private static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.Tree2"; 55 56 private static final int PROCESS_DECODES = 1; 57 private static final int PROCESS_VALIDATORS = 2; 58 private static final int PROCESS_UPDATES = 3; 59 60 private TreeModel _model; 61 private TreeNode _value; 62 private String _var; 63 private String _nodeId; 64 private Map _saved = new HashMap (); 65 66 69 public UITreeData() 70 { 71 setRendererType(DEFAULT_RENDERER_TYPE); 72 } 73 74 75 public String getFamily() 77 { 78 return COMPONENT_FAMILY; 79 } 80 81 public Object saveState(FacesContext context) 83 { 84 Object values[] = new Object [3]; 85 values[0] = super.saveState(context); 86 values[1] = _value; 87 values[2] = _var; 88 return ((Object ) (values)); 89 } 90 91 92 public void restoreState(FacesContext context, Object state) 94 { 95 Object values[] = (Object []) state; 96 super.restoreState(context, values[0]); 97 98 _value = (TreeNode)values[1]; 99 _var = (String )values[2]; 100 } 101 102 public void queueEvent(FacesEvent event) 103 { 104 super.queueEvent(new FacesEventWrapper(event, getNodeId(), this)); 105 } 106 107 108 public void broadcast(FacesEvent event) throws AbortProcessingException 109 { 110 if (event instanceof FacesEventWrapper) 111 { 112 FacesEventWrapper childEvent = (FacesEventWrapper) event; 113 String currNodeId = getNodeId(); 114 setNodeId(childEvent.getNodeId()); 115 FacesEvent nodeEvent = childEvent.getFacesEvent(); 116 nodeEvent.getComponent().broadcast(nodeEvent); 117 setNodeId(currNodeId); 118 return; 119 } else 120 { 121 super.broadcast(event); 122 return; 123 } 124 } 125 126 127 public void processDecodes(FacesContext context) 129 { 130 if (context == null) throw new NullPointerException ("context"); 131 if (!isRendered()) return; 132 133 _model = null; 134 _saved = new HashMap (); 135 136 processNodes(context, PROCESS_DECODES, null, 0); 137 138 setNodeId(null); 139 decode(context); 140 } 141 142 public void processValidators(FacesContext context) 144 { 145 if (context == null) throw new NullPointerException ("context"); 146 if (!isRendered()) return; 147 148 processNodes(context, PROCESS_VALIDATORS, null, 0); 149 150 setNodeId(null); 151 } 152 153 154 public void processUpdates(FacesContext context) 156 { 157 if (context == null) throw new NullPointerException ("context"); 158 if (!isRendered()) return; 159 160 processNodes(context, PROCESS_UPDATES, null, 0); 161 162 setNodeId(null); 163 } 164 165 public String getClientId(FacesContext context) 167 { 168 String ownClientId = super.getClientId(context); 169 if (_nodeId != null) 170 { 171 return ownClientId + NamingContainer.SEPARATOR_CHAR + _nodeId; 172 } else 173 { 174 return ownClientId; 175 } 176 } 177 178 public void setValueBinding(String name, ValueBinding binding) 180 { 181 if ("value".equals(name)) 182 { 183 _model = null; 184 } else if ("nodeVar".equals(name) || "nodeId".equals(name) || "treeVar".equals(name)) 185 { 186 throw new IllegalArgumentException ("name " + name); 187 } 188 super.setValueBinding(name, binding); 189 } 190 191 public void encodeBegin(FacesContext context) throws IOException 193 { 194 200 if (!keepSaved(context)) 201 { 202 _saved = new HashMap (); 203 } 204 205 super.encodeBegin(context); 206 } 207 208 213 public void setValue(TreeNode value) 214 { 215 _model = null; 216 _value = value; 217 } 218 219 220 225 public Object getValue() 226 { 227 if (_value != null) return _value; 228 ValueBinding vb = getValueBinding("value"); 229 return vb != null ? vb.getValue(getFacesContext()) : null; 230 } 231 232 238 public void setVar(String var) 239 { 240 _var = var; 241 } 242 243 244 250 public String getVar() 251 { 252 return _var; 253 } 254 255 260 public TreeNode getNode() 261 { 262 TreeModel model = getDataModel(); 263 264 if (model == null) 265 { 266 return null; 267 } 268 269 return model.getNode(); 270 } 271 272 273 public String getNodeId() 274 { 275 return _nodeId; 276 } 277 278 279 public void setNodeId(String nodeId) 280 { 281 saveDescendantState(); 282 283 _nodeId = nodeId; 284 285 TreeModel model = getDataModel(); 286 if (model == null) 287 { 288 return; 289 } 290 model.setNodeId(nodeId); 291 292 restoreDescendantState(); 293 294 Map requestMap = getFacesContext().getExternalContext().getRequestMap(); 295 296 if (_var != null) 297 { 298 if (nodeId == null) 299 { 300 requestMap.remove(_var); 301 } else 302 { 303 requestMap.put(_var, getNode()); 304 } 305 } 306 } 307 308 309 318 public String [] getPathInformation(String nodeId) 319 { 320 return getDataModel().getPathInformation(nodeId); 321 } 322 323 330 public boolean isLastChild(String nodeId) 331 { 332 return getDataModel().isLastChild(nodeId); 333 } 334 335 342 private TreeModel getDataModel() 343 { 344 if (_model != null) 345 { 346 return _model; 347 } 348 349 Object value = getValue(); 350 if (value != null) 351 { 352 if (value instanceof TreeModel) 353 { 354 _model = (TreeModel) value; 355 } else if (value instanceof TreeNode) 356 { 357 _model = new TreeModel((TreeNode) value); 358 } 359 } 360 361 return _model; 362 } 363 364 private void processNodes(FacesContext context, int processAction, String parentId, int childLevel) 365 { 366 UIComponent facet = null; 367 setNodeId(parentId != null ? parentId + NamingContainer.SEPARATOR_CHAR + childLevel : "0"); 368 TreeNode node = getNode(); 369 370 facet = getFacet(node.getType()); 371 372 if (facet == null) 373 { 374 throw new IllegalArgumentException ("Unable to locate facet with the name: " + node.getType()); 375 } 376 377 switch (processAction) 378 { 379 case PROCESS_DECODES: 380 381 facet.processDecodes(context); 382 break; 383 384 case PROCESS_VALIDATORS: 385 386 facet.processValidators(context); 387 break; 388 389 case PROCESS_UPDATES: 390 391 facet.processUpdates(context); 392 break; 393 } 394 395 processChildNodes(context, node, processAction); 396 } 397 398 406 protected void processChildNodes(FacesContext context, TreeNode parentNode, int processAction) 407 { 408 int kidId = 0; 409 String currId = getNodeId(); 410 411 List children = parentNode.getChildren(); 412 413 for (int i = 0; i < children.size(); i++) 414 { 415 processNodes(context, processAction, currId, kidId++); 416 } 417 } 418 419 424 private void saveDescendantState() 425 { 426 FacesContext context = getFacesContext(); 427 Iterator i = getFacets().values().iterator(); 428 while (i.hasNext()) 429 { 430 UIComponent facet = (UIComponent) i.next(); 431 saveDescendantState(facet, context); 432 } 433 } 434 435 441 private void saveDescendantState(UIComponent component, FacesContext context) 442 { 443 if (component instanceof EditableValueHolder) 444 { 445 EditableValueHolder input = (EditableValueHolder) component; 446 String clientId = component.getClientId(context); 447 SavedState state = (SavedState) _saved.get(clientId); 448 if (state == null) 449 { 450 state = new SavedState(); 451 _saved.put(clientId, state); 452 } 453 state.setValue(input.getLocalValue()); 454 state.setValid(input.isValid()); 455 state.setSubmittedValue(input.getSubmittedValue()); 456 state.setLocalValueSet(input.isLocalValueSet()); 457 } 458 459 List kids = component.getChildren(); 460 for (int i = 0; i < kids.size(); i++) 461 { 462 saveDescendantState((UIComponent) kids.get(i), context); 463 } 464 } 465 466 467 470 private void restoreDescendantState() 471 { 472 FacesContext context = getFacesContext(); 473 Iterator i = getFacets().values().iterator(); 474 while (i.hasNext()) 475 { 476 UIComponent facet = (UIComponent) i.next(); 477 restoreDescendantState(facet, context); 478 } 479 } 480 481 487 private void restoreDescendantState(UIComponent component, FacesContext context) 488 { 489 String id = component.getId(); 490 component.setId(id); 492 if (component instanceof EditableValueHolder) 493 { 494 EditableValueHolder input = (EditableValueHolder) component; 495 String clientId = component.getClientId(context); 496 SavedState state = (SavedState) _saved.get(clientId); 497 if (state == null) 498 { 499 state = new SavedState(); 500 } 501 input.setValue(state.getValue()); 502 input.setValid(state.isValid()); 503 input.setSubmittedValue(state.getSubmittedValue()); 504 input.setLocalValueSet(state.isLocalValueSet()); 505 } 506 507 List kids = component.getChildren(); 508 for (int i = 0; i < kids.size(); i++) 509 { 510 restoreDescendantState((UIComponent)kids.get(i), context); 511 } 512 } 513 514 521 private static class SavedState implements Serializable 522 { 523 524 private Object submittedValue; 525 private boolean valid = true; 526 private Object value; 527 private boolean localValueSet; 528 529 Object getSubmittedValue() 530 { 531 return submittedValue; 532 } 533 534 void setSubmittedValue(Object submittedValue) 535 { 536 this.submittedValue = submittedValue; 537 } 538 539 boolean isValid() 540 { 541 return valid; 542 } 543 544 void setValid(boolean valid) 545 { 546 this.valid = valid; 547 } 548 549 Object getValue() 550 { 551 return value; 552 } 553 554 void setValue(Object value) 555 { 556 this.value = value; 557 } 558 559 boolean isLocalValueSet() 560 { 561 return localValueSet; 562 } 563 564 void setLocalValueSet(boolean localValueSet) 565 { 566 this.localValueSet = localValueSet; 567 } 568 } 569 570 576 private static class FacesEventWrapper extends FacesEvent 577 { 578 579 private FacesEvent _wrappedFacesEvent; 580 private String _nodeId; 581 582 583 public FacesEventWrapper(FacesEvent facesEvent, String nodeId, UIComponent component) 584 { 585 super(component); 586 _wrappedFacesEvent = facesEvent; 587 _nodeId = nodeId; 588 } 589 590 591 public PhaseId getPhaseId() 592 { 593 return _wrappedFacesEvent.getPhaseId(); 594 } 595 596 597 public void setPhaseId(PhaseId phaseId) 598 { 599 _wrappedFacesEvent.setPhaseId(phaseId); 600 } 601 602 603 public void queue() 604 { 605 _wrappedFacesEvent.queue(); 606 } 607 608 609 public String toString() 610 { 611 return _wrappedFacesEvent.toString(); 612 } 613 614 615 public boolean isAppropriateListener(FacesListener faceslistener) 616 { 617 return false; 619 } 620 621 622 public void processListener(FacesListener faceslistener) 623 { 624 throw new UnsupportedOperationException ("This event type is only intended for wrapping a real event"); 625 } 626 627 628 public FacesEvent getFacesEvent() 629 { 630 return _wrappedFacesEvent; 631 } 632 633 634 public String getNodeId() 635 { 636 return _nodeId; 637 } 638 } 639 640 646 private boolean keepSaved(FacesContext context) 647 { 648 Iterator clientIds = _saved.keySet().iterator(); 649 while (clientIds.hasNext()) 650 { 651 String clientId = (String ) clientIds.next(); 652 Iterator messages = context.getMessages(clientId); 653 while (messages.hasNext()) 654 { 655 FacesMessage message = (FacesMessage) messages.next(); 656 if (message.getSeverity().compareTo(FacesMessage.SEVERITY_ERROR) >= 0) 657 { 658 return true; 659 } 660 } 661 } 662 663 return false; 664 } 665 } 666 | Popular Tags |