001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://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 GmbH & Co. KG, please see the 018 * company website: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://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; 029 030import org.opencms.file.CmsObject; 031import org.opencms.i18n.CmsEncoder; 032import org.opencms.main.CmsException; 033import org.opencms.main.CmsIllegalArgumentException; 034import org.opencms.main.CmsLog; 035import org.opencms.main.OpenCms; 036import org.opencms.search.CmsSearchParameters.CmsSearchFieldQuery; 037import org.opencms.util.CmsStringUtil; 038 039import java.util.ArrayList; 040import java.util.Arrays; 041import java.util.Collections; 042import java.util.Iterator; 043import java.util.List; 044import java.util.Map; 045import java.util.TreeMap; 046 047import org.apache.commons.logging.Log; 048import org.apache.lucene.search.BooleanClause; 049import org.apache.lucene.search.BooleanClause.Occur; 050import org.apache.lucene.search.Sort; 051 052/** 053 * Helper class to access the search facility within a jsp.<p> 054 * 055 * Typically, the following fields are available for searching: 056 * <ul> 057 * <li>title - the title of a resource</li> 058 * <li>keywords - the keywords of a resource</li> 059 * <li>description - the description of a resource</li> 060 * <li>content - the aggregated content of a resource</li> 061 * <li>created - the creation date of a resource</li> 062 * <li>lastmodified - the date of the last modification of a resource</li> 063 * <li>path - the path to display the resource</li> 064 * <li>channel - the channel of a resource</li> 065 * <li>contentdefinition - the name of the content definition class of a resource</li> 066 * </ul> 067 * 068 * @since 6.0.0 069 */ 070public class CmsSearch { 071 072 /** The log object for this class. */ 073 private static final Log LOG = CmsLog.getLog(CmsSearch.class); 074 075 /** The result categories of a search. */ 076 protected Map<String, Integer> m_categoriesFound; 077 078 /** The cms object. */ 079 protected transient CmsObject m_cms; 080 081 /** The latest exception. */ 082 protected Exception m_lastException; 083 084 /** The URL which leads to the next result page. */ 085 protected String m_nextUrl; 086 087 /** The number of pages for the result list. */ 088 protected int m_pageCount; 089 090 /** The restriction for the search parameters, used for "search in search result". */ 091 protected CmsSearchParameters m_parameterRestriction; 092 093 /** The search parameters used for searching, build out of the given individual parameter values. */ 094 protected CmsSearchParameters m_parameters; 095 096 /** The URL which leads to the previous result page. */ 097 protected String m_prevUrl; 098 099 /** The current search result. */ 100 protected List<CmsSearchResult> m_result; 101 102 /** The search parameter String. */ 103 protected String m_searchParameters; 104 105 /** The total number of search results matching the query. */ 106 protected int m_searchResultCount; 107 108 /** 109 * Default constructor, used to instantiate the search facility as a bean.<p> 110 */ 111 public CmsSearch() { 112 113 m_parameters = new CmsSearchParameters(); 114 m_parameters.setSearchRoots(""); 115 m_parameters.setSearchPage(1); 116 m_searchResultCount = 0; 117 m_parameters.setSort(CmsSearchParameters.SORT_DEFAULT); 118 m_parameters.setFields(Arrays.asList(CmsSearchIndex.DOC_META_FIELDS)); 119 } 120 121 /** 122 * Adds an individual query for a search field.<p> 123 * 124 * If this is used, any setting made with {@link #setQuery(String)} and {@link #setField(String[])} 125 * will be ignored and only the individual field search settings will be used.<p> 126 * 127 * When combining occurrences of SHOULD, MUST and MUST_NOT, keep the following in mind: 128 * All SHOULD clauses will be grouped and wrapped in one query, 129 * all MUST and MUST_NOT clauses will be grouped in another query. 130 * This means that at least one of the terms which are given as a SHOULD query must occur in the 131 * search result.<p> 132 * 133 * @param fieldQuery the field query to use 134 * 135 * @since 8.0.2 136 */ 137 public void addFieldQuery(CmsSearchFieldQuery fieldQuery) { 138 139 m_parameters.addFieldQuery(fieldQuery); 140 resetLastResult(); 141 } 142 143 /** 144 * Adds an individual query for a search field.<p> 145 * 146 * If this is used, any setting made with {@link #setQuery(String)} and {@link #setField(String[])} 147 * will be ignored and only the individual field search settings will be used.<p> 148 * 149 * When combining occurrences of SHOULD, MUST and MUST_NOT, keep the following in mind: 150 * All SHOULD clauses will be grouped and wrapped in one query, 151 * all MUST and MUST_NOT clauses will be grouped in another query. 152 * This means that at least one of the terms which are given as a SHOULD query must occur in the 153 * search result.<p> 154 * 155 * @param fieldName the field name 156 * @param searchQuery the search query 157 * @param occur the occur parameter for the query in the field 158 * 159 * @since 7.5.1 160 */ 161 public void addFieldQuery(String fieldName, String searchQuery, Occur occur) { 162 163 addFieldQuery(new CmsSearchParameters.CmsSearchFieldQuery(fieldName, searchQuery, occur)); 164 } 165 166 /** 167 * Adds an individual query for a search field that MUST occur.<p> 168 * 169 * If this is used, any setting made with {@link #setQuery(String)} and {@link #setField(String[])} 170 * will be ignored and only the individual field search settings will be used.<p> 171 * 172 * When combining occurrences of SHOULD, MUST and MUST_NOT, keep the following in mind: 173 * All SHOULD clauses will be grouped and wrapped in one query, 174 * all MUST and MUST_NOT clauses will be grouped in another query. 175 * This means that at least one of the terms which are given as a SHOULD query must occur in the 176 * search result.<p> 177 * 178 * @param fieldName the field name 179 * @param searchQuery the search query 180 * 181 * @since 7.5.1 182 */ 183 public void addFieldQueryMust(String fieldName, String searchQuery) { 184 185 addFieldQuery(fieldName, searchQuery, BooleanClause.Occur.MUST); 186 } 187 188 /** 189 * Adds an individual query for a search field that MUST NOT occur.<p> 190 * 191 * If this is used, any setting made with {@link #setQuery(String)} and {@link #setField(String[])} 192 * will be ignored and only the individual field search settings will be used.<p> 193 * 194 * When combining occurrences of SHOULD, MUST and MUST_NOT, keep the following in mind: 195 * All SHOULD clauses will be grouped and wrapped in one query, 196 * all MUST and MUST_NOT clauses will be grouped in another query. 197 * This means that at least one of the terms which are given as a SHOULD query must occur in the 198 * search result.<p> 199 * 200 * @param fieldName the field name 201 * @param searchQuery the search query 202 * 203 * @since 7.5.1 204 */ 205 public void addFieldQueryMustNot(String fieldName, String searchQuery) { 206 207 addFieldQuery(fieldName, searchQuery, BooleanClause.Occur.MUST_NOT); 208 } 209 210 /** 211 * Adds an individual query for a search field that SHOULD occur.<p> 212 * 213 * If this is used, any setting made with {@link #setQuery(String)} and {@link #setField(String[])} 214 * will be ignored and only the individual field search settings will be used.<p> 215 * 216 * When combining occurrences of SHOULD, MUST and MUST_NOT, keep the following in mind: 217 * All SHOULD clauses will be grouped and wrapped in one query, 218 * all MUST and MUST_NOT clauses will be grouped in another query. 219 * This means that at least one of the terms which are given as a SHOULD query must occur in the 220 * search result.<p> 221 * 222 * @param fieldName the field name 223 * @param searchQuery the search query 224 * 225 * @since 7.5.1 226 */ 227 public void addFieldQueryShould(String fieldName, String searchQuery) { 228 229 addFieldQuery(fieldName, searchQuery, BooleanClause.Occur.SHOULD); 230 } 231 232 /** 233 * Returns <code>true</code> if a category overview should be shown as part of the result.<p> 234 * 235 * <b>Please note:</b> The calculation of the category count slows down the search time by an order 236 * of magnitude. Make sure that you only use this feature if it's really required! 237 * Be especially careful if your search result list can become large (> 1000 documents), since in this case 238 * overall system performance will certainly be impacted considerably when calculating the categories.<p> 239 * 240 * @return <code>true</code> if a category overview should be shown as part of the result 241 */ 242 public boolean getCalculateCategories() { 243 244 return m_parameters.getCalculateCategories(); 245 } 246 247 /** 248 * Returns the search categories.<p> 249 * 250 * @return the search categories 251 */ 252 public String[] getCategories() { 253 254 List<String> l = m_parameters.getCategories(); 255 return l.toArray(new String[l.size()]); 256 } 257 258 /** 259 * Returns the maximum number of pages which should be shown.<p> 260 * 261 * @return the maximum number of pages which should be shown 262 */ 263 public int getDisplayPages() { 264 265 return m_parameters.getDisplayPages(); 266 } 267 268 /** 269 * Gets the current fields list.<p> 270 * 271 * @return the fields to search 272 */ 273 public String getFields() { 274 275 if (m_parameters.getFields() == null) { 276 return ""; 277 } 278 StringBuffer result = new StringBuffer(); 279 Iterator<String> it = m_parameters.getFields().iterator(); 280 while (it.hasNext()) { 281 result.append(it.next()); 282 result.append(" "); 283 } 284 return result.toString(); 285 } 286 287 /** 288 * Gets the name of the current search index.<p> 289 * 290 * @return the name of the index 291 */ 292 public String getIndex() { 293 294 return m_parameters.getSearchIndex().getName(); 295 } 296 297 /** 298 * Gets the last exception after a search operation.<p> 299 * 300 * @return the exception occurred in a search operation or null 301 */ 302 public Exception getLastException() { 303 304 return m_lastException; 305 } 306 307 /** 308 * Gets the number of matches displayed on each page.<p> 309 * 310 * @return matches per result page 311 */ 312 public int getMatchesPerPage() { 313 314 return m_parameters.getMatchesPerPage(); 315 } 316 317 /** 318 * Returns the maximum creation date a resource must have to be included in the search result.<p> 319 * 320 * @return the maximum creation date a resource must have to be included in the search result 321 */ 322 public long getMaxDateCreated() { 323 324 return m_parameters.getMaxDateCreated(); 325 } 326 327 /** 328 * Returns the maximum last modification date a resource must have to be included in the search result.<p> 329 * 330 * @return the maximum last modification date a resource must have to be included in the search result 331 */ 332 public long getMaxDateLastModified() { 333 334 return m_parameters.getMaxDateLastModified(); 335 } 336 337 /** 338 * Returns the minimum creation date a resource must have to be included in the search result.<p> 339 * 340 * @return the minimum creation date a resource must have to be included in the search result 341 */ 342 public long getMinDateCreated() { 343 344 return m_parameters.getMinDateCreated(); 345 } 346 347 /** 348 * Returns the minimum last modification date a resource must have to be included in the search result.<p> 349 * 350 * @return the minimum last modification date a resource must have to be included in the search result 351 */ 352 public long getMinDateLastModified() { 353 354 return m_parameters.getMinDateLastModified(); 355 } 356 357 /** 358 * Gets the URL for the link to the next result page.<p> 359 * 360 * @return the URL to the next result page 361 */ 362 public String getNextUrl() { 363 364 return m_nextUrl; 365 } 366 367 /** 368 * Creates a sorted map of URLs to link to other search result pages.<p> 369 * 370 * The key values are Integers representing the page number, the entry 371 * holds the corresponding link.<p> 372 * 373 * @return a map with String URLs 374 */ 375 public Map<Integer, String> getPageLinks() { 376 377 Map<Integer, String> links = new TreeMap<Integer, String>(); 378 if (m_pageCount <= 1) { 379 return links; 380 } 381 int startIndex, endIndex; 382 String link = m_cms.getRequestContext().getUri() + m_parameters.toQueryString() + "&searchPage="; 383 if (getDisplayPages() < 1) { 384 // number of displayed pages not limited, build a map with all available page links 385 startIndex = 1; 386 endIndex = m_pageCount; 387 } else { 388 // limited number of displayed pages, calculate page range 389 int currentPage = getSearchPage(); 390 int countBeforeCurrent = getDisplayPages() / 2; 391 int countAfterCurrent; 392 if ((currentPage - countBeforeCurrent) < 1) { 393 // set count before to number of available pages 394 countBeforeCurrent = currentPage - 1; 395 } 396 // set count after to number of remaining pages (- 1 for current page) 397 countAfterCurrent = getDisplayPages() - countBeforeCurrent - 1; 398 // calculate start and end index 399 startIndex = currentPage - countBeforeCurrent; 400 endIndex = currentPage + countAfterCurrent; 401 // check end index 402 if (endIndex > m_pageCount) { 403 int delta = endIndex - m_pageCount; 404 // decrease start index with delta to get the right number of displayed pages 405 startIndex -= delta; 406 // check start index to avoid values < 1 407 if (startIndex < 1) { 408 startIndex = 1; 409 } 410 endIndex = m_pageCount; 411 } 412 } 413 414 // build the sorted tree map of page links 415 for (int i = startIndex; i <= endIndex; i++) { 416 links.put(Integer.valueOf(i), (link + i)); 417 } 418 return links; 419 } 420 421 /** 422 * Returns the search parameters used for searching, build out of the given individual parameter values.<p> 423 * 424 * @return the search parameters used for searching, build out of the given individual parameter values 425 */ 426 public CmsSearchParameters getParameters() { 427 428 if (m_parameterRestriction != null) { 429 m_parameters = m_parameters.restrict(m_parameterRestriction); 430 } 431 return m_parameters; 432 433 } 434 435 /** 436 * Gets the URL for the link to the previous result page.<p> 437 * 438 * @return the URL to the previous result page 439 */ 440 public String getPreviousUrl() { 441 442 return m_prevUrl; 443 } 444 445 /** 446 * Gets the current search query.<p> 447 * 448 * @return the current query string or null if no query was set before 449 */ 450 public String getQuery() { 451 452 return m_parameters.getQuery(); 453 } 454 455 /** 456 * Gets the minimum search query length.<p> 457 * 458 * @return the minimum search query length 459 */ 460 public int getQueryLength() { 461 462 return m_parameters.getQueryLength(); 463 } 464 465 /** 466 * Gets the current result page.<p> 467 * 468 * @return the current result page 469 */ 470 public int getSearchPage() { 471 472 return m_parameters.getSearchPage(); 473 } 474 475 /** 476 * Returns the search result for the current query, as a list of <code>{@link CmsSearchResult}</code> objects.<p> 477 * 478 * @return the search result (may be empty) or null if no index or query was set before 479 */ 480 public List<CmsSearchResult> getSearchResult() { 481 482 if ((m_cms != null) 483 && (m_result == null) 484 && (m_parameters.getIndex() != null) 485 && (m_parameters.isIgnoreQuery() 486 || CmsStringUtil.isNotEmpty(m_parameters.getQuery()) 487 || (m_parameters.getFieldQueries() != null))) { 488 489 if (!m_parameters.isIgnoreQuery() && (getQueryLength() > 0)) { 490 491 if (m_parameters.getFieldQueries() != null) { 492 // check all field queries if the length of the query is ok 493 for (CmsSearchParameters.CmsSearchFieldQuery fq : m_parameters.getFieldQueries()) { 494 for (String keyword : fq.getSearchTerms()) { 495 if (CmsStringUtil.isEmpty(keyword) || (keyword.trim().length() < getQueryLength())) { 496 497 m_lastException = new CmsSearchException( 498 Messages.get().container( 499 Messages.ERR_QUERY_TOO_SHORT_1, 500 Integer.valueOf(getQueryLength()))); 501 502 return null; 503 } 504 } 505 } 506 507 } else if (m_parameters.getQuery().trim().length() < getQueryLength()) { 508 509 m_lastException = new CmsSearchException( 510 Messages.get().container(Messages.ERR_QUERY_TOO_SHORT_1, Integer.valueOf(getQueryLength()))); 511 512 return null; 513 } 514 } 515 516 try { 517 518 CmsSearchResultList result = m_parameters.getSearchIndex().search(m_cms, getParameters()); 519 520 if (result.size() > 0) { 521 522 m_result = result; 523 m_searchResultCount = result.getHitCount(); 524 m_categoriesFound = result.getCategories(); 525 526 // re-caluclate the number of pages for this search result 527 m_pageCount = m_searchResultCount / m_parameters.getMatchesPerPage(); 528 if ((m_searchResultCount % m_parameters.getMatchesPerPage()) != 0) { 529 m_pageCount++; 530 } 531 532 // re-calculate the URLs to browse forward and backward in the search result 533 String url = m_cms.getRequestContext().getUri() + m_parameters.toQueryString() + "&searchPage="; 534 if (m_parameters.getSearchPage() > 1) { 535 m_prevUrl = url + (m_parameters.getSearchPage() - 1); 536 } 537 if (m_parameters.getSearchPage() < m_pageCount) { 538 m_nextUrl = url + (m_parameters.getSearchPage() + 1); 539 } 540 } else { 541 m_result = Collections.emptyList(); 542 m_searchResultCount = 0; 543 m_categoriesFound = null; 544 m_pageCount = 0; 545 m_prevUrl = null; 546 m_nextUrl = null; 547 } 548 } catch (Exception exc) { 549 550 if (LOG.isDebugEnabled()) { 551 LOG.debug(Messages.get().getBundle().key(Messages.LOG_SEARCHING_FAILED_0), exc); 552 } 553 554 m_result = null; 555 m_searchResultCount = 0; 556 m_pageCount = 0; 557 558 m_lastException = exc; 559 } 560 } 561 562 return m_result; 563 } 564 565 /** 566 * Returns a map of categories (Strings) for the last search result, mapped to the hit count (Integer) of 567 * the documents in this category, or <code>null</code> if the categories have not been calculated.<p> 568 * 569 * @return a map of categories for the last search result 570 * 571 * @see CmsSearch#getCalculateCategories() 572 * @see CmsSearch#setCalculateCategories(boolean) 573 */ 574 public Map<String, Integer> getSearchResultCategories() { 575 576 return m_categoriesFound; 577 } 578 579 /** 580 * Returns the total number of search results matching the query.<p> 581 * 582 * @return the total number of search results matching the query 583 */ 584 public int getSearchResultCount() { 585 586 return m_searchResultCount; 587 } 588 589 /** 590 * Returns the search roots.<p> 591 * 592 * Only resources that are sub-resources of one of the search roots 593 * are included in the search result.<p> 594 * 595 * The search roots are used <i>in addition to</i> the current site root 596 * of the user performing the search.<p> 597 * 598 * By default, the search roots contain only one entry with an empty string.<p> 599 * 600 * @return the search roots 601 */ 602 public String[] getSearchRoots() { 603 604 List<String> l = m_parameters.getRoots(); 605 return l.toArray(new String[l.size()]); 606 } 607 608 /** 609 * Returns the sort order used for sorting the results of s search.<p> 610 * 611 * @return the sort order used for sorting the results of s search 612 */ 613 public Sort getSortOrder() { 614 615 return m_parameters.getSort(); 616 } 617 618 /** 619 * Initializes the bean with the cms object.<p> 620 * 621 * @param cms the cms object 622 */ 623 public void init(CmsObject cms) { 624 625 m_cms = cms; 626 m_result = null; 627 m_lastException = null; 628 m_pageCount = 0; 629 m_nextUrl = null; 630 m_prevUrl = null; 631 } 632 633 /** 634 * Sets the flag that controls calculation of result categories for the next search, 635 * use this only if it's really required since the search can become very slow using this option.<p> 636 * 637 * <b>Please note:</b> The calculation of the category count slows down the search time by an order 638 * of magnitude. Make sure that you only use this feature if it's really required! 639 * Be especially careful if your search result list can become large (> 1000 documents), since in this case 640 * overall system performance will certainly be impacted considerably when calculating the categories.<p> 641 * 642 * @param calculateCategories if <code>true</code>, the category count will be calculated for the next search 643 */ 644 public void setCalculateCategories(boolean calculateCategories) { 645 646 m_parameters.setCalculateCategories(calculateCategories); 647 } 648 649 /** 650 * Sets the search categories, all search results must be in one of the categories, 651 * the category set must match the indexed category exactly.<p> 652 * 653 * All categories will automatically be trimmed and lower cased, since search categories 654 * are also stored this way in the index.<p> 655 * 656 * @param categories the categories to set 657 */ 658 public void setCategories(String[] categories) { 659 660 List<String> setCategories = new ArrayList<String>(); 661 if (categories != null) { 662 if (categories.length != 0) { 663 // ensure all categories are not null, trimmed, not-empty and lowercased 664 String cat; 665 for (int i = 0; i < categories.length; i++) { 666 cat = categories[i]; 667 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(cat)) { 668 // all categories must internally be lower case, 669 // since the index keywords are lower cased as well 670 cat = cat.trim().toLowerCase(); 671 setCategories.add(cat); 672 } 673 } 674 } 675 } 676 m_parameters.setCategories(setCategories); 677 resetLastResult(); 678 } 679 680 /** 681 * Sets the maximum number of pages which should be shown.<p> 682 * 683 * Enter an odd value to achieve a nice, "symmetric" output.<p> 684 * 685 * @param value the maximum number of pages which should be shown 686 */ 687 public void setDisplayPages(int value) { 688 689 m_parameters.setDisplayPages(value); 690 } 691 692 /** 693 * Controls if the excerpt from a field is generated only for searched fields, or for all fields (the default).<p> 694 * 695 * The default setting is <code>false</code>, which means all text fields configured for the excerpt will 696 * be used to generate the excerpt, regardless if they have been searched in or not.<p> 697 * 698 * Please note: A field will only be included in the excerpt if it has been configured as <code>excerpt="true"</code> 699 * in <code>opencms-search.xml</code>. This method controls if so configured fields are used depending on the 700 * fields searched, see {@link #setField(String[])}.<p> 701 * 702 * @param value if <code>true</code>, the excerpt is generated only from the fields actually searched in 703 */ 704 public void setExcerptOnlySearchedFields(boolean value) { 705 706 m_parameters.setExcerptOnlySearchedFields(value); 707 resetLastResult(); 708 } 709 710 /** 711 * Sets the fields to search.<p> 712 * 713 * If the fields are set to <code>null</code>, 714 * or not set at all, the default fields "content" and "meta" are used.<p> 715 * 716 * For a list of valid field names, see the Interface constants of 717 * <code>{@link org.opencms.search.documents.I_CmsDocumentFactory}</code>. 718 * 719 * @param fields the fields to search 720 */ 721 public void setField(String[] fields) { 722 723 m_parameters.setFields(Arrays.asList(fields)); 724 resetLastResult(); 725 } 726 727 /** 728 * Set the name of the index to search.<p> 729 * 730 * A former search result will be deleted.<p> 731 * 732 * @param indexName the name of the index 733 */ 734 public void setIndex(String indexName) { 735 736 resetLastResult(); 737 if (CmsStringUtil.isNotEmpty(indexName)) { 738 try { 739 I_CmsSearchIndex idx = OpenCms.getSearchManager().getIndex(indexName); 740 CmsSearchIndex index = idx instanceof CmsSearchIndex ? (CmsSearchIndex)idx : null; 741 if (index == null) { 742 throw new CmsException(Messages.get().container(Messages.ERR_INDEX_NOT_FOUND_1, indexName)); 743 } 744 m_parameters.setSearchIndex(index); 745 } catch (Exception exc) { 746 if (LOG.isDebugEnabled()) { 747 LOG.debug(Messages.get().getBundle().key(Messages.LOG_INDEX_ACCESS_FAILED_1, indexName), exc); 748 } 749 m_lastException = exc; 750 } 751 } 752 } 753 754 /** 755 * Sets the number of matches per page.<p> 756 * 757 * @param matches the number of matches per page 758 */ 759 public void setMatchesPerPage(int matches) { 760 761 m_parameters.setMatchesPerPage(matches); 762 resetLastResult(); 763 } 764 765 /** 766 * Sets the maximum creation date a resource must have to be included in the search result.<p> 767 * 768 * @param maxDateCreated the maximum creation date to set 769 */ 770 public void setMaxDateCreated(String maxDateCreated) { 771 772 m_parameters.setMaxDateCreated(CmsStringUtil.getLongValue(maxDateCreated, Long.MAX_VALUE, "maxDateCreated")); 773 } 774 775 /** 776 * Sets the maximum last modification date a resource must have to be included in the search result.<p> 777 * 778 * @param maxDateLastModified the maximum last modification date to set 779 */ 780 public void setMaxDateLastModified(String maxDateLastModified) { 781 782 m_parameters.setMaxDateLastModified( 783 CmsStringUtil.getLongValue(maxDateLastModified, Long.MAX_VALUE, "maxDateLastModified")); 784 } 785 786 /** 787 * Sets the minimum creation date a resource must have to be included in the search result.<p> 788 * 789 * @param minDateCreated the minimum creation date to set 790 */ 791 public void setMinDateCreated(String minDateCreated) { 792 793 m_parameters.setMinDateCreated(CmsStringUtil.getLongValue(minDateCreated, Long.MIN_VALUE, "minDateCreated")); 794 } 795 796 /** 797 * Sets the minimum last modification date a resource must have to be included in the search result.<p> 798 * 799 * @param minDateLastModified he minimum last modification date to set 800 */ 801 public void setMinDateLastModified(String minDateLastModified) { 802 803 m_parameters.setMinDateLastModified( 804 CmsStringUtil.getLongValue(minDateLastModified, Long.MIN_VALUE, "minDateLastModified")); 805 } 806 807 /** 808 * Set the parameters to use if a non null instance is provided. <p> 809 * 810 * @param parameters the parameters to use for the search if a non null instance is provided 811 * 812 */ 813 public void setParameters(CmsSearchParameters parameters) { 814 815 if (parameters != null) { 816 m_parameters = parameters; 817 } 818 } 819 820 /** 821 * Sets the search query.<p> 822 * 823 * The syntax of the query depends on the search engine used. 824 * A former search result will be deleted.<p> 825 * 826 * @param query the search query (escaped format) 827 */ 828 public void setQuery(String query) { 829 830 try { 831 m_parameters.setQuery(CmsEncoder.decodeParameter(query)); 832 } catch (CmsIllegalArgumentException iae) { 833 m_lastException = iae; 834 } 835 resetLastResult(); 836 } 837 838 /** 839 * Sets the minimum length of the search query.<p> 840 * 841 * @param length the minimum search query length 842 */ 843 public void setQueryLength(int length) { 844 845 m_parameters.setQueryLength(length); 846 } 847 848 /** 849 * Limits the search to a given of resource type only.<p> 850 * 851 * @param resourceType the resource type to limit the search result to 852 * 853 * @since 7.5.1 854 */ 855 public void setResourceType(String resourceType) { 856 857 setResourceTypes(new String[] {resourceType}); 858 } 859 860 /** 861 * Limits the search to a given list of resource types only.<p> 862 * 863 * @param resourceTypes the resource types to limit the search result to 864 */ 865 public void setResourceTypes(String[] resourceTypes) { 866 867 if (resourceTypes != null) { 868 m_parameters.setResourceTypes(Arrays.asList(resourceTypes)); 869 } else { 870 m_parameters.setResourceTypes(null); 871 } 872 resetLastResult(); 873 } 874 875 /** 876 * Restrict the result of the next search to the results of the last search, 877 * restricted with the provided parameters.<p> 878 * 879 * Use this for "seach in search result" functions.<p> 880 * 881 * @param restriction the restriction to use 882 * 883 * @see CmsSearchParameters#restrict(CmsSearchParameters) 884 */ 885 public void setResultRestriction(CmsSearchParameters restriction) { 886 887 resetLastResult(); 888 m_parameterRestriction = restriction; 889 } 890 891 /** 892 * Sets the current result page.<p> 893 * 894 * Works with jsp bean mechanism for request parameter "searchPage" 895 * that is generated here for page links.<p> 896 * 897 * @param page the current result page 898 */ 899 public void setSearchPage(int page) { 900 901 m_parameters.setSearchPage(page); 902 resetLastResult(); 903 } 904 905 /** 906 * Convenience method to set exactly one search root.<p> 907 * 908 * @param searchRoot the search root to set 909 * 910 * @see #setSearchRoots(String[]) 911 */ 912 public void setSearchRoot(String searchRoot) { 913 914 setSearchRoots(CmsStringUtil.splitAsArray(searchRoot, ",")); 915 } 916 917 /** 918 * Sets the search root list.<p> 919 * 920 * Only resources that are sub-resources of one of the search roots 921 * are included in the search result.<p> 922 * 923 * The search roots set here are used <i>in addition to</i> the current site root 924 * of the user performing the search.<p> 925 * 926 * By default, the search roots contain only one entry with an empty string.<p> 927 * 928 * @param searchRoots the search roots to set 929 */ 930 public void setSearchRoots(String[] searchRoots) { 931 932 List<String> l = new ArrayList<String>(Arrays.asList(searchRoots)); 933 m_parameters.setRoots(l); 934 resetLastResult(); 935 } 936 937 /** 938 * Sets the sort order used for sorting the results of s search.<p> 939 * 940 * @param sortOrder the sort order to set 941 */ 942 public void setSortOrder(Sort sortOrder) { 943 944 m_parameters.setSort(sortOrder); 945 resetLastResult(); 946 } 947 948 /** 949 * Resets the last search result.<p> 950 */ 951 private void resetLastResult() { 952 953 m_result = null; 954 m_lastException = null; 955 m_categoriesFound = null; 956 m_parameterRestriction = null; 957 } 958}