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