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 = _getQueryFromJSONHelper.getColumnsFromSearchModel(model, contextualParameters);
099            queryResults.put("columns", columnIds);
100        }
101        catch (Exception e)
102        {
103            getLogger().error("Cannot get solr query string: " + e.getMessage(), e);
104            throw new ProcessingException("Cannot get solr query string: " + e.getMessage(), e);
105        }
106        
107        return EMPTY_MAP;
108    }
109    
110    private List<String> _getFacetedCriteriaReferencePaths(SearchModel searchModel, Map<String, Object> contextualParameters)
111    {
112        ViewItemContainer facetedCriteria = searchModel.getFacetedCriteria(contextualParameters);
113        return _getFacetedCriteriaReferencePaths(facetedCriteria);
114    }
115    
116    private List<String> _getFacetedCriteriaReferencePaths(ViewItemAccessor viewItemAccessor)
117    {
118        List<String> facets = new ArrayList<>();
119        
120        for (ViewItem viewItem : viewItemAccessor.getViewItems())
121        {
122            if (viewItem instanceof ModelViewItem modelViewItem
123                    && modelViewItem.getDefinition() instanceof ReferencingCriterionDefinition criterion)
124            {
125                facets.add(criterion.getReferencePath());
126            }
127            
128            if (viewItem instanceof ViewItemAccessor itemAccessor)
129            {
130                facets.addAll(_getFacetedCriteriaReferencePaths(itemAccessor));
131            }
132        }
133        
134        return facets;
135    }
136}