001    package org.apache.myfaces.tobago.config;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one or more
005     * contributor license agreements.  See the NOTICE file distributed with
006     * this work for additional information regarding copyright ownership.
007     * The ASF licenses this file to You under the Apache License, Version 2.0
008     * (the "License"); you may not use this file except in compliance with
009     * the License.  You may obtain a copy of the License at
010     *
011     *      http://www.apache.org/licenses/LICENSE-2.0
012     *
013     * Unless required by applicable law or agreed to in writing, software
014     * distributed under the License is distributed on an "AS IS" BASIS,
015     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016     * See the License for the specific language governing permissions and
017     * limitations under the License.
018     */
019    
020    import org.apache.commons.digester.Digester;
021    import org.apache.commons.io.IOUtils;
022    import org.apache.myfaces.tobago.context.MarkupConfig;
023    import org.apache.myfaces.tobago.context.RendererConfig;
024    import org.apache.myfaces.tobago.context.RenderersConfigImpl;
025    import org.slf4j.Logger;
026    import org.slf4j.LoggerFactory;
027    import org.xml.sax.SAXException;
028    
029    import javax.faces.FacesException;
030    import javax.servlet.ServletContext;
031    import java.io.IOException;
032    import java.io.InputStream;
033    import java.net.URL;
034    
035    public class TobagoConfigParser {
036    
037      private static final Logger LOG = LoggerFactory.getLogger(TobagoConfigParser.class);
038    
039      private static final String TOBAGO_CONFIG_DTD_1_0 = "/org/apache/myfaces/tobago/config/tobago-config_1_0.dtd";
040      private static final String TOBAGO_CONFIG_DTD_1_0_29 = "/org/apache/myfaces/tobago/config/tobago-config-1.0.29.dtd";
041      private static final String TOBAGO_CONFIG_DTD_1_0_30 = "/org/apache/myfaces/tobago/config/tobago-config-1.0.30.dtd";
042      private static final String TOBAGO_CONFIG_DTD_1_0_34 = "/org/apache/myfaces/tobago/config/tobago-config-1.0.34.dtd";
043      private static final String TOBAGO_CONFIG_DTD_1_5 = "/org/apache/myfaces/tobago/config/tobago-config-1.5.dtd";
044    
045      public TobagoConfig parse(ServletContext context) throws IOException, SAXException, FacesException {
046    
047        TobagoConfig tobagoConfig = new TobagoConfig();
048        Digester digester = configure(tobagoConfig);
049        parse(context, digester);
050        return tobagoConfig;
051      }
052    
053      private Digester configure(TobagoConfig config) {
054        Digester digester = new Digester();
055        digester.setUseContextClassLoader(true);
056        digester.push(config);
057        digester.setValidating(true);
058    
059        // theme-config
060        digester.addCallMethod("tobago-config/theme-config/default-theme", "setDefaultThemeName", 0);
061        digester.addCallMethod("tobago-config/theme-config/supported-theme", "addSupportedThemeName", 0);
062    
063        // resource dirs
064        digester.addCallMethod("tobago-config/resource-dir", "addResourceDir", 0);
065    
066        // enable ajax
067        digester.addCallMethod("tobago-config/ajax-enabled", "setAjaxEnabled", 0);
068    
069        // see bug TOBAGO-912
070        digester.addCallMethod("tobago-config/fix-resource-order", "setFixResourceOrder", 0);
071    
072        // see bug TOBAGO-916
073        digester.addCallMethod("tobago-config/fix-layout-transparency", "setFixLayoutTransparency", 0);
074    
075        // session secret
076        digester.addCallMethod("tobago-config/create-session-secret", "setCreateSessionSecret", 0);
077        digester.addCallMethod("tobago-config/check-session-secret", "setCheckSessionSecret", 0);
078    
079        // renderer config
080        digester.addObjectCreate("tobago-config/renderers", RenderersConfigImpl.class);
081        digester.addSetNext("tobago-config/renderers", "setRenderersConfig");
082        digester.addObjectCreate("tobago-config/renderers/renderer", RendererConfig.class);
083        digester.addSetNext("tobago-config/renderers/renderer", "addRenderer");
084        digester.addCallMethod("tobago-config/renderers/renderer/name", "setName", 0);
085        digester.addObjectCreate("tobago-config/renderers/renderer/supported-markup", MarkupConfig.class);
086        digester.addSetNext("tobago-config/renderers/renderer/supported-markup", "setMarkupConfig");
087        digester.addCallMethod("tobago-config/renderers/renderer/supported-markup/markup", "addMarkup", 0);
088    
089        return digester;
090      }
091    
092      private void parse(ServletContext context, Digester digester) throws IOException, SAXException, FacesException {
093    
094        String configPath = "/WEB-INF/tobago-config.xml";
095        InputStream input = null;
096        registerDtds(digester);
097        try {
098          input = context.getResourceAsStream(configPath);
099          if (input != null) {
100            digester.parse(input);
101          } else {
102            LOG.warn("No config file found: '" + configPath + "'. Tobago runs with a default configuration.");
103          }
104        } finally {
105          IOUtils.closeQuietly(input);
106        }
107      }
108    
109      private void registerDtds(Digester digester) {
110        registerDtd(digester, "-//Atanion GmbH//DTD Tobago Config 1.0//EN", TOBAGO_CONFIG_DTD_1_0);
111        registerDtd(digester, "-//The Apache Software Foundation//DTD Tobago Config 1.0//EN", TOBAGO_CONFIG_DTD_1_0);
112        registerDtd(digester, "-//The Apache Software Foundation//DTD Tobago Config 1.0.29//EN", TOBAGO_CONFIG_DTD_1_0_29);
113        registerDtd(digester, "-//The Apache Software Foundation//DTD Tobago Config 1.0.30//EN", TOBAGO_CONFIG_DTD_1_0_30);
114        registerDtd(digester, "-//The Apache Software Foundation//DTD Tobago Config 1.0.34//EN", TOBAGO_CONFIG_DTD_1_0_34);
115        registerDtd(digester, "-//The Apache Software Foundation//DTD Tobago Config 1.5//EN", TOBAGO_CONFIG_DTD_1_5);
116      }
117    
118      private void registerDtd(Digester digester, String publicId, String entityUrl) {
119        URL url = TobagoConfigParser.class.getResource(entityUrl);
120        if (LOG.isDebugEnabled()) {
121          LOG.debug("Registering dtd: url='{}'", url);
122        }
123        if (null != url) {
124          digester.register(publicId, url.toString());
125        } else {
126          LOG.warn("Unable to retrieve local DTD '" + entityUrl + "'; trying external URL");
127        }
128      }
129    }