View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.myfaces.tobago.context;
21  
22  import org.apache.myfaces.tobago.internal.config.RendererConfig;
23  import org.apache.myfaces.tobago.internal.config.RenderersConfig;
24  import org.apache.myfaces.tobago.internal.config.RenderersConfigImpl;
25  import org.slf4j.Logger;
26  import org.slf4j.LoggerFactory;
27  
28  import java.io.Serializable;
29  import java.util.ArrayList;
30  import java.util.Collections;
31  import java.util.List;
32  
33  public class ThemeImpl implements Theme, Serializable {
34  
35    private static final long serialVersionUID = 1L;
36  
37    private static final Logger LOG = LoggerFactory.getLogger(ThemeImpl.class);
38  
39    private String name;
40    private String displayName;
41    private ThemeImpl fallback;
42    private String fallbackName;
43    private List<Theme> fallbackList;
44    private RenderersConfigImpl renderersConfig;
45    private ThemeResources productionResources;
46    private ThemeResources resources;
47    private String[] productionScripts;
48    private String[] productionStyles;
49    private String[] scripts;
50    private String[] styles;
51    private boolean versioned;
52    private String version;
53  
54    private boolean unmodifiable = false;
55  
56    public ThemeImpl() {
57      resources = new ThemeResources(false);
58      productionResources = new ThemeResources(true);
59    }
60  
61    private void checkLocked() throws IllegalStateException {
62      if (unmodifiable) {
63        throw new IllegalStateException("The configuration must not be changed after initialization!");
64      }
65    }
66  
67    /**
68     * Lock the configuration, so it cannot be modified any more.
69     */
70    public void lock() {
71      unmodifiable = true;
72    }
73  
74    @Override
75    public String getName() {
76      return name;
77    }
78  
79    public void setName(final String name) {
80      checkLocked();
81      this.name = name;
82    }
83  
84    @Override
85    public String getDisplayName() {
86      return displayName;
87    }
88  
89    public void setDisplayName(final String displayName) {
90      checkLocked();
91      this.displayName = displayName;
92    }
93  
94    public ThemeImpl getFallback() {
95      return fallback;
96    }
97  
98    public void setFallback(final ThemeImpl fallback) {
99      checkLocked();
100     this.fallback = fallback;
101   }
102 
103   public String getFallbackName() {
104     return fallbackName;
105   }
106 
107   public void setFallbackName(final String fallbackName) {
108     checkLocked();
109     this.fallbackName = fallbackName;
110   }
111 
112   @Override
113   public List<Theme> getFallbackList() {
114     return fallbackList;
115   }
116 
117   public void resolveFallbacks() {
118     checkLocked();
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       LOG.debug("fallbackList: {");
128       for (final Theme theme : fallbackList) {
129         LOG.debug("  theme: {}", theme.getName());
130       }
131       LOG.debug("}");
132     }
133   }
134 
135   public void resolveRendererConfig(final RenderersConfig rendererConfigFromTobagoConfig) {
136     checkLocked();
137     if (renderersConfig == null) {
138       renderersConfig = new RenderersConfigImpl();
139     }
140     if (!renderersConfig.isMerged()) {
141       final ThemeImpl fallbackTheme = getFallback();
142       if (fallbackTheme != null) {
143         fallbackTheme.resolveRendererConfig(rendererConfigFromTobagoConfig);
144         final RenderersConfigImpl fallbackRenderersConfig = fallbackTheme.getRenderersConfigImpl();
145         if (fallbackRenderersConfig != null) {
146           renderersConfig.merge(fallbackRenderersConfig, false);
147           LOG.debug("merge markupconfig from {} for {}", fallbackTheme.getName(), getName());
148         }
149       }
150       if (rendererConfigFromTobagoConfig != null) {
151         renderersConfig.merge(rendererConfigFromTobagoConfig, true);
152       }
153       renderersConfig.setMerged(true);
154       LOG.debug("{} {}", getName(), renderersConfig);
155     }
156   }
157 
158   public void resolveResources() {
159     checkLocked();
160     final ThemeImpl fallbackTheme = getFallback();
161     if (fallbackTheme != null) {
162       fallbackTheme.resolveResources();
163       addResources(fallbackTheme.getProductionResources());
164       addResources(fallbackTheme.getResources());
165     }
166   }
167 
168   public void setRenderersConfig(final RenderersConfigImpl renderersConfig) {
169     checkLocked();
170     this.renderersConfig = renderersConfig;
171   }
172 
173   @Override
174   public RenderersConfig getRenderersConfig() {
175     return renderersConfig;
176   }
177 
178   RenderersConfigImpl getRenderersConfigImpl() {
179     return renderersConfig;
180   }
181 
182   public ThemeResources getResources() {
183     return resources;
184   }
185 
186   public ThemeResources getProductionResources() {
187     return productionResources;
188   }
189 
190   public void addResources(final ThemeResources themeResources) {
191     checkLocked();
192 
193     if (themeResources.isProduction()) {
194       productionResources.merge(themeResources);
195     } else {
196       resources.merge(themeResources);
197     }
198   }
199 
200   public void init() {
201     checkLocked();
202     productionScripts = new String[productionResources.getScriptList().size()];
203     for (int i = 0; i < productionResources.getScriptList().size(); i++) {
204       productionScripts[i] = productionResources.getScriptList().get(i).getName();
205     }
206     productionStyles = new String[productionResources.getStyleList().size()];
207     for (int i = 0; i < productionResources.getStyleList().size(); i++) {
208       productionStyles[i] = productionResources.getStyleList().get(i).getName();
209     }
210 
211     scripts = new String[resources.getScriptList().size()];
212     for (int i = 0; i < resources.getScriptList().size(); i++) {
213       scripts[i] = resources.getScriptList().get(i).getName();
214     }
215     styles = new String[resources.getStyleList().size()];
216     for (int i = 0; i < resources.getStyleList().size(); i++) {
217       styles[i] = resources.getStyleList().get(i).getName();
218     }
219 
220   }
221 
222   @Override
223   public String[] getScriptResources(final boolean production) {
224     if (production) {
225       return productionScripts;
226     } else {
227       return scripts;
228     }
229   }
230 
231   @Override
232   public String[] getStyleResources(final boolean production) {
233     if (production) {
234       return productionStyles;
235     } else {
236       return styles;
237     }
238   }
239 
240   public boolean isVersioned() {
241     checkLocked();
242     return versioned;
243   }
244 
245   public void setVersioned(final boolean versioned) {
246     checkLocked();
247     this.versioned = versioned;
248   }
249 
250   @Override
251   public String getVersion() {
252     return version;
253   }
254 
255   public void setVersion(final String version) {
256     checkLocked();
257     this.version = version;
258   }
259 
260   public String toString() {
261     final StringBuilder builder = new StringBuilder();
262     builder.append("Theme:  name='");
263     builder.append(name);
264     builder.append("' fallback=");
265     if (fallback != null) {
266       builder.append("'");
267       builder.append(fallback.getName());
268       builder.append("'");
269     } else {
270       builder.append("null");
271     }
272     builder.append(", \nproductionScripts=[");
273     for (String s : productionScripts != null ? productionScripts : new String[0]) {
274       builder.append("\n");
275       builder.append(s);
276     }
277     builder.append("], \nscripts=[");
278     for (String s : scripts != null ? scripts : new String[0]) {
279       builder.append("\n");
280       builder.append(s);
281     }
282     builder.append("], \nproductionStyles=[");
283     for (String s : productionStyles != null ? productionStyles : new String[0]) {
284       builder.append("\n");
285       builder.append(s);
286     }
287     builder.append("], \nstyles=[");
288     for (String s : styles != null ? styles : new String[0]) {
289       builder.append("\n");
290       builder.append(s);
291     }
292     if (renderersConfig != null) {
293       builder.append("\n");
294       for (final RendererConfig config : renderersConfig.getRendererConfigs()) {
295         builder.append(config);
296         builder.append("\n");
297       }
298     }
299     return builder.toString();
300   }
301 }