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