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    /*
021     * Created 24.06.2003 08:53:35.
022     * $Id: TobagoConfigParser.java 601107 2007-12-04 22:12:14Z bommel $
023     */
024    
025    import org.apache.commons.digester.Digester;
026    import org.apache.commons.io.IOUtils;
027    import org.apache.commons.logging.Log;
028    import org.apache.commons.logging.LogFactory;
029    import org.apache.myfaces.tobago.context.RenderersConfigImpl;
030    import org.apache.myfaces.tobago.context.RendererConfig;
031    import org.apache.myfaces.tobago.context.MarkupConfig;
032    import org.xml.sax.SAXException;
033    
034    import javax.faces.FacesException;
035    import javax.servlet.ServletContext;
036    import java.io.IOException;
037    import java.io.InputStream;
038    import java.net.URL;
039    
040    public class TobagoConfigParser {
041    
042      private static final Log LOG = LogFactory.getLog(TobagoConfigParser.class);
043      private static final String TOBAGO_CONFIG_DTD = "/org/apache/myfaces/tobago/config/tobago-config_1_0.dtd";
044    
045      public TobagoConfig parse(ServletContext context)
046          throws IOException, SAXException, FacesException {
047    
048        TobagoConfig tobagoConfig = new TobagoConfig();
049        Digester digester = configure(tobagoConfig);
050        parse(context, digester);
051        return tobagoConfig;
052      }
053    
054      private Digester configure(TobagoConfig config) {
055        Digester digester = new Digester();
056        digester.setUseContextClassLoader(true);
057        digester.push(config);
058        digester.setValidating(true);
059    
060        // theme-config
061        digester.addCallMethod("tobago-config/theme-config/default-theme", "setDefaultThemeName", 0);
062        digester.addCallMethod("tobago-config/theme-config/supported-theme", "addSupportedThemeName", 0);
063    
064        // mapping rules
065        digester.addObjectCreate("tobago-config/mapping-rule", MappingRule.class);
066        digester.addSetNext("tobago-config/mapping-rule", "addMappingRule");
067        digester.addCallMethod(
068            "tobago-config/mapping-rule/request-uri", "setRequestUri", 0);
069        digester.addCallMethod(
070            "tobago-config/mapping-rule/forward-uri", "setForwardUri", 0);
071        digester.addObjectCreate(
072            "tobago-config/mapping-rule/attribute", Attribute.class);
073        digester.addSetNext(
074            "tobago-config/mapping-rule/attribute", "addAttribute");
075        digester.addCallMethod(
076            "tobago-config/mapping-rule/attribute/key", "setKey", 0);
077        digester.addCallMethod(
078            "tobago-config/mapping-rule/attribute/value", "setValue", 0);
079    
080        // XXX: deprecated! will ever be true (will be removed in next release after 1.0.7)
081        digester.addCallMethod("tobago-config/load-theme-resources-from-classpath", "setLoadThemesFromClasspath", 0);
082    
083        // resource dirs
084        digester.addCallMethod("tobago-config/resource-dir", "addResourceDir", 0);
085    
086        // enable ajax
087        digester.addCallMethod("tobago-config/ajax-enabled", "setAjaxEnabled", 0);
088        digester.addObjectCreate("tobago-config/renderers", RenderersConfigImpl.class);
089        digester.addSetNext("tobago-config/renderers", "setRenderersConfig");
090        digester.addObjectCreate("tobago-config/renderers/renderer", RendererConfig.class);
091        digester.addSetNext("tobago-config/renderers/renderer", "addRenderer");
092        digester.addCallMethod("tobago-config/renderers/renderer/name", "setName", 0);
093        digester.addObjectCreate("tobago-config/renderers/renderer/supported-markup", MarkupConfig.class);
094        digester.addSetNext("tobago-config/renderers/renderer/supported-markup", "setMarkupConfig");
095        digester.addCallMethod("tobago-config/renderers/renderer/supported-markup/markup", "addMarkup", 0);
096    
097        return digester;
098      }
099    
100      // TODO: make it runnable without config file, using defaults
101      private void parse(ServletContext context, Digester digester)
102          throws IOException, SAXException, FacesException {
103    
104        String configPath = "/WEB-INF/tobago-config.xml";
105        InputStream input = null;
106        registerDtd(digester);
107        try {
108          input = context.getResourceAsStream(configPath);
109          if (input != null) {
110            digester.parse(input);
111          } else {
112            throw new FacesException(
113                "No config file found: '" + configPath + "'. Tobago can't run without configuration.");
114          }
115        } finally {
116          IOUtils.closeQuietly(input);
117        }
118      }
119    
120      private void registerDtd(Digester digester) {
121        URL url = TobagoConfigParser.class.getResource(TOBAGO_CONFIG_DTD);
122        if (LOG.isDebugEnabled()) {
123          LOG.debug("registering dtd: url=" + url);
124        }
125        if (null != url) {
126          digester.register(
127              "-//Atanion GmbH//DTD Tobago Config 1.0//EN",
128              url.toString());
129          digester.register(
130              "-//The Apache Software Foundation//DTD Tobago Config 1.0//EN",
131              url.toString());
132        } else {
133          LOG.warn(
134              "unable to retrieve local DTD '" + TOBAGO_CONFIG_DTD
135                  + "'; trying external URL");
136        }
137      }
138    
139    }