001/*
002 *  Copyright 2018 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.runtime.model;
017
018import java.util.ArrayList;
019import java.util.Collections;
020import java.util.LinkedHashMap;
021import java.util.List;
022import java.util.Map;
023
024import org.apache.cocoon.ProcessingException;
025
026import org.ametys.runtime.i18n.I18nizableText;
027import org.ametys.runtime.util.ModifiableLabelable;
028
029/**
030 * View of items
031 */
032public class View implements ViewItemContainer, ModifiableLabelable
033{
034    private String _name;
035    private I18nizableText _label;
036    private I18nizableText _description;
037    private String _iconGlyph;
038    private String _iconDecorator;
039    private String _smallIcon;
040    private String _mediumIcon;
041    private String _largeIcon;
042    
043    private List<ViewItem> _items = new ArrayList<>();
044    
045    /**
046     * Default constructor
047     */
048    public View()
049    {
050    }
051    
052    /**
053     * Creates a view with the given items
054     * @param model the model containing items definitions
055     * @param itemPaths the paths of the items to put in the view
056     */
057    public View(Model model, String... itemPaths)
058    {
059        this(model, true, itemPaths);
060    }
061    
062    /**
063     * Creates a view with the given items
064     * @param model the model containing items definitions
065     * @param recursive if true, will create view items for groups children
066     * @param itemPaths the paths of the items to put in the view
067     */
068    public View(Model model, boolean recursive, String... itemPaths)
069    {
070        for (String itemPath : itemPaths)
071        {
072            if (model.hasModelItem(itemPath))
073            {
074                ModelItem definition = model.getModelItem(itemPath);
075                addViewItem(_getViewItemFromDefinition(definition, recursive));
076            }
077            else
078            {
079                throw new IllegalArgumentException("Item " + itemPath + "not found in " + model.getClass() + " model: " + model.toString());
080            }
081        }
082    }
083
084    private ViewItem _getViewItemFromDefinition(ModelItem definition, Boolean recursive)
085    {
086        if (definition instanceof ModelItemGroup)
087        {
088            ModelViewItemGroup modelViewItemGroup = new ModelViewItemGroup();
089            modelViewItemGroup.setDefinition((ModelItemGroup) definition);
090            
091            if (recursive)
092            {
093                List<ModelItem> children = ((ModelItemGroup) definition).getChildren();
094                for (ModelItem child : children)
095                {
096                    modelViewItemGroup.addViewItem(_getViewItemFromDefinition(child, recursive));
097                }
098            }
099            
100            return modelViewItemGroup;
101        }
102        
103        ViewElement viewElement = new ViewElement();
104        viewElement.setDefinition((ElementDefinition) definition);
105        return viewElement;
106    }
107
108    public String getName()
109    {
110        return _name;
111    }
112
113    public void setName(String name)
114    {
115        _name = name;
116    }
117    
118    public I18nizableText getLabel()
119    {
120        return _label;
121    }
122
123    public void setLabel(I18nizableText label)
124    {
125        _label = label;
126    }
127    
128    public I18nizableText getDescription()
129    {
130        return _description;
131    }
132    
133    public void setDescription(I18nizableText description)
134    {
135        _description = description;
136    }
137    
138    /**
139     * Retrieves the CSS class to use for glyph icon
140     * @return the glyph name.
141     */
142    public String getIconGlyph()
143    {
144        return _iconGlyph;
145    }
146    
147    /**
148     * Set the CSS class to use for glyph icon
149     * @param iconGlyph the glyph name.
150     */
151    public void setIconGlyph(String iconGlyph)
152    {
153        _iconGlyph = iconGlyph;
154    }
155    
156    /**
157     * Retrieves the CSS class to use for decorator above the main icon
158     * @return the glyph name.
159     */
160    public String getIconDecorator()
161    {
162        return _iconDecorator;
163    }
164    
165    /**
166     * Set the CSS class to use for decorator above the main icon
167     * @param iconDecorator the glyph name.
168     */
169    public void setIconDecorator(String iconDecorator)
170    {
171        _iconDecorator = iconDecorator;
172    }
173    
174    /**
175     * Retrieves the URL of the small icon without the context path.
176     * @return the icon URL for the small image 16x16.
177     */
178    public String getSmallIcon()
179    {
180        return _smallIcon;
181    }
182    
183    /**
184     * Set the URL of the small icon.
185     * @param smallIcon the URL of the small icon, without the context path.
186     */
187    public void setSmallIcon(String smallIcon)
188    {
189        _smallIcon = smallIcon;
190    }
191    
192    /**
193     * Retrieves the URL of the small icon without the context path.
194     * @return the icon URL for the medium sized image 32x32.
195     */
196    public String getMediumIcon()
197    {
198        return _mediumIcon;
199    }
200    
201    /**
202     * Set the URL of the medium icon.
203     * @param mediumIcon the URL of the medium icon, without the context path.
204     */
205    public void setMediumIcon(String mediumIcon)
206    {
207        _mediumIcon = mediumIcon;
208    }
209    
210    /**
211     * Retrieves the URL of the small icon without the context path.
212     * @return the icon URL for the large image 48x48.
213     */
214    public String getLargeIcon()
215    {
216        return _largeIcon;
217    }
218    
219    /**
220     * Set the URL of the large icon.
221     * @param largeIcon the URL of the large icon, without the context path.
222     */
223    public void setLargeIcon(String largeIcon)
224    {
225        _largeIcon = largeIcon;
226    }
227    
228    public List<ViewItem> getViewItems()
229    {
230        return Collections.unmodifiableList(this._items);
231    }
232    
233    public boolean hasViewItem(String itemName)
234    {
235        return ViewHelper.hasViewItem(this, itemName);
236    }
237    
238    public void addViewItem(ViewItem item)
239    {
240        _items.add(item);
241    }
242    
243    public void insertViewItem(ViewItem item, int index)
244    {
245        if (index >= 0 && index < _items.size())
246        {
247            _items.add(index, item);
248        }
249        else
250        {
251            throw new IllegalArgumentException("Unable to insert an item at index " + index + ". This group contains " + _items.size() + "items.");
252        }
253    }
254
255    /**
256     * Converts the view in a JSON map
257     * @return The view as a JSON map
258     * @throws ProcessingException If an error occurs when converting the view
259     */
260    public Map<String, Object> toJSON() throws ProcessingException
261    {
262        Map<String, Object> result = new LinkedHashMap<>();
263        
264        result.put("name", getName());
265        result.put("label", getLabel());
266        result.put("description", getDescription());
267        
268        result.put("icon-glyph", getIconGlyph());
269        result.put("icon-decorator", getIconDecorator());
270        result.put("small-icon-path", getSmallIcon());
271        result.put("medium-icon-path", getMediumIcon());
272        result.put("large-icon-path", getLargeIcon());
273    
274        List<Map<String, Object>> groups = new ArrayList<>();
275        for (ViewItem item : getViewItems())
276        {
277            if (item instanceof ViewElement)
278            {
279                result.putAll(item.toJSON());
280            }
281            else
282            {
283                groups.add(item.toJSON());
284            }
285        }
286        
287        if (!groups.isEmpty())
288        {
289            result.put("groups", groups);
290        }
291        
292        return result;
293    }
294    
295    /**
296     * Include the given view to the current one.
297     * Add the items of the view to include if they are not already present in the current view
298     * @param viewToInclude the view to include
299     */
300    public void includeView(View viewToInclude)
301    {
302        ViewHelper.addViewContainerItems(this, viewToInclude, this);
303    }
304}