1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.internal.config;
21
22 import org.apache.commons.beanutils.PropertyUtils;
23 import org.apache.myfaces.tobago.application.ProjectStage;
24 import org.apache.myfaces.tobago.config.TobagoConfig;
25 import org.apache.myfaces.tobago.context.Theme;
26 import org.apache.myfaces.tobago.internal.util.Deprecation;
27 import org.apache.myfaces.tobago.internal.util.JndiUtils;
28 import org.apache.myfaces.tobago.util.FacesVersion;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 import javax.faces.application.Application;
33 import javax.faces.context.FacesContext;
34 import javax.naming.Context;
35 import javax.naming.InitialContext;
36 import javax.naming.NamingException;
37 import javax.servlet.ServletContext;
38 import java.net.URL;
39 import java.util.ArrayList;
40 import java.util.Collections;
41 import java.util.HashSet;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Set;
45
46 public class TobagoConfigImpl extends TobagoConfig {
47
48 private static final Logger LOG = LoggerFactory.getLogger(TobagoConfigImpl.class);
49
50 public static final String TOBAGO_CONFIG = "org.apache.myfaces.tobago.config.TobagoConfig";
51
52 private List<Theme> supportedThemes;
53 private List<String> supportedThemeNames;
54 private Theme defaultTheme;
55 private String defaultThemeName;
56 private List<String> resourceDirs;
57 private Map<String, Theme> availableThemes;
58 private RenderersConfig renderersConfig;
59 private ProjectStage projectStage;
60 private boolean createSessionSecret;
61 private boolean checkSessionSecret;
62 private boolean preventFrameAttacks = true;
63 private List<String> contentSecurityPolicy;
64 private URL url;
65 private Map<String, String> defaultValidatorInfo;
66
67 public TobagoConfigImpl() {
68 supportedThemeNames = new ArrayList<String>();
69 supportedThemes = new ArrayList<Theme>();
70 resourceDirs = new ArrayList<String>();
71 createSessionSecret = true;
72 checkSessionSecret = true;
73 contentSecurityPolicy = new ArrayList<String>();
74 }
75
76 public void addSupportedThemeName(String name) {
77 supportedThemeNames.add(name);
78 }
79
80 public void resolveThemes() {
81 if (defaultThemeName != null) {
82 defaultTheme = availableThemes.get(defaultThemeName);
83 checkThemeIsAvailable(defaultThemeName, defaultTheme);
84 if (LOG.isDebugEnabled()) {
85 LOG.debug("name = '{}'", defaultThemeName);
86 LOG.debug("defaultTheme = '{}'", defaultTheme);
87 }
88 } else {
89 int deep = 0;
90 for (Map.Entry<String, Theme> entry : availableThemes.entrySet()) {
91 Theme theme = entry.getValue();
92 if (theme.getFallbackList().size() > deep) {
93 defaultTheme = theme;
94 deep = theme.getFallbackList().size();
95 }
96 }
97 if (defaultTheme == null) {
98 String error = "Did not found any theme! "
99 + "Please ensure you have a tobago-theme.xml file in your "
100 + "theme jar. Please add a theme jar to your WEB-INF/lib";
101 LOG.error(error);
102 throw new RuntimeException(error);
103 } else {
104 if (LOG.isInfoEnabled()) {
105 LOG.info("Using default Theme {}", defaultTheme.getName());
106 }
107 }
108 }
109 if (!supportedThemeNames.isEmpty()) {
110 for (String name : supportedThemeNames) {
111 Theme theme = availableThemes.get(name);
112 checkThemeIsAvailable(name, theme);
113 supportedThemes.add(theme);
114 if (LOG.isDebugEnabled()) {
115 LOG.debug("name = '{}'", name);
116 LOG.debug("supportedThemes.last() = '{}'", supportedThemes.get(supportedThemes.size() - 1));
117 }
118 }
119 }
120 }
121
122 private void checkThemeIsAvailable(String name, Theme theme) {
123 if (theme == null) {
124 String error = "Theme not found! name: '" + name + "'. "
125 + "Please ensure you have a tobago-theme.xml file in your "
126 + "theme jar. Found the following themes: " + availableThemes.keySet();
127 LOG.error(error);
128 throw new RuntimeException(error);
129 }
130 }
131
132 public Theme getTheme(String name) {
133 if (name == null) {
134 LOG.debug("searching theme: null");
135 return defaultTheme;
136 }
137 if (defaultTheme.getName().equals(name)) {
138 return defaultTheme;
139 }
140 for (Theme theme : supportedThemes) {
141 if (theme.getName().equals(name)) {
142 return theme;
143 }
144 }
145 LOG.debug("searching theme '{}' not found. Using default: {}", name, defaultTheme);
146 return defaultTheme;
147 }
148
149 public void setDefaultThemeName(String defaultThemeName) {
150 this.defaultThemeName = defaultThemeName;
151 }
152
153 public List<Theme> getSupportedThemes() {
154 return Collections.unmodifiableList(supportedThemes);
155 }
156
157 public void addResourceDir(String resourceDir) {
158 if (!resourceDirs.contains(resourceDir)) {
159 if (LOG.isInfoEnabled()) {
160 LOG.info("adding resourceDir = '{}'", resourceDir);
161 }
162 resourceDirs.add(0, resourceDir);
163 }
164 }
165
166 public List<String> getResourceDirs() {
167 return resourceDirs;
168 }
169
170
171 @Deprecated
172 public boolean isAjaxEnabled() {
173 Deprecation.LOG.warn("Ajax is always enabled!");
174 return true;
175 }
176
177 public Theme getDefaultTheme() {
178 return defaultTheme;
179 }
180
181 public void setAvailableThemes(Map<String, Theme> availableThemes) {
182 this.availableThemes = availableThemes;
183 for (Theme theme : this.availableThemes.values()) {
184 addResourceDir(theme.getResourcePath());
185 }
186 }
187
188 public RenderersConfig getRenderersConfig() {
189 return renderersConfig;
190 }
191
192 public void setRenderersConfig(RenderersConfig renderersConfig) {
193 this.renderersConfig = renderersConfig;
194 }
195
196 public ProjectStage getProjectStage() {
197 return projectStage;
198 }
199
200 public void initProjectState(ServletContext servletContext) {
201 String stageName = null;
202 try {
203 Context ctx = new InitialContext();
204 Object obj = JndiUtils.getJndiProperty(ctx, "jsf", "ProjectStage");
205 if (obj != null) {
206 if (obj instanceof String) {
207 stageName = (String) obj;
208 } else {
209 LOG.warn("JNDI lookup for key {} should return a java.lang.String value",
210 ProjectStage.PROJECT_STAGE_JNDI_NAME);
211 }
212 }
213 } catch (NamingException e) {
214
215 }
216
217 if (stageName == null) {
218 stageName = servletContext.getInitParameter(ProjectStage.PROJECT_STAGE_PARAM_NAME);
219 }
220
221 if (stageName == null) {
222 stageName = System.getProperty("org.apache.myfaces.PROJECT_STAGE");
223 }
224
225 if (stageName != null) {
226 try {
227 projectStage = ProjectStage.valueOf(stageName);
228 } catch (IllegalArgumentException e) {
229 LOG.error("Couldn't discover the current project stage", e);
230 }
231 }
232 if (projectStage == null) {
233 if (LOG.isInfoEnabled()) {
234 LOG.info("Couldn't discover the current project stage, using {}", ProjectStage.Production);
235 }
236 projectStage = ProjectStage.Production;
237 }
238 }
239
240 public synchronized void initDefaultValidatorInfo() {
241 if (FacesVersion.supports20()) {
242 final FacesContext facesContext = FacesContext.getCurrentInstance();
243 if (facesContext != null) {
244 try {
245 final Application application = facesContext.getApplication();
246 final Map<String, String> map;
247 map = (Map<String, String>) PropertyUtils.getProperty(application, "defaultValidatorInfo");
248 if (application != null && map.size() > 0) {
249 defaultValidatorInfo = Collections.unmodifiableMap(map);
250 } else {
251 defaultValidatorInfo = Collections.emptyMap();
252 }
253 } catch (Exception e) {
254
255 LOG.error("Can't initialize default validators.", e);
256 defaultValidatorInfo = Collections.emptyMap();
257 }
258 }
259 } else {
260 defaultValidatorInfo = Collections.emptyMap();
261 }
262 }
263
264 public boolean isCreateSessionSecret() {
265 return createSessionSecret;
266 }
267
268 public void setCreateSessionSecret(boolean createSessionSecret) {
269 this.createSessionSecret = createSessionSecret;
270 }
271
272 public boolean isCheckSessionSecret() {
273 return checkSessionSecret;
274 }
275
276 public void setCheckSessionSecret(boolean checkSessionSecret) {
277 this.checkSessionSecret = checkSessionSecret;
278 }
279
280
281 public boolean isPreventFrameAttacks() {
282 return preventFrameAttacks;
283 }
284
285 public void setPreventFrameAttacks(boolean preventFrameAttacks) {
286 this.preventFrameAttacks = preventFrameAttacks;
287 }
288
289 public List<String> getContentSecurityPolicy() {
290 return contentSecurityPolicy;
291 }
292
293 public void addContentSecurityPolicy(String directive) {
294 contentSecurityPolicy.add(directive);
295 }
296
297 public Map<String, String> getDefaultValidatorInfo() {
298
299
300 if (defaultValidatorInfo == null) {
301 initDefaultValidatorInfo();
302 }
303 return defaultValidatorInfo;
304 }
305
306 @Override
307 public String toString() {
308 final StringBuilder builder = new StringBuilder();
309 builder.append("TobagoConfigImpl{");
310 builder.append("\nsupportedThemes=[");
311 for (Theme supportedTheme : supportedThemes) {
312 builder.append(supportedTheme.getName());
313 builder.append(", ");
314 }
315 builder.append("], \ndefaultTheme=");
316 builder.append(defaultTheme.getName());
317 builder.append(", \nresourceDirs=");
318 builder.append(resourceDirs);
319 builder.append(", \navailableThemes=");
320 builder.append(availableThemes.keySet());
321 builder.append(", \nprojectStage=");
322 builder.append(projectStage);
323 builder.append(", \ncreateSessionSecret=");
324 builder.append(createSessionSecret);
325 builder.append(", \ncheckSessionSecret=");
326 builder.append(checkSessionSecret);
327 builder.append(", \nurl=");
328 builder.append(url);
329
330 builder.append(", \nthemes=");
331 Set<Theme> all = new HashSet<Theme>(availableThemes.values());
332 builder.append(all);
333 builder.append('}');
334 return builder.toString();
335 }
336 }