001/* 002 * (C) Copyright 2011 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.theme.styling.service.descriptors; 020 021import java.io.Serializable; 022import java.util.ArrayList; 023import java.util.List; 024 025import org.apache.commons.lang.builder.EqualsBuilder; 026import org.nuxeo.common.xmap.annotation.XNode; 027import org.nuxeo.common.xmap.annotation.XNodeList; 028import org.nuxeo.common.xmap.annotation.XObject; 029 030/** 031 * A flavor represents the set of information that can be used to switch the theme styling on a given page. 032 * <p> 033 * It holds presets that can be referenced in CSS files, as well as logo information. It can extend another flavor, in 034 * case it will its logo and presets. The name and label are not inherited. 035 * <p> 036 * At registration, presets and log information are merged of a previous contribution with the same name already held 037 * that kind of information. When emptying the list of presets. 038 * 039 * @since 5.5 040 */ 041@XObject("flavor") 042public class FlavorDescriptor implements Serializable { 043 044 private static final long serialVersionUID = 1L; 045 046 @XNode("@name") 047 String name; 048 049 @XNode("label") 050 String label; 051 052 @XNode("@extends") 053 String extendsFlavor; 054 055 @XNode("logo") 056 LogoDescriptor logo; 057 058 @XNode("palettePreview") 059 PalettePreview palettePreview; 060 061 /** 062 * @since 7.4 063 */ 064 @XNode("sass@append") 065 boolean appendSass; 066 067 @XNode("presetsList@append") 068 boolean appendPresets; 069 070 /** 071 * @since 7.4 072 */ 073 @XNodeList(value = "sass/import", type = ArrayList.class, componentType = SassImport.class) 074 List<SassImport> sassImports; 075 076 @XNodeList(value = "presetsList/presets", type = ArrayList.class, componentType = FlavorPresets.class) 077 List<FlavorPresets> presets; 078 079 /** 080 * @since 7.4 081 */ 082 @XNodeList(value = "links/icon", type = ArrayList.class, componentType = IconDescriptor.class) 083 List<IconDescriptor> favicons; 084 085 @Override 086 public FlavorDescriptor clone() { 087 FlavorDescriptor clone = new FlavorDescriptor(); 088 clone.setName(getName()); 089 clone.setLabel(getLabel()); 090 LogoDescriptor logo = getLogo(); 091 if (logo != null) { 092 clone.setLogo(logo.clone()); 093 } 094 PalettePreview pp = getPalettePreview(); 095 if (pp != null) { 096 clone.setPalettePreview(pp.clone()); 097 } 098 clone.setExtendsFlavor(getExtendsFlavor()); 099 clone.setAppendPresets(getAppendPresets()); 100 List<FlavorPresets> presets = getPresets(); 101 if (presets != null) { 102 List<FlavorPresets> newPresets = new ArrayList<FlavorPresets>(); 103 for (FlavorPresets item : presets) { 104 newPresets.add(item.clone()); 105 } 106 clone.setPresets(newPresets); 107 } 108 clone.setAppendSass(getAppendSass()); 109 List<SassImport> sassVariables = getSassImports(); 110 if (sassVariables != null) { 111 List<SassImport> cSassVariables = new ArrayList<SassImport>(); 112 for (SassImport var : sassVariables) { 113 cSassVariables.add(var.clone()); 114 } 115 clone.setSassImports(cSassVariables); 116 } 117 List<IconDescriptor> favicons = getFavicons(); 118 if (favicons != null) { 119 List<IconDescriptor> icons = new ArrayList<IconDescriptor>(); 120 for (IconDescriptor icon : favicons) { 121 icons.add(icon.clone()); 122 } 123 clone.setFavicons(icons); 124 } 125 return clone; 126 } 127 128 @Override 129 public boolean equals(Object obj) { 130 if (!(obj instanceof FlavorDescriptor)) { 131 return false; 132 } 133 if (obj == this) { 134 return true; 135 } 136 FlavorDescriptor f = (FlavorDescriptor) obj; 137 return new EqualsBuilder().append(name, f.name).append(label, f.label).append(extendsFlavor, 138 f.extendsFlavor).append(logo, f.logo).append(palettePreview, f.palettePreview).append(appendPresets, 139 f.appendPresets).append(presets, f.presets).append(appendSass, f.appendSass).append(sassImports, 140 f.sassImports).append(favicons, f.favicons).isEquals(); 141 } 142 143 public boolean getAppendPresets() { 144 return appendPresets; 145 } 146 147 /** 148 * @since 7.4 149 */ 150 public boolean getAppendSass() { 151 return appendSass; 152 } 153 154 public String getExtendsFlavor() { 155 return extendsFlavor; 156 } 157 158 /** 159 * @since 7.4 160 */ 161 public List<IconDescriptor> getFavicons() { 162 return favicons; 163 } 164 165 public String getLabel() { 166 return label; 167 } 168 169 public LogoDescriptor getLogo() { 170 return logo; 171 } 172 173 public String getName() { 174 return name; 175 } 176 177 public PalettePreview getPalettePreview() { 178 return palettePreview; 179 } 180 181 public List<FlavorPresets> getPresets() { 182 return presets; 183 } 184 185 /** 186 * @since 7.4 187 */ 188 public List<SassImport> getSassImports() { 189 return sassImports; 190 } 191 192 @Override 193 public int hashCode() { 194 final int prime = 31; 195 int result = 1; 196 result = prime * result + (appendPresets ? 1231 : 1237); 197 result = prime * result + (appendSass ? 1231 : 1237); 198 result = prime * result + ((extendsFlavor == null) ? 0 : extendsFlavor.hashCode()); 199 result = prime * result + ((favicons == null) ? 0 : favicons.hashCode()); 200 result = prime * result + ((label == null) ? 0 : label.hashCode()); 201 result = prime * result + ((logo == null) ? 0 : logo.hashCode()); 202 result = prime * result + ((name == null) ? 0 : name.hashCode()); 203 result = prime * result + ((palettePreview == null) ? 0 : palettePreview.hashCode()); 204 result = prime * result + ((presets == null) ? 0 : presets.hashCode()); 205 result = prime * result + ((sassImports == null) ? 0 : sassImports.hashCode()); 206 return result; 207 } 208 209 public void merge(FlavorDescriptor src) { 210 String newExtend = src.getExtendsFlavor(); 211 if (newExtend != null) { 212 setExtendsFlavor(newExtend); 213 } 214 String newLabel = src.getLabel(); 215 if (newLabel != null) { 216 setLabel(newLabel); 217 } 218 LogoDescriptor logo = src.getLogo(); 219 if (logo != null) { 220 LogoDescriptor newLogo = getLogo(); 221 if (newLogo == null) { 222 newLogo = logo.clone(); 223 } else { 224 // merge logo info 225 if (logo.getHeight() != null) { 226 newLogo.setHeight(logo.getHeight()); 227 } 228 if (logo.getWidth() != null) { 229 newLogo.setWidth(logo.getWidth()); 230 } 231 if (logo.getTitle() != null) { 232 newLogo.setTitle(logo.getTitle()); 233 } 234 if (logo.getPath() != null) { 235 newLogo.setPath(logo.getPath()); 236 } 237 } 238 setLogo(newLogo); 239 } 240 PalettePreview pp = src.getPalettePreview(); 241 if (pp != null) { 242 setPalettePreview(pp); 243 } 244 245 List<FlavorPresets> newPresets = src.getPresets(); 246 if (newPresets != null) { 247 List<FlavorPresets> merged = new ArrayList<FlavorPresets>(); 248 merged.addAll(newPresets); 249 boolean keepOld = src.getAppendPresets() || (newPresets.isEmpty() && !src.getAppendPresets()); 250 if (keepOld) { 251 // add back old contributions 252 List<FlavorPresets> oldPresets = getPresets(); 253 if (oldPresets != null) { 254 merged.addAll(0, oldPresets); 255 } 256 } 257 setPresets(merged); 258 } 259 260 List<SassImport> newSassImports = src.getSassImports(); 261 if (newSassImports != null) { 262 List<SassImport> merged = new ArrayList<SassImport>(); 263 merged.addAll(newSassImports); 264 boolean keepOld = src.getAppendSass() || (newSassImports.isEmpty() && !src.getAppendSass()); 265 if (keepOld) { 266 // add back old contributions 267 List<SassImport> oldSassImports = getSassImports(); 268 if (oldSassImports != null) { 269 merged.addAll(0, oldSassImports); 270 } 271 } 272 setSassImports(merged); 273 } 274 275 List<IconDescriptor> newFavicons = src.getFavicons(); 276 if (newFavicons != null && !newFavicons.isEmpty()) { 277 setFavicons(newFavicons); 278 } 279 280 } 281 282 public void setAppendPresets(boolean appendPresets) { 283 this.appendPresets = appendPresets; 284 } 285 286 /** 287 * @since 7.4 288 */ 289 public void setAppendSass(boolean appendSass) { 290 this.appendSass = appendSass; 291 } 292 293 public void setExtendsFlavor(String extendsFlavor) { 294 this.extendsFlavor = extendsFlavor; 295 } 296 297 /** 298 * @since 7.4 299 */ 300 public void setFavicons(List<IconDescriptor> favicons) { 301 this.favicons = favicons; 302 } 303 304 public void setLabel(String label) { 305 this.label = label; 306 } 307 308 public void setLogo(LogoDescriptor logo) { 309 this.logo = logo; 310 } 311 312 public void setName(String name) { 313 this.name = name; 314 } 315 316 public void setPalettePreview(PalettePreview palettePreview) { 317 this.palettePreview = palettePreview; 318 } 319 320 public void setPresets(List<FlavorPresets> presets) { 321 this.presets = presets; 322 } 323 324 /** 325 * @since 7.4 326 */ 327 public void setSassImports(List<SassImport> sassImports) { 328 this.sassImports = sassImports; 329 } 330 331}