001/* 002 * (C) Copyright 2010 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Anahide Tchertchian 016 */ 017package org.nuxeo.ecm.platform.forms.layout.api.impl; 018 019import java.io.Serializable; 020import java.util.ArrayList; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024 025import org.nuxeo.ecm.platform.forms.layout.api.BuiltinModes; 026import org.nuxeo.ecm.platform.forms.layout.api.LayoutDefinition; 027import org.nuxeo.ecm.platform.forms.layout.api.LayoutRowDefinition; 028import org.nuxeo.ecm.platform.forms.layout.api.RenderingInfo; 029import org.nuxeo.ecm.platform.forms.layout.api.WidgetDefinition; 030import org.nuxeo.ecm.platform.forms.layout.api.WidgetReference; 031 032/** 033 * Default implementation for a layout definition. 034 * <p> 035 * Useful to compute layouts independently from the layout service. 036 * 037 * @author Anahide Tchertchian 038 * @since 5.4 039 */ 040public class LayoutDefinitionImpl implements LayoutDefinition { 041 042 private static final long serialVersionUID = 1L; 043 044 protected String name; 045 046 protected String type; 047 048 protected String typeCategory; 049 050 protected Map<String, Map<String, Serializable>> properties; 051 052 protected Map<String, String> templates; 053 054 protected LayoutRowDefinition[] rows; 055 056 protected Map<String, WidgetDefinition> widgets; 057 058 protected Map<String, List<RenderingInfo>> renderingInfos; 059 060 protected Integer columns; 061 062 protected List<String> aliases; 063 064 protected boolean dynamic = false; 065 066 // needed by GWT serialization 067 protected LayoutDefinitionImpl() { 068 super(); 069 } 070 071 public LayoutDefinitionImpl(String name, String template, WidgetDefinition widgetDefinition) { 072 super(); 073 this.name = name; 074 this.properties = null; 075 this.templates = new HashMap<String, String>(); 076 if (template != null) { 077 this.templates.put(BuiltinModes.ANY, template); 078 } 079 this.widgets = new HashMap<String, WidgetDefinition>(); 080 if (widgetDefinition != null) { 081 this.widgets.put(widgetDefinition.getName(), widgetDefinition); 082 this.rows = new LayoutRowDefinition[] { new LayoutRowDefinitionImpl(null, widgetDefinition.getName()) }; 083 } else { 084 this.rows = new LayoutRowDefinition[0]; 085 } 086 } 087 088 public LayoutDefinitionImpl(String name, Map<String, Map<String, Serializable>> properties, 089 Map<String, String> templates, List<LayoutRowDefinition> rows, List<WidgetDefinition> widgetDefinitions) { 090 super(); 091 this.name = name; 092 this.properties = properties; 093 this.templates = templates; 094 if (rows == null) { 095 this.rows = new LayoutRowDefinition[0]; 096 } else { 097 this.rows = rows.toArray(new LayoutRowDefinition[0]); 098 } 099 this.widgets = new HashMap<String, WidgetDefinition>(); 100 if (widgetDefinitions != null) { 101 for (WidgetDefinition widgetDef : widgetDefinitions) { 102 this.widgets.put(widgetDef.getName(), widgetDef); 103 } 104 } 105 } 106 107 public LayoutDefinitionImpl(String name, Map<String, Map<String, Serializable>> properties, 108 Map<String, String> templates, LayoutRowDefinition[] rows, Map<String, WidgetDefinition> widgets) { 109 super(); 110 this.name = name; 111 this.properties = properties; 112 this.templates = templates; 113 this.rows = rows; 114 this.widgets = widgets; 115 } 116 117 @Override 118 public int getColumns() { 119 if (columns == null) { 120 // compute it 121 columns = new Integer(0); 122 LayoutRowDefinition[] rows = getRows(); 123 for (LayoutRowDefinition def : rows) { 124 int current = def.getWidgetReferences().length; 125 if (current > columns.intValue()) { 126 columns = new Integer(current); 127 } 128 } 129 } 130 return columns.intValue(); 131 } 132 133 @Override 134 public String getName() { 135 return name; 136 } 137 138 public void setName(String name) { 139 this.name = name; 140 } 141 142 /** 143 * @since 6.0 144 */ 145 public String getType() { 146 return type; 147 } 148 149 /** 150 * @since 6.0 151 */ 152 public void setType(String type) { 153 this.type = type; 154 } 155 156 /** 157 * @since 6.0 158 */ 159 public String getTypeCategory() { 160 return typeCategory; 161 } 162 163 /** 164 * @since 6.0 165 */ 166 public void setTypeCategory(String typeCategory) { 167 this.typeCategory = typeCategory; 168 } 169 170 @Override 171 public Map<String, Serializable> getProperties(String layoutMode) { 172 return WidgetDefinitionImpl.getProperties(properties, layoutMode); 173 } 174 175 @Override 176 public Map<String, Map<String, Serializable>> getProperties() { 177 return properties; 178 } 179 180 public void setProperties(Map<String, Map<String, Serializable>> properties) { 181 this.properties = properties; 182 } 183 184 @Override 185 public LayoutRowDefinition[] getRows() { 186 return rows; 187 } 188 189 public void setRows(LayoutRowDefinition[] rows) { 190 this.rows = rows; 191 } 192 193 /** 194 * @since 6.0 195 */ 196 public static String getTemplate(Map<String, String> templates, String mode) { 197 if (templates != null) { 198 String template = templates.get(mode); 199 if (template == null) { 200 template = templates.get(BuiltinModes.ANY); 201 } 202 return template; 203 } 204 return null; 205 } 206 207 @Override 208 public String getTemplate(String mode) { 209 return getTemplate(templates, mode); 210 } 211 212 @Override 213 public Map<String, String> getTemplates() { 214 return templates; 215 } 216 217 public void setTemplates(Map<String, String> templates) { 218 this.templates = templates; 219 } 220 221 @Override 222 public WidgetDefinition getWidgetDefinition(String name) { 223 if (widgets != null) { 224 return widgets.get(name); 225 } 226 return null; 227 } 228 229 @Override 230 public Map<String, List<RenderingInfo>> getRenderingInfos() { 231 return renderingInfos; 232 } 233 234 public void setRenderingInfos(Map<String, List<RenderingInfo>> renderingInfos) { 235 this.renderingInfos = renderingInfos; 236 } 237 238 @Override 239 public List<RenderingInfo> getRenderingInfos(String mode) { 240 return WidgetDefinitionImpl.getRenderingInfos(renderingInfos, mode); 241 } 242 243 public boolean isEmpty() { 244 LayoutRowDefinition[] rows = getRows(); 245 if (rows == null) { 246 return true; 247 } 248 for (LayoutRowDefinition row : rows) { 249 WidgetReference[] refs = row.getWidgetReferences(); 250 if (refs != null) { 251 for (WidgetReference ref : refs) { 252 if (ref.getName() != null && !ref.getName().isEmpty()) { 253 return false; 254 } 255 } 256 } 257 } 258 return true; 259 } 260 261 @Override 262 public List<String> getAliases() { 263 return aliases; 264 } 265 266 public void setAliases(List<String> aliases) { 267 this.aliases = aliases; 268 } 269 270 public boolean isDynamic() { 271 return dynamic; 272 } 273 274 public void setDynamic(boolean dynamic) { 275 this.dynamic = dynamic; 276 } 277 278 @Override 279 public LayoutDefinition clone() { 280 Map<String, Map<String, Serializable>> cprops = null; 281 if (properties != null) { 282 cprops = new HashMap<String, Map<String, Serializable>>(); 283 for (Map.Entry<String, Map<String, Serializable>> entry : properties.entrySet()) { 284 Map<String, Serializable> subProps = entry.getValue(); 285 Map<String, Serializable> csubProps = null; 286 if (subProps != null) { 287 csubProps = new HashMap<String, Serializable>(); 288 csubProps.putAll(subProps); 289 } 290 cprops.put(entry.getKey(), csubProps); 291 } 292 } 293 Map<String, String> ctemplates = null; 294 if (templates != null) { 295 ctemplates = new HashMap<String, String>(); 296 ctemplates.putAll(templates); 297 } 298 LayoutRowDefinition[] crows = null; 299 if (rows != null) { 300 crows = new LayoutRowDefinition[rows.length]; 301 for (int i = 0; i < rows.length; i++) { 302 crows[i] = rows[i].clone(); 303 } 304 } 305 Map<String, WidgetDefinition> cwidgets = null; 306 if (widgets != null) { 307 cwidgets = new HashMap<String, WidgetDefinition>(); 308 for (Map.Entry<String, WidgetDefinition> entry : widgets.entrySet()) { 309 WidgetDefinition w = entry.getValue(); 310 if (w != null) { 311 w = w.clone(); 312 } 313 cwidgets.put(entry.getKey(), w); 314 } 315 } 316 Map<String, List<RenderingInfo>> crenderingInfos = null; 317 if (renderingInfos != null) { 318 crenderingInfos = new HashMap<String, List<RenderingInfo>>(); 319 for (Map.Entry<String, List<RenderingInfo>> item : renderingInfos.entrySet()) { 320 List<RenderingInfo> infos = item.getValue(); 321 List<RenderingInfo> clonedInfos = null; 322 if (infos != null) { 323 clonedInfos = new ArrayList<RenderingInfo>(); 324 for (RenderingInfo info : infos) { 325 clonedInfos.add(info.clone()); 326 } 327 } 328 crenderingInfos.put(item.getKey(), clonedInfos); 329 } 330 } 331 LayoutDefinitionImpl clone = new LayoutDefinitionImpl(name, cprops, ctemplates, crows, cwidgets); 332 clone.setRenderingInfos(crenderingInfos); 333 clone.setType(type); 334 clone.setTypeCategory(typeCategory); 335 if (aliases != null) { 336 clone.setAliases(new ArrayList<String>(aliases)); 337 } 338 clone.setDynamic(dynamic); 339 return clone; 340 } 341 342 /** 343 * @since 7.2 344 */ 345 @Override 346 public boolean equals(Object obj) { 347 if (!(obj instanceof LayoutDefinitionImpl)) { 348 return false; 349 } 350 if (obj == this) { 351 return true; 352 } 353 LayoutDefinitionImpl ld = (LayoutDefinitionImpl) obj; 354 return new EqualsBuilder().append(name, ld.name).append(type, ld.type).append(typeCategory, ld.typeCategory).append( 355 properties, ld.properties).append(templates, ld.templates).append(rows, ld.rows).append(widgets, 356 ld.widgets).append(renderingInfos, ld.renderingInfos).append(aliases, ld.aliases).append(dynamic, 357 ld.dynamic).isEquals(); 358 } 359 360}