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.internal.config;
21  
22  import org.apache.myfaces.tobago.context.ThemeImpl;
23  import org.apache.myfaces.tobago.sanitizer.IgnoringSanitizer;
24  import org.apache.myfaces.tobago.sanitizer.JsoupSanitizer;
25  import org.apache.myfaces.tobago.sanitizer.Sanitizer;
26  import org.slf4j.Logger;
27  import org.slf4j.LoggerFactory;
28  
29  import java.lang.invoke.MethodHandles;
30  import java.util.List;
31  import java.util.Map;
32  import java.util.Properties;
33  
34  public class TobagoConfigMerger {
35  
36    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
37  
38    private final List<TobagoConfigFragment> list;
39  
40    public TobagoConfigMerger(final List<TobagoConfigFragment> list) {
41      this.list =    list;
42    }
43  
44    public TobagoConfigImpl merge() {
45  
46      final TobagoConfigImpl result = new TobagoConfigImpl("fixme"); // fixme workaround
47  
48      // default sanitizer
49      String sanitizerClass = JsoupSanitizer.class.getName();
50      Properties sanitizerProperties = new Properties();
51      sanitizerProperties.setProperty("whitelist", "relaxed");
52  
53      for (TobagoConfigFragment fragment : list) {
54  
55        // default theme
56        final String defaultTheme = fragment.getDefaultThemeName();
57        if (defaultTheme != null) {
58          result.setDefaultThemeName(defaultTheme);
59        }
60  
61        // supported themes
62        for (final String supported : fragment.getSupportedThemeNames()) {
63          result.addSupportedThemeName(supported);
64        }
65  
66        // session secret
67        if (fragment.getCreateSessionSecret() != null) {
68          result.setCreateSessionSecret(fragment.getCreateSessionSecret());
69        }
70        if (fragment.getCheckSessionSecret() != null) {
71          result.setCheckSessionSecret(fragment.getCheckSessionSecret());
72        }
73  
74        if (fragment.getPreventFrameAttacks() != null) {
75          result.setPreventFrameAttacks(fragment.getPreventFrameAttacks());
76        }
77  
78        if (fragment.getContentSecurityPolicy() != null) {
79          result.getContentSecurityPolicy().merge(fragment.getContentSecurityPolicy());
80        }
81  
82        if (fragment.getSecurityAnnotation() != null) {
83          result.setSecurityAnnotation(fragment.getSecurityAnnotation());
84        }
85  
86        if (fragment.getSetNosniffHeader() != null) {
87          result.setSetNosniffHeader(fragment.getSetNosniffHeader());
88        }
89  
90        if (fragment.getSanitizerClass() != null) {
91          sanitizerClass = fragment.getSanitizerClass();
92          sanitizerProperties = fragment.getSanitizerProperties();
93        }
94  
95        if (fragment.getDecodeLineFeed() != null) {
96          result.setDecodeLineFeed(fragment.getDecodeLineFeed());
97        }
98  
99        // theme definition
100       for (final ThemeImpl theme : fragment.getThemeDefinitions()) {
101         result.addAvailableTheme(theme);
102       }
103 
104       // url
105       // todo???
106 
107       final Map<String, String> mimeTypes = result.getMimeTypes();
108       for (final Map.Entry<String, String> entry : fragment.getMimeTypes().entrySet()) {
109         mimeTypes.put(entry.getKey(), entry.getValue());
110       }
111 
112     }
113 
114     resolveThemes(result.getAvailableThemes());
115 
116     if (sanitizerClass != null) {
117       try {
118         final Class<? extends Sanitizer> aClass = Class.forName(sanitizerClass).asSubclass(Sanitizer.class);
119         final Sanitizer sanitizer = aClass.newInstance();
120         sanitizer.setProperties(sanitizerProperties);
121         result.setSanitizer(sanitizer);
122       } catch (final Exception e) {
123         LOG.error("Can't create sanitizer: '" + sanitizerClass + "'", e);
124         result.setSanitizer(new IgnoringSanitizer());
125       }
126     }
127 
128     return result;
129   }
130 
131   private void resolveThemes(final Map<String, ThemeImpl> map) {
132     for (final ThemeImpl theme : map.values()) {
133       final String fallbackName = theme.getFallbackName();
134       final ThemeImpl fallback = map.get(fallbackName);
135       theme.setFallback(fallback);
136     }
137     for (final ThemeImpl theme : map.values()) {
138       theme.resolveFallbacks();
139     }
140     for (final ThemeImpl theme : map.values()) {
141       theme.resolveResources();
142     }
143     for (final ThemeImpl theme : map.values()) {
144       theme.init();
145     }
146   }
147 
148 }