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.lang3.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 @Deprecated 102 public boolean getAppendStyles() { 103 return appendStyles; 104 } 105 106 /** 107 * @deprecated since 7.4: use resources instead 108 */ 109 @Deprecated 110 public List<String> getStyles() { 111 return styles; 112 } 113 114 public boolean getAppendFlavors() { 115 return appendFlavors; 116 } 117 118 public List<String> getFlavors() { 119 return flavors; 120 } 121 122 public void setName(String name) { 123 this.name = name; 124 } 125 126 public void setStyles(List<String> styles) { 127 this.styles = styles; 128 } 129 130 public void setFlavors(List<String> flavors) { 131 this.flavors = flavors; 132 } 133 134 public boolean getAppendResources() { 135 return appendResources; 136 } 137 138 public boolean hasResources() { 139 return !getResources().isEmpty(); 140 } 141 142 public List<String> getResources() { 143 List<String> res = new ArrayList<>(); 144 // BBB 145 if (styles != null) { 146 for (String style : styles) { 147 if (style == null) { 148 continue; 149 } 150 if (style.endsWith(ResourceType.css.name())) { 151 res.add(style); 152 } else { 153 res.add(style + "." + ResourceType.css.name()); 154 } 155 } 156 } 157 if (resources != null) { 158 res.addAll(resources); 159 } 160 return res; 161 } 162 163 public void setResources(List<String> resources) { 164 this.resources = resources; 165 } 166 167 public String getComputedResourceBundleName() { 168 if ("*".equals(getName())) { 169 return RESOURCE_BUNDLE_PREFIX + "*"; 170 } 171 return RESOURCE_BUNDLE_PREFIX + getName().replaceAll("[^a-zA-Z]+", "_"); 172 } 173 174 public ResourceBundle getComputedResourceBundle() { 175 if (hasResources()) { 176 ResourceBundleDescriptor bundle = new ResourceBundleDescriptor(); 177 bundle.setName(getComputedResourceBundleName()); 178 bundle.setResources(getResources()); 179 bundle.setAppend(getAppendResources()); 180 return bundle; 181 } 182 return null; 183 } 184 185 /** 186 * @since 7.4 187 */ 188 public List<String> getResourceBundles() { 189 List<String> all = new ArrayList<>(); 190 if (bundles != null) { 191 all.addAll(bundles); 192 } 193 if (hasResources()) { 194 all.add(getComputedResourceBundleName()); 195 } 196 return all; 197 } 198 199 /** 200 * @since 7.4 201 */ 202 public void setResourceBundles(List<String> bundles) { 203 this.bundles = bundles; 204 } 205 206 public void setAppendStyles(boolean appendStyles) { 207 this.appendStyles = appendStyles; 208 } 209 210 public void setAppendFlavors(boolean appendFlavors) { 211 this.appendFlavors = appendFlavors; 212 } 213 214 public void setAppendResources(boolean appendResources) { 215 this.appendResources = appendResources; 216 } 217 218 /** 219 * @since 7.4 220 */ 221 public String getCharset() { 222 return charset; 223 } 224 225 /** 226 * @since 7.4 227 */ 228 public void setCharset(String charset) { 229 this.charset = charset; 230 } 231 232 public void merge(PageDescriptor src) { 233 String newFlavor = src.getDefaultFlavor(); 234 if (newFlavor != null) { 235 setDefaultFlavor(newFlavor); 236 } 237 238 String newCharset = src.getCharset(); 239 if (newCharset != null) { 240 setCharset(newCharset); 241 } 242 243 List<String> newStyles = src.getStyles(); 244 if (newStyles != null) { 245 List<String> merged = new ArrayList<>(); 246 merged.addAll(newStyles); 247 boolean keepOld = src.getAppendStyles() || (newStyles.isEmpty() && !src.getAppendStyles()); 248 if (keepOld) { 249 // add back old contributions 250 List<String> oldStyles = getStyles(); 251 if (oldStyles != null) { 252 merged.addAll(0, oldStyles); 253 } 254 } 255 setStyles(merged); 256 } 257 258 List<String> newFlavors = src.getFlavors(); 259 if (newFlavors != null) { 260 List<String> merged = new ArrayList<>(); 261 merged.addAll(newFlavors); 262 boolean keepOld = src.getAppendFlavors() || (newFlavors.isEmpty() && !src.getAppendFlavors()); 263 if (keepOld) { 264 // add back old contributions 265 List<String> oldFlavors = getFlavors(); 266 if (oldFlavors != null) { 267 merged.addAll(0, oldFlavors); 268 } 269 } 270 setFlavors(merged); 271 } 272 273 List<String> newResources = src.resources; 274 if (newResources != null) { 275 List<String> merged = new ArrayList<>(); 276 merged.addAll(newResources); 277 boolean keepOld = src.getAppendResources() || (newResources.isEmpty() && !src.getAppendResources()); 278 if (keepOld) { 279 // add back old contributions 280 List<String> oldResources = resources; 281 if (oldResources != null) { 282 merged.addAll(0, oldResources); 283 } 284 } 285 setResources(merged); 286 } 287 288 List<String> newBundles = src.bundles; 289 if (newBundles != null) { 290 List<String> merged = new ArrayList<>(); 291 merged.addAll(newBundles); 292 boolean keepOld = src.getAppendResources() || (newBundles.isEmpty() && !src.getAppendResources()); 293 if (keepOld) { 294 // add back old contributions 295 List<String> oldBundles = bundles; 296 if (oldBundles != null) { 297 merged.addAll(0, oldBundles); 298 } 299 } 300 setResourceBundles(merged); 301 } 302 } 303 304 @Override 305 public PageDescriptor clone() { 306 PageDescriptor clone = new PageDescriptor(); 307 clone.setName(getName()); 308 clone.setCharset(getCharset()); 309 clone.setDefaultFlavor(getDefaultFlavor()); 310 clone.setAppendStyles(getAppendStyles()); 311 List<String> styles = getStyles(); 312 if (styles != null) { 313 clone.setStyles(new ArrayList<>(styles)); 314 } 315 clone.setAppendFlavors(getAppendFlavors()); 316 List<String> flavors = getFlavors(); 317 if (flavors != null) { 318 clone.setFlavors(new ArrayList<>(flavors)); 319 } 320 clone.setAppendResources(getAppendResources()); 321 if (resources != null) { 322 clone.setResources(new ArrayList<>(resources)); 323 } 324 if (bundles != null) { 325 clone.setResourceBundles(new ArrayList<>(bundles)); 326 } 327 return clone; 328 } 329 330 @Override 331 public boolean equals(Object obj) { 332 if (!(obj instanceof PageDescriptor)) { 333 return false; 334 } 335 if (obj == this) { 336 return true; 337 } 338 PageDescriptor p = (PageDescriptor) obj; 339 return new EqualsBuilder().append(name, p.name).append(charset, p.charset).append(defaultFlavor, 340 p.defaultFlavor).append(appendStyles, p.appendStyles).append(styles, p.styles).append(appendFlavors, 341 p.appendFlavors).append(flavors, p.flavors).append(appendResources, p.appendResources).append( 342 resources, p.resources).append(bundles, p.bundles).isEquals(); 343 } 344 345}