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 GmbH & Co. KG, 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.workplace.search;
029
030import org.opencms.file.CmsObject;
031import org.opencms.file.CmsResource;
032import org.opencms.file.CmsResourceFilter;
033import org.opencms.main.CmsException;
034import org.opencms.main.CmsLog;
035import org.opencms.search.CmsSearch;
036import org.opencms.search.CmsSearchParameters;
037import org.opencms.search.CmsSearchResult;
038import org.opencms.util.CmsStringUtil;
039import org.opencms.workplace.explorer.CmsResourceUtil;
040import org.opencms.workplace.list.A_CmsListExplorerDialog;
041import org.opencms.workplace.list.A_CmsListResourceCollector;
042import org.opencms.workplace.list.CmsListItem;
043import org.opencms.workplace.list.I_CmsListResourceCollector;
044
045import java.util.ArrayList;
046import java.util.Arrays;
047import java.util.HashMap;
048import java.util.List;
049import java.util.Map;
050
051import org.apache.commons.logging.Log;
052
053/**
054 * Collector for receiving CmsResources from a search result set.<p>
055 *
056 * @since 6.1.0
057 */
058public class CmsSearchResourcesCollector extends A_CmsListResourceCollector {
059
060    /** Parameter of the default collector name. */
061    public static final String COLLECTOR_NAME = "searchresources";
062
063    /** Meta Parameter name constant. */
064    public static final String PARAM_FIELDS = "fields";
065
066    /** Meta Parameter index name constant. */
067    public static final String PARAM_INDEXNAME = "indexName";
068
069    /** Maximum creation date parameter name constant. */
070    public static final String PARAM_MAXCREATIONDATE = "maxCreationDate";
071
072    /** Maximum last modification date parameter name constant. */
073    public static final String PARAM_MAXLASTMODIFICATIONDATE = "maxLastModificationDate";
074
075    /** Minimum creation date parameter name constant. */
076    public static final String PARAM_MINCREATIONDATE = "minCreationDate";
077
078    /** Minimum last modification date parameter name constant. */
079    public static final String PARAM_MINLASTMODIFICATIONDATE = "minLastModificationDate";
080
081    /** Query Parameter name constant. */
082    public static final String PARAM_QUERY = "query";
083
084    /** Sort Parameter name constant. */
085    public static final String PARAM_SORT = "sort";
086
087    /** Resource cache. */
088    protected Map<String, CmsSearchResult> m_srCache = new HashMap<String, CmsSearchResult>();
089
090    /** Cached search bean. */
091    private CmsSearch m_searchBean;
092
093    /** Cached search results. */
094    private List<CmsSearchResult> m_searchResults;
095
096    /** The log object for this class. */
097    private static final Log LOG = CmsLog.getLog(CmsSearchResourcesCollector.class);
098
099    /**
100     * Constructor, creates a new instance.<p>
101     *
102     * @param wp the workplace object
103     * @param query the search query
104     * @param sort the sort by parameter
105     * @param fields the comma separated list of fields to search
106     * @param searchRoots a list of search roots
107     * @param minCreationDate the minimum creation date of the resources to be searched
108     * @param maxCreationDate the maximum creation date of the resources to be searched
109     * @param minLastModificationDate the minimum creation date of the resources to be searched
110     * @param maxLastModificationDate the maximum creation date of the resources to be searched
111     * @param indexName the index name to search in
112     */
113    public CmsSearchResourcesCollector(
114        A_CmsListExplorerDialog wp,
115        String query,
116        String sort,
117        String fields,
118        List<String> searchRoots,
119        String minCreationDate,
120        String maxCreationDate,
121        String minLastModificationDate,
122        String maxLastModificationDate,
123        String indexName) {
124
125        super(wp);
126        m_collectorParameter += I_CmsListResourceCollector.SEP_PARAM
127            + PARAM_INDEXNAME
128            + I_CmsListResourceCollector.SEP_KEYVAL
129            + indexName;
130        m_collectorParameter += I_CmsListResourceCollector.SEP_PARAM
131            + PARAM_QUERY
132            + I_CmsListResourceCollector.SEP_KEYVAL
133            + query;
134        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(sort)) {
135            m_collectorParameter += I_CmsListResourceCollector.SEP_PARAM
136                + PARAM_SORT
137                + I_CmsListResourceCollector.SEP_KEYVAL
138                + sort;
139        }
140        m_collectorParameter += I_CmsListResourceCollector.SEP_PARAM
141            + PARAM_FIELDS
142            + I_CmsListResourceCollector.SEP_KEYVAL
143            + fields;
144        if ((CmsStringUtil.isNotEmptyOrWhitespaceOnly(minCreationDate)) && (!minCreationDate.equals("0"))) {
145            m_collectorParameter += I_CmsListResourceCollector.SEP_PARAM
146                + PARAM_MINCREATIONDATE
147                + I_CmsListResourceCollector.SEP_KEYVAL
148                + minCreationDate;
149        }
150        if ((CmsStringUtil.isNotEmptyOrWhitespaceOnly(maxCreationDate)) && (!maxCreationDate.equals("0"))) {
151            m_collectorParameter += I_CmsListResourceCollector.SEP_PARAM
152                + PARAM_MAXCREATIONDATE
153                + I_CmsListResourceCollector.SEP_KEYVAL
154                + maxCreationDate;
155        }
156        if ((CmsStringUtil.isNotEmptyOrWhitespaceOnly(minLastModificationDate))
157            && (!minLastModificationDate.equals("0"))) {
158            m_collectorParameter += I_CmsListResourceCollector.SEP_PARAM
159                + PARAM_MINLASTMODIFICATIONDATE
160                + I_CmsListResourceCollector.SEP_KEYVAL
161                + minLastModificationDate;
162        }
163        if ((CmsStringUtil.isNotEmptyOrWhitespaceOnly(maxLastModificationDate))
164            && (!maxLastModificationDate.equals("0"))) {
165            m_collectorParameter += I_CmsListResourceCollector.SEP_PARAM
166                + PARAM_MAXLASTMODIFICATIONDATE
167                + I_CmsListResourceCollector.SEP_KEYVAL
168                + maxLastModificationDate;
169        }
170
171        setResourcesParam(searchRoots);
172    }
173
174    /**
175     * @see org.opencms.file.collectors.I_CmsResourceCollector#getCollectorNames()
176     */
177    public List<String> getCollectorNames() {
178
179        return Arrays.asList(COLLECTOR_NAME);
180    }
181
182    /**
183     * @see org.opencms.workplace.list.A_CmsListResourceCollector#getResources(org.opencms.file.CmsObject, java.util.Map)
184     */
185    @Override
186    public List<CmsResource> getResources(CmsObject cms, Map<String, String> params) {
187
188        List<CmsSearchResult> result = getSearchResults(params);
189        List<CmsResource> resources = new ArrayList<CmsResource>();
190        String siteRoot = cms.getRequestContext().getSiteRoot();
191        int siteLen = siteRoot.length();
192        for (CmsSearchResult sr : result) {
193            try {
194                String resultPath = sr.getPath();
195                if (resultPath.startsWith(siteRoot)) {
196                    resultPath = sr.getPath().substring(siteLen);
197                }
198                CmsResource resource = cms.readResource(resultPath, CmsResourceFilter.ALL);
199                m_resCache.put(resource.getStructureId().toString(), resource);
200                m_srCache.put(resource.getStructureId().toString(), sr);
201                resources.add(resource);
202            } catch (CmsException e) {
203                LOG.warn(e.getLocalizedMessage(), e);
204            }
205        }
206        return resources;
207    }
208
209    /**
210     * Returns the search result object for the given structure id.<p>
211     *
212     * @param structureId the structure id
213     *
214     * @return the resource
215     */
216    public CmsSearchResult getSearchResult(String structureId) {
217
218        return m_srCache.get(structureId);
219    }
220
221    /**
222     * @see org.opencms.workplace.list.A_CmsListResourceCollector#setPage(int)
223     */
224    @Override
225    public void setPage(int page) {
226
227        synchronized (this) {
228            super.setPage(page);
229            m_searchBean = null;
230            m_searchResults = null;
231        }
232    }
233
234    /**
235     * @see org.opencms.workplace.list.A_CmsListResourceCollector#getInternalResources(org.opencms.file.CmsObject, java.util.Map)
236     */
237    @Override
238    protected List<CmsResource> getInternalResources(CmsObject cms, Map<String, String> params) {
239
240        synchronized (this) {
241            if (m_resources == null) {
242                m_resources = getResources(cms, params);
243            }
244        }
245        return m_resources;
246    }
247
248    /**
249     * @see org.opencms.workplace.list.A_CmsListResourceCollector#setAdditionalColumns(org.opencms.workplace.list.CmsListItem, org.opencms.workplace.explorer.CmsResourceUtil)
250     */
251    @Override
252    protected void setAdditionalColumns(CmsListItem item, CmsResourceUtil resUtil) {
253
254        item.set(CmsSearchResultsList.LIST_COLUMN_SCORE, Integer.valueOf(getSearchResult(item.getId()).getScore()));
255    }
256
257    /**
258     * Returns the search bean object.<p>
259     *
260     * @param params the parameter map
261     *
262     * @return the used search bean
263     */
264    private CmsSearch getSearchBean(Map<String, String> params) {
265
266        if (m_searchBean == null) {
267            m_searchBean = new CmsSearch();
268            m_searchBean.init(getWp().getCms());
269            m_searchBean.setParameters(getSearchParameters(params));
270            if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_searchBean.getIndex())) {
271                m_searchBean.setIndex(getWp().getSettings().getUserSettings().getWorkplaceSearchIndexName());
272            }
273            m_searchBean.setMatchesPerPage(getWp().getSettings().getUserSettings().getExplorerFileEntries());
274            m_searchBean.setSearchPage(Integer.parseInt(params.get(I_CmsListResourceCollector.PARAM_PAGE)));
275            // set search roots
276            List<String> resources = getResourceNamesFromParam(params);
277            String[] searchRoots = new String[resources.size()];
278            resources.toArray(searchRoots);
279            for (int i = 0; i < searchRoots.length; i++) {
280                searchRoots[i] = getWp().getCms().addSiteRoot(searchRoots[i]);
281            }
282            m_searchBean.setSearchRoots(searchRoots);
283        } else {
284            int page = Integer.parseInt(params.get(I_CmsListResourceCollector.PARAM_PAGE));
285            if (m_searchBean.getSearchPage() != page) {
286                m_searchBean.setSearchPage(page);
287                m_searchResults = null;
288            }
289        }
290        return m_searchBean;
291    }
292
293    /**
294     * Returns a new search parameters object from the request parameters.<p>
295     *
296     * @param params the parameter map
297     *
298     * @return a search parameters object
299     */
300    private CmsSearchParameters getSearchParameters(Map<String, String> params) {
301
302        CmsSearchParameters searchParams = new CmsSearchParameters();
303        searchParams.setQuery(params.get(PARAM_QUERY));
304        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(params.get(PARAM_SORT))) {
305            searchParams.setSortName(params.get(PARAM_SORT));
306        }
307        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(params.get(PARAM_MINCREATIONDATE))) {
308            searchParams.setMinDateCreated(Long.parseLong(params.get(PARAM_MINCREATIONDATE)));
309        }
310        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(params.get(PARAM_MAXCREATIONDATE))) {
311            searchParams.setMaxDateCreated(Long.parseLong(params.get(PARAM_MAXCREATIONDATE)));
312        }
313        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(params.get(PARAM_MINLASTMODIFICATIONDATE))) {
314            searchParams.setMinDateLastModified(Long.parseLong(params.get(PARAM_MINLASTMODIFICATIONDATE)));
315        }
316        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(params.get(PARAM_MAXLASTMODIFICATIONDATE))) {
317            searchParams.setMaxDateLastModified(Long.parseLong(params.get(PARAM_MAXLASTMODIFICATIONDATE)));
318        }
319        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(params.get(PARAM_INDEXNAME))) {
320            searchParams.setIndex(params.get(PARAM_INDEXNAME));
321        }
322
323        List<String> fields = CmsStringUtil.splitAsList(params.get(PARAM_FIELDS), ',');
324        searchParams.setFields(fields);
325        searchParams.setSearchPage(Integer.parseInt(params.get(I_CmsListResourceCollector.PARAM_PAGE)));
326        return searchParams;
327    }
328
329    /**
330     * Returns the search result list.<p>
331     *
332     * @param params the parameter map
333     *
334     * @return a list of {@link org.opencms.search.CmsSearchResult} objects
335     */
336    private List<CmsSearchResult> getSearchResults(Map<String, String> params) {
337
338        if (m_searchResults == null) {
339            m_searchResults = getSearchBean(params).getSearchResult();
340        }
341        return m_searchResults;
342    }
343}