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.controller;
029
030import org.opencms.file.CmsObject;
031import org.opencms.jsp.search.config.I_CmsSearchConfigurationFacetQuery;
032import org.opencms.jsp.search.config.I_CmsSearchConfigurationFacetQuery.I_CmsFacetQueryItem;
033import org.opencms.jsp.search.state.CmsSearchStateFacet;
034import org.opencms.jsp.search.state.I_CmsSearchStateFacet;
035import org.opencms.search.solr.CmsSolrQuery;
036
037import java.util.Iterator;
038import java.util.Map;
039
040/** Search controller for the query facet options. */
041public class CmsSearchControllerFacetQuery implements I_CmsSearchControllerFacetQuery {
042
043    /** Configuration of the field facet options. */
044    private final I_CmsSearchConfigurationFacetQuery m_config;
045    /** State of the field facets. */
046    private final I_CmsSearchStateFacet m_state;
047
048    /** Constructor taking the managed configuration.
049     * @param config The configuration to manage by the controller.
050     */
051    public CmsSearchControllerFacetQuery(final I_CmsSearchConfigurationFacetQuery config) {
052
053        m_config = config;
054        m_state = new CmsSearchStateFacet();
055    }
056
057    /**
058     * @see org.opencms.jsp.search.controller.I_CmsSearchController#addParametersForCurrentState(java.util.Map)
059     */
060    @Override
061    public void addParametersForCurrentState(final Map<String, String[]> parameters) {
062
063        if (!m_state.getCheckedEntries().isEmpty()) {
064            parameters.put(
065                m_config.getParamKey(),
066                m_state.getCheckedEntries().toArray(new String[m_state.getCheckedEntries().size()]));
067        }
068        if (m_state.getIgnoreChecked()) {
069            parameters.put(m_config.getIgnoreMaxParamKey(), null);
070        }
071
072    }
073
074    /**
075     * @see org.opencms.jsp.search.controller.I_CmsSearchController#addQueryParts(CmsSolrQuery, CmsObject)
076     */
077    @Override
078    public void addQueryParts(CmsSolrQuery query, CmsObject cms) {
079
080        addFacetPart(query);
081        addFilterQueryParts(query);
082    }
083
084    /**
085     * @see org.opencms.jsp.search.controller.I_CmsSearchControllerFacetQuery#getConfig()
086     */
087    @Override
088    public I_CmsSearchConfigurationFacetQuery getConfig() {
089
090        return m_config;
091    }
092
093    /**
094     * @see org.opencms.jsp.search.controller.I_CmsSearchControllerFacetQuery#getState()
095     */
096    @Override
097    public I_CmsSearchStateFacet getState() {
098
099        return m_state;
100    }
101
102    /**
103     * @see org.opencms.jsp.search.controller.I_CmsSearchController#updateForQueryChange()
104     */
105    @Override
106    public void updateForQueryChange() {
107
108        m_state.setIgnoreChecked(true);
109
110    }
111
112    /**
113     * @see org.opencms.jsp.search.controller.I_CmsSearchController#updateFromRequestParameters(java.util.Map, boolean)
114     */
115    @Override
116    public void updateFromRequestParameters(final Map<String, String[]> parameters, boolean isReloaded) {
117
118        m_state.setUseLimit(!parameters.containsKey(m_config.getIgnoreMaxParamKey()));
119
120        if (isReloaded) {
121            // update checked fields
122            m_state.clearChecked();
123            if (!m_state.getIgnoreChecked() && parameters.containsKey(m_config.getParamKey())) {
124                final String[] checked = parameters.get(m_config.getParamKey());
125                for (int i = 0; i < checked.length; i++) {
126                    String checkedEntry = checked[i];
127                    if ((null != checkedEntry) && !checkedEntry.isEmpty()) {
128                        m_state.addChecked(checkedEntry);
129                    }
130                }
131
132            }
133        } else { // use the preselection on first load
134            for (String checked : m_config.getPreSelection()) {
135                m_state.addChecked(checked);
136            }
137        }
138    }
139
140    /** Add query part for the facet, without filters.
141     * @param query The query part that is extended for the facet
142     */
143    protected void addFacetPart(CmsSolrQuery query) {
144
145        query.set("facet", "true");
146        String excludes = m_config.getIgnoreTags().isEmpty() ? "" : "{!ex=" + m_config.getIgnoreTags() + "}";
147        for (I_CmsFacetQueryItem q : m_config.getQueryList()) {
148            query.add("facet.query", excludes + q.getQuery());
149        }
150    }
151
152    /** Adds filter parts to the query.
153     * @param query The query.
154     */
155    protected void addFilterQueryParts(CmsSolrQuery query) {
156
157        if (!m_state.getCheckedEntries().isEmpty()) {
158            final Iterator<String> fieldIterator = m_state.getCheckedEntries().iterator();
159            StringBuffer value = new StringBuffer();
160            value.append("{!tag=").append(m_config.getName()).append("}(").append(fieldIterator.next());
161            final String concater = m_config.getIsAndFacet() ? " AND " : " OR ";
162            while (fieldIterator.hasNext()) {
163                value.append(concater);
164                value.append(fieldIterator.next());
165            }
166            value.append(')');
167            query.add("fq", value.toString());
168        }
169    }
170
171}