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.Set;
024
025import org.apache.avalon.framework.container.ContainerUtil;
026import org.apache.avalon.framework.parameters.Parameters;
027import org.apache.avalon.framework.service.ServiceException;
028import org.apache.avalon.framework.service.ServiceManager;
029import org.apache.cocoon.environment.ObjectModelHelper;
030import org.apache.cocoon.environment.Redirector;
031import org.apache.cocoon.environment.Request;
032import org.apache.cocoon.environment.SourceResolver;
033import org.apache.commons.lang3.StringUtils;
034
035import org.ametys.cms.contenttype.ContentTypesHelper;
036import org.ametys.cms.search.cocoon.SearchAction;
037import org.ametys.cms.search.ui.model.ColumnHelper;
038import org.ametys.cms.search.ui.model.ColumnHelper.Column;
039import org.ametys.cms.search.ui.model.SearchUIColumn;
040import org.ametys.cms.search.ui.model.SearchUIModel;
041import org.ametys.cms.search.ui.model.SearchUIModelHelper;
042import org.ametys.core.cocoon.JSonReader;
043import org.ametys.core.util.AvalonLoggerAdapter;
044
045/**
046 * Create a dynamic model with the given columns and facets and return the model columns if valid.
047 */
048public class GetSolrSearchModelAction extends SearchAction
049{
050    
051    /** The content types helper. */
052    protected ContentTypesHelper _contentTypesHelper;
053    
054    /** The search model helper. */
055    protected SearchUIModelHelper _searchModelHelper;
056    
057    /** The helper for columns */
058    protected ColumnHelper _columnHelper;
059    
060    @Override
061    public void service(ServiceManager serviceManager) throws ServiceException
062    {
063        super.service(serviceManager);
064        _contentTypesHelper = (ContentTypesHelper) serviceManager.lookup(ContentTypesHelper.ROLE);
065        _searchModelHelper = (SearchUIModelHelper) serviceManager.lookup(SearchUIModelHelper.ROLE);
066        _columnHelper = (ColumnHelper) serviceManager.lookup(ColumnHelper.ROLE);
067    }
068    
069    @SuppressWarnings("unchecked")
070    @Override
071    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
072    {
073        Request request = ObjectModelHelper.getRequest(objectModel);
074        
075        Map<String, Object> results = new HashMap<>();
076        request.setAttribute(JSonReader.OBJECT_TO_READ, results);
077        
078        Map<String, Object> jsParameters = _serverCommHelper.getJsParameters();
079        
080        String modelId = (String) jsParameters.get("model");
081        SearchUIModel model = _searchModelManager.getExtension(modelId);
082        
083        Map<String, Object> values = (Map<String, Object>) jsParameters.get("values");
084        
085        String columnsStr = StringUtils.defaultString((String) values.get("columns"));
086        
087        Object facetObj = values.get("facets");
088        List<String> facets = null;
089        if (facetObj != null && facetObj instanceof List<?>)
090        {
091            facets = (List<String>) facetObj;
092        }
093        
094        Object cTypesObj = values.get("contentTypes");
095        Set<String> commonContentTypes = null;
096        if (cTypesObj != null && cTypesObj instanceof List<?>)
097        {
098            Set<String> contentTypes = new HashSet<>((List<String>) cTypesObj);
099            commonContentTypes = _contentTypesHelper.getCommonAncestors(contentTypes);
100        }
101        
102        CriteriaSearchUIModelWrapper modelWrapper = new CriteriaSearchUIModelWrapper(model, manager, _context, new AvalonLoggerAdapter(getLogger()));
103        ContainerUtil.service(modelWrapper, manager);
104        
105        Map<String, Object> contextualParameters = (Map<String, Object>) jsParameters.get("contextualParameters");
106        
107        boolean success = true;
108        try
109        {
110            modelWrapper.setFacetedCriteria(commonContentTypes, facets, contextualParameters);
111        }
112        catch (Exception e)
113        {
114            getLogger().warn("Error setting facets for solr query search.", e);
115            
116            success = false;
117            results.put("error", "facet-error");
118            results.put("message", e.getMessage());
119        }
120        
121        try
122        {
123            modelWrapper.setResultColumns(commonContentTypes, _getColumns(columnsStr, commonContentTypes), contextualParameters);
124        }
125        catch (Exception e)
126        {
127            getLogger().warn("Error setting columns for solr query search.", e);
128            
129            success = false;
130            results.put("error", "column-error");
131            results.put("message", e.getMessage());
132        }
133        
134        results.put("success", success);
135        
136        if (success)
137        {
138            Map<String, SearchUIColumn> resultFields = modelWrapper.getResultFields(contextualParameters);
139            results.put("columns", _searchModelHelper.getColumnListInfo(resultFields));
140        }
141        
142        return EMPTY_MAP;
143    }
144    
145    private Collection<Column> _getColumns(String columnsStr, Set<String> baseContentTypes)
146    {
147        return _columnHelper.getColumns(columnsStr, baseContentTypes);
148    }
149    
150}