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.jsp.search.config.parser;
029
030import org.opencms.jsp.search.config.CmsSearchConfigurationCommon;
031import org.opencms.jsp.search.config.I_CmsSearchConfiguration;
032import org.opencms.jsp.search.config.I_CmsSearchConfigurationCommon;
033import org.opencms.jsp.search.config.I_CmsSearchConfigurationDidYouMean;
034import org.opencms.jsp.search.config.I_CmsSearchConfigurationFacetField;
035import org.opencms.jsp.search.config.I_CmsSearchConfigurationFacetQuery;
036import org.opencms.jsp.search.config.I_CmsSearchConfigurationFacetRange;
037import org.opencms.jsp.search.config.I_CmsSearchConfigurationHighlighting;
038import org.opencms.jsp.search.config.I_CmsSearchConfigurationPagination;
039import org.opencms.jsp.search.config.I_CmsSearchConfigurationSorting;
040import org.opencms.main.CmsLog;
041import org.opencms.util.CmsPair;
042
043import java.util.Collections;
044import java.util.Map;
045
046import org.apache.commons.logging.Log;
047
048/** Search configuration parser reading a configuration containing a plain Solr query.
049 * Only fl might be added additionally. */
050public class CmsPlainQuerySearchConfigurationParser implements I_CmsSearchConfigurationParser {
051
052    /** Logger for the class. */
053    protected static final Log LOG = CmsLog.getLog(CmsPlainQuerySearchConfigurationParser.class);
054
055    /** The default return fields. */
056    private static final String DEFAULT_FL = "id,path";
057
058    /** The whole query string. */
059    protected String m_queryString;
060
061    /** The optional base configuration that should be changed by the JSON configuration. */
062    private I_CmsSearchConfiguration m_baseConfig;
063
064    /** Constructor taking the JSON as String.
065     * @param query The query that is passed to Solr.
066     */
067    public CmsPlainQuerySearchConfigurationParser(String query) {
068
069        this(query, null);
070    }
071
072    /** Constructor taking the JSON as String.
073     * @param query The query that is passed to Solr (additional Solr params).
074     * @param baseConfig A base configuration that is adjusted by the JSON configuration string.
075     */
076    public CmsPlainQuerySearchConfigurationParser(String query, I_CmsSearchConfiguration baseConfig) {
077
078        if ((null != query) && !(query.startsWith("fl=") || query.contains("&fl="))) {
079            query = query + "&fl=" + DEFAULT_FL;
080        }
081        m_queryString = query;
082        m_baseConfig = baseConfig;
083
084    }
085
086    /**
087     * @see org.opencms.jsp.search.config.parser.I_CmsSearchConfigurationParser#parseCommon()
088     */
089    public I_CmsSearchConfigurationCommon parseCommon() {
090
091        String index = null;
092        String queryString = m_queryString;
093        CmsPair<String, String> idxExtract = extractParam(queryString, "index");
094        CmsPair<String, String> coreExtract = extractParam(idxExtract.getFirst(), "core");
095        return new CmsSearchConfigurationCommon(
096            null,
097            null,
098            null,
099            null,
100            Boolean.TRUE,
101            Boolean.TRUE,
102            null,
103            idxExtract.getSecond(),
104            coreExtract.getSecond(),
105            coreExtract.getFirst(),
106            null,
107            null,
108            null);
109    }
110
111    /**
112    * @see org.opencms.jsp.search.config.parser.I_CmsSearchConfigurationParser#parseDidYouMean()
113    */
114    public I_CmsSearchConfigurationDidYouMean parseDidYouMean() {
115
116        return null != m_baseConfig ? m_baseConfig.getDidYouMeanConfig() : null;
117    }
118
119    /**
120     * @see org.opencms.jsp.search.config.parser.I_CmsSearchConfigurationParser#parseFieldFacets()
121     */
122    public Map<String, I_CmsSearchConfigurationFacetField> parseFieldFacets() {
123
124        return null != m_baseConfig ? m_baseConfig.getFieldFacetConfigs() : Collections.emptyMap();
125    }
126
127    /**
128     * @see org.opencms.jsp.search.config.parser.I_CmsSearchConfigurationParser#parseHighlighter()
129     */
130    public I_CmsSearchConfigurationHighlighting parseHighlighter() {
131
132        return null != m_baseConfig ? m_baseConfig.getHighlighterConfig() : null;
133    }
134
135    /**
136     * @see org.opencms.jsp.search.config.parser.I_CmsSearchConfigurationParser#parsePagination()
137     */
138    public I_CmsSearchConfigurationPagination parsePagination() {
139
140        return null != m_baseConfig ? m_baseConfig.getPaginationConfig() : null;
141    }
142
143    /**
144     * @see org.opencms.jsp.search.config.parser.I_CmsSearchConfigurationParser#parseQueryFacet()
145     */
146    public I_CmsSearchConfigurationFacetQuery parseQueryFacet() {
147
148        return null != m_baseConfig ? m_baseConfig.getQueryFacetConfig() : null;
149    }
150
151    /**
152     * @see org.opencms.jsp.search.config.parser.I_CmsSearchConfigurationParser#parseRangeFacets()
153     */
154    public Map<String, I_CmsSearchConfigurationFacetRange> parseRangeFacets() {
155
156        return null != m_baseConfig ? m_baseConfig.getRangeFacetConfigs() : Collections.emptyMap();
157    }
158
159    /**
160     * @see org.opencms.jsp.search.config.parser.I_CmsSearchConfigurationParser#parseSorting()
161     */
162    public I_CmsSearchConfigurationSorting parseSorting() {
163
164        return null != m_baseConfig ? m_baseConfig.getSortConfig() : null;
165    }
166
167    /**
168     * Extracts the value of a parameter from a query string.
169     *
170     * For example, extractParam("a=foo&b=bar", "a") will return CmsPair("b=bar", "foo").
171     * @param params the parameter string.
172     * @param paramKey the key of the parameter to extract the value for.
173     * @return a pair of "params without the extracted parameter" and the value of the extracted parameter.
174     */
175    CmsPair<String, String> extractParam(String params, String paramKey) {
176
177        String extract = null;
178        int beginIdx = params.indexOf(paramKey + "=");
179        if (beginIdx >= 0) {
180            String sub = params.substring(beginIdx + paramKey.length() + 1);
181            int endIdx = sub.indexOf("&");
182            if (endIdx >= 0) {
183                extract = sub.substring(0, endIdx);
184                params = params.substring(0, beginIdx) + sub.substring(endIdx + 1);
185            } else {
186                extract = sub;
187                params = beginIdx > 0 ? params.substring(0, beginIdx - 1) : ""; // cut trailing '&'
188            }
189        }
190        return new CmsPair<>(params, extract);
191
192    }
193}