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 RuntimeException("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       for (final Theme theme : fallbackList) {
128         LOG.debug("fallbackList: {}", theme.getName());
129       }
130     }
131   }
132 
133   public void resolveRendererConfig(final RenderersConfig rendererConfigFromTobagoConfig) {
134     checkLocked();
135     if (renderersConfig == null) {
136       renderersConfig = new RenderersConfigImpl();
137     }
138     if (!renderersConfig.isMerged()) {
139       final ThemeImpl fallback = getFallback();
140       if (fallback != null) {
141         fallback.resolveRendererConfig(rendererConfigFromTobagoConfig);
142         final RenderersConfigImpl fallbackRenderersConfig = fallback.getRenderersConfigImpl();
143         if (fallbackRenderersConfig != null) {
144           renderersConfig.merge(fallbackRenderersConfig, false);
145           if (LOG.isDebugEnabled()) {
146             LOG.debug("merge markupconfig from {} for {}", fallback.getName(), getName());
147           }
148         }
149       }
150       if (rendererConfigFromTobagoConfig != null) {
151         renderersConfig.merge(rendererConfigFromTobagoConfig, true);
152       }
153       renderersConfig.setMerged(true);
154       if (LOG.isDebugEnabled()) {
155         LOG.debug("{} {}", getName(), renderersConfig);
156       }
157     }
158   }
159 
160   public void resolveResources() {
161     checkLocked();
162     final ThemeImpl fallback = getFallback();
163     if (fallback != null) {
164       fallback.resolveResources();
165       addResources(fallback.getProductionResources());
166       addResources(fallback.getResources());
167     }
168   }
169 
170   public void setRenderersConfig(final RenderersConfigImpl renderersConfig) {
171     checkLocked();
172     this.renderersConfig = renderersConfig;
173   }
174 
175   @Override
176   public RenderersConfig getRenderersConfig() {
177     return renderersConfig;
178   }
179 
180   RenderersConfigImpl getRenderersConfigImpl() {
181     return renderersConfig;
182   }
183 
184   public ThemeResources getResources() {
185     return resources;
186   }
187 
188   public ThemeResources getProductionResources() {
189     return productionResources;
190   }
191 
192   public void addResources(final ThemeResources themeResources) {
193     checkLocked();
194 
195     if (themeResources.isProduction()) {
196       productionResources.merge(themeResources);
197     } else {
198       resources.merge(themeResources);
199     }
200   }
201 
202   public void init() {
203     checkLocked();
204     productionScripts = new String[productionResources.getScriptList().size()];
205     for (int i = 0; i < productionResources.getScriptList().size(); i++) {
206       productionScripts[i] = productionResources.getScriptList().get(i).getName();
207     }
208     productionStyles = new String[productionResources.getStyleList().size()];
209     for (int i = 0; i < productionResources.getStyleList().size(); i++) {
210       productionStyles[i] = productionResources.getStyleList().get(i).getName();
211     }
212 
213     scripts = new String[resources.getScriptList().size()];
214     for (int i = 0; i < resources.getScriptList().size(); i++) {
215       scripts[i] = resources.getScriptList().get(i).getName();
216     }
217     styles = new String[resources.getStyleList().size()];
218     for (int i = 0; i < resources.getStyleList().size(); i++) {
219       styles[i] = resources.getStyleList().get(i).getName();
220     }
221 
222   }
223 
224   @Override
225   public String[] getScriptResources(final boolean production) {
226     if (production) {
227       return productionScripts;
228     } else {
229       return scripts;
230     }
231   }
232 
233   @Override
234   public String[] getStyleResources(final boolean production) {
235     if (production) {
236       return productionStyles;
237     } else {
238       return styles;
239     }
240   }
241 
242   public boolean isVersioned() {
243     checkLocked();
244     return versioned;
245   }
246 
247   public void setVersioned(final boolean versioned) {
248     checkLocked();
249     this.versioned = versioned;
250   }
251 
252   @Override
253   public String getVersion() {
254     return version;
255   }
256 
257   public void setVersion(final String version) {
258     checkLocked();
259     this.version = version;
260   }
261 
262   public String toString() {
263     final StringBuilder builder = new StringBuilder();
264     builder.append("Theme:  name='");
265     builder.append(name);
266     builder.append("' fallback=");
267     if (fallback != null) {
268       builder.append("'");
269       builder.append(fallback.getName());
270       builder.append("'");
271     } else {
272       builder.append("null");
273     }
274     builder.append(", \nproductionScripts=[");
275     for (String s : productionScripts != null ? productionScripts : new String[0]) {
276       builder.append("\n");
277       builder.append(s);
278     }
279     builder.append("], \nscripts=[");
280     for (String s : scripts != null ? scripts : new String[0]) {
281       builder.append("\n");
282       builder.append(s);
283     }
284     builder.append("], \nproductionStyles=[");
285     for (String s : productionStyles != null ? productionStyles : new String[0]) {
286       builder.append("\n");
287       builder.append(s);
288     }
289     builder.append("], \nstyles=[");
290     for (String s : styles != null ? styles : new String[0]) {
291       builder.append("\n");
292       builder.append(s);
293     }
294     if (renderersConfig != null) {
295       builder.append("\n");
296       for (final RendererConfig config : renderersConfig.getRendererConfigs()) {
297         builder.append(config);
298         builder.append("\n");
299       }
300     }
301     return builder.toString();
302   }
303 }