001/*
002 *  Copyright 2023 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.content.consistency;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.Iterator;
021import java.util.LinkedHashMap;
022import java.util.List;
023import java.util.Map;
024
025import org.apache.avalon.framework.component.Component;
026import org.apache.avalon.framework.service.ServiceException;
027import org.apache.avalon.framework.service.ServiceManager;
028import org.apache.avalon.framework.service.Serviceable;
029
030import org.ametys.core.ui.Callable;
031import org.ametys.plugins.workflow.support.WorkflowHelper;
032import org.ametys.runtime.i18n.I18nizableText;
033
034import com.opensymphony.workflow.loader.StepDescriptor;
035
036/**
037 * Provide the search model for Content consistency search
038 */
039public class ContentConstitencySearchModel implements Component, Serviceable
040{
041    /** The avalon role */
042    public static final String ROLE = ContentConstitencySearchModel.class.getName();
043    private WorkflowHelper _workflowHelper;
044    
045    public void service(ServiceManager manager) throws ServiceException
046    {
047        _workflowHelper = (WorkflowHelper) manager.lookup(WorkflowHelper.ROLE);
048    }
049    
050    /**
051     * Get the model for a content consistency search
052     * @return the model
053     */
054    @Callable
055    public Map<String, Object> getModel()
056    {
057        Map<String, Object> model = new HashMap<>();
058        
059        // Proxy configuration
060        model.put("searchMethodName", "searchResults");
061        model.put("searchRole", "org.ametys.cms.content.consistency.ContentConsistencySearcher");
062        
063        model.put("columns", getColumns());
064        
065        model.put("criteria", getCriteria());
066        
067        model.put("facets", getFacets());
068        
069        return model;
070    }
071    
072    /**
073     * Provide the list of column.
074     * Any column additional column must not be sortable as there info won't be present in the search result.
075     * @return a json description of the column
076     */
077    protected List<Map<String, Object>> getColumns()
078    {
079        // Columns configuration
080        List<Map<String, Object>> columns = new ArrayList<>();
081        columns.add(Map.of(
082                "id", ContentConsistencyResult.TITLE,
083                "label", new I18nizableText("plugin.cms", "PLUGINS_CMS_METADATA_TITLE_LABEL"),
084                "type", "string",
085                "multiple", false));
086        columns.add(Map.of(
087                "id", ContentConsistencyResult.CONTENT_TYPES,
088                "label", new I18nizableText("plugin.cms", "UITOOL_SEARCH_CONTENT_ALL_CONTENT_TYPE"),
089                "type", "string",
090                "multiple", true,
091                "renderer", "Ametys.plugins.cms.content.tool.GlobalContentConsistencyTool.renderContentType"));
092        columns.add(Map.of(
093                "id", ContentConsistencyResult.LAST_CONTRIBUTOR,
094                "label", new I18nizableText("plugin.cms", "UITOOL_SEARCH_CONTENT_AUTHOR"),
095                "type", "user",
096                "multiple", false,
097                "renderer", "Ametys.plugins.cms.search.SearchGridHelper.renderUser"));
098        columns.add(Map.of(
099                "id", ContentConsistencyResult.WORKFLOW_STEP,
100                "label", new I18nizableText("plugin.cms", "UITOOL_SEARCH_CONTENT_WORKFLOW_STEP"),
101                "type", "int",
102                "multiple", false,
103                "renderer", "Ametys.plugins.cms.search.SearchGridHelper.renderWorkflowStep",
104                "converter", "Ametys.plugins.cms.search.SearchGridHelper.convertWorkflowStep"));
105        columns.add(Map.of(
106                "id", ContentConsistencyResult.DATE,
107                "label", new I18nizableText("plugin.cms", "PLUGINS_CMS_GLOBAL_CONTENT_CONSISTENCY_CHECK_DATE"),
108                "type", "datetime",
109                "multiple", false));
110        columns.add(Map.of(
111                "id", ContentConsistencyResult.SUCCESS,
112                "label", new I18nizableText("plugin.cms", "PLUGINS_CMS_GLOBAL_CONTENT_CONSISTENCY_SUCCESS_COUNT"),
113                "hidden", true,
114                "type", "int",
115                "multiple", false));
116        columns.add(Map.of(
117                "id", ContentConsistencyResult.UNAUTHORIZED,
118                "label", new I18nizableText("plugin.cms", "PLUGINS_CMS_GLOBAL_CONTENT_CONSISTENCY_UNAUTHORIZED_COUNT"),
119                "type", "int",
120                "multiple", false));
121        columns.add(Map.of(
122                "id", ContentConsistencyResult.UNKNOWN,
123                "label", new I18nizableText("plugin.cms", "PLUGINS_CMS_GLOBAL_CONTENT_CONSISTENCY_UNKNOWN_COUNT"),
124                "type", "int",
125                "multiple", false));
126        columns.add(Map.of(
127                "id", ContentConsistencyResult.NOT_FOUND,
128                "label", new I18nizableText("plugin.cms", "PLUGINS_CMS_GLOBAL_CONTENT_CONSISTENCY_NOT_FOUND_COUNT"),
129                "type", "int",
130                "multiple", false));
131        columns.add(Map.of(
132                "id", ContentConsistencyResult.SERVER_ERROR,
133                "label", new I18nizableText("plugin.cms", "PLUGINS_CMS_GLOBAL_CONTENT_CONSISTENCY_SERVER_ERROR_COUNT"),
134                "type", "int",
135                "multiple", false));
136        return columns;
137    }
138    
139    /**
140     * Get the criteria for the search
141     * @return the JSON description of the criteria
142     */
143    protected Map<String, Object> getCriteria()
144    {
145        Map<String, Object> criteria = new LinkedHashMap<>(); // order is important here
146        criteria.put("title", Map.of(
147                "label", new I18nizableText("plugin.cms", "PLUGINS_CMS_METADATA_TITLE_LABEL"),
148                "description", new I18nizableText("plugin.cms", "PLUGINS_CMS_METADATA_TITLE_DESCRIPTION"),
149                "type", "STRING"
150                ));
151        
152        List<Map<String, Object>> workflowStep = new ArrayList<>();
153        workflowStep.add(Map.of("label", new I18nizableText("plugin.cms", "WIDGET_COMBOBOX_ALL_OPTIONS"), "value", 0));
154        for (Iterator iterator = _workflowHelper.getWorkflowDescriptor("content").getSteps().iterator(); iterator.hasNext();)
155        {
156            StepDescriptor step = (StepDescriptor) iterator.next();
157            workflowStep.add(Map.of("label", new I18nizableText(null, step.getName()), "value", step.getId()));
158        }
159
160        criteria.put("workflowStep", Map.of(
161                "label", new I18nizableText("plugin.cms", "UITOOL_SEARCH_CONTENT_WORKFLOW_STEP"),
162                "description", new I18nizableText("plugin.cms", "UITOOL_SEARCH_CONTENT_WORKFLOW_STEP"),
163                "type", "LONG",
164                "enumeration", workflowStep,
165                "default-value", 0 // - Tous -
166                ));
167        
168        Map<String, Object> ctype = new HashMap<>();
169        ctype.put("label", new I18nizableText("plugin.cms", "UITOOL_SEARCH_CONTENT_ALL_CONTENT_TYPE"));
170        ctype.put("description", new I18nizableText("plugin.cms", "UITOOL_SEARCH_CONTENT_ALL_CONTENT_TYPE"));
171        ctype.put("type", "STRING");
172        ctype.put("multiple", false);
173        ctype.put("enumeration", null);
174        ctype.put("widget", "edition.select-content-types");
175        ctype.put("widget-params", Map.of("emptyText", new I18nizableText("plugin.cms", "WIDGET_COMBOBOX_ALL_OPTIONS")));
176        criteria.put("contentTypes", ctype);
177        
178        criteria.put("contributor", Map.of(
179                "label", new I18nizableText("plugin.cms", "UITOOL_SEARCH_CONTENT_AUTHOR"),
180                "description", new I18nizableText("plugin.cms", "UITOOL_SEARCH_CONTENT_AUTHOR"),
181                "type", "USER"
182                ));
183        return criteria;
184    }
185    
186    /**
187     * Get the facets for the search
188     * @return the JSON description of the facets
189     */
190    protected List<Map<String, Object>> getFacets()
191    {
192        List<Map<String, Object>> facets = new ArrayList<>();
193        facets.add(Map.of(
194                "name", ContentConsistencyResult.LAST_CONTRIBUTOR,
195                "label", new I18nizableText("plugin.cms", "UITOOL_SEARCH_CONTENT_AUTHOR"),
196                "type", "criterion",
197                "children", new ArrayList())); // needs to be mutable to add the value later
198        facets.add(Map.of(
199                "name", ContentConsistencyResult.WORKFLOW_STEP,
200                "label", new I18nizableText("plugin.cms", "UITOOL_SEARCH_CONTENT_WORKFLOW_STEP"),
201                "type", "criterion",
202                "children", new ArrayList())); // needs to be mutable to add the value later
203        facets.add(Map.of(
204                "name", ContentConsistencyResult.CONTENT_TYPES,
205                "label", new I18nizableText("plugin.cms", "UITOOL_SEARCH_CONTENT_ALL_CONTENT_TYPE"),
206                "type", "criterion",
207                "children", new ArrayList())); // needs to be mutable to add the value later
208        return facets;
209    }
210}