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.galleries.shared.CmsGallerySearchScope;
031import org.opencms.file.CmsObject;
032import org.opencms.file.CmsResource;
033import org.opencms.file.types.CmsResourceTypeFunctionConfig;
034import org.opencms.i18n.CmsLocaleManager;
035import org.opencms.main.OpenCms;
036import org.opencms.search.A_CmsSearchIndex;
037import org.opencms.search.CmsSearchUtil;
038import org.opencms.search.fields.CmsSearchField;
039import org.opencms.search.fields.CmsSearchFieldConfiguration;
040import org.opencms.search.solr.CmsSolrQuery;
041import org.opencms.util.CmsPair;
042import org.opencms.util.CmsUUID;
043import org.opencms.xml.containerpage.CmsXmlDynamicFunctionHandler;
044
045import java.util.ArrayList;
046import java.util.Arrays;
047import java.util.Collection;
048import java.util.Iterator;
049import java.util.List;
050
051import org.apache.solr.client.solrj.SolrQuery.ORDER;
052
053/**
054 * Parameters used for the gallery search index.<p>
055 *
056 * @since 8.0.0
057 */
058public class CmsGallerySearchParameters {
059
060    /** Sort parameter constants. */
061    public enum CmsGallerySortParam {
062
063        /** Sort by date created ascending. */
064        dateCreated_asc,
065
066        /** Sort by date created descending. */
067        dateCreated_desc,
068
069        /** Sort date expired ascending. */
070        dateExpired_asc,
071
072        /** Sort date expired descending. */
073        dateExpired_desc,
074
075        /** Sort by date modified ascending. */
076        dateLastModified_asc,
077
078        /** Sort by date modified descending. */
079        dateLastModified_desc,
080
081        /** Sort date released ascending. */
082        dateReleased_asc,
083
084        /** Sort date released descending. */
085        dateReleased_desc,
086
087        /** Sort by length ascending. */
088        length_asc,
089
090        /** Sort by length descending. */
091        length_desc,
092
093        /** Sort by VFS root path ascending. */
094        path_asc,
095
096        /** Sort by VFS root path descending. */
097        path_desc,
098
099        /** Sort by score ascending. */
100        score,
101
102        /** Sort state ascending. */
103        state_asc,
104
105        /** Sort state descending. */
106        state_desc,
107
108        /** Sort by title ascending. */
109        title_asc,
110
111        /** Sort by title ascending. */
112        title_desc,
113
114        /** Sort by type ascending. */
115        type_asc,
116
117        /** Sort by type descending. */
118        type_desc,
119
120        /** Sort created by ascending. */
121        userCreated_asc,
122
123        /** Sort created by descending. */
124        userCreated_desc,
125
126        /** Sort modified by ascending. */
127        userLastModified_asc,
128
129        /** Sort modified by descending. */
130        userLastModified_desc;
131
132        /** The default sort parameter. */
133        public static final CmsGallerySortParam DEFAULT = title_asc;
134    }
135
136    /**
137     * Helper class to store a time range.<p>
138     */
139    class CmsGallerySearchTimeRange {
140
141        /** The end time of the time range. */
142        long m_endTime;
143
144        /** The start time of the time range. */
145        long m_startTime;
146
147        /**
148         * Default constructor.<p>
149         *
150         * This will create an object where the start date is equal to
151         * {@link Long#MIN_VALUE} and the end date is equal to {@link Long#MAX_VALUE}.<p>
152         */
153        public CmsGallerySearchTimeRange() {
154
155            m_startTime = Long.MIN_VALUE;
156            m_endTime = Long.MAX_VALUE;
157        }
158
159        /**
160         * Constructor with start and end time.<p>
161         *
162         * @param startTime the start time of the time range
163         * @param endTime the end time of the time range
164         */
165        public CmsGallerySearchTimeRange(long startTime, long endTime) {
166
167            m_startTime = startTime;
168            m_endTime = endTime;
169        }
170
171        /**
172         * Returns the end time of the time range.<p>
173         *
174         * @return the end time of the time range
175         */
176        public long getEndTime() {
177
178            return m_endTime;
179        }
180
181        /**
182         * Returns the start time of the time range.<p>
183         *
184         * @return the start time of the time range
185         */
186        public long getStartTime() {
187
188            return m_startTime;
189        }
190    }
191
192    /** The allowed dynamic function ids. */
193    private Collection<CmsUUID> m_allowedFunctions;
194
195    /** The categories to search in. */
196    private List<String> m_categories;
197
198    /** The container types to search in. */
199    private List<String> m_containerTypes;
200
201    /** The time range for the date of resource creation to consider in the search. */
202    private CmsGallerySearchTimeRange m_dateCreatedTimeRange;
203
204    /** The time range for the date of resource last modification to consider in the search. */
205    private CmsGallerySearchTimeRange m_dateLastModifiedTimeRange;
206
207    /** The list of folders to search in. */
208    private List<String> m_folders;
209
210    /** Enlists all VFS folders to perform a search in. */
211    private List<String> m_foldersToSearchIn;
212
213    /** The galleries to search in. */
214    private List<String> m_galleries;
215
216    /** Indicates the search exclude property should be ignored. */
217    private boolean m_ignoreSearchExclude;
218
219    /** The locale for the search. */
220    private String m_locale;
221
222    /** The number of search results per page. */
223    private int m_matchesPerPage;
224
225    /** The sitemap reference path. */
226    private String m_referencePath;
227
228    /** The resource types to search for. */
229    private List<String> m_resourceTypes;
230
231    /** The requested page of the result. */
232    private int m_resultPage;
233
234    /** The gallery search scope. */
235    private CmsGallerySearchScope m_scope;
236
237    /** The sort order for the search result. */
238    private CmsGallerySortParam m_sortOrder;
239
240    /** Search words to search for. */
241    private String m_words;
242
243    /**
244     * Default constructor.<p>
245     */
246    public CmsGallerySearchParameters() {
247
248        m_resultPage = 1;
249        m_matchesPerPage = 10;
250    }
251
252    /**
253     * Returns the categories that have been included in the search.<p>
254     *
255     * If no categories have been set, then <code>null</code> is returned.<p>
256     *
257     * @return the categories that have been included in the search
258     */
259    public List<String> getCategories() {
260
261        return m_categories;
262    }
263
264    /**
265     * Returns the container types that have been included in the search.<p>
266     *
267     * @return the container types that have been included in the search
268     */
269    public List<String> getContainerTypes() {
270
271        return m_containerTypes;
272    }
273
274    /**
275     * Returns the time range for the date of creation that has been used for the search result.<p>
276     *
277     * In case this time range has not been set, this will return an object
278     * where the start date is equal to {@link Long#MIN_VALUE} and the end date is equal to {@link Long#MAX_VALUE}.<p>
279     *
280     * @return the time range for the date of creation that has been used for the search result
281     */
282    public CmsGallerySearchTimeRange getDateCreatedRange() {
283
284        if (m_dateCreatedTimeRange == null) {
285            m_dateCreatedTimeRange = new CmsGallerySearchTimeRange();
286        }
287        return m_dateCreatedTimeRange;
288    }
289
290    /**
291     * Returns the time range for the dadelete examplete of last modification that has been used for the search result.<p>
292     *
293     * In case this time range has not been set, this will return an object
294     * where the start date is equal to {@link Long#MIN_VALUE} and the end date is equal to {@link Long#MAX_VALUE}.<p>
295     *
296     * @return the time range for the date of last modification that has been used for the search result
297     */
298    public CmsGallerySearchTimeRange getDateLastModifiedRange() {
299
300        if (m_dateLastModifiedTimeRange == null) {
301            m_dateLastModifiedTimeRange = new CmsGallerySearchTimeRange();
302        }
303        return m_dateLastModifiedTimeRange;
304    }
305
306    /**
307     * Returns the list of folders to search in.<p>
308     *
309     * @return a list of paths of VFS folders
310     */
311    public List<String> getFolders() {
312
313        return m_folders;
314    }
315
316    /**
317     * Returns the galleries that have been included in the search.<p>
318     *
319     * If no galleries have been set, then <code>null</code> is returned.<p>
320     *
321     * @return the galleries that have been included in the search
322     */
323    public List<String> getGalleries() {
324
325        return m_galleries;
326    }
327
328    /**
329     * Returns the locale that has been used for the search.<p>
330     *
331     * If no locale has been set, then <code>null</code> is returned.<p>
332     *
333     * @return the locale that has been used for the search
334     */
335    public String getLocale() {
336
337        if (m_locale == null) {
338            m_locale = CmsLocaleManager.getDefaultLocale().toString();
339        }
340        return m_locale;
341    }
342
343    /**
344     * Returns the maximum number of matches per result page.<p>
345     *
346     * @return the the maximum number of matches per result page
347     *
348     * @see #getMatchesPerPage()
349     * @see #setResultPage(int)
350     */
351    public int getMatchesPerPage() {
352
353        return m_matchesPerPage;
354    }
355
356    /**
357     * Returns a CmsSolrQuery representation of this class.
358     * @param cms the openCms object.
359     * @return CmsSolrQuery representation of this class.
360     */
361    public CmsSolrQuery getQuery(CmsObject cms) {
362
363        final CmsSolrQuery query = new CmsSolrQuery();
364
365        // set categories
366        query.setCategories(m_categories);
367
368        // set container types
369        if (null != m_containerTypes) {
370            query.addFilterQuery(CmsSearchField.FIELD_CONTAINER_TYPES, m_containerTypes, false, false);
371        }
372
373        // Set date created time filter
374        query.addFilterQuery(
375            CmsSearchUtil.getDateCreatedTimeRangeFilterQuery(
376                CmsSearchField.FIELD_DATE_CREATED,
377                getDateCreatedRange().m_startTime,
378                getDateCreatedRange().m_endTime));
379
380        // Set date last modified time filter
381        query.addFilterQuery(
382            CmsSearchUtil.getDateCreatedTimeRangeFilterQuery(
383                CmsSearchField.FIELD_DATE_LASTMODIFIED,
384                getDateLastModifiedRange().m_startTime,
385                getDateLastModifiedRange().m_endTime));
386
387        // set scope / folders to search in
388        m_foldersToSearchIn = new ArrayList<String>();
389        addFoldersToSearchIn(m_folders);
390        addFoldersToSearchIn(m_galleries);
391        setSearchFolders(cms);
392        query.addFilterQuery(
393            CmsSearchField.FIELD_PARENT_FOLDERS,
394            new ArrayList<String>(m_foldersToSearchIn),
395            false,
396            true);
397
398        if (!m_ignoreSearchExclude) {
399            // Reference for the values: CmsGallerySearchIndex.java, field EXCLUDE_PROPERTY_VALUES
400            query.addFilterQuery(
401                "-" + CmsSearchField.FIELD_SEARCH_EXCLUDE,
402                Arrays.asList(
403                    new String[] {
404                        A_CmsSearchIndex.PROPERTY_SEARCH_EXCLUDE_VALUE_ALL,
405                        A_CmsSearchIndex.PROPERTY_SEARCH_EXCLUDE_VALUE_GALLERY}),
406                false,
407                true);
408        }
409
410        // set matches per page
411        query.setRows(new Integer(m_matchesPerPage));
412
413        // set resource types
414        if (null != m_resourceTypes) {
415            List<String> resourceTypes = new ArrayList<>(m_resourceTypes);
416            if (m_resourceTypes.contains(CmsResourceTypeFunctionConfig.TYPE_NAME)
417                && !m_resourceTypes.contains(CmsXmlDynamicFunctionHandler.TYPE_FUNCTION)) {
418                resourceTypes.add(CmsXmlDynamicFunctionHandler.TYPE_FUNCTION);
419            }
420            query.setResourceTypes(resourceTypes);
421        }
422
423        // set result page
424        query.setStart(new Integer((m_resultPage - 1) * m_matchesPerPage));
425
426        // set search locale
427        if (null != m_locale) {
428            query.setLocales(CmsLocaleManager.getLocale(m_locale));
429        }
430
431        // set search words
432        if (null != m_words) {
433            query.setQuery(m_words);
434        }
435
436        // set sort order
437        query.setSort(getSort().getFirst(), getSort().getSecond());
438
439        // set result collapsing by id
440        query.addFilterQuery("{!collapse field=id}");
441
442        query.setFields(CmsGallerySearchResult.getRequiredSolrFields());
443
444        if ((m_allowedFunctions != null) && !m_allowedFunctions.isEmpty()) {
445            String functionFilter = "((-type:("
446                + CmsXmlDynamicFunctionHandler.TYPE_FUNCTION
447                + " OR "
448                + CmsResourceTypeFunctionConfig.TYPE_NAME
449                + ")) OR (id:(";
450            Iterator<CmsUUID> it = m_allowedFunctions.iterator();
451            while (it.hasNext()) {
452                CmsUUID id = it.next();
453                functionFilter += id.toString();
454                if (it.hasNext()) {
455                    functionFilter += " OR ";
456                }
457            }
458            functionFilter += ")))";
459            query.addFilterQuery(functionFilter);
460        }
461
462        return query;
463    }
464
465    /**
466     * Gets the reference path.<p>
467     *
468     * @return the gallery reference path
469     */
470    public String getReferencePath() {
471
472        return m_referencePath;
473    }
474
475    /**
476     * Returns the names of the resource types that have been included in the search result.<p>
477     *
478     * If no resource types have been set, then <code>null</code> is returned.<p>
479     *
480     * @return the names of the resource types that have been included in the search result
481     */
482    public List<String> getResourceTypes() {
483
484        return m_resourceTypes;
485    }
486
487    /**
488     * Returns the index of the requested result page.<p>
489     *
490     * @return the index of the requested result page
491     *
492     * @see #setResultPage(int)
493     * @see #getMatchesPerPage()
494     * @see #setMatchesPerPage(int)
495     */
496    public int getResultPage() {
497
498        return m_resultPage;
499    }
500
501    /**
502     * The gallery search scope.<p>
503     *
504     * @return the gallery search scope
505     */
506    public CmsGallerySearchScope getScope() {
507
508        if (m_scope == null) {
509            return OpenCms.getWorkplaceManager().getGalleryDefaultScope();
510        }
511        return m_scope;
512    }
513
514    /**
515     * Returns the words (terms) that have been used for the full text search.<p>
516     *
517     * If no search words have been set, then <code>null</code> is returned.<p>
518     *
519     * @return the words (terms) that have been used for the full text search
520     */
521    public String getSearchWords() {
522
523        return m_words;
524    }
525
526    /**
527     * Returns the sort order that has been used in the search.<p>
528     *
529     * If the sort parameter has not been set the default sort order
530     * defined by {@link CmsGallerySortParam#DEFAULT} is used.<p>
531     *
532     * @return the sort order that has been used in the search
533     */
534    public CmsGallerySortParam getSortOrder() {
535
536        if (m_sortOrder == null) {
537
538            m_sortOrder = CmsGallerySortParam.DEFAULT;
539        }
540        return m_sortOrder;
541    }
542
543    /**
544     * Returns the search exclude property ignore flag.<p>
545     *
546     * @return the search exclude property ignore flag
547     */
548    public boolean isIgnoreSearchExclude() {
549
550        return m_ignoreSearchExclude;
551    }
552
553    /**
554     * Sets the allowed dynamic function ids.<p>
555     *
556     * @param allowedFunctions the allowed dynamic function ids
557     */
558    public void setAllowedFunctions(Collection<CmsUUID> allowedFunctions) {
559
560        m_allowedFunctions = allowedFunctions;
561    }
562
563    /**
564     * Sets the categories for the search.<p>
565     *
566     * Results are found only if they are contained in at least one of the given categories.
567     *
568     * @param categories the categories to set
569     */
570    public void setCategories(List<String> categories) {
571
572        m_categories = categories;
573    }
574
575    /**
576     * Sets the container types for the search.<p>
577     *
578     * Results are found only if they are compatible with one of the given container types.
579     * If no container type is set, results compatible with any container will be returned in the search result.<p>
580     *
581     * @param containerTypes the container types to set
582     */
583    public void setContainerTypes(List<String> containerTypes) {
584
585        m_containerTypes = containerTypes;
586    }
587
588    /**
589     * Sets the time range for the date of resource creation to consider in the search.<p>
590     *
591     * @param startTime the start time of the time range
592     * @param endTime the end time of the time range
593     */
594    public void setDateCreatedTimeRange(long startTime, long endTime) {
595
596        if (m_dateCreatedTimeRange == null) {
597            m_dateCreatedTimeRange = new CmsGallerySearchTimeRange(startTime, endTime);
598        }
599    }
600
601    /**
602     * Sets the time range for the date of resource last modification to consider in the search.<p>
603     *
604     * @param startTime the start time of the time range
605     * @param endTime the end time of the time range
606     */
607    public void setDateLastModifiedTimeRange(long startTime, long endTime) {
608
609        if (m_dateLastModifiedTimeRange == null) {
610            m_dateLastModifiedTimeRange = new CmsGallerySearchTimeRange(startTime, endTime);
611        }
612    }
613
614    /**
615     * Sets the folders to search in.<p>
616     *
617     * @param folders the list of VFS folders
618     */
619    public void setFolders(List<String> folders) {
620
621        m_folders = folders;
622    }
623
624    /**
625     * Sets the galleries for the search.<p>
626     *
627     * Results are found only if they are contained in one of the given galleries.
628     * If no gallery is set, results from all galleries will be returned in the search result.<p>
629     *
630     * @param galleries the galleries to set
631     */
632    public void setGalleries(List<String> galleries) {
633
634        m_galleries = galleries;
635    }
636
637    /**
638     * Sets the search exclude property ignore flag.<p>
639     *
640     * @param excludeForPageEditor the search exclude property ignore flag
641     */
642    public void setIgnoreSearchExclude(boolean excludeForPageEditor) {
643
644        m_ignoreSearchExclude = excludeForPageEditor;
645    }
646
647    /**
648     * Sets the maximum number of matches per result page.<p>
649     *
650     * Use this together with {@link #setResultPage(int)} in order to split the result
651     * in more than one page.<p>
652     *
653     * @param matchesPerPage the the maximum number of matches per result page to set
654     *
655     * @see #getMatchesPerPage()
656     * @see #setResultPage(int)
657     */
658    public void setMatchesPerPage(int matchesPerPage) {
659
660        m_matchesPerPage = matchesPerPage;
661    }
662
663    /**
664     * Sets the gallery reference path.<p>
665     *
666     * @param referencePath the gallery reference path
667     */
668    public void setReferencePath(String referencePath) {
669
670        m_referencePath = referencePath;
671    }
672
673    /**
674     * Sets the names of the resource types to include in the search result.<p>
675     *
676     * Results are found only if they resources match one of the given resource type names.
677     * If no resource type name is set, all resource types will be returned in the search result.<p>
678     *
679     * @param resourceTypes the names of the resource types to include in the search result
680     */
681    public void setResourceTypes(List<String> resourceTypes) {
682
683        m_resourceTypes = resourceTypes;
684    }
685
686    /**
687     * Sets the index of the result page that should be returned.<p>
688     *
689     * Use this together with {@link #setMatchesPerPage(int)} in order to split the result
690     * in more than one page.<p>
691     *
692     * @param resultPage the index of the result page to return
693     *
694     * @see #getResultPage()
695     * @see #getMatchesPerPage()
696     * @see #setMatchesPerPage(int)
697     */
698    public void setResultPage(int resultPage) {
699
700        m_resultPage = resultPage;
701    }
702
703    /**
704     * Sets the search scope.<p>
705     *
706     * @param scope the search scope
707     */
708    public void setScope(CmsGallerySearchScope scope) {
709
710        m_scope = scope;
711    }
712
713    /**
714     * Sets the locale for the search.<p>
715     *
716     * Results are found only if they match the given locale.
717     * If no locale is set, results for all locales will be returned in the search result.<p>
718     *
719     * @param locale the locale to set
720     */
721    public void setSearchLocale(String locale) {
722
723        m_locale = locale;
724    }
725
726    /**
727     * Sets the words (terms) for the full text search.<p>
728     *
729     * Results are found only if they text extraction for the resource contains all given search words.
730     * If no search word is set, all resources will be returned in the search result.<p>
731     *
732     * Please note that this should be a list of words separated by white spaces.
733     * Simple Lucene modifiers such as (+), (-) and (*) are allowed, but anything more complex then this
734     * will be removed.<p>
735     *
736     * @param words the words (terms) for the full text search to set
737     */
738    public void setSearchWords(String words) {
739
740        m_words = words;
741    }
742
743    /**
744     * Sets the sort order for the search.<p>
745     *
746     * @param sortOrder the sort order to set
747     */
748    public void setSortOrder(CmsGallerySortParam sortOrder) {
749
750        m_sortOrder = sortOrder;
751    }
752
753    /**
754     * Adds folders to perform the search in.
755     * @param folders Folders to search in.
756     */
757    private void addFoldersToSearchIn(final List<String> folders) {
758
759        if (null == folders) {
760            return;
761        }
762
763        for (String folder : folders) {
764            if (!CmsResource.isFolder(folder)) {
765                folder += "/";
766            }
767
768            m_foldersToSearchIn.add(folder);
769        }
770    }
771
772    /**
773     * Checks if the given list of resource type names contains a function-like type.<p>
774     *
775     * @param resourceTypes the collection of resource types
776     * @return true if the list contains a function-like type
777     */
778    private boolean containsFunctionType(List<String> resourceTypes) {
779
780        if (resourceTypes.contains(CmsXmlDynamicFunctionHandler.TYPE_FUNCTION)) {
781            return true;
782        }
783        if (resourceTypes.contains(CmsResourceTypeFunctionConfig.TYPE_NAME)) {
784            return true;
785        }
786        return false;
787    }
788
789    /**
790     * Returns the Lucene sort indicated by the selected sort order.<p>
791     *
792     * @return the Lucene sort indicated by the selected sort order
793     *
794     * @see #getSortOrder()
795     */
796    private CmsPair<String, org.apache.solr.client.solrj.SolrQuery.ORDER> getSort() {
797
798        final String sortTitle = CmsSearchFieldConfiguration.getLocaleExtendedName(
799            CmsSearchField.FIELD_TITLE_UNSTORED,
800            getLocale()) + "_s";
801
802        switch (getSortOrder()) {
803            case dateCreated_asc:
804                return CmsPair.create(CmsSearchField.FIELD_DATE_CREATED, ORDER.asc);
805            case dateCreated_desc:
806                return CmsPair.create(CmsSearchField.FIELD_DATE_CREATED, ORDER.desc);
807            case dateExpired_asc:
808                return CmsPair.create(CmsSearchField.FIELD_DATE_EXPIRED, ORDER.asc);
809            case dateExpired_desc:
810                return CmsPair.create(CmsSearchField.FIELD_DATE_EXPIRED, ORDER.desc);
811            case dateLastModified_asc:
812                return CmsPair.create(CmsSearchField.FIELD_DATE_LASTMODIFIED, ORDER.asc);
813            case dateLastModified_desc:
814                return CmsPair.create(CmsSearchField.FIELD_DATE_LASTMODIFIED, ORDER.desc);
815            case dateReleased_asc:
816                return CmsPair.create(CmsSearchField.FIELD_DATE_RELEASED, ORDER.asc);
817            case dateReleased_desc:
818                return CmsPair.create(CmsSearchField.FIELD_DATE_RELEASED, ORDER.desc);
819            case length_asc:
820                return CmsPair.create(CmsSearchField.FIELD_SIZE, ORDER.asc);
821            case length_desc:
822                return CmsPair.create(CmsSearchField.FIELD_SIZE, ORDER.desc);
823            case path_asc:
824                return CmsPair.create(CmsSearchField.FIELD_PATH, ORDER.asc);
825            case path_desc:
826                return CmsPair.create(CmsSearchField.FIELD_PATH, ORDER.desc);
827            case score:
828                return CmsPair.create(CmsSearchField.FIELD_SCORE, ORDER.asc);
829            case state_asc:
830                return CmsPair.create(CmsSearchField.FIELD_STATE, ORDER.asc);
831            case state_desc:
832                return CmsPair.create(CmsSearchField.FIELD_STATE, ORDER.desc);
833            case title_asc:
834                return CmsPair.create(sortTitle, ORDER.asc);
835            case title_desc:
836                return CmsPair.create(sortTitle, ORDER.desc);
837            case type_asc:
838                return CmsPair.create(CmsSearchField.FIELD_TYPE, ORDER.asc);
839            case type_desc:
840                return CmsPair.create(CmsSearchField.FIELD_TYPE, ORDER.desc);
841            case userCreated_asc:
842                return CmsPair.create(CmsSearchField.FIELD_USER_CREATED, ORDER.asc);
843            case userCreated_desc:
844                return CmsPair.create(CmsSearchField.FIELD_USER_CREATED, ORDER.desc);
845            case userLastModified_asc:
846                return CmsPair.create(CmsSearchField.FIELD_USER_LAST_MODIFIED, ORDER.asc);
847            case userLastModified_desc:
848                return CmsPair.create(CmsSearchField.FIELD_USER_LAST_MODIFIED, ORDER.desc);
849            default:
850                return CmsPair.create(sortTitle, ORDER.asc);
851        }
852    }
853
854    /**
855     * Applies the defined search folders to the Solr query.
856     *
857     * @param obj The current CmsObject object.
858     */
859    private void setSearchFolders(CmsObject obj) {
860
861        // check if parentFolders to search in have been set
862        // if this evaluates false, the search folders have already been set, so
863        // there's no need to add a scope filter
864        if (m_foldersToSearchIn.isEmpty()) {
865            // only append scope filter if no no folders or galleries given
866            setSearchScopeFilter(obj);
867        }
868    }
869
870    /**
871     * Sets the search scope.
872     *
873     * @param cms The current CmsObject object.
874     */
875    private void setSearchScopeFilter(CmsObject cms) {
876
877        final List<String> searchRoots = CmsSearchUtil.computeScopeFolders(cms, this);
878
879        // If the resource types contain the type "function" also
880        // add "/system/modules/" to the search path
881
882        if ((null != getResourceTypes()) && containsFunctionType(getResourceTypes())) {
883            searchRoots.add("/system/modules/");
884        }
885
886        addFoldersToSearchIn(searchRoots);
887    }
888}