1 17 package org.alfresco.web.bean; 18 19 import java.io.Serializable ; 20 import java.text.MessageFormat ; 21 import java.text.SimpleDateFormat ; 22 import java.util.ArrayList ; 23 import java.util.Date ; 24 import java.util.HashMap ; 25 import java.util.List ; 26 import java.util.Map ; 27 28 import javax.faces.component.UISelectBoolean; 29 import javax.faces.context.FacesContext; 30 import javax.faces.event.ActionEvent; 31 import javax.faces.model.DataModel; 32 import javax.faces.model.ListDataModel; 33 import javax.faces.model.SelectItem; 34 import javax.transaction.UserTransaction ; 35 36 import org.alfresco.model.ContentModel; 37 import org.alfresco.repo.cache.ExpiringValueCache; 38 import org.alfresco.repo.content.MimetypeMap; 39 import org.alfresco.repo.security.permissions.AccessDeniedException; 40 import org.alfresco.service.ServiceRegistry; 41 import org.alfresco.service.cmr.dictionary.AspectDefinition; 42 import org.alfresco.service.cmr.dictionary.DataTypeDefinition; 43 import org.alfresco.service.cmr.dictionary.DictionaryService; 44 import org.alfresco.service.cmr.dictionary.PropertyDefinition; 45 import org.alfresco.service.cmr.dictionary.TypeDefinition; 46 import org.alfresco.service.cmr.repository.ChildAssociationRef; 47 import org.alfresco.service.cmr.repository.ContentReader; 48 import org.alfresco.service.cmr.repository.ContentService; 49 import org.alfresco.service.cmr.repository.ContentWriter; 50 import org.alfresco.service.cmr.repository.MimetypeService; 51 import org.alfresco.service.cmr.repository.NodeRef; 52 import org.alfresco.service.cmr.repository.NodeService; 53 import org.alfresco.service.cmr.search.SearchService; 54 import org.alfresco.service.cmr.security.AccessStatus; 55 import org.alfresco.service.cmr.security.PermissionService; 56 import org.alfresco.service.namespace.NamespaceService; 57 import org.alfresco.service.namespace.QName; 58 import org.alfresco.service.namespace.RegexQNamePattern; 59 import org.alfresco.util.CachingDateFormat; 60 import org.alfresco.web.app.Application; 61 import org.alfresco.web.bean.SearchContext.RangeProperties; 62 import org.alfresco.web.bean.repository.MapNode; 63 import org.alfresco.web.bean.repository.Node; 64 import org.alfresco.web.bean.repository.Repository; 65 import org.alfresco.web.bean.repository.User; 66 import org.alfresco.web.config.AdvancedSearchConfigElement; 67 import org.alfresco.web.config.AdvancedSearchConfigElement.CustomProperty; 68 import org.alfresco.web.data.IDataContainer; 69 import org.alfresco.web.data.QuickSort; 70 import org.alfresco.web.ui.common.Utils; 71 import org.alfresco.web.ui.common.component.UIModeList; 72 import org.alfresco.web.ui.common.component.UIPanel.ExpandedEvent; 73 import org.alfresco.web.ui.repo.component.UICategorySelector; 74 import org.alfresco.web.ui.repo.component.UISearchCustomProperties; 75 76 85 public class AdvancedSearchBean 86 { 87 90 public AdvancedSearchBean() 91 { 92 panels.put(PANEL_CATEGORIES, false); 94 panels.put(PANEL_ATTRS, false); 95 panels.put(PANEL_CUSTOM, false); 96 } 97 98 99 102 105 public void setNavigator(NavigationBean navigator) 106 { 107 this.navigator = navigator; 108 } 109 110 113 public void setNodeService(NodeService nodeService) 114 { 115 this.nodeService = nodeService; 116 } 117 118 121 public void setNamespaceService(NamespaceService namespaceService) 122 { 123 this.namespaceService = namespaceService; 124 } 125 126 129 public void setSearchService(SearchService searchService) 130 { 131 this.searchService = searchService; 132 } 133 134 137 public void setPermissionService(PermissionService permissionService) 138 { 139 this.permissionService = permissionService; 140 } 141 142 145 public Map <String , Boolean > getPanels() 146 { 147 return this.panels; 148 } 149 150 153 public void setPanels(Map <String , Boolean > panels) 154 { 155 this.panels = panels; 156 } 157 158 161 public String getSearchDescription() 162 { 163 return this.searchDescription; 164 } 165 166 169 public void setSearchDescription(String searchDescription) 170 { 171 this.searchDescription = searchDescription; 172 } 173 174 177 public String getSearchName() 178 { 179 return this.searchName; 180 } 181 182 185 public void setSearchName(String searchName) 186 { 187 this.searchName = searchName; 188 } 189 190 193 public String getSavedSearch() 194 { 195 return this.savedSearch; 196 } 197 198 201 public void setSavedSearch(String savedSearch) 202 { 203 this.savedSearch = savedSearch; 204 } 205 206 209 public String getEditSearchName() 210 { 211 return this.editSearchName; 212 } 213 214 217 public void setEditSearchName(String editSearchName) 218 { 219 this.editSearchName = editSearchName; 220 } 221 222 225 public boolean isSearchSaveGlobal() 226 { 227 return this.searchSaveGlobal; 228 } 229 230 233 public void setSearchSaveGlobal(boolean searchSaveGlobal) 234 { 235 this.searchSaveGlobal = searchSaveGlobal; 236 } 237 238 241 public String getLookin() 242 { 243 return this.lookin; 244 } 245 246 249 public void setLookin(String lookIn) 250 { 251 this.lookin = lookIn; 252 } 253 254 257 public NodeRef getLocation() 258 { 259 return this.location; 260 } 261 262 265 public void setLocation(NodeRef location) 266 { 267 this.location = location; 268 } 269 270 273 public String getMode() 274 { 275 return this.mode; 276 } 277 278 281 public void setMode(String mode) 282 { 283 this.mode = mode; 284 } 285 286 289 public String getSavedSearchMode() 290 { 291 return this.savedSearchMode; 292 } 293 294 297 public void setSavedSearchMode(String savedSearchMode) 298 { 299 this.savedSearchMode = savedSearchMode; 300 } 301 302 305 public boolean isAllowEdit() 306 { 307 boolean allow = (this.savedSearch != null && NO_SELECTION.equals(this.savedSearch) == false); 308 if (allow) 309 { 310 NodeRef savedSearchRef = new NodeRef(Repository.getStoreRef(), this.savedSearch); 311 allow = (permissionService.hasPermission(savedSearchRef, PermissionService.WRITE) == AccessStatus.ALLOWED); 312 } 313 return allow; 314 } 315 316 319 public void setAllowEdit(boolean allowEdit) 320 { 321 } 323 324 327 public String getText() 328 { 329 return this.text; 330 } 331 332 335 public void setText(String text) 336 { 337 this.text = text; 338 } 339 340 345 public DataModel getCategoriesDataModel() 346 { 347 if (this.categoriesDataModel == null) 348 { 349 this.categoriesDataModel = new ListDataModel(); 350 } 351 352 this.categoriesDataModel.setWrappedData(this.categories); 353 354 return this.categoriesDataModel; 355 } 356 357 360 public boolean getLocationChildren() 361 { 362 return this.locationChildren; 363 } 364 365 368 public void setLocationChildren(boolean locationChildren) 369 { 370 this.locationChildren = locationChildren; 371 } 372 373 376 public Date getCreatedDateFrom() 377 { 378 return this.createdDateFrom; 379 } 380 381 384 public void setCreatedDateFrom(Date createdDate) 385 { 386 this.createdDateFrom = createdDate; 387 } 388 389 392 public String getDescription() 393 { 394 return this.description; 395 } 396 397 400 public void setDescription(String description) 401 { 402 this.description = description; 403 } 404 405 408 public Date getModifiedDateFrom() 409 { 410 return this.modifiedDateFrom; 411 } 412 413 416 public void setModifiedDateFrom(Date modifiedDate) 417 { 418 this.modifiedDateFrom = modifiedDate; 419 } 420 421 424 public Date getCreatedDateTo() 425 { 426 return this.createdDateTo; 427 } 428 429 432 public void setCreatedDateTo(Date createdDateTo) 433 { 434 this.createdDateTo = createdDateTo; 435 } 436 437 440 public Date getModifiedDateTo() 441 { 442 return this.modifiedDateTo; 443 } 444 445 448 public void setModifiedDateTo(Date modifiedDateTo) 449 { 450 this.modifiedDateTo = modifiedDateTo; 451 } 452 453 456 public String getTitle() 457 { 458 return this.title; 459 } 460 461 464 public void setTitle(String title) 465 { 466 this.title = title; 467 } 468 469 472 public String getAuthor() 473 { 474 return this.author; 475 } 476 477 480 public void setAuthor(String author) 481 { 482 this.author = author; 483 } 484 485 488 public boolean isModifiedDateChecked() 489 { 490 return this.modifiedDateChecked; 491 } 492 493 496 public void setModifiedDateChecked(boolean modifiedDateChecked) 497 { 498 this.modifiedDateChecked = modifiedDateChecked; 499 } 500 501 504 public boolean isCreatedDateChecked() 505 { 506 return this.createdDateChecked; 507 } 508 509 512 public String getContentType() 513 { 514 return this.contentType; 515 } 516 517 520 public void setContentType(String contentType) 521 { 522 this.contentType = contentType; 523 } 524 525 528 public String getContentFormat() 529 { 530 return this.contentFormat; 531 } 532 533 536 public void setContentFormat(String contentFormat) 537 { 538 this.contentFormat = contentFormat; 539 } 540 541 544 public Map <String , Object > getCustomProperties() 545 { 546 return this.customProperties; 547 } 548 549 552 public void setCustomProperties(Map <String , Object > customProperties) 553 { 554 this.customProperties = customProperties; 555 } 556 557 560 public void setCreatedDateChecked(boolean createdDateChecked) 561 { 562 this.createdDateChecked = createdDateChecked; 563 } 564 565 568 public List <SelectItem> getContentTypes() 569 { 570 if (this.contentTypes == null) 571 { 572 FacesContext context = FacesContext.getCurrentInstance(); 573 574 this.contentTypes = new ArrayList <SelectItem>(5); 576 this.contentTypes.add(new SelectItem(ContentModel.TYPE_CONTENT.toString(), 577 Application.getMessage(context, MSG_CONTENT))); 578 579 List <String > types = getSearchConfig().getContentTypes(); 581 if (types != null) 582 { 583 DictionaryService dictionaryService = Repository.getServiceRegistry(context).getDictionaryService(); 584 for (String type : types) 585 { 586 QName idQName = Repository.resolveToQName(type); 587 TypeDefinition typeDef = dictionaryService.getType(idQName); 588 589 if (typeDef != null && dictionaryService.isSubClass(typeDef.getName(), ContentModel.TYPE_CONTENT)) 590 { 591 String label = typeDef.getTitle(); 593 594 if (label == null) 596 { 597 label = idQName.getLocalName(); 598 } 599 600 this.contentTypes.add(new SelectItem(idQName.toString(), label)); 601 } 602 } 603 604 QuickSort sorter = new QuickSort(this.contentTypes, "label", true, IDataContainer.SORT_CASEINSENSITIVE); 606 sorter.sort(); 607 } 608 } 609 610 return this.contentTypes; 611 } 612 613 616 public List <SelectItem> getContentFormats() 617 { 618 if (this.contentFormats == null) 619 { 620 this.contentFormats = new ArrayList <SelectItem>(80); 621 ServiceRegistry registry = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); 622 MimetypeService mimetypeService = registry.getMimetypeService(); 623 624 Map <String , String > mimeTypes = mimetypeService.getDisplaysByMimetype(); 626 for (String mimeType : mimeTypes.keySet()) 627 { 628 this.contentFormats.add(new SelectItem(mimeType, mimeTypes.get(mimeType))); 629 } 630 631 QuickSort sorter = new QuickSort(this.contentFormats, "label", true, IDataContainer.SORT_CASEINSENSITIVE); 633 sorter.sort(); 634 635 this.contentFormats.add(0, new SelectItem("", Application.getMessage(FacesContext.getCurrentInstance(), MSG_ALL_FORMATS))); 637 } 638 639 return this.contentFormats; 640 } 641 642 643 646 649 public void reset(ActionEvent event) 650 { 651 resetFields(); 652 this.savedSearch = null; 653 } 654 655 private void resetFields() 656 { 657 this.text = ""; 658 this.mode = MODE_ALL; 659 this.lookin = LOOKIN_ALL; 660 this.contentType = null; 661 this.contentFormat = null; 662 this.location = null; 663 this.locationChildren = true; 664 this.categories = new ArrayList <Node>(2); 665 this.title = null; 666 this.description = null; 667 this.author = null; 668 this.createdDateFrom = null; 669 this.createdDateTo = null; 670 this.modifiedDateFrom = null; 671 this.modifiedDateTo = null; 672 this.createdDateChecked = false; 673 this.modifiedDateChecked = false; 674 this.customProperties.clear(); 675 } 676 677 680 public String search() 681 { 682 SearchContext search = new SearchContext(); 685 686 search.setText(this.text); 688 689 search.setForceAndTerms(Application.getClientConfig(FacesContext.getCurrentInstance()).getForceAndTerms()); 691 692 if (this.mode.equals(MODE_ALL)) 693 { 694 search.setMode(SearchContext.SEARCH_ALL); 695 } 696 else if (this.mode.equals(MODE_FILES_TEXT)) 697 { 698 search.setMode(SearchContext.SEARCH_FILE_NAMES_CONTENTS); 699 } 700 else if (this.mode.equals(MODE_FILES)) 701 { 702 search.setMode(SearchContext.SEARCH_FILE_NAMES); 703 } 704 else if (this.mode.equals(MODE_FOLDERS)) 705 { 706 search.setMode(SearchContext.SEARCH_SPACE_NAMES); 707 } 708 709 if (this.description != null && this.description.length() != 0) 711 { 712 search.addAttributeQuery(ContentModel.PROP_DESCRIPTION, this.description); 713 } 714 if (this.title != null && this.title.length() != 0) 715 { 716 search.addAttributeQuery(ContentModel.PROP_TITLE, this.title); 717 } 718 if (this.author != null && this.author.length() != 0) 719 { 720 search.addAttributeQuery(ContentModel.PROP_AUTHOR, this.author); 721 } 722 if (this.contentFormat != null && this.contentFormat.length() != 0) 723 { 724 search.setMimeType(this.contentFormat); 725 } 726 if (this.createdDateChecked == true) 727 { 728 SimpleDateFormat df = CachingDateFormat.getDateFormat(); 729 String strCreatedDate = df.format(this.createdDateFrom); 730 String strCreatedDateTo = df.format(this.createdDateTo); 731 search.addRangeQuery(ContentModel.PROP_CREATED, strCreatedDate, strCreatedDateTo, true); 732 } 733 if (this.modifiedDateChecked == true) 734 { 735 SimpleDateFormat df = CachingDateFormat.getDateFormat(); 736 String strModifiedDate = df.format(this.modifiedDateFrom); 737 String strModifiedDateTo = df.format(this.modifiedDateTo); 738 search.addRangeQuery(ContentModel.PROP_MODIFIED, strModifiedDate, strModifiedDateTo, true); 739 } 740 741 for (String qname : this.customProperties.keySet()) 743 { 744 Object value = this.customProperties.get(qname); 745 DataTypeDefinition typeDef = getCustomPropertyLookup().get(qname); 746 if (typeDef != null) 747 { 748 QName typeName = typeDef.getName(); 749 if (DataTypeDefinition.DATE.equals(typeName) || DataTypeDefinition.DATETIME.equals(typeName)) 750 { 751 if (value != null && Boolean.valueOf(value.toString()) == true) 753 { 754 SimpleDateFormat df = CachingDateFormat.getDateFormat(); 755 String strDateFrom = df.format(this.customProperties.get( 756 UISearchCustomProperties.PREFIX_DATE_FROM + qname)); 757 String strDateTo = df.format(this.customProperties.get( 758 UISearchCustomProperties.PREFIX_DATE_TO + qname)); 759 search.addRangeQuery(QName.createQName(qname), strDateFrom, strDateTo, true); 760 } 761 } 762 else if (DataTypeDefinition.BOOLEAN.equals(typeName)) 763 { 764 if (((Boolean )value) == true) 765 { 766 search.addFixedValueQuery(QName.createQName(qname), value.toString()); 767 } 768 } 769 else if (DataTypeDefinition.NODE_REF.equals(typeName) || DataTypeDefinition.CATEGORY.equals(typeName)) 770 { 771 if (value != null) 772 { 773 search.addFixedValueQuery(QName.createQName(qname), value.toString()); 774 } 775 } 776 else if (DataTypeDefinition.INT.equals(typeName) || DataTypeDefinition.LONG.equals(typeName) || 777 DataTypeDefinition.FLOAT.equals(typeName) || DataTypeDefinition.DOUBLE.equals(typeName)) 778 { 779 String strVal = value.toString(); 780 if (strVal != null && strVal.length() != 0) 781 { 782 search.addFixedValueQuery(QName.createQName(qname), strVal); 783 } 784 } 785 else 786 { 787 String strVal = value.toString(); 789 if (strVal != null && strVal.length() != 0) 790 { 791 search.addAttributeQuery(QName.createQName(qname), strVal); 792 } 793 } 794 } 795 } 796 797 if (this.lookin.equals(LOOKIN_OTHER) && this.location != null) 799 { 800 search.setLocation(SearchContext.getPathFromSpaceRef(this.location, this.locationChildren)); 801 } 802 803 if (this.categories.size() != 0) 805 { 806 String [] paths = new String [this.categories.size()]; 807 for (int i=0; i<paths.length; i++) 808 { 809 Node category = this.categories.get(i); 810 boolean includeChildren = (Boolean )category.getProperties().get(INCLUDE_CHILDREN); 811 paths[i] = SearchContext.getPathFromSpaceRef(category.getNodeRef(), includeChildren); 812 } 813 search.setCategories(paths); 814 } 815 816 if (this.contentType != null) 818 { 819 search.setContentType(this.contentType); 820 } 821 822 this.navigator.setSearchContext(search); 825 826 return OUTCOME_BROWSE; 827 } 828 829 832 public String saveNewSearch() 833 { 834 this.searchDescription = null; 835 this.searchName = null; 836 this.searchSaveGlobal = false; 837 838 return "saveNewSearch"; 839 } 840 841 844 public String saveEditSearch() 845 { 846 this.searchDescription = null; 847 this.searchName = null; 848 this.editSearchName = null; 849 850 try 852 { 853 NodeRef searchRef = new NodeRef(Repository.getStoreRef(), this.savedSearch); 854 Node searchNode = new Node(searchRef); 855 if (this.nodeService.exists(searchRef) && searchNode.hasPermission(PermissionService.WRITE)) 856 { 857 Node node = new Node(searchRef); 858 this.searchName = node.getName(); 859 this.editSearchName = this.searchName; 860 this.searchDescription = (String )node.getProperties().get(ContentModel.PROP_DESCRIPTION); 861 } 862 else 863 { 864 this.savedSearch = null; 866 } 867 } 868 catch (Throwable err) 869 { 870 this.savedSearch = null; 872 } 873 874 return "saveEditSearch"; 875 } 876 877 880 public String saveNewSearchOK() 881 { 882 String outcome = OUTCOME_BROWSE; 883 884 NodeRef searchesRef; 885 if (isSearchSaveGlobal() == true) 886 { 887 searchesRef = getGlobalSearchesRef(); 888 } 889 else 890 { 891 searchesRef = getUserSearchesRef(); 892 } 893 894 SearchContext search = this.navigator.getSearchContext(); 895 if (searchesRef != null && search != null) 896 { 897 UserTransaction tx = null; 898 try 899 { 900 FacesContext context = FacesContext.getCurrentInstance(); 901 tx = Repository.getUserTransaction(context); 902 tx.begin(); 903 904 Map <QName, Serializable > props = new HashMap <QName, Serializable >(2, 1.0f); 906 props.put(ContentModel.PROP_NAME, this.searchName); 907 props.put(ContentModel.PROP_DESCRIPTION, this.searchDescription); 908 ChildAssociationRef childRef = this.nodeService.createNode( 909 searchesRef, 910 ContentModel.ASSOC_CONTAINS, 911 QName.createQName(NamespaceService.ALFRESCO_URI, QName.createValidLocalName(this.searchName)), 912 ContentModel.TYPE_CONTENT, 913 props); 914 915 ContentService contentService = Repository.getServiceRegistry(context).getContentService(); 916 ContentWriter writer = contentService.getWriter(childRef.getChildRef(), ContentModel.PROP_CONTENT, true); 917 918 writer.setMimetype(MimetypeMap.MIMETYPE_XML); 920 writer.setEncoding("UTF-8"); 921 922 writer.putContent(search.toXML()); 924 925 tx.commit(); 926 927 this.cachedSavedSearches.clear(); 928 this.savedSearch = null; 929 } 930 catch (Throwable e) 931 { 932 try { if (tx != null) {tx.rollback();} } catch (Exception ex) {} 933 Utils.addErrorMessage(MessageFormat.format(Application.getMessage( 934 FacesContext.getCurrentInstance(), MSG_ERROR_SAVE_SEARCH), e.getMessage()), e); 935 outcome = null; 936 } 937 } 938 939 return outcome; 940 } 941 942 945 public String saveEditSearchOK() 946 { 947 String outcome = OUTCOME_BROWSE; 948 949 SearchContext search = this.navigator.getSearchContext(); 950 if (search != null) 951 { 952 UserTransaction tx = null; 953 try 954 { 955 FacesContext context = FacesContext.getCurrentInstance(); 956 tx = Repository.getUserTransaction(context); 957 tx.begin(); 958 959 NodeRef searchRef = new NodeRef(Repository.getStoreRef(), this.savedSearch); 962 if (this.nodeService.exists(searchRef)) 963 { 964 Map <QName, Serializable > props = this.nodeService.getProperties(searchRef); 965 props.put(ContentModel.PROP_NAME, this.searchName); 966 props.put(ContentModel.PROP_DESCRIPTION, this.searchDescription); 967 this.nodeService.setProperties(searchRef, props); 968 969 ContentService contentService = Repository.getServiceRegistry(context).getContentService(); 970 ContentWriter writer = contentService.getWriter(searchRef, ContentModel.PROP_CONTENT, true); 971 972 writer.setMimetype(MimetypeMap.MIMETYPE_XML); 974 writer.setEncoding("UTF-8"); 975 976 writer.putContent(search.toXML()); 978 979 tx.commit(); 980 } 981 982 this.cachedSavedSearches.clear(); 983 this.savedSearch = null; 984 } 985 catch (Throwable e) 986 { 987 try { if (tx != null) {tx.rollback();} } catch (Exception ex) {} 988 Utils.addErrorMessage(MessageFormat.format(Application.getMessage( 989 FacesContext.getCurrentInstance(), MSG_ERROR_SAVE_SEARCH), e.getMessage()), e); 990 outcome = null; 991 } 992 } 993 994 return outcome; 995 } 996 997 1000 public List <SelectItem> getSavedSearches() 1001 { 1002 List <SelectItem> savedSearches = cachedSavedSearches.get(); 1003 if (savedSearches == null) 1004 { 1005 FacesContext fc = FacesContext.getCurrentInstance(); 1006 ServiceRegistry services = Repository.getServiceRegistry(fc); 1007 1008 NodeRef searchesRef = null; 1010 if (SAVED_SEARCHES_USER.equals(getSavedSearchMode()) == true) 1011 { 1012 searchesRef = getUserSearchesRef(); 1013 } 1014 else if (SAVED_SEARCHES_GLOBAL.equals(getSavedSearchMode()) == true) 1015 { 1016 searchesRef = getGlobalSearchesRef(); 1017 } 1018 1019 if (searchesRef != null) 1021 { 1022 DictionaryService dd = services.getDictionaryService(); 1023 1024 List <ChildAssociationRef> childRefs = nodeService.getChildAssocs( 1025 searchesRef, 1026 ContentModel.ASSOC_CONTAINS, 1027 RegexQNamePattern.MATCH_ALL); 1028 1029 savedSearches = new ArrayList <SelectItem>(childRefs.size() + 1); 1030 if (childRefs.size() != 0) 1031 { 1032 for (ChildAssociationRef ref : childRefs) 1033 { 1034 Node childNode = new Node(ref.getChildRef()); 1035 if (dd.isSubClass(childNode.getType(), ContentModel.TYPE_CONTENT)) 1036 { 1037 savedSearches.add(new SelectItem(childNode.getId(), childNode.getName())); 1038 } 1039 } 1040 1041 QuickSort sorter = new QuickSort(savedSearches, "label", true, IDataContainer.SORT_CASEINSENSITIVE); 1043 sorter.sort(); 1044 } 1045 } 1046 else 1047 { 1048 savedSearches = new ArrayList <SelectItem>(1); 1050 } 1051 1052 savedSearches.add(0, new SelectItem(NO_SELECTION, 1054 Application.getMessage(FacesContext.getCurrentInstance(), MSG_SELECT_SAVED_SEARCH))); 1055 1056 cachedSavedSearches.put(savedSearches); 1058 } 1059 1060 return savedSearches; 1061 } 1062 1063 1066 public void savedSearchModeChanged(ActionEvent event) 1067 { 1068 UIModeList savedModeList = (UIModeList)event.getComponent(); 1069 1070 String viewMode = savedModeList.getValue().toString(); 1072 1073 setSavedSearchMode(viewMode); 1075 1076 this.cachedSavedSearches.clear(); 1079 this.savedSearch = null; 1080 } 1081 1082 1085 public void selectSearch(ActionEvent event) 1086 { 1087 if (NO_SELECTION.equals(savedSearch) == false) 1088 { 1089 NodeRef searchSearchRef = new NodeRef(Repository.getStoreRef(), savedSearch); 1091 ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); 1092 ContentService cs = services.getContentService(); 1093 try 1094 { 1095 if (services.getNodeService().exists(searchSearchRef)) 1096 { 1097 ContentReader reader = cs.getReader(searchSearchRef, ContentModel.PROP_CONTENT); 1098 SearchContext search = new SearchContext().fromXML(reader.getContentString()); 1099 1100 initialiseFromContext(search); 1103 } 1104 } 1105 catch (Throwable err) 1106 { 1107 Utils.addErrorMessage(MessageFormat.format(Application.getMessage( 1108 FacesContext.getCurrentInstance(), MSG_ERROR_RESTORE_SEARCH), err.getMessage()), err); 1109 } 1110 } 1111 } 1112 1113 1118 private void initialiseFromContext(SearchContext search) 1119 { 1120 resetFields(); 1121 1122 this.text = search.getText(); 1123 1124 switch (search.getMode()) 1125 { 1126 case SearchContext.SEARCH_ALL: 1127 this.mode = MODE_ALL; 1128 break; 1129 case SearchContext.SEARCH_FILE_NAMES_CONTENTS: 1130 this.mode = MODE_FILES_TEXT; 1131 break; 1132 case SearchContext.SEARCH_FILE_NAMES: 1133 this.mode = MODE_FILES; 1134 break; 1135 case SearchContext.SEARCH_SPACE_NAMES: 1136 this.mode = MODE_FOLDERS; 1137 break; 1138 } 1139 this.panels.put(PANEL_RESTRICT, true); 1140 1141 if (search.getLocation() != null) 1142 { 1143 this.locationChildren = search.getLocation().endsWith("//*"); 1144 this.location = findNodeRefFromPath(search.getLocation()); 1145 this.lookin = LOOKIN_OTHER; 1146 this.panels.put(PANEL_LOCATION, true); 1147 } 1148 1149 String [] categories = search.getCategories(); 1150 if (categories != null && categories.length != 0) 1151 { 1152 for (String category : categories) 1153 { 1154 NodeRef categoryRef = findNodeRefFromPath(category); 1155 if (categoryRef != null) 1156 { 1157 Node categoryNode = new MapNode(categoryRef); 1158 categoryNode.getProperties().put(INCLUDE_CHILDREN, category.endsWith("//*")); 1160 this.categories.add(categoryNode); 1161 } 1162 } 1163 this.panels.put(PANEL_CATEGORIES, true); 1164 } 1165 1166 this.contentType = search.getContentType(); 1167 this.contentFormat = search.getMimeType(); 1168 1169 this.description = search.getAttributeQuery(ContentModel.PROP_DESCRIPTION); 1170 this.title = search.getAttributeQuery(ContentModel.PROP_TITLE); 1171 this.author = search.getAttributeQuery(ContentModel.PROP_AUTHOR); 1172 if (this.contentType != null || this.contentFormat != null || 1173 this.description != null || this.title != null || this.author != null) 1174 { 1175 this.panels.put(PANEL_ATTRS, true); 1176 } 1177 1178 RangeProperties createdDate = search.getRangeProperty(ContentModel.PROP_CREATED); 1179 if (createdDate != null) 1180 { 1181 this.createdDateFrom = Utils.parseXMLDateFormat(createdDate.lower); 1182 this.createdDateTo = Utils.parseXMLDateFormat(createdDate.upper); 1183 this.createdDateChecked = true; 1184 this.panels.put(PANEL_ATTRS, true); 1185 } 1186 RangeProperties modifiedDate = search.getRangeProperty(ContentModel.PROP_MODIFIED); 1187 if (modifiedDate != null) 1188 { 1189 this.modifiedDateFrom = Utils.parseXMLDateFormat(modifiedDate.lower); 1190 this.modifiedDateTo = Utils.parseXMLDateFormat(modifiedDate.upper); 1191 this.modifiedDateChecked = true; 1192 this.panels.put(PANEL_ATTRS, true); 1193 } 1194 1195 for (String qname : getCustomPropertyLookup().keySet()) 1197 { 1198 DataTypeDefinition typeDef = getCustomPropertyLookup().get(qname); 1199 if (typeDef != null) 1200 { 1201 QName typeName = typeDef.getName(); 1202 if (DataTypeDefinition.DATE.equals(typeName) || DataTypeDefinition.DATETIME.equals(typeName)) 1203 { 1204 RangeProperties dateProps = search.getRangeProperty(QName.createQName(qname)); 1205 if (dateProps != null) 1206 { 1207 this.customProperties.put(UISearchCustomProperties.PREFIX_DATE_FROM + qname, 1208 Utils.parseXMLDateFormat(dateProps.lower)); 1209 this.customProperties.put(UISearchCustomProperties.PREFIX_DATE_TO + qname, 1210 Utils.parseXMLDateFormat(dateProps.upper)); 1211 this.customProperties.put(qname, true); 1212 this.panels.put(PANEL_CUSTOM, true); 1213 } 1214 } 1215 else if (DataTypeDefinition.BOOLEAN.equals(typeName)) 1216 { 1217 String strBool = search.getFixedValueQuery(QName.createQName(qname)); 1218 if (strBool != null) 1219 { 1220 this.customProperties.put(qname, Boolean.parseBoolean(strBool)); 1221 this.panels.put(PANEL_CUSTOM, true); 1222 } 1223 } 1224 else if (DataTypeDefinition.NODE_REF.equals(typeName) || DataTypeDefinition.CATEGORY.equals(typeName)) 1225 { 1226 String strNodeRef = search.getFixedValueQuery(QName.createQName(qname)); 1227 if (strNodeRef != null) 1228 { 1229 this.customProperties.put(qname, new NodeRef(strNodeRef)); 1230 this.panels.put(PANEL_CUSTOM, true); 1231 } 1232 } 1233 else if (DataTypeDefinition.INT.equals(typeName) || DataTypeDefinition.LONG.equals(typeName) || 1234 DataTypeDefinition.FLOAT.equals(typeName) || DataTypeDefinition.DOUBLE.equals(typeName)) 1235 { 1236 this.customProperties.put(qname, search.getFixedValueQuery(QName.createQName(qname))); 1239 this.panels.put(PANEL_CUSTOM, true); 1240 } 1241 else 1242 { 1243 this.customProperties.put(qname, search.getAttributeQuery(QName.createQName(qname))); 1244 this.panels.put(PANEL_CUSTOM, true); 1245 } 1246 } 1247 } 1248 } 1249 1250 1257 private NodeRef findNodeRefFromPath(String xpath) 1258 { 1259 if (xpath.endsWith("//*")) 1260 { 1261 xpath = xpath.substring(0, xpath.lastIndexOf("//*")); 1262 } 1263 else if (xpath.endsWith("/*")) 1264 { 1265 xpath = xpath.substring(0, xpath.lastIndexOf("/*")); 1266 } 1267 NodeRef rootRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId()); 1268 List <NodeRef> results = null; 1269 try 1270 { 1271 results = searchService.selectNodes( 1272 rootRef, 1273 xpath, 1274 null, 1275 namespaceService, 1276 false); 1277 } 1278 catch (AccessDeniedException err) 1279 { 1280 } 1282 1283 return (results != null && results.size() == 1) ? results.get(0) : null; 1284 } 1285 1286 1289 private NodeRef getUserSearchesRef() 1290 { 1291 if (userSearchesRef == null) 1292 { 1293 NodeRef globalRef = getGlobalSearchesRef(); 1294 if (globalRef != null) 1295 { 1296 FacesContext fc = FacesContext.getCurrentInstance(); 1297 User user = Application.getCurrentUser(fc); 1298 String xpath = NamespaceService.APP_MODEL_PREFIX + ":" + QName.createValidLocalName(user.getUserName()); 1299 1300 List <NodeRef> results = null; 1301 try 1302 { 1303 results = searchService.selectNodes( 1304 globalRef, 1305 xpath, 1306 null, 1307 namespaceService, 1308 false); 1309 } 1310 catch (AccessDeniedException err) 1311 { 1312 } 1314 1315 if (results != null) 1316 { 1317 if (results.size() == 1) 1318 { 1319 userSearchesRef = results.get(0); 1320 } 1321 else if (results.size() == 0 && new Node(globalRef).hasPermission(PermissionService.ADD_CHILDREN)) 1322 { 1323 Map <QName, Serializable > props = new HashMap <QName, Serializable >(2, 1.0f); 1326 props.put(ContentModel.PROP_NAME, user.getUserName()); 1327 ChildAssociationRef childRef = nodeService.createNode( 1328 globalRef, 1329 ContentModel.ASSOC_CONTAINS, 1330 QName.createQName(NamespaceService.APP_MODEL_1_0_URI, QName.createValidLocalName(user.getUserName())), 1331 ContentModel.TYPE_FOLDER, 1332 props); 1333 1334 userSearchesRef = childRef.getChildRef(); 1335 } 1336 } 1337 } 1338 } 1339 1340 return userSearchesRef; 1341 } 1342 1343 1346 private NodeRef getGlobalSearchesRef() 1347 { 1348 if (globalSearchesRef == null) 1349 { 1350 FacesContext fc = FacesContext.getCurrentInstance(); 1351 String xpath = Application.getRootPath(fc) + "/" + 1352 Application.getGlossaryFolderName(fc) + "/" + 1353 Application.getSavedSearchesFolderName(fc); 1354 1355 List <NodeRef> results = null; 1356 try 1357 { 1358 results = searchService.selectNodes( 1359 nodeService.getRootNode(Repository.getStoreRef()), 1360 xpath, 1361 null, 1362 namespaceService, 1363 false); 1364 } 1365 catch (AccessDeniedException err) 1366 { 1367 } 1369 1370 if (results != null && results.size() == 1) 1371 { 1372 globalSearchesRef = results.get(0); 1373 } 1374 } 1375 1376 return globalSearchesRef; 1377 } 1378 1379 1382 public void addCategory(ActionEvent event) 1383 { 1384 UICategorySelector selector = (UICategorySelector)event.getComponent().findComponent("catSelector"); 1385 UISelectBoolean chkChildren = (UISelectBoolean)event.getComponent().findComponent("chkCatChildren"); 1386 1387 NodeRef categoryRef = (NodeRef)selector.getValue(); 1388 if (categoryRef != null) 1389 { 1390 Node categoryNode = new MapNode(categoryRef); 1391 categoryNode.getProperties().put(INCLUDE_CHILDREN, chkChildren.isSelected()); 1393 this.categories.add(categoryNode); 1394 } 1395 } 1396 1397 1400 public void removeCategory(ActionEvent event) 1401 { 1402 Node node = (Node)this.categoriesDataModel.getRowData(); 1403 if (node != null) 1404 { 1405 this.categories.remove(node); 1406 } 1407 } 1408 1409 1412 private AdvancedSearchConfigElement getSearchConfig() 1413 { 1414 if (searchConfigElement == null) 1415 { 1416 searchConfigElement = (AdvancedSearchConfigElement)Application.getConfigService( 1417 FacesContext.getCurrentInstance()).getConfig("Advanced Search"). 1418 getConfigElement(AdvancedSearchConfigElement.CONFIG_ELEMENT_ID); 1419 } 1420 1421 return searchConfigElement; 1422 } 1423 1424 1429 private Map <String , DataTypeDefinition> getCustomPropertyLookup() 1430 { 1431 if (customPropertyLookup == null) 1432 { 1433 customPropertyLookup = new HashMap <String , DataTypeDefinition>(7, 1.0f); 1434 List <CustomProperty> customProps = getSearchConfig().getCustomProperties(); 1435 if (customProps != null) 1436 { 1437 DictionaryService dd = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getDictionaryService(); 1438 for (CustomProperty customProp : customProps) 1439 { 1440 PropertyDefinition propDef = null; 1441 QName propQName = Repository.resolveToQName(customProp.Property); 1442 if (customProp.Type != null) 1443 { 1444 QName type = Repository.resolveToQName(customProp.Type); 1445 TypeDefinition typeDef = dd.getType(type); 1446 propDef = typeDef.getProperties().get(propQName); 1447 } 1448 else if (customProp.Aspect != null) 1449 { 1450 QName aspect = Repository.resolveToQName(customProp.Aspect); 1451 AspectDefinition aspectDef = dd.getAspect(aspect); 1452 propDef = aspectDef.getProperties().get(propQName); 1453 } 1454 customPropertyLookup.put(propQName.toString(), propDef.getDataType()); 1455 } 1456 } 1457 } 1458 return customPropertyLookup; 1459 } 1460 1461 1464 public void expandPanel(ActionEvent event) 1465 { 1466 if (event instanceof ExpandedEvent) 1467 { 1468 this.panels.put(event.getComponent().getId(), ((ExpandedEvent)event).State); 1469 } 1470 } 1471 1472 1473 1476 private static final String MSG_CONTENT = "content"; 1477 private static final String MSG_ALL_FORMATS = "all_formats"; 1478 private static final String MSG_ERROR_SAVE_SEARCH = "error_save_search"; 1479 private static final String MSG_ERROR_RESTORE_SEARCH = "error_restore_search"; 1480 private static final String MSG_SELECT_SAVED_SEARCH = "select_saved_search"; 1481 1482 private static final String OUTCOME_BROWSE = "browse"; 1483 1484 private static final String PANEL_CUSTOM = "custom-panel"; 1485 private static final String PANEL_ATTRS = "attrs-panel"; 1486 private static final String PANEL_CATEGORIES = "categories-panel"; 1487 private static final String PANEL_RESTRICT = "restrict-panel"; 1488 private static final String PANEL_LOCATION = "location-panel"; 1489 1490 private static final String INCLUDE_CHILDREN = "includeChildren"; 1491 1492 private static final String MODE_ALL = "all"; 1493 private static final String MODE_FILES_TEXT = "files_text"; 1494 private static final String MODE_FILES = "files"; 1495 private static final String MODE_FOLDERS = "folders"; 1496 1497 private static final String LOOKIN_ALL = "all"; 1498 private static final String LOOKIN_OTHER = "other"; 1499 1500 private static final String SAVED_SEARCHES_USER = "user"; 1501 private static final String SAVED_SEARCHES_GLOBAL = "global"; 1502 1503 private static final String NO_SELECTION = "NONE"; 1504 1505 1506 protected NodeService nodeService; 1507 1508 1509 protected NamespaceService namespaceService; 1510 1511 1512 protected NavigationBean navigator; 1513 1514 1515 protected SearchService searchService; 1516 1517 1518 protected PermissionService permissionService; 1519 1520 1521 protected AdvancedSearchConfigElement searchConfigElement = null; 1522 1523 1524 private Map <String , Boolean > panels = new HashMap (5, 1.0f); 1525 1526 1527 private String searchName; 1528 private String searchDescription; 1529 1530 1531 private Map <String , Object > customProperties = new HashMap (5, 1.0f); 1532 1533 1534 private Map <String , DataTypeDefinition> customPropertyLookup = null; 1535 1536 1537 private List <SelectItem> contentTypes; 1538 1539 1540 private List <SelectItem> contentFormats; 1541 1542 1543 private String contentType; 1544 1545 1546 private String contentFormat; 1547 1548 1549 private String text = ""; 1550 1551 1552 private String mode = MODE_ALL; 1553 1554 1555 private String lookin = LOOKIN_ALL; 1556 1557 1558 private NodeRef location = null; 1559 1560 1561 private List <Node> categories = new ArrayList <Node>(2); 1562 1563 1564 private DataModel categoriesDataModel = null; 1565 1566 1567 private String title = null; 1568 1569 1570 private String description = null; 1571 1572 1573 private Date createdDateFrom = null; 1574 1575 1576 private Date createdDateTo = null; 1577 1578 1579 private Date modifiedDateFrom = null; 1580 1581 1582 private Date modifiedDateTo = null; 1583 1584 1585 private boolean locationChildren = true; 1586 1587 1588 private String author = null; 1589 1590 private boolean modifiedDateChecked = false; 1591 private boolean createdDateChecked = false; 1592 1593 1594 private NodeRef globalSearchesRef = null; 1595 1596 1597 private NodeRef userSearchesRef = null; 1598 1599 1600 private String savedSearch = null; 1601 1602 1603 private String savedSearchMode = SAVED_SEARCHES_USER; 1604 1605 1606 private String editSearchName = null; 1607 1608 1609 private boolean searchSaveGlobal = false; 1610 1611 1612 private ExpiringValueCache<List <SelectItem>> cachedSavedSearches = new ExpiringValueCache<List <SelectItem>>(); 1613} 1614 | Popular Tags |