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.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import org.apache.avalon.framework.parameters.Parameters;
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.cocoon.ProcessingException;
027import org.apache.cocoon.acting.ServiceableAction;
028import org.apache.cocoon.environment.ObjectModelHelper;
029import org.apache.cocoon.environment.Redirector;
030import org.apache.cocoon.environment.Request;
031import org.apache.cocoon.environment.SourceResolver;
032
033import org.ametys.cms.search.GetQueryFromJSONHelper;
034import org.ametys.cms.search.model.SearchModel;
035import org.ametys.cms.search.model.impl.ReferencingCriterionDefinition;
036import org.ametys.cms.search.query.Query;
037import org.ametys.core.cocoon.JSonReader;
038import org.ametys.core.util.ServerCommHelper;
039import org.ametys.runtime.model.ModelViewItem;
040import org.ametys.runtime.model.ViewItem;
041import org.ametys.runtime.model.ViewItemAccessor;
042import org.ametys.runtime.model.ViewItemContainer;
043
044/**
045 * Get a solr query string from a search tool.
046 */
047public class GetSolrQueryAction extends ServiceableAction
048{
049    /** The server comm helper */
050    protected ServerCommHelper _serverCommHelper;
051    
052    /** the helper to get query infos from JSON */
053    protected GetQueryFromJSONHelper _getQueryFromJSONHelper;
054    
055    @Override
056    public void service(ServiceManager smanager) throws ServiceException
057    {
058        super.service(smanager);
059        _serverCommHelper = (ServerCommHelper) smanager.lookup(ServerCommHelper.ROLE);
060        _getQueryFromJSONHelper = (GetQueryFromJSONHelper) smanager.lookup(GetQueryFromJSONHelper.ROLE);
061    }
062    
063    @Override
064    @SuppressWarnings ("unchecked")
065    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
066    {
067        Request request = ObjectModelHelper.getRequest(objectModel);
068        
069        Map<String, Object> queryResults = new HashMap<>();
070        request.setAttribute(JSonReader.OBJECT_TO_READ, queryResults);
071        
072        Map<String, Object> jsParameters = _serverCommHelper.getJsParameters();
073        
074        
075        Map<String, Object> contextualParameters = (Map<String, Object>) jsParameters.get("contextualParameters");
076        
077        if (contextualParameters == null)
078        {
079            contextualParameters = new HashMap<> ();
080        }
081        
082        SearchModel model = _getQueryFromJSONHelper.getSearchModel(jsParameters, "id");
083        
084        try
085        {
086            List<String> cTypesToFill = new ArrayList<>();
087            Query query = _getQueryFromJSONHelper.getQueryFromModel(model, jsParameters, cTypesToFill);
088            
089            // Set the query string into the results.
090            queryResults.put("query", query.build());
091            queryResults.put("contentTypes", cTypesToFill);
092            
093            // Get the model facets and set them into the results.
094            List<String> facets = _getFacetedCriteriaReferencePaths(model, contextualParameters);
095            queryResults.put("facets", facets);
096            
097            // Get the model columns and set them into the results.
098            List<String> columnIds = (List<String>) jsParameters.get("columns");
099            if (columnIds == null || columnIds.isEmpty())
100            {
101                columnIds = _getQueryFromJSONHelper.getColumnsFromSearchModel(model, contextualParameters);
102            }
103            queryResults.put("columns", columnIds);
104        }
105        catch (Exception e)
106        {
107            getLogger().error("Cannot get solr query string: " + e.getMessage(), e);
108            throw new ProcessingException("Cannot get solr query string: " + e.getMessage(), e);
109        }
110        
111        return EMPTY_MAP;
112    }
113    
114    private List<String> _getFacetedCriteriaReferencePaths(SearchModel searchModel, Map<String, Object> contextualParameters)
115    {
116        ViewItemContainer facetedCriteria = searchModel.getFacetedCriteria(contextualParameters);
117        return _getFacetedCriteriaReferencePaths(facetedCriteria);
118    }
119    
120    private List<String> _getFacetedCriteriaReferencePaths(ViewItemAccessor viewItemAccessor)
121    {
122        List<String> facets = new ArrayList<>();
123        
124        for (ViewItem viewItem : viewItemAccessor.getViewItems())
125        {
126            if (viewItem instanceof ModelViewItem modelViewItem
127                    && modelViewItem.getDefinition() instanceof ReferencingCriterionDefinition criterion)
128            {
129                facets.add(criterion.getReferencePath());
130            }
131            
132            if (viewItem instanceof ViewItemAccessor itemAccessor)
133            {
134                facets.addAll(_getFacetedCriteriaReferencePaths(itemAccessor));
135            }
136        }
137        
138        return facets;
139    }
140}