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.config.TobagoConfig;
23  import org.apache.myfaces.tobago.exception.TobagoConfigurationException;
24  import org.slf4j.Logger;
25  import org.slf4j.LoggerFactory;
26  import org.xml.sax.SAXException;
27  
28  import javax.servlet.ServletContext;
29  import javax.servlet.ServletException;
30  import javax.xml.parsers.ParserConfigurationException;
31  import java.io.IOException;
32  import java.net.URISyntaxException;
33  import java.net.URL;
34  import java.util.ArrayList;
35  import java.util.Enumeration;
36  import java.util.List;
37  
38  public class TobagoConfigBuilder {
39  
40    private static final Logger LOG = LoggerFactory.getLogger(TobagoConfigBuilder.class);
41  
42    private static final String WEB_INF_TOBAGO_CONFIG_XML = "WEB-INF/tobago-config.xml";
43    private static final String META_INF_TOBAGO_CONFIG_XML = "META-INF/tobago-config.xml";
44  
45    private List<TobagoConfigFragment> configFragmentList;
46    private ServletContext servletContext;
47  
48    public TobagoConfigBuilder(final ServletContext servletContext) {
49      this.servletContext = servletContext;
50      this.configFragmentList = new ArrayList<>();
51    }
52  
53    public TobagoConfigBuilder(final ServletContext servletContext, final List<TobagoConfigFragment> configFragmentList) {
54      this(servletContext);
55      this.configFragmentList.addAll(configFragmentList);
56    }
57  
58    public static void init(final ServletContext servletContext) {
59      try {
60        final TobagoConfigBuilder builder = new TobagoConfigBuilder(servletContext);
61        builder.build();
62      } catch (final Exception e) {
63        final String error = "Error while deployment. Tobago can't be initialized! Application will not run correctly!";
64        LOG.error(error, e);
65        throw new TobagoConfigurationException(error, e);
66      }
67    }
68  
69    public TobagoConfig build()
70        throws URISyntaxException, SAXException, ParserConfigurationException, ServletException, IOException {
71      final TobagoConfigImpl tobagoConfig = initializeConfigFromFiles();
72      // prepare themes
73      tobagoConfig.resolveThemes();
74      tobagoConfig.initDefaultValidatorInfo();
75      tobagoConfig.lock();
76  
77      servletContext.setAttribute(TobagoConfig.TOBAGO_CONFIG, tobagoConfig);
78      return tobagoConfig;
79    }
80  
81    protected TobagoConfigImpl initializeConfigFromFiles()
82        throws ServletException, IOException, SAXException, ParserConfigurationException, URISyntaxException {
83      configFromClasspath();
84      configFromWebInf();
85      final TobagoConfigSorter sorter = new TobagoConfigSorter(configFragmentList);
86      sorter.sort();
87      return sorter.merge();
88    }
89  
90    private void configFromWebInf()
91        throws IOException, SAXException, ParserConfigurationException, URISyntaxException {
92  
93      final URL url = servletContext.getResource("/" + WEB_INF_TOBAGO_CONFIG_XML);
94      if (url != null) {
95        configFragmentList.add(new TobagoConfigParser().parse(url));
96      }
97    }
98  
99    private void configFromClasspath() throws ServletException {
100 
101     try {
102       if (LOG.isInfoEnabled()) {
103         LOG.info("Searching for '" + META_INF_TOBAGO_CONFIG_XML + "'");
104       }
105       final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
106       final Enumeration<URL> urls = classLoader.getResources(META_INF_TOBAGO_CONFIG_XML);
107       while (urls.hasMoreElements()) {
108         final URL themeUrl = urls.nextElement();
109         try {
110           final TobagoConfigFragment fragment = new TobagoConfigParser().parse(themeUrl);
111           fragment.setUrl(themeUrl);
112           configFragmentList.add(fragment);
113 
114           // tomcat uses jar
115           // weblogic uses zip
116           // IBM WebSphere uses wsjar
117           final String protocol = themeUrl.getProtocol();
118           if (!"jar".equals(protocol) && !"zip".equals(protocol) && !"wsjar".equals(protocol)) {
119             LOG.warn("Unknown protocol '" + themeUrl + "'");
120           }
121         } catch (final Exception e) {
122           throw new Exception(e.getClass().getName() + " on themeUrl: " + themeUrl, e);
123         }
124       }
125     } catch (final Exception e) {
126       final String msg = "while loading ";
127       LOG.error(msg, e);
128       throw new ServletException(msg, e);
129     }
130   }
131 }