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