001 package org.apache.myfaces.tobago.context; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one or more 005 * contributor license agreements. See the NOTICE file distributed with 006 * this work for additional information regarding copyright ownership. 007 * The ASF licenses this file to You under the Apache License, Version 2.0 008 * (the "License"); you may not use this file except in compliance with 009 * the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019 020 import org.apache.myfaces.tobago.internal.config.RendererConfig; 021 import org.apache.myfaces.tobago.internal.config.RenderersConfig; 022 import org.apache.myfaces.tobago.internal.config.RenderersConfigImpl; 023 import org.slf4j.Logger; 024 import org.slf4j.LoggerFactory; 025 026 import java.io.Serializable; 027 import java.util.ArrayList; 028 import java.util.Collections; 029 import java.util.List; 030 031 public class ThemeImpl implements Theme, Serializable { 032 033 private static final long serialVersionUID = 1L; 034 035 private static final Logger LOG = LoggerFactory.getLogger(ThemeImpl.class); 036 037 private String name; 038 039 private String displayName; 040 041 private String deprecatedName; 042 043 private String resourcePath; 044 045 private ThemeImpl fallback; 046 047 private String fallbackName; 048 049 private List<Theme> fallbackList; 050 051 private RenderersConfigImpl renderersConfig; 052 053 private ThemeResources productionResources; 054 055 private ThemeResources resources; 056 057 private String[] productionScripts; 058 059 private String[] productionStyles; 060 061 private String[] scripts; 062 063 private String[] styles; 064 065 066 public String getName() { 067 return name; 068 } 069 070 public void setName(String name) { 071 this.name = name; 072 } 073 074 public String getDisplayName() { 075 return displayName; 076 } 077 078 public void setDisplayName(String displayName) { 079 this.displayName = displayName; 080 } 081 082 public String getDeprecatedName() { 083 return deprecatedName; 084 } 085 086 public void setDeprecatedName(String deprecatedName) { 087 this.deprecatedName = deprecatedName; 088 } 089 090 public String getResourcePath() { 091 return resourcePath; 092 } 093 094 public void setResourcePath(String resourcePath) { 095 this.resourcePath = resourcePath; 096 } 097 098 public ThemeImpl getFallback() { 099 return fallback; 100 } 101 102 public void setFallback(ThemeImpl fallback) { 103 this.fallback = fallback; 104 } 105 106 public String getFallbackName() { 107 return fallbackName; 108 } 109 110 public void setFallbackName(String fallbackName) { 111 this.fallbackName = fallbackName; 112 } 113 114 public List<Theme> getFallbackList() { 115 return fallbackList; 116 } 117 118 public void resolveFallbacks() { 119 fallbackList = new ArrayList<Theme>(); 120 ThemeImpl actual = this; 121 while (actual != null) { 122 fallbackList.add(actual); 123 actual = actual.getFallback(); 124 } 125 fallbackList = Collections.unmodifiableList(fallbackList); 126 if (LOG.isDebugEnabled()) { 127 for (Theme theme : fallbackList) { 128 LOG.debug("fallbackList: {}", theme.getName()); 129 } 130 } 131 } 132 133 public void resolveRendererConfig(RenderersConfig rendererConfigFromTobagoConfig) { 134 if (renderersConfig == null) { 135 renderersConfig = new RenderersConfigImpl(); 136 } 137 if (!renderersConfig.isMerged()) { 138 ThemeImpl fallback = getFallback(); 139 if (fallback != null) { 140 fallback.resolveRendererConfig(rendererConfigFromTobagoConfig); 141 RenderersConfigImpl fallbackRenderersConfig = fallback.getRenderersConfigImpl(); 142 if (fallbackRenderersConfig != null) { 143 renderersConfig.merge(fallbackRenderersConfig, false); 144 if (LOG.isDebugEnabled()) { 145 LOG.debug("merge markupconfig from {} for {}", fallback.getName(), getName()); 146 } 147 } 148 } 149 if (rendererConfigFromTobagoConfig != null) { 150 renderersConfig.merge(rendererConfigFromTobagoConfig, true); 151 } 152 renderersConfig.setMerged(true); 153 if (LOG.isDebugEnabled()) { 154 LOG.debug("{} {}", getName(), renderersConfig); 155 } 156 } 157 } 158 159 public void resolveResources() { 160 ThemeImpl fallback = getFallback(); 161 if (fallback != null) { 162 fallback.resolveResources(); 163 addResources(fallback.getProductionResources()); 164 addResources(fallback.getResources()); 165 } 166 } 167 168 public String toString() { 169 StringBuilder builder = new StringBuilder(); 170 builder.append("Theme: "); 171 builder.append(name); 172 if (renderersConfig != null) { 173 builder.append("\n"); 174 for (RendererConfig config : renderersConfig.getRendererConfigs()) { 175 builder.append(config); 176 builder.append("\n"); 177 } 178 } 179 return builder.toString(); 180 } 181 182 public void setRenderersConfig(RenderersConfigImpl renderersConfig) { 183 this.renderersConfig = renderersConfig; 184 } 185 186 public RenderersConfig getRenderersConfig() { 187 return renderersConfig; 188 } 189 190 RenderersConfigImpl getRenderersConfigImpl() { 191 return renderersConfig; 192 } 193 194 public ThemeResources getResources() { 195 return resources; 196 } 197 198 public ThemeResources getProductionResources() { 199 return productionResources; 200 } 201 202 public void addResources(ThemeResources resources) { 203 if (resources.isProduction()) { 204 if (productionResources != null) { 205 merge(productionResources, resources); 206 } else { 207 productionResources = resources.copy(); 208 } 209 } else { 210 if (this.resources != null) { 211 merge(this.resources, resources); 212 } else { 213 this.resources = resources.copy(); 214 } 215 } 216 } 217 218 public void init() { 219 if (productionResources != null) { 220 productionScripts = new String[productionResources.getScriptList().size()]; 221 for (int i = 0; i< productionResources.getScriptList().size(); i++) { 222 productionScripts[i] = productionResources.getScriptList().get(i).getName(); 223 } 224 productionStyles = new String[productionResources.getStyleList().size()]; 225 for (int i = 0; i< productionResources.getStyleList().size(); i++) { 226 productionStyles[i] = productionResources.getStyleList().get(i).getName(); 227 } 228 } 229 230 if (resources != null) { 231 scripts = new String[resources.getScriptList().size()]; 232 for (int i = 0; i< resources.getScriptList().size(); i++) { 233 scripts[i] = resources.getScriptList().get(i).getName(); 234 } 235 styles = new String[resources.getStyleList().size()]; 236 for (int i = 0; i< resources.getStyleList().size(); i++) { 237 styles[i] = resources.getStyleList().get(i).getName(); 238 } 239 } 240 241 } 242 243 private void merge(ThemeResources resources, ThemeResources toAddResources) { 244 if (resources == toAddResources) { 245 return; 246 } 247 for (int i = toAddResources.getScriptList().size()-1; i >= 0; i--) { 248 ThemeScript script = toAddResources.getScriptList().get(i); 249 resources.getScriptList().remove(script); 250 resources.getScriptList().add(0, script); 251 } 252 for (int i = toAddResources.getStyleList().size()-1; i >= 0; i--) { 253 ThemeStyle style = toAddResources.getStyleList().get(i); 254 resources.getStyleList().remove(style); 255 resources.getStyleList().add(0, style); 256 } 257 } 258 259 public String[] getScriptResources(boolean production) { 260 if (production) { 261 return productionScripts; 262 } 263 return scripts; 264 } 265 266 public String[] getStyleResources(boolean production) { 267 if (production) { 268 return productionStyles; 269 } 270 return styles; 271 } 272 }