001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.search.galleries; 029 030import org.opencms.ade.configuration.CmsFunctionAvailability; 031import org.opencms.ade.galleries.shared.CmsGallerySearchScope; 032import org.opencms.file.CmsObject; 033import org.opencms.file.CmsPropertyDefinition; 034import org.opencms.file.CmsResource; 035import org.opencms.file.types.CmsResourceTypeFunctionConfig; 036import org.opencms.i18n.CmsLocaleManager; 037import org.opencms.main.CmsLog; 038import org.opencms.main.OpenCms; 039import org.opencms.search.A_CmsSearchIndex; 040import org.opencms.search.CmsSearchUtil; 041import org.opencms.search.fields.CmsSearchField; 042import org.opencms.search.fields.CmsSearchFieldConfiguration; 043import org.opencms.search.solr.CmsSolrQuery; 044import org.opencms.util.CmsPair; 045import org.opencms.util.CmsUUID; 046import org.opencms.xml.containerpage.CmsXmlDynamicFunctionHandler; 047 048import java.util.ArrayList; 049import java.util.Arrays; 050import java.util.Collection; 051import java.util.Collections; 052import java.util.List; 053import java.util.Locale; 054import java.util.Set; 055import java.util.stream.Collectors; 056 057import org.apache.commons.logging.Log; 058import org.apache.solr.client.solrj.SolrQuery.ORDER; 059 060import com.google.common.base.Joiner; 061 062/** 063 * Parameters used for the gallery search index.<p> 064 * 065 * @since 8.0.0 066 */ 067public class CmsGallerySearchParameters { 068 069 /** Sort parameter constants. */ 070 public enum CmsGallerySortParam { 071 072 /** Sort by date created ascending. */ 073 dateCreated_asc, 074 075 /** Sort by date created descending. */ 076 dateCreated_desc, 077 078 /** Sort date expired ascending. */ 079 dateExpired_asc, 080 081 /** Sort date expired descending. */ 082 dateExpired_desc, 083 084 /** Sort by date modified ascending. */ 085 dateLastModified_asc, 086 087 /** Sort by date modified descending. */ 088 dateLastModified_desc, 089 090 /** Sort date released ascending. */ 091 dateReleased_asc, 092 093 /** Sort date released descending. */ 094 dateReleased_desc, 095 096 /** Sort by length ascending. */ 097 length_asc, 098 099 /** Sort by length descending. */ 100 length_desc, 101 102 /** Sort by VFS root path ascending. */ 103 path_asc, 104 105 /** Sort by VFS root path descending. */ 106 path_desc, 107 108 /** Sort by score descending. */ 109 score, 110 111 /** Sort state ascending. */ 112 state_asc, 113 114 /** Sort state descending. */ 115 state_desc, 116 117 /** Sort by title ascending. */ 118 title_asc, 119 120 /** Sort by title ascending. */ 121 title_desc, 122 123 /** Sort by type ascending. */ 124 type_asc, 125 126 /** Sort by type descending. */ 127 type_desc, 128 129 /** Sort created by ascending. */ 130 userCreated_asc, 131 132 /** Sort created by descending. */ 133 userCreated_desc, 134 135 /** Sort modified by ascending. */ 136 userLastModified_asc, 137 138 /** Sort modified by descending. */ 139 userLastModified_desc; 140 141 /** The default sort parameter. */ 142 public static final CmsGallerySortParam DEFAULT = title_asc; 143 } 144 145 /** 146 * Helper class to store a time range.<p> 147 */ 148 class CmsGallerySearchTimeRange { 149 150 /** The end time of the time range. */ 151 long m_endTime; 152 153 /** The start time of the time range. */ 154 long m_startTime; 155 156 /** 157 * Default constructor.<p> 158 * 159 * This will create an object where the start date is equal to 160 * {@link Long#MIN_VALUE} and the end date is equal to {@link Long#MAX_VALUE}.<p> 161 */ 162 public CmsGallerySearchTimeRange() { 163 164 m_startTime = Long.MIN_VALUE; 165 m_endTime = Long.MAX_VALUE; 166 } 167 168 /** 169 * Constructor with start and end time.<p> 170 * 171 * @param startTime the start time of the time range 172 * @param endTime the end time of the time range 173 */ 174 public CmsGallerySearchTimeRange(long startTime, long endTime) { 175 176 m_startTime = startTime; 177 m_endTime = endTime; 178 } 179 180 /** 181 * Returns the end time of the time range.<p> 182 * 183 * @return the end time of the time range 184 */ 185 public long getEndTime() { 186 187 return m_endTime; 188 } 189 190 /** 191 * Returns the start time of the time range.<p> 192 * 193 * @return the start time of the time range 194 */ 195 public long getStartTime() { 196 197 return m_startTime; 198 } 199 } 200 201 /** Logge instance for this class. */ 202 private static final Log LOG = CmsLog.getLog(CmsGallerySearchParameters.class); 203 204 /** The categories to search in. */ 205 private List<String> m_categories; 206 207 /** The container types to search in. */ 208 private List<String> m_containerTypes; 209 210 /** The time range for the date of resource creation to consider in the search. */ 211 private CmsGallerySearchTimeRange m_dateCreatedTimeRange; 212 213 /** The time range for the date of resource last modification to consider in the search. */ 214 private CmsGallerySearchTimeRange m_dateLastModifiedTimeRange; 215 216 /** The set of functions to be excluded from the search result (may be null). */ 217 private Set<CmsUUID> m_excludedFunctions; 218 219 /** The list of folders to search in. */ 220 private List<String> m_folders; 221 222 /** Enlists all VFS folders to perform a search in. */ 223 private List<String> m_foldersToSearchIn; 224 225 /** If true, empty search result should be returned regardless of other settings. */ 226 private boolean m_forceEmptyResult; 227 228 /** Function availability. */ 229 private CmsFunctionAvailability m_functionAvailability; 230 231 /** The galleries to search in. */ 232 private List<String> m_galleries; 233 234 /** Indicates the search exclude property should be ignored. */ 235 private boolean m_ignoreSearchExclude; 236 237 /** Set of functions to include (whitelist). */ 238 private Set<CmsUUID> m_includedFunctions; 239 240 /** Indicates if expired and unreleased resources should be included in the search. */ 241 private boolean m_includeExpired; 242 243 /** The locale for the search. */ 244 private String m_locale; 245 246 /** The number of search results per page. */ 247 private int m_matchesPerPage; 248 249 /** The sitemap reference path. */ 250 private String m_referencePath; 251 252 /** The resource types to search for. */ 253 private List<String> m_resourceTypes; 254 255 /** The requested page of the result. */ 256 private int m_resultPage; 257 258 /** The gallery search scope. */ 259 private CmsGallerySearchScope m_scope; 260 261 /** The sort order for the search result. */ 262 private CmsGallerySortParam m_sortOrder; 263 264 /** The template compatibility. */ 265 private String m_templateCompatibility; 266 267 /** Search words to search for. */ 268 private String m_words; 269 270 /** 271 * Default constructor.<p> 272 */ 273 public CmsGallerySearchParameters() { 274 275 m_resultPage = 1; 276 m_matchesPerPage = 10; 277 } 278 279 /** 280 * Returns the categories that have been included in the search.<p> 281 * 282 * If no categories have been set, then <code>null</code> is returned.<p> 283 * 284 * @return the categories that have been included in the search 285 */ 286 public List<String> getCategories() { 287 288 return m_categories; 289 } 290 291 /** 292 * Returns the container types that have been included in the search.<p> 293 * 294 * @return the container types that have been included in the search 295 */ 296 public List<String> getContainerTypes() { 297 298 return m_containerTypes; 299 } 300 301 /** 302 * Returns the time range for the date of creation that has been used for the search result.<p> 303 * 304 * In case this time range has not been set, this will return an object 305 * where the start date is equal to {@link Long#MIN_VALUE} and the end date is equal to {@link Long#MAX_VALUE}.<p> 306 * 307 * @return the time range for the date of creation that has been used for the search result 308 */ 309 public CmsGallerySearchTimeRange getDateCreatedRange() { 310 311 if (m_dateCreatedTimeRange == null) { 312 m_dateCreatedTimeRange = new CmsGallerySearchTimeRange(); 313 } 314 return m_dateCreatedTimeRange; 315 } 316 317 /** 318 * Returns the time range for the dadelete examplete of last modification that has been used for the search result.<p> 319 * 320 * In case this time range has not been set, this will return an object 321 * where the start date is equal to {@link Long#MIN_VALUE} and the end date is equal to {@link Long#MAX_VALUE}.<p> 322 * 323 * @return the time range for the date of last modification that has been used for the search result 324 */ 325 public CmsGallerySearchTimeRange getDateLastModifiedRange() { 326 327 if (m_dateLastModifiedTimeRange == null) { 328 m_dateLastModifiedTimeRange = new CmsGallerySearchTimeRange(); 329 } 330 return m_dateLastModifiedTimeRange; 331 } 332 333 /** 334 * Gets the set of structure IDs of functions to exclude from the search result. 335 * 336 * @return the set of structure IDs to exclude 337 */ 338 public Set<CmsUUID> getExcludedFunctions() { 339 340 return m_excludedFunctions; 341 } 342 343 /** 344 * Returns the list of folders to search in.<p> 345 * 346 * @return a list of paths of VFS folders 347 */ 348 public List<String> getFolders() { 349 350 return m_folders; 351 } 352 353 /** 354 * Returns the galleries that have been included in the search.<p> 355 * 356 * If no galleries have been set, then <code>null</code> is returned.<p> 357 * 358 * @return the galleries that have been included in the search 359 */ 360 public List<String> getGalleries() { 361 362 return m_galleries; 363 } 364 365 /** 366 * Gets the set of ids of functions to include. 367 * 368 * <p>Note: If the id of a function is returned in the ID set returned by thsi method, 369 * the function may still be excluded from search results based on other parameters. 370 * 371 * @return the included functions 372 */ 373 public Set<CmsUUID> getIncludedFunctions() { 374 375 return m_includedFunctions; 376 } 377 378 /** 379 * Returns the locale that has been used for the search.<p> 380 * 381 * If no locale has been set, then <code>null</code> is returned.<p> 382 * 383 * @return the locale that has been used for the search 384 */ 385 public String getLocale() { 386 387 if (m_locale == null) { 388 m_locale = CmsLocaleManager.getDefaultLocale().toString(); 389 } 390 return m_locale; 391 } 392 393 /** 394 * Returns the maximum number of matches per result page.<p> 395 * 396 * @return the the maximum number of matches per result page 397 * 398 * @see #getMatchesPerPage() 399 * @see #setResultPage(int) 400 */ 401 public int getMatchesPerPage() { 402 403 return m_matchesPerPage; 404 } 405 406 /** 407 * Returns a CmsSolrQuery representation of this class. 408 * @param cms the openCms object. 409 * @return CmsSolrQuery representation of this class. 410 */ 411 public CmsSolrQuery getQuery(CmsObject cms) { 412 413 final CmsSolrQuery query = new CmsSolrQuery(); 414 415 // set categories 416 query.setCategories(m_categories); 417 418 // set container types 419 if (null != m_containerTypes) { 420 query.addFilterQuery(CmsSearchField.FIELD_CONTAINER_TYPES, m_containerTypes, false, false); 421 } 422 423 // Set date created time filter 424 query.addFilterQuery( 425 CmsSearchUtil.getDateCreatedTimeRangeFilterQuery( 426 CmsSearchField.FIELD_DATE_CREATED, 427 getDateCreatedRange().m_startTime, 428 getDateCreatedRange().m_endTime)); 429 430 // Set date last modified time filter 431 query.addFilterQuery( 432 CmsSearchUtil.getDateCreatedTimeRangeFilterQuery( 433 CmsSearchField.FIELD_DATE_LASTMODIFIED, 434 getDateLastModifiedRange().m_startTime, 435 getDateLastModifiedRange().m_endTime)); 436 437 // set scope / folders to search in 438 m_foldersToSearchIn = new ArrayList<String>(); 439 addFoldersToSearchIn(m_folders); 440 addFoldersToSearchIn(m_galleries); 441 setSearchFolders(cms); 442 query.addFilterQuery( 443 CmsSearchField.FIELD_PARENT_FOLDERS, 444 new ArrayList<String>(m_foldersToSearchIn), 445 false, 446 true); 447 448 if (!m_ignoreSearchExclude) { 449 // Reference for the values: CmsGallerySearchIndex.java, field EXCLUDE_PROPERTY_VALUES 450 query.addFilterQuery( 451 "-" + CmsSearchField.FIELD_SEARCH_EXCLUDE, 452 Arrays.asList( 453 new String[] { 454 A_CmsSearchIndex.PROPERTY_SEARCH_EXCLUDE_VALUE_ALL, 455 A_CmsSearchIndex.PROPERTY_SEARCH_EXCLUDE_VALUE_GALLERY}), 456 false, 457 true); 458 } 459 460 // set matches per page 461 query.setRows(new Integer(m_matchesPerPage)); 462 463 // set resource types 464 if (null != m_resourceTypes) { 465 List<String> resourceTypes = new ArrayList<>(m_resourceTypes); 466 if (m_resourceTypes.contains(CmsResourceTypeFunctionConfig.TYPE_NAME) 467 && !m_resourceTypes.contains(CmsXmlDynamicFunctionHandler.TYPE_FUNCTION)) { 468 resourceTypes.add(CmsXmlDynamicFunctionHandler.TYPE_FUNCTION); 469 } 470 query.setResourceTypes(resourceTypes); 471 } 472 473 // set result page 474 query.setStart(new Integer((m_resultPage - 1) * m_matchesPerPage)); 475 476 // set search locale 477 if (null != m_locale) { 478 Locale l = CmsLocaleManager.getLocale(m_locale); 479 List<Locale> locales = new ArrayList<>(3); 480 locales.add(l); 481 if (!l.getVariant().isEmpty()) { 482 locales.add(new Locale(l.getLanguage(), l.getCountry())); 483 } 484 if (!l.getCountry().isEmpty()) { 485 locales.add(new Locale(l.getLanguage())); 486 } 487 query.setLocales(locales); 488 } 489 490 // set search words 491 if (null != m_words) { 492 query.setQuery(m_words); 493 } 494 495 // set sort order 496 query.setSort(getSort().getFirst(), getSort().getSecond()); 497 498 // set result collapsing by id 499 // add sort criteria to possibly speed up performance and prevent sorting by score - not sure if a good solution 500 query.addFilterQuery( 501 "{!collapse field=id sort='" 502 + CmsSearchField.FIELD_INSTANCEDATE 503 + CmsSearchField.FIELD_POSTFIX_DATE 504 + " asc'}"); 505 506 query.setFields(CmsGallerySearchResult.getRequiredSolrFields()); 507 508 if ((m_functionAvailability != null) && m_functionAvailability.isDefined()) { 509 String notFunction = "(*:* AND -type:(" 510 + CmsXmlDynamicFunctionHandler.TYPE_FUNCTION 511 + " OR " 512 + CmsResourceTypeFunctionConfig.TYPE_NAME 513 + "))"; 514 Collection<CmsUUID> whitelist = m_functionAvailability.getWhitelist(); 515 Collection<CmsUUID> blacklist = new ArrayList<>(m_functionAvailability.getBlacklist()); 516 CmsUUID dummyId = CmsUUID.getNullUUID(); 517 blacklist.add(dummyId); 518 String idClause; 519 if (whitelist != null) { 520 whitelist = new ArrayList<>(whitelist); 521 whitelist.add(dummyId); 522 String whitelistIdCondition = whitelist.stream().map(id -> id.toString()).collect( 523 Collectors.joining(" OR ")); 524 idClause = "id:(" + whitelistIdCondition + ")"; 525 } else { 526 idClause = "*:* AND -id:(" 527 + blacklist.stream().map(id -> id.toString()).collect(Collectors.joining(" OR ")) 528 + ") "; 529 } 530 String functionFilter = "(" + notFunction + " OR (" + idClause + "))"; 531 query.addFilterQuery(functionFilter); 532 } 533 534 if ((m_resourceTypes != null) && m_resourceTypes.contains(CmsResourceTypeFunctionConfig.TYPE_NAME)) { 535 if ((m_excludedFunctions != null) && (m_excludedFunctions.size() > 0)) { 536 List<CmsUUID> excludedFunctions = new ArrayList<>(m_excludedFunctions); 537 Collections.sort(excludedFunctions); 538 String orList = Joiner.on(" OR ").join(excludedFunctions); 539 String filter = "*:* AND -id:(" + orList + ")"; 540 query.addFilterQuery(filter); 541 } 542 if (m_includedFunctions != null) { 543 List<CmsUUID> includedFunctions = new ArrayList<>(m_includedFunctions); 544 // not sure if order of terms matters for filter query caching in Solr, so normalize order just in case 545 Collections.sort(includedFunctions); 546 List<String> conditions = new ArrayList<>(); 547 String notFunction = "(*:* AND -type:(" 548 + CmsXmlDynamicFunctionHandler.TYPE_FUNCTION 549 + " OR " 550 + CmsResourceTypeFunctionConfig.TYPE_NAME 551 + "))"; 552 conditions.add(notFunction); 553 for (CmsUUID id : includedFunctions) { 554 conditions.add("id:" + id); 555 } 556 String includedFunctionsFilter = Joiner.on(" OR ").join(conditions); 557 query.addFilterQuery(includedFunctionsFilter); 558 } 559 } 560 561 if (m_templateCompatibility != null) { 562 if (m_templateCompatibility.matches("^[0-9a-zA-Z_]+$")) { 563 String fieldName = CmsPropertyDefinition.PROPERTY_TEMPLATE_COMPATILIBITY + "_prop"; 564 query.addFilterQuery("(*:* NOT " + fieldName + ":*) OR " + fieldName + ":" + m_templateCompatibility); 565 } else { 566 LOG.warn( 567 "Invalid template compatibility value: " 568 + m_templateCompatibility 569 + ". Must only contain digits, letters (a-z) or underscores."); 570 } 571 } 572 573 // include expired/unreleased 574 if (m_includeExpired) { 575 query.removeExpiration(); 576 } 577 578 return query; 579 } 580 581 /** 582 * Gets the reference path.<p> 583 * 584 * @return the gallery reference path 585 */ 586 public String getReferencePath() { 587 588 return m_referencePath; 589 } 590 591 /** 592 * Returns the names of the resource types that have been included in the search result.<p> 593 * 594 * If no resource types have been set, then <code>null</code> is returned.<p> 595 * 596 * @return the names of the resource types that have been included in the search result 597 */ 598 public List<String> getResourceTypes() { 599 600 return m_resourceTypes; 601 } 602 603 /** 604 * Returns the index of the requested result page.<p> 605 * 606 * @return the index of the requested result page 607 * 608 * @see #setResultPage(int) 609 * @see #getMatchesPerPage() 610 * @see #setMatchesPerPage(int) 611 */ 612 public int getResultPage() { 613 614 return m_resultPage; 615 } 616 617 /** 618 * The gallery search scope.<p> 619 * 620 * @return the gallery search scope 621 */ 622 public CmsGallerySearchScope getScope() { 623 624 if (m_scope == null) { 625 return OpenCms.getWorkplaceManager().getGalleryDefaultScope(); 626 } 627 return m_scope; 628 } 629 630 /** 631 * Returns the words (terms) that have been used for the full text search.<p> 632 * 633 * If no search words have been set, then <code>null</code> is returned.<p> 634 * 635 * @return the words (terms) that have been used for the full text search 636 */ 637 public String getSearchWords() { 638 639 return m_words; 640 } 641 642 /** 643 * Returns the sort order that has been used in the search.<p> 644 * 645 * If the sort parameter has not been set the default sort order 646 * defined by {@link CmsGallerySortParam#DEFAULT} is used.<p> 647 * 648 * @return the sort order that has been used in the search 649 */ 650 public CmsGallerySortParam getSortOrder() { 651 652 if (m_sortOrder == null) { 653 654 m_sortOrder = CmsGallerySortParam.DEFAULT; 655 } 656 return m_sortOrder; 657 } 658 659 /** 660 * Gets the template compatibility. 661 * 662 * <p>If set, matches those resources whose template.compatibility property is either empty or contains the value (possibly together with other values, separated by whitespace). 663 * 664 * @return the template compatibility 665 */ 666 public String getTemplateCompatibility() { 667 668 return m_templateCompatibility; 669 } 670 671 /** 672 * If this returns true, an empty search result should be returned, regardless of other settings. 673 * 674 * @return true if an empty search result should be forced 675 */ 676 public boolean isForceEmptyResult() { 677 678 return m_forceEmptyResult; 679 } 680 681 /** 682 * Returns the search exclude property ignore flag.<p> 683 * 684 * @return the search exclude property ignore flag 685 */ 686 public boolean isIgnoreSearchExclude() { 687 688 return m_ignoreSearchExclude; 689 } 690 691 /** 692 * Returns a flag, indicating if release and expiration date should be ignored.<p> 693 * 694 * @return a flag, indicating if release and expiration date should be ignored 695 */ 696 public boolean isIncludeExpired() { 697 698 return m_includeExpired; 699 } 700 701 /** 702 * Sets the categories for the search.<p> 703 * 704 * Results are found only if they are contained in at least one of the given categories. 705 * 706 * @param categories the categories to set 707 */ 708 public void setCategories(List<String> categories) { 709 710 m_categories = categories; 711 } 712 713 /** 714 * Sets the container types for the search.<p> 715 * 716 * Results are found only if they are compatible with one of the given container types. 717 * If no container type is set, results compatible with any container will be returned in the search result.<p> 718 * 719 * @param containerTypes the container types to set 720 */ 721 public void setContainerTypes(List<String> containerTypes) { 722 723 m_containerTypes = containerTypes; 724 } 725 726 /** 727 * Sets the time range for the date of resource creation to consider in the search.<p> 728 * 729 * @param startTime the start time of the time range 730 * @param endTime the end time of the time range 731 */ 732 public void setDateCreatedTimeRange(long startTime, long endTime) { 733 734 if (m_dateCreatedTimeRange == null) { 735 m_dateCreatedTimeRange = new CmsGallerySearchTimeRange(startTime, endTime); 736 } 737 } 738 739 /** 740 * Sets the time range for the date of resource last modification to consider in the search.<p> 741 * 742 * @param startTime the start time of the time range 743 * @param endTime the end time of the time range 744 */ 745 public void setDateLastModifiedTimeRange(long startTime, long endTime) { 746 747 if (m_dateLastModifiedTimeRange == null) { 748 m_dateLastModifiedTimeRange = new CmsGallerySearchTimeRange(startTime, endTime); 749 } 750 } 751 752 /** 753 * Sets the structure IDs of functions to exclude from the search results. 754 * 755 * @param excludedFunctions the structure IDs of functions to exclude 756 */ 757 public void setExcludedFunctions(Set<CmsUUID> excludedFunctions) { 758 759 m_excludedFunctions = excludedFunctions; 760 761 } 762 763 /** 764 * Sets the folders to search in.<p> 765 * 766 * @param folders the list of VFS folders 767 */ 768 public void setFolders(List<String> folders) { 769 770 m_folders = folders; 771 } 772 773 /** 774 * Enables/disables the 'force empty result' flag. 775 * 776 * If this is set to true, an empty search result should be returned regardless of the other parameters. 777 * 778 * @param forceEmptyResult if true, force an empty search result 779 */ 780 public void setForceEmptyResult(boolean forceEmptyResult) { 781 782 m_forceEmptyResult = forceEmptyResult; 783 } 784 785 /** 786 * Sets the dynamic function availability. 787 * 788 * @param dynamicFunctionAvailability the dynamic function availability 789 */ 790 public void setFunctionAvailability(CmsFunctionAvailability dynamicFunctionAvailability) { 791 792 m_functionAvailability = dynamicFunctionAvailability; 793 } 794 795 /** 796 * Sets the galleries for the search.<p> 797 * 798 * Results are found only if they are contained in one of the given galleries. 799 * If no gallery is set, results from all galleries will be returned in the search result.<p> 800 * 801 * @param galleries the galleries to set 802 */ 803 public void setGalleries(List<String> galleries) { 804 805 m_galleries = galleries; 806 } 807 808 /** 809 * Sets the search exclude property ignore flag.<p> 810 * 811 * @param excludeForPageEditor the search exclude property ignore flag 812 */ 813 public void setIgnoreSearchExclude(boolean excludeForPageEditor) { 814 815 m_ignoreSearchExclude = excludeForPageEditor; 816 } 817 818 /** 819 * Sets the ids of functions to include. 820 * 821 * @param includedFunctions the ids of functions to include 822 */ 823 public void setIncludedFunctions(Set<CmsUUID> includedFunctions) { 824 825 m_includedFunctions = includedFunctions; 826 } 827 828 /** 829 * Set the flag, determining if expired and unreleased resources should be shown. 830 * @param includeExpired iff <code>true</code> expired and unreleased resources are shown. 831 */ 832 public void setIncludeExpired(boolean includeExpired) { 833 834 m_includeExpired = includeExpired; 835 836 } 837 838 /** 839 * Sets the maximum number of matches per result page.<p> 840 * 841 * Use this together with {@link #setResultPage(int)} in order to split the result 842 * in more than one page.<p> 843 * 844 * @param matchesPerPage the the maximum number of matches per result page to set 845 * 846 * @see #getMatchesPerPage() 847 * @see #setResultPage(int) 848 */ 849 public void setMatchesPerPage(int matchesPerPage) { 850 851 m_matchesPerPage = matchesPerPage; 852 } 853 854 /** 855 * Sets the gallery reference path.<p> 856 * 857 * @param referencePath the gallery reference path 858 */ 859 public void setReferencePath(String referencePath) { 860 861 m_referencePath = referencePath; 862 } 863 864 /** 865 * Sets the names of the resource types to include in the search result.<p> 866 * 867 * Results are found only if they resources match one of the given resource type names. 868 * If no resource type name is set, all resource types will be returned in the search result.<p> 869 * 870 * @param resourceTypes the names of the resource types to include in the search result 871 */ 872 public void setResourceTypes(List<String> resourceTypes) { 873 874 m_resourceTypes = resourceTypes; 875 } 876 877 /** 878 * Sets the index of the result page that should be returned.<p> 879 * 880 * Use this together with {@link #setMatchesPerPage(int)} in order to split the result 881 * in more than one page.<p> 882 * 883 * @param resultPage the index of the result page to return 884 * 885 * @see #getResultPage() 886 * @see #getMatchesPerPage() 887 * @see #setMatchesPerPage(int) 888 */ 889 public void setResultPage(int resultPage) { 890 891 m_resultPage = resultPage; 892 } 893 894 /** 895 * Sets the search scope.<p> 896 * 897 * @param scope the search scope 898 */ 899 public void setScope(CmsGallerySearchScope scope) { 900 901 m_scope = scope; 902 } 903 904 /** 905 * Sets the locale for the search.<p> 906 * 907 * Results are found only if they match the given locale. 908 * If no locale is set, results for all locales will be returned in the search result.<p> 909 * 910 * @param locale the locale to set 911 */ 912 public void setSearchLocale(String locale) { 913 914 m_locale = locale; 915 } 916 917 /** 918 * Sets the words (terms) for the full text search.<p> 919 * 920 * Results are found only if they text extraction for the resource contains all given search words. 921 * If no search word is set, all resources will be returned in the search result.<p> 922 * 923 * Please note that this should be a list of words separated by white spaces. 924 * Simple Lucene modifiers such as (+), (-) and (*) are allowed, but anything more complex then this 925 * will be removed.<p> 926 * 927 * @param words the words (terms) for the full text search to set 928 */ 929 public void setSearchWords(String words) { 930 931 m_words = words; 932 } 933 934 /** 935 * Sets the sort order for the search.<p> 936 * 937 * @param sortOrder the sort order to set 938 */ 939 public void setSortOrder(CmsGallerySortParam sortOrder) { 940 941 m_sortOrder = sortOrder; 942 } 943 944 /** 945 * Sets the template compatibility string. 946 * 947 * @param compatibility the template compatibility string 948 */ 949 public void setTemplateCompatibility(String compatibility) { 950 951 m_templateCompatibility = compatibility; 952 } 953 954 /** 955 * Adds folders to perform the search in. 956 * @param folders Folders to search in. 957 */ 958 private void addFoldersToSearchIn(final List<String> folders) { 959 960 if (null == folders) { 961 return; 962 } 963 964 for (String folder : folders) { 965 if (!CmsResource.isFolder(folder)) { 966 folder += "/"; 967 } 968 969 m_foldersToSearchIn.add(folder); 970 } 971 } 972 973 /** 974 * Checks if the given list of resource type names contains a function-like type.<p> 975 * 976 * @param resourceTypes the collection of resource types 977 * @return true if the list contains a function-like type 978 */ 979 private boolean containsFunctionType(List<String> resourceTypes) { 980 981 if (resourceTypes.contains(CmsXmlDynamicFunctionHandler.TYPE_FUNCTION)) { 982 return true; 983 } 984 if (resourceTypes.contains(CmsResourceTypeFunctionConfig.TYPE_NAME)) { 985 return true; 986 } 987 return false; 988 } 989 990 /** 991 * Returns the Lucene sort indicated by the selected sort order.<p> 992 * 993 * @return the Lucene sort indicated by the selected sort order 994 * 995 * @see #getSortOrder() 996 */ 997 private CmsPair<String, org.apache.solr.client.solrj.SolrQuery.ORDER> getSort() { 998 999 final String sortTitle = CmsSearchFieldConfiguration.getLocaleExtendedName( 1000 CmsSearchField.FIELD_DISPTITLE, 1001 getLocale()) + "_sort"; 1002 1003 switch (getSortOrder()) { 1004 case dateCreated_asc: 1005 return CmsPair.create(CmsSearchField.FIELD_DATE_CREATED, ORDER.asc); 1006 case dateCreated_desc: 1007 return CmsPair.create(CmsSearchField.FIELD_DATE_CREATED, ORDER.desc); 1008 case dateExpired_asc: 1009 return CmsPair.create(CmsSearchField.FIELD_DATE_EXPIRED, ORDER.asc); 1010 case dateExpired_desc: 1011 return CmsPair.create(CmsSearchField.FIELD_DATE_EXPIRED, ORDER.desc); 1012 case dateLastModified_asc: 1013 return CmsPair.create(CmsSearchField.FIELD_DATE_LASTMODIFIED, ORDER.asc); 1014 case dateLastModified_desc: 1015 return CmsPair.create(CmsSearchField.FIELD_DATE_LASTMODIFIED, ORDER.desc); 1016 case dateReleased_asc: 1017 return CmsPair.create(CmsSearchField.FIELD_DATE_RELEASED, ORDER.asc); 1018 case dateReleased_desc: 1019 return CmsPair.create(CmsSearchField.FIELD_DATE_RELEASED, ORDER.desc); 1020 case length_asc: 1021 return CmsPair.create(CmsSearchField.FIELD_SIZE, ORDER.asc); 1022 case length_desc: 1023 return CmsPair.create(CmsSearchField.FIELD_SIZE, ORDER.desc); 1024 case path_asc: 1025 return CmsPair.create(CmsSearchField.FIELD_PATH, ORDER.asc); 1026 case path_desc: 1027 return CmsPair.create(CmsSearchField.FIELD_PATH, ORDER.desc); 1028 case score: 1029 return CmsPair.create(CmsSearchField.FIELD_SCORE, ORDER.desc); 1030 case state_asc: 1031 return CmsPair.create(CmsSearchField.FIELD_STATE, ORDER.asc); 1032 case state_desc: 1033 return CmsPair.create(CmsSearchField.FIELD_STATE, ORDER.desc); 1034 case title_asc: 1035 return CmsPair.create(sortTitle, ORDER.asc); 1036 case title_desc: 1037 return CmsPair.create(sortTitle, ORDER.desc); 1038 case type_asc: 1039 return CmsPair.create(CmsSearchField.FIELD_TYPE, ORDER.asc); 1040 case type_desc: 1041 return CmsPair.create(CmsSearchField.FIELD_TYPE, ORDER.desc); 1042 case userCreated_asc: 1043 return CmsPair.create(CmsSearchField.FIELD_USER_CREATED, ORDER.asc); 1044 case userCreated_desc: 1045 return CmsPair.create(CmsSearchField.FIELD_USER_CREATED, ORDER.desc); 1046 case userLastModified_asc: 1047 return CmsPair.create(CmsSearchField.FIELD_USER_LAST_MODIFIED, ORDER.asc); 1048 case userLastModified_desc: 1049 return CmsPair.create(CmsSearchField.FIELD_USER_LAST_MODIFIED, ORDER.desc); 1050 default: 1051 return CmsPair.create(sortTitle, ORDER.asc); 1052 } 1053 } 1054 1055 /** 1056 * Applies the defined search folders to the Solr query. 1057 * 1058 * @param obj The current CmsObject object. 1059 */ 1060 private void setSearchFolders(CmsObject obj) { 1061 1062 // check if parentFolders to search in have been set 1063 // if this evaluates false, the search folders have already been set, so 1064 // there's no need to add a scope filter 1065 if (m_foldersToSearchIn.isEmpty()) { 1066 // only append scope filter if no no folders or galleries given 1067 setSearchScopeFilter(obj); 1068 } 1069 } 1070 1071 /** 1072 * Sets the search scope. 1073 * 1074 * @param cms The current CmsObject object. 1075 */ 1076 private void setSearchScopeFilter(CmsObject cms) { 1077 1078 final List<String> searchRoots = CmsSearchUtil.computeScopeFolders(cms, this); 1079 1080 // If the resource types contain the type "function" also 1081 // add "/system/modules/" to the search path 1082 1083 if ((null != getResourceTypes()) && containsFunctionType(getResourceTypes())) { 1084 searchRoots.add("/system/modules/"); 1085 } 1086 1087 addFoldersToSearchIn(searchRoots); 1088 } 1089}