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 time range for the date of resource creation to consider in the search. */ 208 private CmsGallerySearchTimeRange m_dateCreatedTimeRange; 209 210 /** The time range for the date of resource last modification to consider in the search. */ 211 private CmsGallerySearchTimeRange m_dateLastModifiedTimeRange; 212 213 /** The set of functions to be excluded from the search result (may be null). */ 214 private Set<CmsUUID> m_excludedFunctions; 215 216 /** The list of folders to search in. */ 217 private List<String> m_folders; 218 219 /** Enlists all VFS folders to perform a search in. */ 220 private List<String> m_foldersToSearchIn; 221 222 /** If true, empty search result should be returned regardless of other settings. */ 223 private boolean m_forceEmptyResult; 224 225 /** Function availability. */ 226 private CmsFunctionAvailability m_functionAvailability; 227 228 /** The galleries to search in. */ 229 private List<String> m_galleries; 230 231 /** Indicates the search exclude property should be ignored. */ 232 private boolean m_ignoreSearchExclude; 233 234 /** Set of functions to include (whitelist). */ 235 private Set<CmsUUID> m_includedFunctions; 236 237 /** Indicates if expired and unreleased resources should be included in the search. */ 238 private boolean m_includeExpired; 239 240 /** The locale for the search. */ 241 private String m_locale; 242 243 /** The number of search results per page. */ 244 private int m_matchesPerPage; 245 246 /** The sitemap reference path. */ 247 private String m_referencePath; 248 249 /** The resource types to search for. */ 250 private List<String> m_resourceTypes; 251 252 /** The requested page of the result. */ 253 private int m_resultPage; 254 255 /** The gallery search scope. */ 256 private CmsGallerySearchScope m_scope; 257 258 /** The sort order for the search result. */ 259 private CmsGallerySortParam m_sortOrder; 260 261 /** The template compatibility. */ 262 private String m_templateCompatibility; 263 264 /** Search words to search for. */ 265 private String m_words; 266 267 /** 268 * Default constructor.<p> 269 */ 270 public CmsGallerySearchParameters() { 271 272 m_resultPage = 1; 273 m_matchesPerPage = 10; 274 } 275 276 /** 277 * Returns the categories that have been included in the search.<p> 278 * 279 * If no categories have been set, then <code>null</code> is returned.<p> 280 * 281 * @return the categories that have been included in the search 282 */ 283 public List<String> getCategories() { 284 285 return m_categories; 286 } 287 288 /** 289 * Returns the time range for the date of creation that has been used for the search result.<p> 290 * 291 * In case this time range has not been set, this will return an object 292 * where the start date is equal to {@link Long#MIN_VALUE} and the end date is equal to {@link Long#MAX_VALUE}.<p> 293 * 294 * @return the time range for the date of creation that has been used for the search result 295 */ 296 public CmsGallerySearchTimeRange getDateCreatedRange() { 297 298 if (m_dateCreatedTimeRange == null) { 299 m_dateCreatedTimeRange = new CmsGallerySearchTimeRange(); 300 } 301 return m_dateCreatedTimeRange; 302 } 303 304 /** 305 * Returns the time range for the dadelete examplete of last modification that has been used for the search result.<p> 306 * 307 * In case this time range has not been set, this will return an object 308 * where the start date is equal to {@link Long#MIN_VALUE} and the end date is equal to {@link Long#MAX_VALUE}.<p> 309 * 310 * @return the time range for the date of last modification that has been used for the search result 311 */ 312 public CmsGallerySearchTimeRange getDateLastModifiedRange() { 313 314 if (m_dateLastModifiedTimeRange == null) { 315 m_dateLastModifiedTimeRange = new CmsGallerySearchTimeRange(); 316 } 317 return m_dateLastModifiedTimeRange; 318 } 319 320 /** 321 * Gets the set of structure IDs of functions to exclude from the search result. 322 * 323 * @return the set of structure IDs to exclude 324 */ 325 public Set<CmsUUID> getExcludedFunctions() { 326 327 return m_excludedFunctions; 328 } 329 330 /** 331 * Returns the list of folders to search in.<p> 332 * 333 * @return a list of paths of VFS folders 334 */ 335 public List<String> getFolders() { 336 337 return m_folders; 338 } 339 340 /** 341 * Returns the galleries that have been included in the search.<p> 342 * 343 * If no galleries have been set, then <code>null</code> is returned.<p> 344 * 345 * @return the galleries that have been included in the search 346 */ 347 public List<String> getGalleries() { 348 349 return m_galleries; 350 } 351 352 /** 353 * Gets the set of ids of functions to include. 354 * 355 * <p>Note: If the id of a function is returned in the ID set returned by thsi method, 356 * the function may still be excluded from search results based on other parameters. 357 * 358 * @return the included functions 359 */ 360 public Set<CmsUUID> getIncludedFunctions() { 361 362 return m_includedFunctions; 363 } 364 365 /** 366 * Returns the locale that has been used for the search.<p> 367 * 368 * If no locale has been set, then <code>null</code> is returned.<p> 369 * 370 * @return the locale that has been used for the search 371 */ 372 public String getLocale() { 373 374 if (m_locale == null) { 375 m_locale = CmsLocaleManager.getDefaultLocale().toString(); 376 } 377 return m_locale; 378 } 379 380 /** 381 * Returns the maximum number of matches per result page.<p> 382 * 383 * @return the the maximum number of matches per result page 384 * 385 * @see #getMatchesPerPage() 386 * @see #setResultPage(int) 387 */ 388 public int getMatchesPerPage() { 389 390 return m_matchesPerPage; 391 } 392 393 /** 394 * Returns a CmsSolrQuery representation of this class. 395 * @param cms the openCms object. 396 * @return CmsSolrQuery representation of this class. 397 */ 398 public CmsSolrQuery getQuery(CmsObject cms) { 399 400 final CmsSolrQuery query = new CmsSolrQuery(); 401 402 // set categories 403 query.setCategories(m_categories); 404 405 // Set date created time filter 406 query.addFilterQuery( 407 CmsSearchUtil.getDateCreatedTimeRangeFilterQuery( 408 CmsSearchField.FIELD_DATE_CREATED, 409 getDateCreatedRange().m_startTime, 410 getDateCreatedRange().m_endTime)); 411 412 // Set date last modified time filter 413 query.addFilterQuery( 414 CmsSearchUtil.getDateCreatedTimeRangeFilterQuery( 415 CmsSearchField.FIELD_DATE_LASTMODIFIED, 416 getDateLastModifiedRange().m_startTime, 417 getDateLastModifiedRange().m_endTime)); 418 419 // set scope / folders to search in 420 m_foldersToSearchIn = new ArrayList<String>(); 421 addFoldersToSearchIn(m_folders); 422 addFoldersToSearchIn(m_galleries); 423 setSearchFolders(cms); 424 query.addFilterQuery( 425 CmsSearchField.FIELD_PARENT_FOLDERS, 426 new ArrayList<String>(m_foldersToSearchIn), 427 false, 428 true); 429 430 if (!m_ignoreSearchExclude) { 431 // Reference for the values: CmsGallerySearchIndex.java, field EXCLUDE_PROPERTY_VALUES 432 query.addFilterQuery( 433 "-" + CmsSearchField.FIELD_SEARCH_EXCLUDE, 434 Arrays.asList( 435 new String[] { 436 A_CmsSearchIndex.PROPERTY_SEARCH_EXCLUDE_VALUE_ALL, 437 A_CmsSearchIndex.PROPERTY_SEARCH_EXCLUDE_VALUE_GALLERY}), 438 false, 439 true); 440 } 441 442 // set matches per page 443 query.setRows(Integer.valueOf(m_matchesPerPage)); 444 445 // set resource types 446 if (null != m_resourceTypes) { 447 List<String> resourceTypes = new ArrayList<>(m_resourceTypes); 448 if (m_resourceTypes.contains(CmsResourceTypeFunctionConfig.TYPE_NAME) 449 && !m_resourceTypes.contains(CmsXmlDynamicFunctionHandler.TYPE_FUNCTION)) { 450 resourceTypes.add(CmsXmlDynamicFunctionHandler.TYPE_FUNCTION); 451 } 452 query.setResourceTypes(resourceTypes); 453 } 454 455 // set result page 456 query.setStart(Integer.valueOf((m_resultPage - 1) * m_matchesPerPage)); 457 458 // set search locale 459 if (null != m_locale) { 460 Locale l = CmsLocaleManager.getLocale(m_locale); 461 List<Locale> locales = new ArrayList<>(3); 462 locales.add(l); 463 if (!l.getVariant().isEmpty()) { 464 locales.add(new Locale(l.getLanguage(), l.getCountry())); 465 } 466 if (!l.getCountry().isEmpty()) { 467 locales.add(new Locale(l.getLanguage())); 468 } 469 query.setLocales(locales); 470 } 471 472 // set search words 473 if (null != m_words) { 474 query.setQuery(m_words); 475 } 476 477 // set sort order 478 query.setSort(getSort().getFirst(), getSort().getSecond()); 479 480 // set result collapsing by id 481 // add sort criteria to possibly speed up performance and prevent sorting by score - not sure if a good solution 482 query.addFilterQuery( 483 "{!collapse field=id sort='" 484 + CmsSearchField.FIELD_INSTANCEDATE 485 + CmsSearchField.FIELD_POSTFIX_DATE 486 + " asc'}"); 487 488 query.setFields(CmsGallerySearchResult.getRequiredSolrFields()); 489 490 if ((m_functionAvailability != null) && m_functionAvailability.isDefined()) { 491 String notFunction = "(*:* AND -type:(" 492 + CmsXmlDynamicFunctionHandler.TYPE_FUNCTION 493 + " OR " 494 + CmsResourceTypeFunctionConfig.TYPE_NAME 495 + "))"; 496 Collection<CmsUUID> whitelist = m_functionAvailability.getWhitelist(); 497 Collection<CmsUUID> blacklist = new ArrayList<>(m_functionAvailability.getBlacklist()); 498 CmsUUID dummyId = CmsUUID.getNullUUID(); 499 blacklist.add(dummyId); 500 String idClause; 501 if (whitelist != null) { 502 whitelist = new ArrayList<>(whitelist); 503 whitelist.add(dummyId); 504 String whitelistIdCondition = whitelist.stream().map(id -> id.toString()).collect( 505 Collectors.joining(" OR ")); 506 idClause = "id:(" + whitelistIdCondition + ")"; 507 } else { 508 idClause = "*:* AND -id:(" 509 + blacklist.stream().map(id -> id.toString()).collect(Collectors.joining(" OR ")) 510 + ") "; 511 } 512 String functionFilter = "(" + notFunction + " OR (" + idClause + "))"; 513 query.addFilterQuery(functionFilter); 514 } 515 516 if ((m_resourceTypes != null) && m_resourceTypes.contains(CmsResourceTypeFunctionConfig.TYPE_NAME)) { 517 if ((m_excludedFunctions != null) && (m_excludedFunctions.size() > 0)) { 518 List<CmsUUID> excludedFunctions = new ArrayList<>(m_excludedFunctions); 519 Collections.sort(excludedFunctions); 520 String orList = Joiner.on(" OR ").join(excludedFunctions); 521 String filter = "*:* AND -id:(" + orList + ")"; 522 query.addFilterQuery(filter); 523 } 524 if (m_includedFunctions != null) { 525 List<CmsUUID> includedFunctions = new ArrayList<>(m_includedFunctions); 526 // not sure if order of terms matters for filter query caching in Solr, so normalize order just in case 527 Collections.sort(includedFunctions); 528 List<String> conditions = new ArrayList<>(); 529 String notFunction = "(*:* AND -type:(" 530 + CmsXmlDynamicFunctionHandler.TYPE_FUNCTION 531 + " OR " 532 + CmsResourceTypeFunctionConfig.TYPE_NAME 533 + "))"; 534 conditions.add(notFunction); 535 for (CmsUUID id : includedFunctions) { 536 conditions.add("id:" + id); 537 } 538 String includedFunctionsFilter = Joiner.on(" OR ").join(conditions); 539 query.addFilterQuery(includedFunctionsFilter); 540 } 541 } 542 543 if (m_templateCompatibility != null) { 544 if (m_templateCompatibility.matches("^[0-9a-zA-Z_]+$")) { 545 String fieldName = CmsPropertyDefinition.PROPERTY_TEMPLATE_COMPATILIBITY + "_prop"; 546 query.addFilterQuery("(*:* NOT " + fieldName + ":*) OR " + fieldName + ":" + m_templateCompatibility); 547 } else { 548 LOG.warn( 549 "Invalid template compatibility value: " 550 + m_templateCompatibility 551 + ". Must only contain digits, letters (a-z) or underscores."); 552 } 553 } 554 555 // include expired/unreleased 556 if (m_includeExpired) { 557 query.removeExpiration(); 558 } 559 560 return query; 561 } 562 563 /** 564 * Gets the reference path.<p> 565 * 566 * @return the gallery reference path 567 */ 568 public String getReferencePath() { 569 570 return m_referencePath; 571 } 572 573 /** 574 * Returns the names of the resource types that have been included in the search result.<p> 575 * 576 * If no resource types have been set, then <code>null</code> is returned.<p> 577 * 578 * @return the names of the resource types that have been included in the search result 579 */ 580 public List<String> getResourceTypes() { 581 582 return m_resourceTypes; 583 } 584 585 /** 586 * Returns the index of the requested result page.<p> 587 * 588 * @return the index of the requested result page 589 * 590 * @see #setResultPage(int) 591 * @see #getMatchesPerPage() 592 * @see #setMatchesPerPage(int) 593 */ 594 public int getResultPage() { 595 596 return m_resultPage; 597 } 598 599 /** 600 * The gallery search scope.<p> 601 * 602 * @return the gallery search scope 603 */ 604 public CmsGallerySearchScope getScope() { 605 606 if (m_scope == null) { 607 return OpenCms.getWorkplaceManager().getGalleryDefaultScope(); 608 } 609 return m_scope; 610 } 611 612 /** 613 * Returns the words (terms) that have been used for the full text search.<p> 614 * 615 * If no search words have been set, then <code>null</code> is returned.<p> 616 * 617 * @return the words (terms) that have been used for the full text search 618 */ 619 public String getSearchWords() { 620 621 return m_words; 622 } 623 624 /** 625 * Returns the sort order that has been used in the search.<p> 626 * 627 * If the sort parameter has not been set the default sort order 628 * defined by {@link CmsGallerySortParam#DEFAULT} is used.<p> 629 * 630 * @return the sort order that has been used in the search 631 */ 632 public CmsGallerySortParam getSortOrder() { 633 634 if (m_sortOrder == null) { 635 636 m_sortOrder = CmsGallerySortParam.DEFAULT; 637 } 638 return m_sortOrder; 639 } 640 641 /** 642 * Gets the template compatibility. 643 * 644 * <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). 645 * 646 * @return the template compatibility 647 */ 648 public String getTemplateCompatibility() { 649 650 return m_templateCompatibility; 651 } 652 653 /** 654 * If this returns true, an empty search result should be returned, regardless of other settings. 655 * 656 * @return true if an empty search result should be forced 657 */ 658 public boolean isForceEmptyResult() { 659 660 return m_forceEmptyResult; 661 } 662 663 /** 664 * Returns the search exclude property ignore flag.<p> 665 * 666 * @return the search exclude property ignore flag 667 */ 668 public boolean isIgnoreSearchExclude() { 669 670 return m_ignoreSearchExclude; 671 } 672 673 /** 674 * Returns a flag, indicating if release and expiration date should be ignored.<p> 675 * 676 * @return a flag, indicating if release and expiration date should be ignored 677 */ 678 public boolean isIncludeExpired() { 679 680 return m_includeExpired; 681 } 682 683 /** 684 * Sets the categories for the search.<p> 685 * 686 * Results are found only if they are contained in at least one of the given categories. 687 * 688 * @param categories the categories to set 689 */ 690 public void setCategories(List<String> categories) { 691 692 m_categories = categories; 693 } 694 695 /** 696 * Sets the time range for the date of resource creation to consider in the search.<p> 697 * 698 * @param startTime the start time of the time range 699 * @param endTime the end time of the time range 700 */ 701 public void setDateCreatedTimeRange(long startTime, long endTime) { 702 703 if (m_dateCreatedTimeRange == null) { 704 m_dateCreatedTimeRange = new CmsGallerySearchTimeRange(startTime, endTime); 705 } 706 } 707 708 /** 709 * Sets the time range for the date of resource last modification to consider in the search.<p> 710 * 711 * @param startTime the start time of the time range 712 * @param endTime the end time of the time range 713 */ 714 public void setDateLastModifiedTimeRange(long startTime, long endTime) { 715 716 if (m_dateLastModifiedTimeRange == null) { 717 m_dateLastModifiedTimeRange = new CmsGallerySearchTimeRange(startTime, endTime); 718 } 719 } 720 721 /** 722 * Sets the structure IDs of functions to exclude from the search results. 723 * 724 * @param excludedFunctions the structure IDs of functions to exclude 725 */ 726 public void setExcludedFunctions(Set<CmsUUID> excludedFunctions) { 727 728 m_excludedFunctions = excludedFunctions; 729 730 } 731 732 /** 733 * Sets the folders to search in.<p> 734 * 735 * @param folders the list of VFS folders 736 */ 737 public void setFolders(List<String> folders) { 738 739 m_folders = folders; 740 } 741 742 /** 743 * Enables/disables the 'force empty result' flag. 744 * 745 * If this is set to true, an empty search result should be returned regardless of the other parameters. 746 * 747 * @param forceEmptyResult if true, force an empty search result 748 */ 749 public void setForceEmptyResult(boolean forceEmptyResult) { 750 751 m_forceEmptyResult = forceEmptyResult; 752 } 753 754 /** 755 * Sets the dynamic function availability. 756 * 757 * @param dynamicFunctionAvailability the dynamic function availability 758 */ 759 public void setFunctionAvailability(CmsFunctionAvailability dynamicFunctionAvailability) { 760 761 m_functionAvailability = dynamicFunctionAvailability; 762 } 763 764 /** 765 * Sets the galleries for the search.<p> 766 * 767 * Results are found only if they are contained in one of the given galleries. 768 * If no gallery is set, results from all galleries will be returned in the search result.<p> 769 * 770 * @param galleries the galleries to set 771 */ 772 public void setGalleries(List<String> galleries) { 773 774 m_galleries = galleries; 775 } 776 777 /** 778 * Sets the search exclude property ignore flag.<p> 779 * 780 * @param excludeForPageEditor the search exclude property ignore flag 781 */ 782 public void setIgnoreSearchExclude(boolean excludeForPageEditor) { 783 784 m_ignoreSearchExclude = excludeForPageEditor; 785 } 786 787 /** 788 * Sets the ids of functions to include. 789 * 790 * @param includedFunctions the ids of functions to include 791 */ 792 public void setIncludedFunctions(Set<CmsUUID> includedFunctions) { 793 794 m_includedFunctions = includedFunctions; 795 } 796 797 /** 798 * Set the flag, determining if expired and unreleased resources should be shown. 799 * @param includeExpired iff <code>true</code> expired and unreleased resources are shown. 800 */ 801 public void setIncludeExpired(boolean includeExpired) { 802 803 m_includeExpired = includeExpired; 804 805 } 806 807 /** 808 * Sets the maximum number of matches per result page.<p> 809 * 810 * Use this together with {@link #setResultPage(int)} in order to split the result 811 * in more than one page.<p> 812 * 813 * @param matchesPerPage the the maximum number of matches per result page to set 814 * 815 * @see #getMatchesPerPage() 816 * @see #setResultPage(int) 817 */ 818 public void setMatchesPerPage(int matchesPerPage) { 819 820 m_matchesPerPage = matchesPerPage; 821 } 822 823 /** 824 * Sets the gallery reference path.<p> 825 * 826 * @param referencePath the gallery reference path 827 */ 828 public void setReferencePath(String referencePath) { 829 830 m_referencePath = referencePath; 831 } 832 833 /** 834 * Sets the names of the resource types to include in the search result.<p> 835 * 836 * Results are found only if they resources match one of the given resource type names. 837 * If no resource type name is set, all resource types will be returned in the search result.<p> 838 * 839 * @param resourceTypes the names of the resource types to include in the search result 840 */ 841 public void setResourceTypes(List<String> resourceTypes) { 842 843 m_resourceTypes = resourceTypes; 844 } 845 846 /** 847 * Sets the index of the result page that should be returned.<p> 848 * 849 * Use this together with {@link #setMatchesPerPage(int)} in order to split the result 850 * in more than one page.<p> 851 * 852 * @param resultPage the index of the result page to return 853 * 854 * @see #getResultPage() 855 * @see #getMatchesPerPage() 856 * @see #setMatchesPerPage(int) 857 */ 858 public void setResultPage(int resultPage) { 859 860 m_resultPage = resultPage; 861 } 862 863 /** 864 * Sets the search scope.<p> 865 * 866 * @param scope the search scope 867 */ 868 public void setScope(CmsGallerySearchScope scope) { 869 870 m_scope = scope; 871 } 872 873 /** 874 * Sets the locale for the search.<p> 875 * 876 * Results are found only if they match the given locale. 877 * If no locale is set, results for all locales will be returned in the search result.<p> 878 * 879 * @param locale the locale to set 880 */ 881 public void setSearchLocale(String locale) { 882 883 m_locale = locale; 884 } 885 886 /** 887 * Sets the words (terms) for the full text search.<p> 888 * 889 * Results are found only if they text extraction for the resource contains all given search words. 890 * If no search word is set, all resources will be returned in the search result.<p> 891 * 892 * Please note that this should be a list of words separated by white spaces. 893 * Simple Lucene modifiers such as (+), (-) and (*) are allowed, but anything more complex then this 894 * will be removed.<p> 895 * 896 * @param words the words (terms) for the full text search to set 897 */ 898 public void setSearchWords(String words) { 899 900 m_words = words; 901 } 902 903 /** 904 * Sets the sort order for the search.<p> 905 * 906 * @param sortOrder the sort order to set 907 */ 908 public void setSortOrder(CmsGallerySortParam sortOrder) { 909 910 m_sortOrder = sortOrder; 911 } 912 913 /** 914 * Sets the template compatibility string. 915 * 916 * @param compatibility the template compatibility string 917 */ 918 public void setTemplateCompatibility(String compatibility) { 919 920 m_templateCompatibility = compatibility; 921 } 922 923 /** 924 * Adds folders to perform the search in. 925 * @param folders Folders to search in. 926 */ 927 private void addFoldersToSearchIn(final List<String> folders) { 928 929 if (null == folders) { 930 return; 931 } 932 933 for (String folder : folders) { 934 if (!CmsResource.isFolder(folder)) { 935 folder += "/"; 936 } 937 938 m_foldersToSearchIn.add(folder); 939 } 940 } 941 942 /** 943 * Checks if the given list of resource type names contains a function-like type.<p> 944 * 945 * @param resourceTypes the collection of resource types 946 * @return true if the list contains a function-like type 947 */ 948 private boolean containsFunctionType(List<String> resourceTypes) { 949 950 if (resourceTypes.contains(CmsXmlDynamicFunctionHandler.TYPE_FUNCTION)) { 951 return true; 952 } 953 if (resourceTypes.contains(CmsResourceTypeFunctionConfig.TYPE_NAME)) { 954 return true; 955 } 956 return false; 957 } 958 959 /** 960 * Returns the Lucene sort indicated by the selected sort order.<p> 961 * 962 * @return the Lucene sort indicated by the selected sort order 963 * 964 * @see #getSortOrder() 965 */ 966 private CmsPair<String, org.apache.solr.client.solrj.SolrQuery.ORDER> getSort() { 967 968 final String sortTitle = CmsSearchFieldConfiguration.getLocaleExtendedName( 969 CmsSearchField.FIELD_DISPTITLE, 970 getLocale()) + "_sort"; 971 972 switch (getSortOrder()) { 973 case dateCreated_asc: 974 return CmsPair.create(CmsSearchField.FIELD_DATE_CREATED, ORDER.asc); 975 case dateCreated_desc: 976 return CmsPair.create(CmsSearchField.FIELD_DATE_CREATED, ORDER.desc); 977 case dateExpired_asc: 978 return CmsPair.create(CmsSearchField.FIELD_DATE_EXPIRED, ORDER.asc); 979 case dateExpired_desc: 980 return CmsPair.create(CmsSearchField.FIELD_DATE_EXPIRED, ORDER.desc); 981 case dateLastModified_asc: 982 return CmsPair.create(CmsSearchField.FIELD_DATE_LASTMODIFIED, ORDER.asc); 983 case dateLastModified_desc: 984 return CmsPair.create(CmsSearchField.FIELD_DATE_LASTMODIFIED, ORDER.desc); 985 case dateReleased_asc: 986 return CmsPair.create(CmsSearchField.FIELD_DATE_RELEASED, ORDER.asc); 987 case dateReleased_desc: 988 return CmsPair.create(CmsSearchField.FIELD_DATE_RELEASED, ORDER.desc); 989 case length_asc: 990 return CmsPair.create(CmsSearchField.FIELD_SIZE, ORDER.asc); 991 case length_desc: 992 return CmsPair.create(CmsSearchField.FIELD_SIZE, ORDER.desc); 993 case path_asc: 994 return CmsPair.create(CmsSearchField.FIELD_PATH, ORDER.asc); 995 case path_desc: 996 return CmsPair.create(CmsSearchField.FIELD_PATH, ORDER.desc); 997 case score: 998 return CmsPair.create(CmsSearchField.FIELD_SCORE, ORDER.desc); 999 case state_asc: 1000 return CmsPair.create(CmsSearchField.FIELD_STATE, ORDER.asc); 1001 case state_desc: 1002 return CmsPair.create(CmsSearchField.FIELD_STATE, ORDER.desc); 1003 case title_asc: 1004 return CmsPair.create(sortTitle, ORDER.asc); 1005 case title_desc: 1006 return CmsPair.create(sortTitle, ORDER.desc); 1007 case type_asc: 1008 return CmsPair.create(CmsSearchField.FIELD_TYPE, ORDER.asc); 1009 case type_desc: 1010 return CmsPair.create(CmsSearchField.FIELD_TYPE, ORDER.desc); 1011 case userCreated_asc: 1012 return CmsPair.create(CmsSearchField.FIELD_USER_CREATED, ORDER.asc); 1013 case userCreated_desc: 1014 return CmsPair.create(CmsSearchField.FIELD_USER_CREATED, ORDER.desc); 1015 case userLastModified_asc: 1016 return CmsPair.create(CmsSearchField.FIELD_USER_LAST_MODIFIED, ORDER.asc); 1017 case userLastModified_desc: 1018 return CmsPair.create(CmsSearchField.FIELD_USER_LAST_MODIFIED, ORDER.desc); 1019 default: 1020 return CmsPair.create(sortTitle, ORDER.asc); 1021 } 1022 } 1023 1024 /** 1025 * Applies the defined search folders to the Solr query. 1026 * 1027 * @param obj The current CmsObject object. 1028 */ 1029 private void setSearchFolders(CmsObject obj) { 1030 1031 // check if parentFolders to search in have been set 1032 // if this evaluates false, the search folders have already been set, so 1033 // there's no need to add a scope filter 1034 if (m_foldersToSearchIn.isEmpty()) { 1035 // only append scope filter if no no folders or galleries given 1036 setSearchScopeFilter(obj); 1037 } 1038 } 1039 1040 /** 1041 * Sets the search scope. 1042 * 1043 * @param cms The current CmsObject object. 1044 */ 1045 private void setSearchScopeFilter(CmsObject cms) { 1046 1047 final List<String> searchRoots = CmsSearchUtil.computeScopeFolders(cms, this); 1048 1049 // If the resource types contain the type "function" also 1050 // add "/system/modules/" to the search path 1051 1052 if ((null != getResourceTypes()) && containsFunctionType(getResourceTypes())) { 1053 searchRoots.add("/system/modules/"); 1054 } 1055 1056 addFoldersToSearchIn(searchRoots); 1057 } 1058}