1 17 package org.alfresco.web.ui.repo.component; 18 19 import java.io.IOException ; 20 import java.util.Collection ; 21 import java.util.Map ; 22 23 import javax.faces.component.EditableValueHolder; 24 import javax.faces.component.NamingContainer; 25 import javax.faces.component.UIComponent; 26 import javax.faces.component.UIInput; 27 import javax.faces.context.FacesContext; 28 import javax.faces.context.ResponseWriter; 29 import javax.faces.el.ValueBinding; 30 import javax.faces.event.AbortProcessingException; 31 import javax.faces.event.ActionEvent; 32 import javax.faces.event.FacesEvent; 33 import javax.transaction.UserTransaction ; 34 35 import org.alfresco.service.cmr.dictionary.DictionaryService; 36 import org.alfresco.service.cmr.repository.NodeRef; 37 import org.alfresco.service.cmr.repository.NodeService; 38 import org.alfresco.web.app.Application; 39 import org.alfresco.web.bean.repository.Repository; 40 import org.alfresco.web.ui.common.Utils; 41 import org.alfresco.web.ui.common.WebResources; 42 43 48 public abstract class AbstractItemSelector extends UIInput 49 { 50 private static final String MSG_GO_UP = "go_up"; 51 private static final String MSG_OK = "ok"; 52 private static final String MSG_CANCEL = "cancel"; 53 54 private final static String OK_BUTTON = "_ok"; 55 protected final static String OPTION = "_option"; 56 57 protected final static int MODE_BEFORE_SELECTION = 0; 58 protected final static int MODE_INITIAL_SELECTION = 1; 59 protected final static int MODE_DRILLDOWN_SELECTION = 2; 60 protected final static int MODE_CONFIRM_SELECTION = 3; 61 protected final static int MODE_CANCEL_SELECTION = 4; 62 63 64 protected String label = null; 65 66 67 protected Integer spacing = null; 68 69 70 protected int mode = MODE_BEFORE_SELECTION; 71 72 73 protected String navigationId = null; 74 75 76 protected String initialSelectionId = null; 77 78 79 protected Boolean disabled; 80 81 82 85 88 public AbstractItemSelector() 89 { 90 setRendererType(null); 92 } 93 94 97 public abstract String getFamily(); 98 99 104 public abstract String getDefaultLabel(); 105 106 112 public abstract String getParentNodeId(FacesContext context); 113 114 120 public abstract Collection <NodeRef> getChildrenForNode(FacesContext context); 121 122 128 public abstract Collection <NodeRef> getRootChildren(FacesContext context); 129 130 133 public abstract String getItemIcon(); 134 135 138 public void restoreState(FacesContext context, Object state) 139 { 140 Object values[] = (Object [])state; 141 super.restoreState(context, values[0]); 143 this.label = (String )values[1]; 144 this.spacing = (Integer )values[2]; 145 this.mode = ((Integer )values[3]).intValue(); 146 this.navigationId = (String )values[4]; 147 this.initialSelectionId = (String )values[5]; 148 this.disabled = (Boolean )values[6]; 149 } 150 151 154 public Object saveState(FacesContext context) 155 { 156 Object values[] = new Object [7]; 157 values[0] = super.saveState(context); 159 values[1] = this.label; 160 values[2] = this.spacing; 161 values[3] = this.mode; 162 values[4] = this.navigationId; 163 values[5] = this.initialSelectionId; 164 values[6] = this.disabled; 165 return (values); 166 } 167 168 171 public void decode(FacesContext context) 172 { 173 Map requestMap = context.getExternalContext().getRequestParameterMap(); 174 String fieldId = getHiddenFieldName(); 175 String value = (String )requestMap.get(fieldId); 176 177 int mode = this.mode; 178 if (value != null && value.length() != 0) 179 { 180 182 String id = null; 185 int sepIndex = value.indexOf(NamingContainer.SEPARATOR_CHAR); 186 if (sepIndex != -1) 187 { 188 mode = Integer.parseInt(value.substring(0, sepIndex)); 189 if (value.length() > sepIndex + 1) 190 { 191 id = value.substring(sepIndex + 1); 192 } 193 } 194 else 195 { 196 mode = Integer.parseInt(value); 197 } 198 199 ItemSelectorEvent event = new ItemSelectorEvent(this, mode, id); 201 this.queueEvent(event); 202 } 203 204 if (mode == MODE_CONFIRM_SELECTION) 205 { 206 String selection = (String )requestMap.get(getClientId(context) + OPTION); 209 if (selection != null && selection.length() != 0) 210 { 211 ((EditableValueHolder)this).setSubmittedValue(new NodeRef(Repository.getStoreRef(), selection)); 212 } 213 } 214 } 215 216 219 public void broadcast(FacesEvent event) throws AbortProcessingException 220 { 221 if (event instanceof ItemSelectorEvent) 222 { 223 ItemSelectorEvent spaceEvent = (ItemSelectorEvent)event; 224 this.mode = spaceEvent.Mode; 225 this.navigationId = spaceEvent.Id; 226 } 227 else 228 { 229 super.broadcast(event); 230 } 231 } 232 233 236 public void encodeBegin(FacesContext context) throws IOException 237 { 238 if (isRendered() == false) 239 { 240 return; 241 } 242 243 NodeService service = getNodeService(context); 244 245 if (isDisabled()) 246 { 247 ResponseWriter out = context.getResponseWriter(); 249 250 NodeRef nodeRef = (NodeRef)getSubmittedValue(); 252 if (nodeRef == null) 253 { 254 Object val = getValue(); 255 if (val instanceof NodeRef) 256 { 257 nodeRef = (NodeRef)val; 258 } 259 else if (val instanceof String && ((String )val).length() != 0) 260 { 261 nodeRef = new NodeRef((String )val); 262 } 263 } 264 265 if (nodeRef != null) 267 { 268 out.write(Repository.getNameForNode(service, nodeRef)); 269 } 270 } 271 else 272 { 273 String clientId = getClientId(context); 275 276 StringBuilder buf = new StringBuilder (512); 277 Map attrs = this.getAttributes(); 278 boolean showValueInHiddenField = false; 279 NodeRef value = null; 280 281 String image = null; 282 if (getItemIcon() != null) 283 { 284 image = "<span style='padding-right:4px'>" + Utils.buildImageTag(context, getItemIcon(), null, "absmiddle") + "</span>"; 285 } 286 287 switch (this.mode) 288 { 289 case MODE_BEFORE_SELECTION: 290 case MODE_CONFIRM_SELECTION: 291 case MODE_CANCEL_SELECTION: 292 { 293 UserTransaction tx = null; 294 try 295 { 296 tx = Repository.getUserTransaction(context, true); 297 tx.begin(); 298 299 NodeRef submittedValue = (NodeRef)getSubmittedValue(); 300 if (submittedValue != null) 301 { 302 value = submittedValue; 303 } 304 else 305 { 306 Object val = getValue(); 307 if (val instanceof NodeRef) 308 { 309 value = (NodeRef)val; 310 } 311 else if (val instanceof String && ((String )val).length() != 0) 312 { 313 value = new NodeRef((String )val); 314 } 315 } 316 317 String label; 319 if (value == null) 320 { 321 label = getLabel(); 322 323 if (label == null) 325 { 326 label = getDefaultLabel(); 327 } 328 } 329 else 330 { 331 label = Repository.getNameForNode(service, value); 332 showValueInHiddenField = true; 333 } 334 335 buf.append("<span"); 337 if (attrs.get("style") != null) 338 { 339 buf.append(" style=\"") 340 .append(attrs.get("style")) 341 .append('"'); 342 } 343 if (attrs.get("styleClass") != null) 344 { 345 buf.append(" class=") 346 .append(attrs.get("styleClass")); 347 } 348 buf.append(">"); 349 350 int theMode = MODE_INITIAL_SELECTION; 353 354 if (value == null && this.getInitialSelection() != null) 356 { 357 value = new NodeRef(Repository.getStoreRef(), this.getInitialSelection()); 358 } 359 360 String fieldValue; 362 if (value != null) 363 { 364 fieldValue = encodeFieldValues(theMode, value.getId()); 365 } 366 else 367 { 368 fieldValue = encodeFieldValues(theMode, null); 369 } 370 buf.append("<a HREF='#' onclick=\""); 371 buf.append(Utils.generateFormSubmit(context, this, getHiddenFieldName(), fieldValue)); 372 buf.append('"'); 373 if (attrs.get("nodeStyle") != null) 374 { 375 buf.append(" style=\"") 376 .append(attrs.get("nodeStyle")) 377 .append('"'); 378 } 379 if (attrs.get("nodeStyleClass") != null) 380 { 381 buf.append(" class=") 382 .append(attrs.get("nodeStyleClass")); 383 } 384 buf.append(">") 385 .append(label) 386 .append("</a></span>"); 387 388 tx.commit(); 389 } 390 catch (Throwable err) 391 { 392 try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} 393 Utils.addErrorMessage(err.getMessage(), err); 394 } 395 396 break; 397 } 398 399 case MODE_DRILLDOWN_SELECTION: 400 case MODE_INITIAL_SELECTION: 401 { 402 buf.append("<table border=0 cellspacing=1 cellpadding=1"); 405 if (attrs.get("style") != null) 406 { 407 buf.append(" style=\"") 408 .append(attrs.get("style")) 409 .append('"'); 410 } 411 if (attrs.get("styleClass") != null) 412 { 413 buf.append(" class=") 414 .append(attrs.get("styleClass")); 415 } 416 buf.append(">"); 417 418 if (this.mode == MODE_INITIAL_SELECTION) 422 { 423 this.navigationId = getParentNodeId(context); 424 } 425 426 if (this.navigationId != null) 428 { 429 String id = getParentNodeId(context); 432 433 buf.append("<tr><td></td><td>"); 434 435 String upImage = Utils.buildImageTag(context, WebResources.IMAGE_GO_UP, null, "absmiddle"); 436 437 renderNodeLink(context, id, Application.getMessage(context, MSG_GO_UP), upImage, buf); 439 buf.append("</td></tr>"); 440 } 441 442 String okButtonId = clientId + OK_BUTTON; 443 boolean okButtonEnabled = false; 444 445 Collection <NodeRef> childRefs; 447 if (this.navigationId != null) 448 { 449 childRefs = getChildrenForNode(context); 451 } 452 else 453 { 454 childRefs = getRootChildren(context); 456 } 457 458 UserTransaction tx = null; 459 try 460 { 461 tx = Repository.getUserTransaction(context, true); 462 tx.begin(); 463 464 for (NodeRef childRef : childRefs) 465 { 466 String childId = childRef.getId(); 468 buf.append("<tr><td><input type='radio' name='") 469 .append(clientId).append(OPTION).append("' value='") 470 .append(childId).append("'"); 471 if (childId.equals(this.initialSelectionId)) 472 { 473 buf.append(" checked"); 474 475 okButtonEnabled = true; 477 478 this.initialSelectionId = null; 480 } 481 buf.append(" onclick=\"javascript:document.getElementById('") 482 .append(okButtonId) 483 .append("').disabled=false;\""); 484 buf.append("/></td><td>"); 485 486 NodeRef childNodeRef = new NodeRef(Repository.getStoreRef(), childId); 488 String name = Repository.getNameForNode(service, childNodeRef); 489 renderNodeLink(context, childId, name, image, buf); 490 buf.append("</td></tr>"); 491 } 492 493 String fieldValue = encodeFieldValues(MODE_CONFIRM_SELECTION, null); 495 buf.append("<tr style='padding-top:4px'><td></td><td align=center>") 496 .append("<input type='button' ") 497 .append(okButtonEnabled == false ? "disabled" : "") 498 .append(" onclick=\"") 499 .append(Utils.generateFormSubmit(context, this, getHiddenFieldName(), fieldValue)) 500 .append("\" value='") 501 .append(Application.getMessage(context, MSG_OK)) 502 .append("' id='") 503 .append(okButtonId) 504 .append("'> "); 505 506 fieldValue = encodeFieldValues(MODE_CANCEL_SELECTION, null); 508 buf.append("<input type='button' onclick=\"") 509 .append(Utils.generateFormSubmit(context, this, getHiddenFieldName(), fieldValue)) 510 .append("\" value='") 511 .append(Application.getMessage(context, MSG_CANCEL)) 512 .append("'></td></tr>"); 513 514 buf.append("</table>"); 515 516 tx.commit(); 517 } 518 catch (Throwable err) 519 { 520 try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} 521 throw new RuntimeException (err); 522 } 523 524 break; 525 } 526 } 527 528 buf.append("<input type='hidden' name='"); 531 buf.append(clientId); 532 buf.append("_selected' id='"); 533 buf.append(clientId); 534 buf.append("_selected' value='"); 535 if (showValueInHiddenField) 536 { 537 buf.append(value); 538 } 539 buf.append("'/>"); 540 541 context.getResponseWriter().write(buf.toString()); 542 } 543 } 544 545 546 549 552 public String getLabel() 553 { 554 ValueBinding vb = getValueBinding("label"); 555 if (vb != null) 556 { 557 this.label = (String )vb.getValue(getFacesContext()); 558 } 559 560 return this.label; 561 } 562 563 566 public void setLabel(String label) 567 { 568 this.label = label; 569 } 570 571 574 public Integer getSpacing() 575 { 576 ValueBinding vb = getValueBinding("spacing"); 577 if (vb != null) 578 { 579 this.spacing = (Integer )vb.getValue(getFacesContext()); 580 } 581 582 if (this.spacing != null) 583 { 584 return this.spacing.intValue(); 585 } 586 else 587 { 588 return 2; 590 } 591 } 592 593 596 public void setSpacing(Integer spacing) 597 { 598 this.spacing = spacing; 599 } 600 601 604 public String getInitialSelection() 605 { 606 ValueBinding vb = getValueBinding("initialSelection"); 607 if (vb != null) 608 { 609 this.initialSelectionId = (String )vb.getValue(getFacesContext()); 610 } 611 612 return this.initialSelectionId; 613 } 614 615 618 public void setInitialSelection(String initialSelection) 619 { 620 this.initialSelectionId = initialSelection; 621 } 622 623 628 public boolean isDisabled() 629 { 630 if (this.disabled == null) 631 { 632 ValueBinding vb = getValueBinding("disabled"); 633 if (vb != null) 634 { 635 this.disabled = (Boolean )vb.getValue(getFacesContext()); 636 } 637 } 638 639 if (this.disabled == null) 640 { 641 this.disabled = Boolean.FALSE; 642 } 643 644 return this.disabled; 645 } 646 647 652 public void setDisabled(boolean disabled) 653 { 654 this.disabled = disabled; 655 } 656 657 658 661 668 protected String getHiddenFieldName() 669 { 670 return this.getClientId(getFacesContext()); 671 } 672 673 protected String encodeFieldValues(int mode, String id) 674 { 675 if (id != null) 676 { 677 return Integer.toString(mode) + NamingContainer.SEPARATOR_CHAR + id; 678 } 679 else 680 { 681 return Integer.toString(mode); 682 } 683 } 684 685 693 protected String renderNodeLink(FacesContext context, String id, String name, String prefix, StringBuilder buf) 694 { 695 buf.append("<a HREF='#' onclick=\""); 696 String fieldValue = encodeFieldValues(MODE_DRILLDOWN_SELECTION, id); 697 buf.append(Utils.generateFormSubmit(context, this, getHiddenFieldName(), fieldValue)); 698 buf.append('"'); 699 Map attrs = this.getAttributes(); 700 if (attrs.get("nodeStyle") != null) 701 { 702 buf.append(" style=\"") 703 .append(attrs.get("nodeStyle")) 704 .append('"'); 705 } 706 if (attrs.get("nodeStyleClass") != null) 707 { 708 buf.append(" class=") 709 .append(attrs.get("nodeStyleClass")); 710 } 711 buf.append('>'); 712 713 if (prefix != null) 714 { 715 buf.append(prefix); 716 } 717 buf.append(Utils.encode(name)); 718 719 buf.append("</a>"); 720 721 return buf.toString(); 722 } 723 724 731 protected static NodeService getNodeService(FacesContext context) 732 { 733 NodeService service = Repository.getServiceRegistry(context).getNodeService(); 734 if (service == null) 735 { 736 throw new IllegalStateException ("Unable to obtain NodeService bean reference."); 737 } 738 739 return service; 740 } 741 742 749 protected static DictionaryService getDictionaryService(FacesContext context) 750 { 751 DictionaryService service = Repository.getServiceRegistry(context).getDictionaryService(); 752 if (service == null) 753 { 754 throw new IllegalStateException ("Unable to obtain DictionaryService bean reference."); 755 } 756 757 return service; 758 } 759 760 763 public static class ItemSelectorEvent extends ActionEvent 764 { 765 public ItemSelectorEvent(UIComponent component, int mode, String id) 766 { 767 super(component); 768 Mode = mode; 769 Id = id; 770 } 771 772 public int Mode; 773 private String Id; 774 } 775 } 776 | Popular Tags |