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 String resourcePath;
42    private ThemeImpl fallback;
43    private String fallbackName;
44    private List<Theme> fallbackList;
45    private RenderersConfigImpl renderersConfig;
46    private ThemeResources productionResources;
47    private ThemeResources resources;
48    private String[] productionScripts;
49    private String[] productionStyles;
50    private String[] scripts;
51    private String[] styles;
52    private boolean versioned;
53    private String version;
54  
55    private boolean unmodifiable = false;
56  
57    public ThemeImpl() {
58      resources = new ThemeResources(false);
59      productionResources = new ThemeResources(true);
60    }
61  
62    private void checkLocked() throws IllegalStateException {
63      if (unmodifiable) {
64        throw new RuntimeException("The configuration must not be changed after initialization!");
65      }
66    }
67  
68    /**
69     * Lock the configuration, so it cannot be modified any more.
70     */
71    public void lock() {
72      unmodifiable = true;
73    }
74  
75    @Override
76    public String getName() {
77      return name;
78    }
79  
80    public void setName(final String name) {
81      checkLocked();
82      this.name = name;
83    }
84  
85    @Override
86    public String getDisplayName() {
87      return displayName;
88    }
89  
90    public void setDisplayName(final String displayName) {
91      checkLocked();
92      this.displayName = displayName;
93    }
94  
95    @Override
96    public String getResourcePath() {
97      return resourcePath;
98    }
99  
100   public void setResourcePath(final String resourcePath) {
101     checkLocked();
102     this.resourcePath = resourcePath;
103   }
104 
105   public ThemeImpl getFallback() {
106     return fallback;
107   }
108 
109   public void setFallback(final ThemeImpl fallback) {
110     checkLocked();
111     this.fallback = fallback;
112   }
113 
114   public String getFallbackName() {
115     return fallbackName;
116   }
117 
118   public void setFallbackName(final String fallbackName) {
119     checkLocked();
120     this.fallbackName = fallbackName;
121   }
122 
123   @Override
124   public List<Theme> getFallbackList() {
125     return fallbackList;
126   }
127 
128   public void resolveFallbacks() {
129     checkLocked();
130     fallbackList = new ArrayList<Theme>();
131     ThemeImpl actual = this;
132     while (actual != null) {
133       fallbackList.add(actual);
134       actual = actual.getFallback();
135     }
136     fallbackList = Collections.unmodifiableList(fallbackList);
137     if (LOG.isDebugEnabled()) {
138       for (final Theme theme : fallbackList) {
139         LOG.debug("fallbackList: {}", theme.getName());
140       }
141     }
142   }
143 
144   public void resolveRendererConfig(final RenderersConfig rendererConfigFromTobagoConfig) {
145     checkLocked();
146     if (renderersConfig == null) {
147       renderersConfig = new RenderersConfigImpl();
148     }
149     if (!renderersConfig.isMerged()) {
150       final ThemeImpl fallback = getFallback();
151       if (fallback != null) {
152         fallback.resolveRendererConfig(rendererConfigFromTobagoConfig);
153         final RenderersConfigImpl fallbackRenderersConfig = fallback.getRenderersConfigImpl();
154         if (fallbackRenderersConfig != null) {
155           renderersConfig.merge(fallbackRenderersConfig, false);
156           if (LOG.isDebugEnabled()) {
157             LOG.debug("merge markupconfig from {} for {}", fallback.getName(), getName());
158           }
159         }
160       }
161       if (rendererConfigFromTobagoConfig != null) {
162         renderersConfig.merge(rendererConfigFromTobagoConfig, true);
163       }
164       renderersConfig.setMerged(true);
165       if (LOG.isDebugEnabled()) {
166         LOG.debug("{} {}", getName(), renderersConfig);
167       }
168     }
169   }
170 
171   public void resolveResources() {
172     checkLocked();
173     final ThemeImpl fallback = getFallback();
174     if (fallback != null) {
175       fallback.resolveResources();
176       addResources(fallback.getProductionResources());
177       addResources(fallback.getResources());
178     }
179   }
180 
181   public void setRenderersConfig(final RenderersConfigImpl renderersConfig) {
182     checkLocked();
183     this.renderersConfig = renderersConfig;
184   }
185 
186   @Override
187   public RenderersConfig getRenderersConfig() {
188     return renderersConfig;
189   }
190 
191   RenderersConfigImpl getRenderersConfigImpl() {
192     return renderersConfig;
193   }
194 
195   public ThemeResources getResources() {
196     return resources;
197   }
198 
199   public ThemeResources getProductionResources() {
200     return productionResources;
201   }
202 
203   public void addResources(final ThemeResources themeResources) {
204     checkLocked();
205 
206     if (themeResources.isProduction()) {
207       productionResources.merge(themeResources);
208     } else {
209       resources.merge(themeResources);
210     }
211   }
212 
213   public void init() {
214     checkLocked();
215     productionScripts = new String[productionResources.getScriptList().size()];
216     for (int i = 0; i < productionResources.getScriptList().size(); i++) {
217       productionScripts[i] = productionResources.getScriptList().get(i).getName();
218     }
219     productionStyles = new String[productionResources.getStyleList().size()];
220     for (int i = 0; i < productionResources.getStyleList().size(); i++) {
221       productionStyles[i] = productionResources.getStyleList().get(i).getName();
222     }
223 
224     scripts = new String[resources.getScriptList().size()];
225     for (int i = 0; i < resources.getScriptList().size(); i++) {
226       scripts[i] = resources.getScriptList().get(i).getName();
227     }
228     styles = new String[resources.getStyleList().size()];
229     for (int i = 0; i < resources.getStyleList().size(); i++) {
230       styles[i] = resources.getStyleList().get(i).getName();
231     }
232 
233   }
234 
235   @Override
236   public String[] getScriptResources(final boolean production) {
237     if (production) {
238       return productionScripts;
239     } else {
240       return scripts;
241     }
242   }
243 
244   @Override
245   public String[] getStyleResources(final boolean production) {
246     if (production) {
247       return productionStyles;
248     } else {
249       return styles;
250     }
251   }
252 
253   public boolean isVersioned() {
254     checkLocked();
255     return versioned;
256   }
257 
258   public void setVersioned(final boolean versioned) {
259     checkLocked();
260     this.versioned = versioned;
261   }
262 
263   @Override
264   public String getVersion() {
265     return version;
266   }
267 
268   public void setVersion(final String version) {
269     checkLocked();
270     this.version = version;
271   }
272 
273   public String toString() {
274     final StringBuilder builder = new StringBuilder();
275     builder.append("Theme:  name='");
276     builder.append(name);
277     builder.append("' fallback=");
278     if (fallback != null) {
279       builder.append("'");
280       builder.append(fallback.getName());
281       builder.append("'");
282     } else {
283       builder.append("null");
284     }
285     builder.append(", \nproductionScripts=[");
286     for (String s : productionScripts != null ? productionScripts : new String[0]) {
287       builder.append("\n");
288       builder.append(s);
289     }
290     builder.append("], \nscripts=[");
291     for (String s : scripts != null ? scripts : new String[0]) {
292       builder.append("\n");
293       builder.append(s);
294     }
295     builder.append("], \nproductionStyles=[");
296     for (String s : productionStyles != null ? productionStyles : new String[0]) {
297       builder.append("\n");
298       builder.append(s);
299     }
300     builder.append("], \nstyles=[");
301     for (String s : styles != null ? styles : new String[0]) {
302       builder.append("\n");
303       builder.append(s);
304     }
305     if (renderersConfig != null) {
306       builder.append("\n");
307       for (final RendererConfig config : renderersConfig.getRendererConfigs()) {
308         builder.append(config);
309         builder.append("\n");
310       }
311     }
312     return builder.toString();
313   }
314 }