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.xml.xml2json.document;
029
030import org.opencms.file.CmsFile;
031import org.opencms.file.CmsResourceFilter;
032import org.opencms.i18n.CmsLocaleManager;
033import org.opencms.json.JSONException;
034import org.opencms.json.JSONObject;
035import org.opencms.jsp.search.config.CmsSearchConfiguration;
036import org.opencms.jsp.search.config.I_CmsSearchConfigurationCommon;
037import org.opencms.jsp.search.config.parser.CmsSimpleSearchConfigurationParser;
038import org.opencms.jsp.search.config.parser.simplesearch.CmsConfigParserUtils;
039import org.opencms.jsp.search.config.parser.simplesearch.CmsConfigurationBean;
040import org.opencms.jsp.search.controller.CmsSearchController;
041import org.opencms.jsp.search.result.CmsSearchResultWrapper;
042import org.opencms.jsp.search.result.I_CmsSearchResourceBean;
043import org.opencms.main.CmsException;
044import org.opencms.main.OpenCms;
045import org.opencms.search.CmsSearchException;
046import org.opencms.search.solr.CmsSolrIndex;
047import org.opencms.search.solr.CmsSolrQuery;
048import org.opencms.search.solr.CmsSolrResultList;
049import org.opencms.xml.content.CmsXmlContent;
050import org.opencms.xml.content.CmsXmlContentFactory;
051import org.opencms.xml.xml2json.CmsJsonRequest;
052import org.opencms.xml.xml2json.handler.CmsJsonHandlerContext;
053import org.opencms.xml.xml2json.handler.CmsJsonHandlerException;
054import org.opencms.xml.xml2json.handler.CmsJsonHandlerXmlContent.PathNotFoundException;
055
056import java.util.Collections;
057import java.util.Locale;
058
059/**
060 * Class representing a JSON document for a CMS list.
061 */
062public class CmsJsonDocumentList extends CmsJsonDocumentXmlContent {
063
064    /** The maximum number of list items to be returned. */
065    private final static Integer MAX_ROWS = Integer.valueOf(600);
066
067    /**
068     * Creates a new JSON document.<p>
069     *
070     * @param jsonRequest the JSON request
071     * @param xmlContent the listconfig XML content
072     * @throws Exception if something goes wrong
073     */
074    public CmsJsonDocumentList(CmsJsonRequest jsonRequest, CmsXmlContent xmlContent)
075    throws Exception {
076
077        super(jsonRequest, xmlContent);
078        m_throwException = false;
079    }
080
081    /**
082     * @see org.opencms.xml.xml2json.document.I_CmsJsonDocument#getJson()
083     */
084    @Override
085    public Object getJson()
086    throws JSONException, CmsException, CmsJsonHandlerException, PathNotFoundException, Exception {
087
088        super.getJson();
089        insertJsonList();
090        return m_json;
091    }
092
093    /**
094     * @see org.opencms.xml.xml2json.document.CmsJsonDocumentXmlContent#isLocaleAllRequest()
095     */
096    @Override
097    protected boolean isLocaleAllRequest() {
098
099        return false;
100    }
101
102    /**
103     * @see org.opencms.xml.xml2json.document.CmsJsonDocumentXmlContent#isLocalePathRequest()
104     */
105    @Override
106    protected boolean isLocalePathRequest() {
107
108        return false;
109    }
110
111    /**
112     * @see org.opencms.xml.xml2json.document.CmsJsonDocumentXmlContent#isLocaleRequest()
113     */
114    @Override
115    protected boolean isLocaleRequest() {
116
117        return true;
118    }
119
120    /**
121     * @see org.opencms.xml.xml2json.document.CmsJsonDocumentXmlContent#isShowFallbackLocaleRequest()
122     */
123    @Override
124    protected boolean isShowFallbackLocaleRequest() {
125
126        return true;
127    }
128
129    /**
130     * @see org.opencms.xml.xml2json.document.CmsJsonDocumentXmlContent#isShowWrapperRequest()
131     */
132    @Override
133    protected boolean isShowWrapperRequest() {
134
135        return false;
136    }
137
138    /**
139     * Evaluates the list configuration and returns the search result.<p>
140     *
141     * @param context the handler context
142     * @return the search result
143     * @throws JSONException if something goes wrong
144     * @throws CmsSearchException if something goes wrong
145     */
146    private CmsSearchResultWrapper getSearchResult(CmsJsonHandlerContext context)
147    throws JSONException, CmsSearchException {
148
149        CmsConfigurationBean listConfigurationBean = CmsConfigParserUtils.parseListConfiguration(
150            context.getCms(),
151            context.getResource());
152        CmsSimpleSearchConfigurationParser searchConfigurationParser = new CmsSimpleSearchConfigurationParser(
153            context.getCms(),
154            listConfigurationBean,
155            "{}");
156        Locale locale = CmsLocaleManager.getLocale(m_jsonRequest.getParamLocale());
157        Locale selectedLocale = OpenCms.getLocaleManager().getBestMatchingLocale(
158            locale,
159            Collections.emptyList(),
160            m_xmlContent.getLocales());
161        searchConfigurationParser.setSearchLocale(selectedLocale);
162        String paramSort = m_jsonRequest.getParamSort();
163        if (paramSort != null) {
164            searchConfigurationParser.setSortOption(paramSort);
165        }
166
167        CmsSolrQuery query = searchConfigurationParser.getInitialQuery();
168        Integer paramStart = m_jsonRequest.getParamStart();
169        Integer paramRows = m_jsonRequest.getParamRows();
170        if (paramStart != null) {
171            query.setStart(paramStart);
172        }
173        if (paramRows != null) {
174            query.setRows(paramRows);
175        } else {
176            query.setRows(MAX_ROWS);
177        }
178        CmsSearchController searchController = new CmsSearchController(
179            new CmsSearchConfiguration(searchConfigurationParser, context.getCms()));
180        searchController.addQueryParts(query, context.getCms());
181        I_CmsSearchConfigurationCommon searchConfigurationCommon = searchController.getCommon().getConfig();
182        CmsSolrIndex index = OpenCms.getSearchManager().getIndexSolr(searchConfigurationCommon.getSolrIndex());
183        CmsSolrResultList solrResultList = index.search(
184            context.getCms(),
185            query,
186            true,
187            null,
188            false,
189            CmsResourceFilter.DEFAULT,
190            searchConfigurationCommon.getMaxReturnedResults());
191        return new CmsSearchResultWrapper(searchController, solrResultList, query, context.getCms(), null);
192    }
193
194    /**
195     * If the request parameter "list" is set, evaluates the list configuration and inserts
196     * the result into this JSON document.<p>
197     *
198     * @throws Exception if something goes wrong
199     */
200    private void insertJsonList() throws Exception {
201
202        Boolean paramContent = m_jsonRequest.getParamContent();
203        if (paramContent.booleanValue()) {
204            CmsSearchResultWrapper searchResult = getSearchResult(m_context);
205            insertJsonListInfo(searchResult);
206            insertJsonListItems(searchResult);
207        }
208    }
209
210    /**
211     * Inserts information about the list result into this JSON document.<p>
212     *
213     * @param searchResult the search result
214     * @throws JSONException if something goes wrong
215     */
216    private void insertJsonListInfo(CmsSearchResultWrapper searchResult) throws JSONException {
217
218        JSONObject jsonObject = new JSONObject(true);
219        jsonObject.put("numFound", searchResult.getNumFound());
220        m_json.put("listInfo", jsonObject);
221    }
222
223    /**
224     * Inserts the list items into this JSON document.<p>
225     *
226     * @param searchResult the search result
227     * @throws Exception if something goes wrong
228     */
229    private void insertJsonListItems(CmsSearchResultWrapper searchResult) throws Exception {
230
231        for (I_CmsSearchResourceBean searchResourceBean : searchResult.getSearchResults()) {
232            CmsFile file = searchResourceBean.getXmlContent().getFile();
233            CmsXmlContent xmlContent = CmsXmlContentFactory.unmarshal(m_context.getCms(), file);
234            CmsJsonDocumentEmbeddedXmlContent jsonDocument = new CmsJsonDocumentEmbeddedXmlContent(
235                m_jsonRequest,
236                xmlContent);
237            m_json.append("list", jsonDocument.getJson());
238        }
239    }
240}