001/* 002 * (C) Copyright 2011 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.theme.styling.service.descriptors; 018 019import java.util.ArrayList; 020import java.util.List; 021 022import org.apache.commons.lang.builder.EqualsBuilder; 023import org.nuxeo.common.xmap.annotation.XNode; 024import org.nuxeo.common.xmap.annotation.XNodeList; 025import org.nuxeo.common.xmap.annotation.XObject; 026import org.nuxeo.ecm.web.resources.api.ResourceBundle; 027import org.nuxeo.ecm.web.resources.api.ResourceType; 028import org.nuxeo.ecm.web.resources.core.ResourceBundleDescriptor; 029 030/** 031 * Descriptor to associate resources and flavors to a page. 032 * 033 * @since 7.4 034 */ 035@XObject("page") 036public class PageDescriptor { 037 038 public static final String RESOURCE_BUNDLE_PREFIX = "pageResourceBundle_"; 039 040 @XNode("@name") 041 String name; 042 043 /** 044 * @since 7.4 045 */ 046 @XNode("@charset") 047 String charset; 048 049 @XNode("defaultFlavor") 050 String defaultFlavor; 051 052 /** 053 * @deprecated since 7.4: use resources instead 054 */ 055 @Deprecated 056 @XNode("styles@append") 057 boolean appendStyles; 058 059 /** 060 * @deprecated since 7.4: use resources instead 061 */ 062 @Deprecated 063 @XNodeList(value = "styles/style", type = ArrayList.class, componentType = String.class) 064 List<String> styles; 065 066 @XNode("flavors@append") 067 boolean appendFlavors; 068 069 @XNodeList(value = "flavors/flavor", type = ArrayList.class, componentType = String.class) 070 List<String> flavors; 071 072 @XNode("resources@append") 073 boolean appendResources; 074 075 @XNodeList(value = "resources/resource", type = ArrayList.class, componentType = String.class) 076 List<String> resources; 077 078 /** 079 * @since 7.4 080 */ 081 @XNodeList(value = "resources/bundle", type = ArrayList.class, componentType = String.class) 082 List<String> bundles; 083 084 public String getName() { 085 return name; 086 } 087 088 public String getDefaultFlavor() { 089 return defaultFlavor; 090 } 091 092 public void setDefaultFlavor(String defaultFlavor) { 093 this.defaultFlavor = defaultFlavor; 094 } 095 096 /** 097 * @deprecated since 7.4: use resources instead 098 */ 099 public boolean getAppendStyles() { 100 return appendStyles; 101 } 102 103 /** 104 * @deprecated since 7.4: use resources instead 105 */ 106 public List<String> getStyles() { 107 return styles; 108 } 109 110 public boolean getAppendFlavors() { 111 return appendFlavors; 112 } 113 114 public List<String> getFlavors() { 115 return flavors; 116 } 117 118 public void setName(String name) { 119 this.name = name; 120 } 121 122 public void setStyles(List<String> styles) { 123 this.styles = styles; 124 } 125 126 public void setFlavors(List<String> flavors) { 127 this.flavors = flavors; 128 } 129 130 public boolean getAppendResources() { 131 return appendResources; 132 } 133 134 public boolean hasResources() { 135 return !getResources().isEmpty(); 136 } 137 138 public List<String> getResources() { 139 List<String> res = new ArrayList<String>(); 140 // BBB 141 if (styles != null) { 142 for (String style : styles) { 143 if (style == null) { 144 continue; 145 } 146 if (style.endsWith(ResourceType.css.name())) { 147 res.add(style); 148 } else { 149 res.add(style + "." + ResourceType.css.name()); 150 } 151 } 152 } 153 if (resources != null) { 154 res.addAll(resources); 155 } 156 return res; 157 } 158 159 public void setResources(List<String> resources) { 160 this.resources = resources; 161 } 162 163 public String getComputedResourceBundleName() { 164 if ("*".equals(getName())) { 165 return RESOURCE_BUNDLE_PREFIX + "*"; 166 } 167 return RESOURCE_BUNDLE_PREFIX + getName().replaceAll("[^a-zA-Z]+", "_"); 168 } 169 170 public ResourceBundle getComputedResourceBundle() { 171 if (hasResources()) { 172 ResourceBundleDescriptor bundle = new ResourceBundleDescriptor(); 173 bundle.setName(getComputedResourceBundleName()); 174 bundle.setResources(getResources()); 175 bundle.setAppend(getAppendResources()); 176 return bundle; 177 } 178 return null; 179 } 180 181 /** 182 * @since 7.4 183 */ 184 public List<String> getResourceBundles() { 185 List<String> all = new ArrayList<String>(); 186 if (bundles != null) { 187 all.addAll(bundles); 188 } 189 if (hasResources()) { 190 all.add(getComputedResourceBundleName()); 191 } 192 return all; 193 } 194 195 /** 196 * @since 7.4 197 */ 198 public void setResourceBundles(List<String> bundles) { 199 this.bundles = bundles; 200 } 201 202 public void setAppendStyles(boolean appendStyles) { 203 this.appendStyles = appendStyles; 204 } 205 206 public void setAppendFlavors(boolean appendFlavors) { 207 this.appendFlavors = appendFlavors; 208 } 209 210 public void setAppendResources(boolean appendResources) { 211 this.appendResources = appendResources; 212 } 213 214 /** 215 * @since 7.4 216 */ 217 public String getCharset() { 218 return charset; 219 } 220 221 /** 222 * @since 7.4 223 */ 224 public void setCharset(String charset) { 225 this.charset = charset; 226 } 227 228 public void merge(PageDescriptor src) { 229 String newFlavor = src.getDefaultFlavor(); 230 if (newFlavor != null) { 231 setDefaultFlavor(newFlavor); 232 } 233 234 String newCharset = src.getCharset(); 235 if (newCharset != null) { 236 setCharset(newCharset); 237 } 238 239 List<String> newStyles = src.getStyles(); 240 if (newStyles != null) { 241 List<String> merged = new ArrayList<String>(); 242 merged.addAll(newStyles); 243 boolean keepOld = src.getAppendStyles() || (newStyles.isEmpty() && !src.getAppendStyles()); 244 if (keepOld) { 245 // add back old contributions 246 List<String> oldStyles = getStyles(); 247 if (oldStyles != null) { 248 merged.addAll(0, oldStyles); 249 } 250 } 251 setStyles(merged); 252 } 253 254 List<String> newFlavors = src.getFlavors(); 255 if (newFlavors != null) { 256 List<String> merged = new ArrayList<String>(); 257 merged.addAll(newFlavors); 258 boolean keepOld = src.getAppendFlavors() || (newFlavors.isEmpty() && !src.getAppendFlavors()); 259 if (keepOld) { 260 // add back old contributions 261 List<String> oldFlavors = getFlavors(); 262 if (oldFlavors != null) { 263 merged.addAll(0, oldFlavors); 264 } 265 } 266 setFlavors(merged); 267 } 268 269 List<String> newResources = src.resources; 270 if (newResources != null) { 271 List<String> merged = new ArrayList<String>(); 272 merged.addAll(newResources); 273 boolean keepOld = src.getAppendResources() || (newResources.isEmpty() && !src.getAppendResources()); 274 if (keepOld) { 275 // add back old contributions 276 List<String> oldResources = resources; 277 if (oldResources != null) { 278 merged.addAll(0, oldResources); 279 } 280 } 281 setResources(merged); 282 } 283 284 List<String> newBundles = src.bundles; 285 if (newBundles != null) { 286 List<String> merged = new ArrayList<String>(); 287 merged.addAll(newBundles); 288 boolean keepOld = src.getAppendResources() || (newBundles.isEmpty() && !src.getAppendResources()); 289 if (keepOld) { 290 // add back old contributions 291 List<String> oldBundles = bundles; 292 if (oldBundles != null) { 293 merged.addAll(0, oldBundles); 294 } 295 } 296 setResourceBundles(merged); 297 } 298 } 299 300 @Override 301 public PageDescriptor clone() { 302 PageDescriptor clone = new PageDescriptor(); 303 clone.setName(getName()); 304 clone.setCharset(getCharset()); 305 clone.setDefaultFlavor(getDefaultFlavor()); 306 clone.setAppendStyles(getAppendStyles()); 307 List<String> styles = getStyles(); 308 if (styles != null) { 309 clone.setStyles(new ArrayList<String>(styles)); 310 } 311 clone.setAppendFlavors(getAppendFlavors()); 312 List<String> flavors = getFlavors(); 313 if (flavors != null) { 314 clone.setFlavors(new ArrayList<String>(flavors)); 315 } 316 clone.setAppendResources(getAppendResources()); 317 if (resources != null) { 318 clone.setResources(new ArrayList<String>(resources)); 319 } 320 if (bundles != null) { 321 clone.setResourceBundles(new ArrayList<String>(bundles)); 322 } 323 return clone; 324 } 325 326 @Override 327 public boolean equals(Object obj) { 328 if (!(obj instanceof PageDescriptor)) { 329 return false; 330 } 331 if (obj == this) { 332 return true; 333 } 334 PageDescriptor p = (PageDescriptor) obj; 335 return new EqualsBuilder().append(name, p.name).append(charset, p.charset).append(defaultFlavor, 336 p.defaultFlavor).append(appendStyles, p.appendStyles).append(styles, p.styles).append(appendFlavors, 337 p.appendFlavors).append(flavors, p.flavors).append(appendResources, p.appendResources).append( 338 resources, p.resources).append(bundles, p.bundles).isEquals(); 339 } 340 341}