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