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.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  
25  import java.io.Serializable;
26  import java.util.ArrayList;
27  import java.util.Collections;
28  import java.util.List;
29  
30  public class ThemeImpl implements Theme, Serializable {
31  
32    private static final long serialVersionUID = 1L;
33  
34    private static final Logger LOG = LoggerFactory.getLogger(ThemeImpl.class);
35  
36    private String name;
37    private String displayName;
38    private ThemeImpl fallback;
39    private String fallbackName;
40    private List<Theme> fallbackList;
41    private ThemeResources productionResources;
42    private ThemeResources resources;
43    private String[] productionScripts;
44    private String[] productionStyles;
45    private String[] scripts;
46    private String[] styles;
47    private boolean versioned;
48    private String version;
49  
50    private boolean unmodifiable = false;
51  
52    public ThemeImpl() {
53      resources = new ThemeResources(false);
54      productionResources = new ThemeResources(true);
55    }
56  
57    private void checkLocked() throws IllegalStateException {
58      if (unmodifiable) {
59        throw new IllegalStateException("The configuration must not be changed after initialization!");
60      }
61    }
62  
63    /**
64     * Lock the configuration, so it cannot be modified any more.
65     */
66    public void lock() {
67      unmodifiable = true;
68    }
69  
70    @Override
71    public String getName() {
72      return name;
73    }
74  
75    public void setName(final String name) {
76      checkLocked();
77      this.name = name;
78    }
79  
80    @Override
81    public String getDisplayName() {
82      return displayName;
83    }
84  
85    public void setDisplayName(final String displayName) {
86      checkLocked();
87      this.displayName = displayName;
88    }
89  
90    public ThemeImpl getFallback() {
91      return fallback;
92    }
93  
94    public void setFallback(final ThemeImpl fallback) {
95      checkLocked();
96      this.fallback = fallback;
97    }
98  
99    public String getFallbackName() {
100     return fallbackName;
101   }
102 
103   public void setFallbackName(final String fallbackName) {
104     checkLocked();
105     this.fallbackName = fallbackName;
106   }
107 
108   @Override
109   public List<Theme> getFallbackList() {
110     return fallbackList;
111   }
112 
113   public void resolveFallbacks() {
114     checkLocked();
115     fallbackList = new ArrayList<>();
116     ThemeImpl actual = this;
117     while (actual != null) {
118       fallbackList.add(actual);
119       actual = actual.getFallback();
120     }
121     fallbackList = Collections.unmodifiableList(fallbackList);
122     if (LOG.isDebugEnabled()) {
123       LOG.debug("fallbackList: {");
124       for (final Theme theme : fallbackList) {
125         LOG.debug("  theme: {}", theme.getName());
126       }
127       LOG.debug("}");
128     }
129   }
130 
131   public void resolveResources() {
132     checkLocked();
133     final ThemeImpl fallbackTheme = getFallback();
134     if (fallbackTheme != null) {
135       fallbackTheme.resolveResources();
136       addResources(fallbackTheme.getProductionResources());
137       addResources(fallbackTheme.getResources());
138     }
139   }
140 
141   public ThemeResources getResources() {
142     return resources;
143   }
144 
145   public ThemeResources getProductionResources() {
146     return productionResources;
147   }
148 
149   private void addResources(final ThemeResources themeResources) {
150     checkLocked();
151 
152     if (themeResources.isProduction()) {
153       productionResources.merge(themeResources);
154     } else {
155       resources.merge(themeResources);
156     }
157   }
158 
159   public void init() {
160     checkLocked();
161     productionScripts = new String[productionResources.getScriptList().size()];
162     for (int i = 0; i < productionResources.getScriptList().size(); i++) {
163       productionScripts[i] = productionResources.getScriptList().get(i).getName();
164     }
165     productionStyles = new String[productionResources.getStyleList().size()];
166     for (int i = 0; i < productionResources.getStyleList().size(); i++) {
167       productionStyles[i] = productionResources.getStyleList().get(i).getName();
168     }
169 
170     scripts = new String[resources.getScriptList().size()];
171     for (int i = 0; i < resources.getScriptList().size(); i++) {
172       scripts[i] = resources.getScriptList().get(i).getName();
173     }
174     styles = new String[resources.getStyleList().size()];
175     for (int i = 0; i < resources.getStyleList().size(); i++) {
176       styles[i] = resources.getStyleList().get(i).getName();
177     }
178 
179   }
180 
181   @Override
182   public String[] getScriptResources(final boolean production) {
183     if (production) {
184       return productionScripts;
185     } else {
186       return scripts;
187     }
188   }
189 
190   @Override
191   public String[] getStyleResources(final boolean production) {
192     if (production) {
193       return productionStyles;
194     } else {
195       return styles;
196     }
197   }
198 
199   public boolean isVersioned() {
200     checkLocked();
201     return versioned;
202   }
203 
204   public void setVersioned(final boolean versioned) {
205     checkLocked();
206     this.versioned = versioned;
207   }
208 
209   @Override
210   public String getVersion() {
211     return version;
212   }
213 
214   public void setVersion(final String version) {
215     checkLocked();
216     this.version = version;
217   }
218 
219   public String toString() {
220     final StringBuilder builder = new StringBuilder();
221     builder.append("Theme:  name='");
222     builder.append(name);
223     builder.append("' fallback=");
224     if (fallback != null) {
225       builder.append("'");
226       builder.append(fallback.getName());
227       builder.append("'");
228     } else {
229       builder.append("null");
230     }
231     builder.append(", \nproductionScripts=[");
232     for (final String s : productionScripts != null ? productionScripts : new String[0]) {
233       builder.append("\n");
234       builder.append(s);
235     }
236     builder.append("], \nscripts=[");
237     for (final String s : scripts != null ? scripts : new String[0]) {
238       builder.append("\n");
239       builder.append(s);
240     }
241     builder.append("], \nproductionStyles=[");
242     for (final String s : productionStyles != null ? productionStyles : new String[0]) {
243       builder.append("\n");
244       builder.append(s);
245     }
246     builder.append("], \nstyles=[");
247     for (final String s : styles != null ? styles : new String[0]) {
248       builder.append("\n");
249       builder.append(s);
250     }
251     return builder.toString();
252   }
253 }