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<>(); 079 if (template != null) { 080 this.templates.put(BuiltinModes.ANY, template); 081 } 082 this.widgets = new HashMap<>(); 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<>(); 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 = Integer.valueOf(0); 125 LayoutRowDefinition[] rows = getRows(); 126 for (LayoutRowDefinition def : rows) { 127 int current = def.getWidgetReferences().length; 128 if (current > columns.intValue()) { 129 columns = Integer.valueOf(current); 130 } 131 } 132 } 133 return columns.intValue(); 134 } 135 136 @Override 137 public String getName() { 138 return name; 139 } 140 141 @Override 142 public void setName(String name) { 143 this.name = name; 144 } 145 146 /** 147 * @since 6.0 148 */ 149 @Override 150 public String getType() { 151 return type; 152 } 153 154 /** 155 * @since 6.0 156 */ 157 public void setType(String type) { 158 this.type = type; 159 } 160 161 /** 162 * @since 6.0 163 */ 164 @Override 165 public String getTypeCategory() { 166 return typeCategory; 167 } 168 169 /** 170 * @since 6.0 171 */ 172 public void setTypeCategory(String typeCategory) { 173 this.typeCategory = typeCategory; 174 } 175 176 @Override 177 public Map<String, Serializable> getProperties(String layoutMode) { 178 return WidgetDefinitionImpl.getProperties(properties, layoutMode); 179 } 180 181 @Override 182 public Map<String, Map<String, Serializable>> getProperties() { 183 return properties; 184 } 185 186 @Override 187 public void setProperties(Map<String, Map<String, Serializable>> properties) { 188 this.properties = properties; 189 } 190 191 @Override 192 public LayoutRowDefinition[] getRows() { 193 return rows; 194 } 195 196 @Override 197 public void setRows(LayoutRowDefinition[] rows) { 198 this.rows = rows; 199 } 200 201 /** 202 * @since 6.0 203 */ 204 public static String getTemplate(Map<String, String> templates, String mode) { 205 if (templates != null) { 206 String template = templates.get(mode); 207 if (template == null) { 208 template = templates.get(BuiltinModes.ANY); 209 } 210 return template; 211 } 212 return null; 213 } 214 215 @Override 216 public String getTemplate(String mode) { 217 return getTemplate(templates, mode); 218 } 219 220 @Override 221 public Map<String, String> getTemplates() { 222 return templates; 223 } 224 225 @Override 226 public void setTemplates(Map<String, String> templates) { 227 this.templates = templates; 228 } 229 230 @Override 231 public WidgetDefinition getWidgetDefinition(String name) { 232 if (widgets != null) { 233 return widgets.get(name); 234 } 235 return null; 236 } 237 238 @Override 239 public Map<String, WidgetDefinition> getWidgetDefinitions() { 240 return widgets; 241 } 242 243 @Override 244 public Map<String, List<RenderingInfo>> getRenderingInfos() { 245 return renderingInfos; 246 } 247 248 @Override 249 public void setRenderingInfos(Map<String, List<RenderingInfo>> renderingInfos) { 250 this.renderingInfos = renderingInfos; 251 } 252 253 @Override 254 public List<RenderingInfo> getRenderingInfos(String mode) { 255 return WidgetDefinitionImpl.getRenderingInfos(renderingInfos, mode); 256 } 257 258 @Override 259 public boolean isEmpty() { 260 LayoutRowDefinition[] rows = getRows(); 261 if (rows == null) { 262 return true; 263 } 264 for (LayoutRowDefinition row : rows) { 265 WidgetReference[] refs = row.getWidgetReferences(); 266 if (refs != null) { 267 for (WidgetReference ref : refs) { 268 if (ref.getName() != null && !ref.getName().isEmpty()) { 269 return false; 270 } 271 } 272 } 273 } 274 return true; 275 } 276 277 @Override 278 public List<String> getAliases() { 279 return aliases; 280 } 281 282 public void setAliases(List<String> aliases) { 283 this.aliases = aliases; 284 } 285 286 @Override 287 public boolean isDynamic() { 288 return dynamic; 289 } 290 291 public void setDynamic(boolean dynamic) { 292 this.dynamic = dynamic; 293 } 294 295 @Override 296 public LayoutDefinition clone() { 297 Map<String, Map<String, Serializable>> cprops = null; 298 if (properties != null) { 299 cprops = new HashMap<>(); 300 for (Map.Entry<String, Map<String, Serializable>> entry : properties.entrySet()) { 301 Map<String, Serializable> subProps = entry.getValue(); 302 Map<String, Serializable> csubProps = null; 303 if (subProps != null) { 304 csubProps = new HashMap<>(); 305 csubProps.putAll(subProps); 306 } 307 cprops.put(entry.getKey(), csubProps); 308 } 309 } 310 Map<String, String> ctemplates = null; 311 if (templates != null) { 312 ctemplates = new HashMap<>(); 313 ctemplates.putAll(templates); 314 } 315 LayoutRowDefinition[] crows = null; 316 if (rows != null) { 317 crows = new LayoutRowDefinition[rows.length]; 318 for (int i = 0; i < rows.length; i++) { 319 crows[i] = rows[i].clone(); 320 } 321 } 322 Map<String, WidgetDefinition> cwidgets = null; 323 if (widgets != null) { 324 cwidgets = new LinkedHashMap<>(); 325 for (Map.Entry<String, WidgetDefinition> entry : widgets.entrySet()) { 326 WidgetDefinition w = entry.getValue(); 327 if (w != null) { 328 w = w.clone(); 329 } 330 cwidgets.put(entry.getKey(), w); 331 } 332 } 333 Map<String, List<RenderingInfo>> crenderingInfos = null; 334 if (renderingInfos != null) { 335 crenderingInfos = new HashMap<>(); 336 for (Map.Entry<String, List<RenderingInfo>> item : renderingInfos.entrySet()) { 337 List<RenderingInfo> infos = item.getValue(); 338 List<RenderingInfo> clonedInfos = null; 339 if (infos != null) { 340 clonedInfos = new ArrayList<>(); 341 for (RenderingInfo info : infos) { 342 clonedInfos.add(info.clone()); 343 } 344 } 345 crenderingInfos.put(item.getKey(), clonedInfos); 346 } 347 } 348 LayoutDefinitionImpl clone = new LayoutDefinitionImpl(name, cprops, ctemplates, crows, cwidgets); 349 clone.setRenderingInfos(crenderingInfos); 350 clone.setType(type); 351 clone.setTypeCategory(typeCategory); 352 if (aliases != null) { 353 clone.setAliases(new ArrayList<>(aliases)); 354 } 355 clone.setDynamic(dynamic); 356 return clone; 357 } 358 359 /** 360 * @since 7.2 361 */ 362 @Override 363 public boolean equals(Object obj) { 364 if (!(obj instanceof LayoutDefinitionImpl)) { 365 return false; 366 } 367 if (obj == this) { 368 return true; 369 } 370 LayoutDefinitionImpl ld = (LayoutDefinitionImpl) obj; 371 return new EqualsBuilder().append(name, ld.name).append(type, ld.type).append(typeCategory, ld.typeCategory).append( 372 properties, ld.properties).append(templates, ld.templates).append(rows, ld.rows).append(widgets, 373 ld.widgets).append(renderingInfos, ld.renderingInfos).append(aliases, ld.aliases).append(dynamic, 374 ld.dynamic).isEquals(); 375 } 376 377}