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.search.ui.model.impl;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022import java.util.Optional;
023
024import org.ametys.cms.search.ui.model.SearchUIColumn;
025import org.ametys.cms.search.ui.model.SearchUIColumnHelper;
026import org.ametys.plugins.repository.model.RepeaterDefinition;
027import org.ametys.plugins.repository.model.RepeaterViewItem;
028import org.ametys.runtime.model.DefinitionContext;
029import org.ametys.runtime.model.ModelViewItem;
030import org.ametys.runtime.model.ViewItem;
031import org.ametys.runtime.model.ViewItemAccessor;
032
033/**
034 * This class represents a result column
035 */
036public class RepeaterSearchUIColumn extends RepeaterViewItem implements SearchUIColumn<RepeaterDefinition>
037{
038    private int _width = -1;
039    private boolean _hidden;
040    private boolean _editable = true;
041    private boolean _sortable = true;
042    private boolean _allowSortOnMultipleJoin;
043    private Optional<String> _defaultSorter = Optional.empty();
044    private Optional<String> _renderer = Optional.empty();
045    private Optional<String> _converter = Optional.empty();
046    private String _name;
047    @Override
048    public void setName(String name)
049    {
050        _name = name;
051    }
052    
053    @Override
054    public String getName()
055    {
056        if (_name != null)
057        {
058            return _name;
059        }
060        return super.getName();
061    }
062
063    public int getWidth()
064    {
065        return _width > 0
066                ? _width
067                : SearchUIColumnHelper.getDefaultColumnWidth(this);
068    }
069    
070    public void setWidth (int width)
071    {
072        _width = width;
073    }
074    
075    public boolean isHidden()
076    {
077        return _hidden;
078    }
079    
080    public void setHidden (boolean hidden)
081    {
082        _hidden = hidden;
083    }
084    
085    public boolean isEditable()
086    {
087        return _editable && SearchUIColumnHelper.isEditionAllowed(this);
088    }
089    
090    public void setEditable (boolean editable)
091    {
092        _editable = editable;
093    }
094    
095    public boolean isSortable()
096    {
097        return _sortable && SearchUIColumnHelper.isSortAllowed(this);
098    }
099    
100    public void setSortable (boolean sortable)
101    {
102        _sortable = sortable;
103    }
104    
105    public boolean allowSortOnMultipleJoin()
106    {
107        return _allowSortOnMultipleJoin;
108    }
109    
110    public void setAllowSortOnMultipleJoin(boolean allowSortOnMultipleJoin)
111    {
112        _allowSortOnMultipleJoin = allowSortOnMultipleJoin;
113    }
114    
115    public String getDefaultSorter()
116    {
117        return isSortable()
118                ? _defaultSorter.orElse(null)
119                : null;
120    }
121    
122    public void setDefaultSorter(Optional<String> defaultSorter)
123    {
124        _defaultSorter = defaultSorter;
125    }
126    
127    public String getRenderer()
128    {
129        return _renderer
130                .orElse("Ametys.plugins.cms.search.SearchGridHelper.renderRepeater");
131    }
132    
133    public void setRenderer(Optional<String> renderer)
134    {
135        this._renderer = renderer;
136    }
137    
138    public String getConverter()
139    {
140        return _converter
141                .orElse("Ametys.plugins.cms.search.SearchGridHelper.convertRepeater");
142    }
143    
144    public void setConverter(Optional<String> converter)
145    {
146        this._converter = converter;
147    }
148    
149    @Override
150    public RepeaterSearchUIColumn createInstance()
151    {
152        return new RepeaterSearchUIColumn();
153    }
154
155    @Override
156    public Map<String, Object> toJSON(DefinitionContext context)
157    {
158        Map<String, Object> json = super.toJSON(context);
159
160        if (!json.isEmpty())
161        {
162            json.putAll(SearchUIColumnHelper.columnPropertiesToJSON(this));
163        }
164        return json;
165    }
166    
167    @Override
168    protected Map<String, Object> _childrenToJSON(DefinitionContext context)
169    {
170        Map<String, Object> result = new HashMap<>();
171        List<Map<String, Object>> subColumnsAsJSON = new ArrayList<>();
172        
173        for (ModelViewItem subColumn : _getSubColumns(this))
174        {
175            subColumnsAsJSON.add(subColumn.toJSON(context));
176        }
177        
178        result.put("columns", subColumnsAsJSON);
179        return result;
180    }
181    
182    private List<ModelViewItem> _getSubColumns(ViewItemAccessor viewItemAccessor)
183    {
184        List<ModelViewItem> subColumns = new ArrayList<>();
185        
186        org.ametys.plugins.repository.model.ViewHelper.visitView(viewItemAccessor,
187            (element, definition) -> {
188                // attribute
189                subColumns.add(element);
190            },
191            (group, definition) -> {
192                // composite
193                // CMS-10740 - explode composite to have all its children at first level
194                subColumns.addAll(_getSubColumns(group));
195            },
196            (group, definition) -> {
197                // repeater
198                subColumns.add(group);
199            },
200            group -> {
201                // group
202                subColumns.addAll(_getSubColumns(group));
203            }
204        );
205        
206        return subColumns;
207    }
208    
209    @Override
210    public void copyTo(ViewItem item)
211    {
212        super.copyTo(item);
213        
214        assert item instanceof RepeaterSearchUIColumn;
215        RepeaterSearchUIColumn column = (RepeaterSearchUIColumn) item;
216        column.setName(_name);
217        column.setWidth(_width);
218        column.setHidden(_hidden);
219        
220        column.setEditable(_editable);
221        column.setSortable(_sortable);
222        column.setAllowSortOnMultipleJoin(_allowSortOnMultipleJoin);
223        column.setDefaultSorter(_defaultSorter);
224        
225        column.setRenderer(_renderer);
226        column.setConverter(_converter);
227    }
228}