1 17 package org.alfresco.web.bean; 18 19 import java.io.IOException ; 20 import java.io.Writer ; 21 import java.text.MessageFormat ; 22 import java.text.SimpleDateFormat ; 23 import java.util.ArrayList ; 24 import java.util.Collections ; 25 import java.util.Date ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 import java.util.Map ; 29 30 import javax.faces.component.UIComponent; 31 import javax.faces.context.FacesContext; 32 import javax.faces.context.ResponseWriter; 33 import javax.faces.event.ActionEvent; 34 import javax.transaction.UserTransaction ; 35 36 import org.alfresco.error.AlfrescoRuntimeException; 37 import org.alfresco.model.ContentModel; 38 import org.alfresco.model.ForumModel; 39 import org.alfresco.service.cmr.dictionary.DictionaryService; 40 import org.alfresco.service.cmr.dictionary.TypeDefinition; 41 import org.alfresco.service.cmr.repository.AssociationRef; 42 import org.alfresco.service.cmr.repository.ChildAssociationRef; 43 import org.alfresco.service.cmr.repository.ContentReader; 44 import org.alfresco.service.cmr.repository.ContentService; 45 import org.alfresco.service.cmr.repository.InvalidNodeRefException; 46 import org.alfresco.service.cmr.repository.NodeRef; 47 import org.alfresco.service.cmr.repository.NodeService; 48 import org.alfresco.service.cmr.search.QueryParameterDefinition; 49 import org.alfresco.service.cmr.search.SearchService; 50 import org.alfresco.service.cmr.security.PermissionService; 51 import org.alfresco.service.namespace.NamespaceService; 52 import org.alfresco.service.namespace.QName; 53 import org.alfresco.service.namespace.RegexQNamePattern; 54 import org.alfresco.web.app.AlfrescoNavigationHandler; 55 import org.alfresco.web.app.Application; 56 import org.alfresco.web.app.context.IContextListener; 57 import org.alfresco.web.app.context.UIContextService; 58 import org.alfresco.web.bean.repository.MapNode; 59 import org.alfresco.web.bean.repository.Node; 60 import org.alfresco.web.bean.repository.NodePropertyResolver; 61 import org.alfresco.web.bean.repository.QNameNodeMap; 62 import org.alfresco.web.bean.repository.Repository; 63 import org.alfresco.web.config.ViewsConfigElement; 64 import org.alfresco.web.ui.common.Utils; 65 import org.alfresco.web.ui.common.component.UIActionLink; 66 import org.alfresco.web.ui.common.component.UIModeList; 67 import org.alfresco.web.ui.common.component.data.UIColumn; 68 import org.alfresco.web.ui.common.component.data.UIRichList; 69 import org.alfresco.web.ui.common.renderer.data.IRichListRenderer; 70 import org.apache.commons.logging.Log; 71 import org.apache.commons.logging.LogFactory; 72 import org.springframework.util.StringUtils; 73 74 79 public class ForumsBean implements IContextListener, NodeEventListener 80 { 81 private static Log logger = LogFactory.getLog(ForumsBean.class); 82 private static final String PAGE_NAME_FORUMS = "forums"; 83 private static final String PAGE_NAME_FORUM = "forum"; 84 private static final String PAGE_NAME_TOPIC = "topic"; 85 86 87 protected NodeService nodeService; 88 89 90 protected ContentService contentService; 91 92 93 protected DictionaryService dictionaryService; 94 95 96 protected SearchService searchService; 97 98 99 protected NamespaceService namespaceService; 100 101 102 protected BrowseBean browseBean; 103 104 105 protected NavigationBean navigator; 106 107 108 protected ViewsConfigElement viewsConfig = null; 109 110 111 protected UIRichList forumsRichList; 112 protected UIRichList forumRichList; 113 protected UIRichList topicRichList; 114 115 116 private List <Node> forums; 117 private List <Node> topics; 118 private List <Node> posts; 119 120 121 private String forumsViewMode; 122 123 124 private int forumsPageSize; 125 126 127 private String forumViewMode; 128 129 130 private int forumPageSize; 131 132 133 private String topicViewMode; 134 135 136 private int topicPageSize; 137 138 139 142 145 public ForumsBean() 146 { 147 UIContextService.getInstance(FacesContext.getCurrentInstance()).registerBean(this); 148 149 initFromClientConfig(); 150 } 151 152 153 156 159 public void setNodeService(NodeService nodeService) 160 { 161 this.nodeService = nodeService; 162 } 163 164 169 public void setContentService(ContentService contentService) 170 { 171 this.contentService = contentService; 172 } 173 174 177 public void setDictionaryService(DictionaryService dictionaryService) 178 { 179 this.dictionaryService = dictionaryService; 180 } 181 182 185 public void setSearchService(SearchService searchService) 186 { 187 this.searchService = searchService; 188 } 189 190 193 public void setNamespaceService(NamespaceService namespaceService) 194 { 195 this.namespaceService = namespaceService; 196 } 197 198 203 public void setBrowseBean(BrowseBean browseBean) 204 { 205 this.browseBean = browseBean; 206 } 207 208 211 public void setNavigator(NavigationBean navigator) 212 { 213 this.navigator = navigator; 214 } 215 216 219 public void setForumsRichList(UIRichList forumsRichList) 220 { 221 this.forumsRichList = forumsRichList; 222 if (this.forumsRichList != null) 223 { 224 this.forumsRichList.setInitialSortColumn( 226 this.viewsConfig.getDefaultSortColumn(PAGE_NAME_FORUMS)); 227 this.forumsRichList.setInitialSortDescending( 228 this.viewsConfig.hasDescendingSort(PAGE_NAME_FORUMS)); 229 } 230 } 231 232 235 public UIRichList getForumsRichList() 236 { 237 return this.forumsRichList; 238 } 239 240 243 public String getForumsViewMode() 244 { 245 return this.forumsViewMode; 246 } 247 248 251 public void setForumsViewMode(String forumsViewMode) 252 { 253 this.forumsViewMode = forumsViewMode; 254 } 255 256 259 public int getForumsPageSize() 260 { 261 return this.forumsPageSize; 262 } 263 264 267 public void setForumsPageSize(int forumsPageSize) 268 { 269 this.forumsPageSize = forumsPageSize; 270 } 271 272 275 public void setTopicRichList(UIRichList topicRichList) 276 { 277 this.topicRichList = topicRichList; 278 279 if (this.topicRichList != null) 280 { 281 this.topicRichList.setInitialSortColumn( 283 this.viewsConfig.getDefaultSortColumn(PAGE_NAME_TOPIC)); 284 this.topicRichList.setInitialSortDescending( 285 this.viewsConfig.hasDescendingSort(PAGE_NAME_TOPIC)); 286 } 287 } 288 289 292 public UIRichList getTopicRichList() 293 { 294 return this.topicRichList; 295 } 296 297 300 public String getTopicViewMode() 301 { 302 return this.topicViewMode; 303 } 304 305 308 public void setTopicViewMode(String topicViewMode) 309 { 310 this.topicViewMode = topicViewMode; 311 } 312 313 316 public int getTopicPageSize() 317 { 318 return this.topicPageSize; 319 } 320 321 324 public void setTopicPageSize(int topicPageSize) 325 { 326 this.topicPageSize = topicPageSize; 327 } 328 329 332 public void setForumRichList(UIRichList forumRichList) 333 { 334 this.forumRichList = forumRichList; 335 336 if (this.forumRichList != null) 337 { 338 this.forumRichList.setInitialSortColumn( 340 this.viewsConfig.getDefaultSortColumn(PAGE_NAME_FORUM)); 341 this.forumRichList.setInitialSortDescending( 342 this.viewsConfig.hasDescendingSort(PAGE_NAME_FORUM)); 343 } 344 } 345 346 349 public UIRichList getForumRichList() 350 { 351 return this.forumRichList; 352 } 353 354 357 public String getForumViewMode() 358 { 359 return this.forumViewMode; 360 } 361 362 365 public void setForumViewMode(String forumViewMode) 366 { 367 this.forumViewMode = forumViewMode; 368 } 369 370 373 public int getForumPageSize() 374 { 375 return this.forumPageSize; 376 } 377 378 381 public void setForumPageSize(int forumPageSize) 382 { 383 this.forumPageSize = forumPageSize; 384 } 385 386 public List <Node> getForums() 387 { 388 if (this.forums == null) 389 { 390 getNodes(); 391 } 392 393 return this.forums; 394 } 395 396 public List <Node> getTopics() 397 { 398 if (this.topics == null) 399 { 400 getNodes(); 401 } 402 403 return this.topics; 404 } 405 406 public List <Node> getPosts() 407 { 408 if (this.posts == null) 409 { 410 getNodes(); 411 } 412 413 return this.posts; 414 } 415 416 private void getNodes() 417 { 418 long startTime = 0; 419 if (logger.isDebugEnabled()) 420 startTime = System.currentTimeMillis(); 421 422 UserTransaction tx = null; 423 try 424 { 425 FacesContext context = FacesContext.getCurrentInstance(); 426 tx = Repository.getUserTransaction(context, true); 427 tx.begin(); 428 429 String parentNodeId = this.navigator.getCurrentNodeId(); 431 432 NodeRef parentRef; 433 if (parentNodeId == null) 434 { 435 parentRef = this.nodeService.getRootNode(Repository.getStoreRef()); 437 } 438 else 439 { 440 parentRef = new NodeRef(Repository.getStoreRef(), parentNodeId); 442 } 443 444 List <ChildAssociationRef> childRefs = this.nodeService.getChildAssocs(parentRef, 445 ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); 446 this.forums = new ArrayList <Node>(childRefs.size()); 447 this.topics = new ArrayList <Node>(childRefs.size()); 448 this.posts = new ArrayList <Node>(childRefs.size()); 449 450 for (ChildAssociationRef ref: childRefs) 451 { 452 NodeRef nodeRef = ref.getChildRef(); 454 455 if (this.nodeService.exists(nodeRef)) 456 { 457 QName type = this.nodeService.getType(nodeRef); 459 460 TypeDefinition typeDef = this.dictionaryService.getType(type); 462 463 if (typeDef != null) 464 { 465 467 if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_SYSTEM_FOLDER) == false) 468 { 469 if (this.dictionaryService.isSubClass(type, ForumModel.TYPE_FORUMS) || 470 this.dictionaryService.isSubClass(type, ForumModel.TYPE_FORUM)) 471 { 472 MapNode node = new MapNode(nodeRef, this.nodeService, true); 474 node.addPropertyResolver("icon", this.browseBean.resolverSpaceIcon); 475 node.addPropertyResolver("smallIcon", this.resolverSmallIcon); 476 477 this.forums.add(node); 478 } 479 if (this.dictionaryService.isSubClass(type, ForumModel.TYPE_TOPIC)) 480 { 481 MapNode node = new MapNode(nodeRef, this.nodeService, true); 483 node.addPropertyResolver("icon", this.browseBean.resolverSpaceIcon); 484 node.addPropertyResolver("smallIcon", this.resolverSmallIcon); 485 node.addPropertyResolver("replies", this.resolverReplies); 486 487 this.topics.add(node); 488 } 489 else if (this.dictionaryService.isSubClass(type, ForumModel.TYPE_POST)) 490 { 491 MapNode node = new MapNode(nodeRef, this.nodeService, true); 493 494 this.browseBean.setupCommonBindingProperties(node); 495 node.addPropertyResolver("smallIcon", this.resolverSmallIcon); 496 node.addPropertyResolver("message", this.resolverContent); 497 node.addPropertyResolver("replyTo", this.resolverReplyTo); 498 499 this.posts.add(node); 500 } 501 } 502 } 503 else 504 { 505 if (logger.isWarnEnabled()) 506 logger.warn("Found invalid object in database: id = " + nodeRef + ", type = " + type); 507 } 508 } 509 } 510 511 tx.commit(); 513 } 514 catch (InvalidNodeRefException refErr) 515 { 516 Utils.addErrorMessage(MessageFormat.format(Application.getMessage( 517 FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object [] {refErr.getNodeRef()}) ); 518 this.forums = Collections.<Node>emptyList(); 519 this.topics = Collections.<Node>emptyList(); 520 this.posts = Collections.<Node>emptyList(); 521 try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} 522 } 523 catch (Throwable err) 524 { 525 Utils.addErrorMessage(MessageFormat.format(Application.getMessage( 526 FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err); 527 this.forums = Collections.<Node>emptyList(); 528 this.topics = Collections.<Node>emptyList(); 529 this.posts = Collections.<Node>emptyList(); 530 try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} 531 } 532 533 if (logger.isDebugEnabled()) 534 { 535 long endTime = System.currentTimeMillis(); 536 logger.debug("Time to query and build forums nodes: " + (endTime - startTime) + "ms"); 537 } 538 } 539 540 541 544 547 public void contextUpdated() 548 { 549 if (logger.isDebugEnabled()) 550 logger.debug("Invalidating forums components..."); 551 552 if (this.forumsRichList != null) 554 { 555 this.forumsRichList.setValue(null); 556 if (this.forumsRichList.getInitialSortColumn() == null) 557 { 558 this.forumsRichList.setInitialSortColumn( 560 this.viewsConfig.getDefaultSortColumn(PAGE_NAME_FORUMS)); 561 this.forumsRichList.setInitialSortDescending( 562 this.viewsConfig.hasDescendingSort(PAGE_NAME_FORUMS)); 563 } 564 } 565 566 if (this.forumRichList != null) 567 { 568 this.forumRichList.setValue(null); 569 if (this.forumRichList.getInitialSortColumn() == null) 570 { 571 this.forumRichList.setInitialSortColumn( 573 this.viewsConfig.getDefaultSortColumn(PAGE_NAME_FORUM)); 574 this.forumRichList.setInitialSortDescending( 575 this.viewsConfig.hasDescendingSort(PAGE_NAME_FORUM)); 576 } 577 } 578 579 if (this.topicRichList != null) 580 { 581 this.topicRichList.setValue(null); 582 if (this.topicRichList.getInitialSortColumn() == null) 583 { 584 this.topicRichList.setInitialSortColumn( 586 this.viewsConfig.getDefaultSortColumn(PAGE_NAME_TOPIC)); 587 this.topicRichList.setInitialSortDescending( 588 this.viewsConfig.hasDescendingSort(PAGE_NAME_TOPIC)); 589 } 590 } 591 592 this.forums = null; 594 this.topics = null; 595 this.posts = null; 596 } 597 598 599 602 605 public void created(Node node, QName type) 606 { 607 if (node.containsPropertyResolver("checkIn") == true) 609 { 610 node.addPropertyResolver("checkIn", this.resolverCheckIn); 611 } 612 613 node.addPropertyResolver("beingDiscussed", this.resolverBeingDiscussed); 615 616 if (type.equals(ForumModel.TYPE_FORUMS) || 618 type.equals(ForumModel.TYPE_FORUM) || 619 type.equals(ForumModel.TYPE_TOPIC)) 620 { 621 node.addPropertyResolver("smallIcon", resolverSmallIcon); 623 } 624 } 625 626 627 630 635 public void forumsViewModeChanged(ActionEvent event) 636 { 637 UIModeList viewList = (UIModeList)event.getComponent(); 638 639 String viewMode = viewList.getValue().toString(); 641 642 setForumsViewMode(viewMode); 644 645 this.forumsPageSize = this.viewsConfig.getDefaultPageSize(PAGE_NAME_FORUMS, 647 this.forumsViewMode); 648 649 if (logger.isDebugEnabled()) 650 logger.debug("Set default forums page size to: " + this.forumsPageSize); 651 } 652 653 658 public void forumViewModeChanged(ActionEvent event) 659 { 660 UIModeList viewList = (UIModeList)event.getComponent(); 661 662 String viewMode = viewList.getValue().toString(); 664 665 setForumViewMode(viewMode); 667 668 this.forumPageSize = this.viewsConfig.getDefaultPageSize(PAGE_NAME_FORUM, 670 this.forumViewMode); 671 672 if (logger.isDebugEnabled()) 673 logger.debug("Set default forum page size to: " + this.forumPageSize); 674 } 675 676 681 public void topicViewModeChanged(ActionEvent event) 682 { 683 UIModeList viewList = (UIModeList)event.getComponent(); 684 685 String viewMode = viewList.getValue().toString(); 687 688 setTopicViewMode(viewMode); 690 691 this.topicPageSize = this.viewsConfig.getDefaultPageSize(PAGE_NAME_TOPIC, 693 this.topicViewMode); 694 695 if (logger.isDebugEnabled()) 696 logger.debug("Set default topic page size to: " + this.topicPageSize); 697 } 698 699 705 public void discuss(ActionEvent event) 706 { 707 UIActionLink link = (UIActionLink)event.getComponent(); 708 Map <String , String > params = link.getParameterMap(); 709 String id = params.get("id"); 710 if (id == null || id.length() == 0) 711 { 712 throw new AlfrescoRuntimeException("discuss called without an id"); 713 } 714 715 FacesContext context = FacesContext.getCurrentInstance(); 716 717 NodeRef nodeRef = new NodeRef(Repository.getStoreRef(), id); 718 719 if (this.nodeService.hasAspect(nodeRef, ForumModel.ASPECT_DISCUSSABLE) == false) 720 { 721 throw new AlfrescoRuntimeException("discuss called for an object that does not have a discussion!"); 722 } 723 724 List <ChildAssociationRef> children = this.nodeService.getChildAssocs(nodeRef, 726 ForumModel.ASSOC_DISCUSSION, RegexQNamePattern.MATCH_ALL); 727 728 if (children.size() != 1) 730 { 731 throw new IllegalStateException ("Node has the discussable aspect but does not have 1 child, it has " + 732 children.size() + " children!"); 733 } 734 735 NodeRef forumNodeRef = children.get(0).getChildRef(); 737 this.browseBean.clickSpace(forumNodeRef); 738 context.getApplication().getNavigationHandler().handleNavigation(context, null, "showForum"); 739 } 740 741 746 public String deleteForumsOK() 747 { 748 String outcomeOverride = "browse"; 749 750 Node node = this.browseBean.getActionSpace(); 752 ChildAssociationRef assoc = this.nodeService.getPrimaryParent(node.getNodeRef()); 753 if (assoc != null) 754 { 755 NodeRef parent = assoc.getParentRef(); 756 QName parentType = this.nodeService.getType(parent); 757 if (parentType.equals(ForumModel.TYPE_FORUMS)) 758 { 759 outcomeOverride = "forumsDeleted"; 760 } 761 } 762 763 String outcome = this.browseBean.deleteSpaceOK(); 765 766 if (outcome != null) 768 { 769 outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + 771 AlfrescoNavigationHandler.DIALOG_SEPARATOR + outcomeOverride; 772 } 773 774 return outcome; 775 } 776 777 782 public String deleteForumOK() 783 { 784 String outcomeOverride = "browse"; 785 786 Node forumSpace = this.browseBean.getActionSpace(); 789 ChildAssociationRef assoc = this.nodeService.getPrimaryParent(forumSpace.getNodeRef()); 790 if (assoc != null) 791 { 792 NodeRef parent = assoc.getParentRef(); 794 795 QName type = assoc.getTypeQName(); 797 if (type.equals(ForumModel.ASSOC_DISCUSSION)) 798 { 799 this.nodeService.removeAspect(parent, ForumModel.ASPECT_DISCUSSABLE); 802 } 803 804 QName parentType = this.nodeService.getType(parent); 808 if (parentType.equals(ForumModel.TYPE_FORUMS)) 809 { 810 outcomeOverride = "forumDeleted"; 811 } 812 } 813 814 String outcome = this.browseBean.deleteSpaceOK(); 816 817 if (outcome != null) 819 { 820 outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + 822 AlfrescoNavigationHandler.DIALOG_SEPARATOR + outcomeOverride; 823 } 824 825 return outcome; 826 } 827 828 833 public String deleteTopicOK() 834 { 835 String outcomeOverride = "browse"; 836 837 Node node = this.browseBean.getActionSpace(); 839 ChildAssociationRef assoc = this.nodeService.getPrimaryParent(node.getNodeRef()); 840 if (assoc != null) 841 { 842 NodeRef parent = assoc.getParentRef(); 843 QName parentType = this.nodeService.getType(parent); 844 if (parentType.equals(ForumModel.TYPE_FORUM)) 845 { 846 outcomeOverride = "topicDeleted"; 847 } 848 } 849 850 String outcome = this.browseBean.deleteSpaceOK(); 852 853 if (outcome != null) 855 { 856 outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + 857 AlfrescoNavigationHandler.DIALOG_SEPARATOR + outcomeOverride; 858 } 859 860 return outcome; 861 } 862 863 868 public String deletePostOK() 869 { 870 String outcome = this.browseBean.deleteFileOK(); 872 873 if (outcome != null) 875 { 876 outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; 877 } 878 879 return outcome; 880 } 881 882 883 886 public NodePropertyResolver resolverCheckIn = new NodePropertyResolver() { 887 public Object get(Node node) 888 { 889 boolean canCheckin = false; 890 891 if (node.hasAspect(ContentModel.ASPECT_WORKING_COPY)) 894 { 895 if (node.hasAspect(ForumModel.ASPECT_DISCUSSABLE)) 896 { 897 NodeRef lockedNodeRef = (NodeRef)nodeService.getProperty(node.getNodeRef(), ContentModel.PROP_COPY_REFERENCE); 899 if (lockedNodeRef != null) 900 { 901 Node lockedNode = new Node(lockedNodeRef); 902 canCheckin = node.hasPermission(PermissionService.CHECK_IN) && 903 lockedNode.hasPermission(PermissionService.CONTRIBUTOR); 904 } 905 } 906 else 907 { 908 canCheckin = node.hasPermission(PermissionService.CHECK_IN); 911 } 912 } 913 914 return canCheckin; 915 } 916 }; 917 918 public NodePropertyResolver resolverSmallIcon = new NodePropertyResolver() { 919 public Object get(Node node) { 920 QNameNodeMap props = (QNameNodeMap)node.getProperties(); 921 String icon = (String )props.getRaw("app:icon"); 922 923 if (icon != null) 924 { 925 icon = StringUtils.replace(icon, "_large", ""); 926 } 927 else 928 { 929 icon = BrowseBean.SPACE_SMALL_DEFAULT; 930 } 931 932 return icon; 933 } 934 }; 935 936 public NodePropertyResolver resolverBeingDiscussed = new NodePropertyResolver() { 937 public Object get(Node node) { 938 return node.hasAspect(ForumModel.ASPECT_DISCUSSABLE); 939 } 940 }; 941 942 public NodePropertyResolver resolverReplies = new NodePropertyResolver() { 943 public Object get(Node node) 944 { 945 String repliesXPath = "./*[(subtypeOf('" + ForumModel.TYPE_POST + "'))]"; 947 List <NodeRef> replies = searchService.selectNodes( 948 node.getNodeRef(), 949 repliesXPath, 950 new QueryParameterDefinition[] {}, 951 namespaceService, 952 false); 953 954 int noReplies = replies.size() - 1; 956 957 if (noReplies < 0) 958 { 959 noReplies = 0; 960 } 961 962 return new Integer (noReplies); 963 } 964 }; 965 966 public NodePropertyResolver resolverContent = new NodePropertyResolver() { 967 public Object get(Node node) 968 { 969 String content = null; 970 971 975 ContentReader reader = contentService.getReader(node.getNodeRef(), 976 ContentModel.PROP_CONTENT); 977 978 if (reader != null) 979 { 980 content = reader.getContentString(); 981 } 982 983 return content; 984 } 985 }; 986 987 public NodePropertyResolver resolverReplyTo = new NodePropertyResolver() { 988 public Object get(Node node) 989 { 990 993 String replyTo = null; 994 995 List <AssociationRef> assocs = nodeService.getTargetAssocs(node.getNodeRef(), 996 ContentModel.ASSOC_REFERENCES); 997 998 if (assocs.size() > 0) 1001 { 1002 AssociationRef assoc = assocs.get(0); 1003 NodeRef target = assoc.getTargetRef(); 1004 Node targetNode = new Node(target); 1005 replyTo = (String )targetNode.getProperties().get("creator"); 1006 } 1007 1008 return replyTo; 1009 } 1010 }; 1011 1012 1017 public static String createPostFileName() 1018 { 1019 StringBuilder name = new StringBuilder ("posted-"); 1020 1021 SimpleDateFormat dateFormat = new SimpleDateFormat ("dd-MM-yyyy-hh:mm:ss"); 1023 name.append(dateFormat.format(new Date ())); 1024 1025 name.append(".html"); 1027 1028 return name.toString(); 1029 } 1030 1031 1032 1035 1038 private void initFromClientConfig() 1039 { 1040 this.viewsConfig = (ViewsConfigElement)Application.getConfigService( 1041 FacesContext.getCurrentInstance()).getConfig("Views"). 1042 getConfigElement(ViewsConfigElement.CONFIG_ELEMENT_ID); 1043 1044 this.forumsViewMode = this.viewsConfig.getDefaultView(PAGE_NAME_FORUMS); 1046 this.forumsPageSize = this.viewsConfig.getDefaultPageSize(PAGE_NAME_FORUMS, 1047 this.forumsViewMode); 1048 1049 this.forumViewMode = this.viewsConfig.getDefaultView(PAGE_NAME_FORUM); 1051 this.forumPageSize = this.viewsConfig.getDefaultPageSize(PAGE_NAME_FORUM, 1052 this.forumViewMode); 1053 1054 this.topicViewMode = this.viewsConfig.getDefaultView(PAGE_NAME_TOPIC); 1056 this.topicPageSize = this.viewsConfig.getDefaultPageSize(PAGE_NAME_TOPIC, 1057 this.topicViewMode); 1058 1059 if (logger.isDebugEnabled()) 1060 { 1061 logger.debug("Set default forums view mode to: " + this.forumsViewMode); 1062 logger.debug("Set default forums page size to: " + this.forumsPageSize); 1063 logger.debug("Set default forum view mode to: " + this.forumViewMode); 1064 logger.debug("Set default forum page size to: " + this.forumPageSize); 1065 logger.debug("Set default topic view mode to: " + this.topicViewMode); 1066 logger.debug("Set default topic page size to: " + this.topicPageSize); 1067 } 1068 } 1069 1070 1075 public static class TopicBubbleViewRenderer implements IRichListRenderer 1076 { 1077 public static final String VIEWMODEID = "bubble"; 1078 1079 1082 public String getViewModeID() 1083 { 1084 return VIEWMODEID; 1085 } 1086 1087 1090 public void renderListBefore(FacesContext context, UIRichList richList, UIColumn[] columns) 1091 throws IOException 1092 { 1093 } 1095 1096 1099 public void renderListRow(FacesContext context, UIRichList richList, UIColumn[] columns, Object row) 1100 throws IOException 1101 { 1102 ResponseWriter out = context.getResponseWriter(); 1103 1104 UIColumn primaryColumn = null; 1107 UIColumn actionsColumn = null; 1108 for (int i = 0; i < columns.length; i++) 1109 { 1110 if (columns[i].isRendered()) 1111 { 1112 if (columns[i].getPrimary()) 1113 { 1114 primaryColumn = columns[i]; 1115 } 1116 else if (columns[i].getActions()) 1117 { 1118 actionsColumn = columns[i]; 1119 } 1120 } 1121 } 1122 1123 if (primaryColumn == null) 1124 { 1125 if (logger.isWarnEnabled()) 1126 logger.warn("No primary column found for RichList definition: " + richList.getId()); 1127 } 1128 1129 out.write("<tr>"); 1130 1131 Node node = (Node)row; 1132 if (node.getProperties().get("replyTo") == null) 1133 { 1134 renderNewPostBubble(context, out, node, primaryColumn, actionsColumn, columns); 1135 } 1136 else 1137 { 1138 renderReplyToBubble(context, out, node, primaryColumn, actionsColumn, columns); 1139 } 1140 1141 out.write("</tr>"); 1142 1143 out.write("<tr><td><div style='padding:3px'></div></td></tr>"); 1145 } 1146 1147 1150 public void renderListAfter(FacesContext context, UIRichList richList, UIColumn[] columns) 1151 throws IOException 1152 { 1153 ResponseWriter out = context.getResponseWriter(); 1154 1155 out.write("<tr><td colspan='99' align='right'>"); 1156 for (Iterator i = richList.getChildren().iterator(); i.hasNext(); ) 1157 { 1158 UIComponent child = (UIComponent)i.next(); 1160 if (child instanceof UIColumn == false) 1161 { 1162 Utils.encodeRecursive(context, child); 1163 } 1164 } 1165 out.write("</td></tr>"); 1166 } 1167 1168 1176 public static void renderBubbleTop(Writer out, String contextPath, 1177 String colour, String titleBgColour) throws IOException 1178 { 1179 out.write("<table border='0' cellpadding='0' cellspacing='0' width='100%'><tr>"); 1180 out.write("<td style='background: url("); 1181 out.write(contextPath); 1182 out.write("/images/parts/"); 1183 out.write(colour); 1184 out.write("header_1.gif) no-repeat #FFFFFF;' width='24' height='24'></td>"); 1185 out.write("<td style='background: url("); 1186 out.write(contextPath); 1187 out.write("/images/parts/"); 1188 out.write(colour); 1189 out.write("header_2.gif) repeat-x "); 1190 out.write(titleBgColour); 1191 out.write("'>"); 1192 } 1193 1194 1201 public static void renderBubbleMiddle(Writer out, String contextPath, String colour) 1202 throws IOException 1203 { 1204 out.write("</td>"); 1205 out.write("<td style='background: url("); 1206 out.write(contextPath); 1207 out.write("/images/parts/"); 1208 out.write(colour); 1209 out.write("header_3.gif) no-repeat #FFFFFF;' width='24' height='24'></td>"); 1210 out.write("</tr><tr>"); 1211 out.write("<td width='24' height='13'><img width='24' height='13' alt='' SRC='"); 1212 out.write(contextPath); 1213 out.write("/images/parts/"); 1214 out.write(colour); 1215 out.write("body_1.gif' /></td>"); 1216 out.write("<td background='"); 1217 out.write(contextPath); 1218 out.write("/images/parts/"); 1219 out.write(colour); 1220 out.write("body_2.gif'><img width='21' height='13' alt='' SRC='"); 1221 out.write(contextPath); 1222 out.write("/images/parts/"); 1223 out.write(colour); 1224 out.write("body_2.gif' /></td>"); 1225 out.write("<td width='24' height='13'><img width='24' height='13' alt='' SRC='"); 1226 out.write(contextPath); 1227 out.write("/images/parts/"); 1228 out.write(colour); 1229 out.write("body_3.gif' /></td>"); 1230 out.write("</tr><tr>"); 1231 out.write("<td width='24' height='13' background='"); 1232 out.write(contextPath); 1233 out.write("/images/parts/"); 1234 out.write(colour); 1235 out.write("body_4.gif'><img width='24' height='4' alt='' SRC='"); 1236 out.write(contextPath); 1237 out.write("/images/parts/"); 1238 out.write(colour); 1239 out.write("body_4.gif' /></td>"); 1240 out.write("<td>"); 1241 } 1242 1243 1250 public static void renderBubbleBottom(Writer out, String contextPath, String colour) 1251 throws IOException 1252 { 1253 out.write("</td>"); 1254 out.write("<td width='24' height='13' background='"); 1255 out.write(contextPath); 1256 out.write("/images/parts/"); 1257 out.write(colour); 1258 out.write("body_6.gif'><img width='24' height='3' alt='' SRC='"); 1259 out.write(contextPath); 1260 out.write("/images/parts/"); 1261 out.write(colour); 1262 out.write("body_6.gif' /></td>"); 1263 out.write("</tr><tr>"); 1264 out.write("<td width='24' height='13'><img width='24' height='13' alt='' SRC='"); 1265 out.write(contextPath); 1266 out.write("/images/parts/"); 1267 out.write(colour); 1268 out.write("body_7.gif' /></td>"); 1269 out.write("<td background='"); 1270 out.write(contextPath); 1271 out.write("/images/parts/"); 1272 out.write(colour); 1273 out.write("body_8.gif'><img width='20' height='13' alt='' SRC='"); 1274 out.write(contextPath); 1275 out.write("/images/parts/"); 1276 out.write(colour); 1277 out.write("body_8.gif' /></td>"); 1278 out.write("<td width='24' height='13'><img width='24' height='13' alt='' SRC='"); 1279 out.write(contextPath); 1280 out.write("/images/parts/"); 1281 out.write(colour); 1282 out.write("body_9.gif' /></td>"); 1283 out.write("</tr></table>"); 1284 } 1285 1286 1296 private void renderNewPostBubble(FacesContext context, ResponseWriter out, Node node, 1297 UIColumn primaryColumn, UIColumn actionsColumn, UIColumn[] columns) throws IOException 1298 { 1299 String contextPath = context.getExternalContext().getRequestContextPath(); 1300 String colour = "orange"; 1301 1302 out.write("<td><table border='0' cellpadding='0' cellspacing='0' width='100%'><tr>"); 1303 out.write("<td valign='top'><img SRC='"); 1304 out.write(contextPath); 1305 out.write("/images/icons/user_large.gif'/><br/>"); 1306 out.write((String )node.getProperties().get("creator")); 1307 out.write("</td><td width='100%'>"); 1308 1309 renderBubbleTop(out, contextPath, colour, "#FCC75E"); 1310 renderHeaderContents(context, out, primaryColumn, actionsColumn, columns); 1311 renderBubbleMiddle(out, contextPath, colour); 1312 renderBodyContents(context, primaryColumn); 1313 renderBubbleBottom(out, contextPath, colour); 1314 1315 out.write("</td><td><div style='width:32px;' /></td></table></td>"); 1316 } 1317 1318 1328 private void renderReplyToBubble(FacesContext context, ResponseWriter out, Node node, 1329 UIColumn primaryColumn, UIColumn actionsColumn, UIColumn[] columns) throws IOException 1330 { 1331 String contextPath = context.getExternalContext().getRequestContextPath(); 1332 String colour = "yellow"; 1333 1334 out.write("<td width='100%'><table border='0' cellpadding='0' cellspacing='0' width='100%'><tr>"); 1335 out.write("<td><div style='width:32px;' /></td><td width='100%'>"); 1336 1337 renderBubbleTop(out, contextPath, colour, "#FFF5A3"); 1338 renderHeaderContents(context, out, primaryColumn, actionsColumn, columns); 1339 renderBubbleMiddle(out, contextPath, colour); 1340 renderBodyContents(context, primaryColumn); 1341 renderBubbleBottom(out, contextPath, colour); 1342 1343 out.write("</td><td valign='top'><img SRC='"); 1344 out.write(contextPath); 1345 out.write("/images/icons/user_large.gif'/><br/>"); 1346 out.write((String )node.getProperties().get("creator")); 1347 out.write("</td></table></td>"); 1348 } 1349 1350 private void renderHeaderContents(FacesContext context, ResponseWriter out, 1351 UIColumn primaryColumn, UIColumn actionsColumn, UIColumn[] columns) throws IOException 1352 { 1353 out.write("<table width='100%' cellpadding='2' cellspacing='2' border='0'><tr>"); 1355 1356 for (int i = 0; i < columns.length; i++) 1357 { 1358 UIColumn column = columns[i]; 1359 1360 if (column.isRendered() == true && 1361 column.getPrimary() == false && 1362 column.getActions() == false) 1363 { 1364 UIComponent header = column.getFacet("header"); 1366 if (header != null) 1367 { 1368 out.write("<td><nobr><b>"); 1369 Utils.encodeRecursive(context, header); 1370 out.write("</nobr></b></td>"); 1371 } 1372 1373 if (column.getChildCount() != 0) 1375 { 1376 out.write("<td><nobr>"); 1377 Utils.encodeRecursive(context, column); 1378 out.write("</nobr></td>"); 1379 } 1380 } 1381 } 1382 1383 out.write("<td align='right' width='100%'><nobr>"); 1385 if (actionsColumn != null && actionsColumn.getChildCount() != 0) 1386 { 1387 Utils.encodeRecursive(context, actionsColumn); 1388 } 1389 out.write("</nobr></td></tr></table>"); 1390 } 1391 1392 1398 private void renderBodyContents(FacesContext context, UIColumn primaryColumn) 1399 throws IOException 1400 { 1401 if (primaryColumn != null && primaryColumn.getChildCount() != 0) 1403 { 1404 Utils.encodeRecursive(context, primaryColumn); 1405 } 1406 } 1407 } 1408} 1409 | Popular Tags |