001/*
002 *  Copyright 2016 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.cms.search.solr;
017
018import java.util.Collection;
019import java.util.HashMap;
020import java.util.HashSet;
021import java.util.List;
022import java.util.Map;
023import java.util.Optional;
024import java.util.Set;
025
026import org.apache.avalon.framework.container.ContainerUtil;
027import org.apache.avalon.framework.parameters.Parameters;
028import org.apache.avalon.framework.service.ServiceException;
029import org.apache.avalon.framework.service.ServiceManager;
030import org.apache.cocoon.environment.ObjectModelHelper;
031import org.apache.cocoon.environment.Redirector;
032import org.apache.cocoon.environment.Request;
033import org.apache.cocoon.environment.SourceResolver;
034import org.apache.commons.lang3.StringUtils;
035
036import org.ametys.cms.contenttype.ContentTypesHelper;
037import org.ametys.cms.search.cocoon.SearchAction;
038import org.ametys.cms.search.ui.model.ColumnHelper;
039import org.ametys.cms.search.ui.model.ColumnHelper.Column;
040import org.ametys.cms.search.ui.model.SearchUIColumn;
041import org.ametys.cms.search.ui.model.SearchUIModel;
042import org.ametys.cms.search.ui.model.SearchUIModelHelper;
043import org.ametys.core.cocoon.JSonReader;
044import org.ametys.core.util.AvalonLoggerAdapter;
045
046/**
047 * Create a dynamic model with the given columns and facets and return the model columns if valid.
048 */
049public class GetSolrSearchModelAction extends SearchAction
050{
051    
052    /** The content types helper. */
053    protected ContentTypesHelper _contentTypesHelper;
054    
055    /** The search model helper. */
056    protected SearchUIModelHelper _searchModelHelper;
057    
058    /** The helper for columns */
059    protected ColumnHelper _columnHelper;
060    
061    @Override
062    public void service(ServiceManager serviceManager) throws ServiceException
063    {
064        super.service(serviceManager);
065        _contentTypesHelper = (ContentTypesHelper) serviceManager.lookup(ContentTypesHelper.ROLE);
066        _searchModelHelper = (SearchUIModelHelper) serviceManager.lookup(SearchUIModelHelper.ROLE);
067        _columnHelper = (ColumnHelper) serviceManager.lookup(ColumnHelper.ROLE);
068    }
069    
070    @SuppressWarnings("unchecked")
071    @Override
072    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
073    {
074        Request request = ObjectModelHelper.getRequest(objectModel);
075        
076        Map<String, Object> results = new HashMap<>();
077        request.setAttribute(JSonReader.OBJECT_TO_READ, results);
078        
079        Map<String, Object> jsParameters = _serverCommHelper.getJsParameters();
080        
081        String modelId = (String) jsParameters.get("model");
082        SearchUIModel model = _searchModelManager.getExtension(modelId);
083        
084        Map<String, Object> values = (Map<String, Object>) jsParameters.get("values");
085        
086        String columnsStr = StringUtils.defaultString((String) values.get("columns"));
087        
088        Object facetObj = values.get("facets");
089        List<String> facets = null;
090        if (facetObj != null && facetObj instanceof List<?>)
091        {
092            facets = (List<String>) facetObj;
093        }
094        
095        Object cTypesObj = values.get("contentTypes");
096        String baseContentType = null;
097        if (cTypesObj != null && cTypesObj instanceof List<?>)
098        {
099            Set<String> contentTypes = new HashSet<>((List<String>) cTypesObj);
100            baseContentType = _contentTypesHelper.getCommonAncestor(contentTypes);
101        }
102        
103        CriteriaSearchUIModelWrapper modelWrapper = new CriteriaSearchUIModelWrapper(model, manager, _context, new AvalonLoggerAdapter(getLogger()));
104        ContainerUtil.service(modelWrapper, manager);
105        
106        Map<String, Object> contextualParameters = (Map<String, Object>) jsParameters.get("contextualParameters");
107        
108        boolean success = true;
109        try
110        {
111            modelWrapper.setFacetedCriteria(baseContentType, facets, contextualParameters);
112        }
113        catch (Exception e)
114        {
115            getLogger().warn("Error setting facets for solr query search.", e);
116            
117            success = false;
118            results.put("error", "facet-error");
119            results.put("message", e.getMessage());
120        }
121        
122        try
123        {
124            modelWrapper.setResultColumns(baseContentType, _getColumns(columnsStr, baseContentType), contextualParameters);
125        }
126        catch (Exception e)
127        {
128            getLogger().warn("Error setting columns for solr query search.", e);
129            
130            success = false;
131            results.put("error", "column-error");
132            results.put("message", e.getMessage());
133        }
134        
135        results.put("success", success);
136        
137        if (success)
138        {
139            Map<String, SearchUIColumn> resultFields = modelWrapper.getResultFields(contextualParameters);
140            results.put("columns", _searchModelHelper.getColumnListInfo(resultFields));
141        }
142        
143        return EMPTY_MAP;
144    }
145    
146    private Collection<Column> _getColumns(String columnsStr, String baseContentType)
147    {
148        return _columnHelper.getColumns(columnsStr, Optional.ofNullable(baseContentType));
149    }
150    
151}