Author: craigmcc
Date: Tue Jan  2 11:02:36 2007
New Revision: 491897

URL: http://svn.apache.org/viewvc?view=rev&rev=491897
Log:
Beginnings of support for optional parsing of faces-config.xml files
(SHALE-262) to register components, converters, renderers, and validators.
Hasn't been tested yet other than being able to instantiate the helper, but
that will come next.

Added:
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/config/
    
shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/config/ConfigParser.java
   (with props)
    
shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/config/package.html
   (with props)
    shale/framework/trunk/shale-test/src/test/java/org/apache/shale/test/config/
    
shale/framework/trunk/shale-test/src/test/java/org/apache/shale/test/config/ConfigParserTestCase.java
   (with props)
Modified:
    shale/framework/trunk/shale-test/pom.xml

Modified: shale/framework/trunk/shale-test/pom.xml
URL: 
http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/pom.xml?view=diff&rev=491897&r1=491896&r2=491897
==============================================================================
--- shale/framework/trunk/shale-test/pom.xml (original)
+++ shale/framework/trunk/shale-test/pom.xml Tue Jan  2 11:02:36 2007
@@ -34,6 +34,14 @@
 
     <dependencies>
 
+        <!-- Required only for using the org.apache.shale.test.config package 
-->
+        <dependency>
+            <groupId>commons-digester</groupId>
+            <artifactId>commons-digester</artifactId>
+            <version>1.8</version>
+            <optional>true</optional>
+        </dependency>
+
         <dependency>
             <groupId>htmlunit</groupId>
             <artifactId>htmlunit</artifactId>

Added: 
shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/config/ConfigParser.java
URL: 
http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/config/ConfigParser.java?view=auto&rev=491897
==============================================================================
--- 
shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/config/ConfigParser.java
 (added)
+++ 
shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/config/ConfigParser.java
 Tue Jan  2 11:02:36 2007
@@ -0,0 +1,411 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.test.config;
+
+import java.io.IOException;
+import java.net.URL;
+import javax.faces.FactoryFinder;
+import javax.faces.application.Application;
+import javax.faces.application.ApplicationFactory;
+import javax.faces.render.RenderKit;
+import javax.faces.render.RenderKitFactory;
+import javax.faces.render.Renderer;
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.Rule;
+import org.apache.shale.test.mock.MockRenderKit;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * <p>Utility class to parse JavaServer Faces configuration resources, and
+ * register JSF artifacts with the mock object hierarchy.</p>
+ *
+ * <p>The following artifacts are registered:</p>
+ * <ul>
+ *     <li><code>Converter</code> (by-id and by-class)</li>
+ *     <li><code>RenderKit</code> and <code>Renderer</code></li>
+ *     <li><code>UIComponent</code></li>
+ *     <li><code>Validator</code></li>
+ * </ul>
+ *
+ * <p>Note that any declared <em>factory</em> instances are explicitly
+ * <strong>NOT</strong> registered, allowing the mock object hierarchy
+ * of the Shale Test Framework to manage these APIs.</p>
+ *
+ * <p><strong>USAGE NOTE</strong> - If you are using an instance of this
+ * class within a subclass of <code>AbstractJsfTestCase</code> or
+ * <code>AbstractJmockJsfTestCase</code>, be sure you have completed the
+ * <code>setUp()</code> processing in this base class before calling one
+ * of the <code>parse()</code> methods.</p>
+ */
+public final class ConfigParser {
+    
+
+    // ------------------------------------------------------------ 
Constructors
+
+
+    /** Creates a new instance of ConfigParser */
+    public ConfigParser() {
+    }
+    
+
+    // ------------------------------------------------------ Instance 
Variables
+
+
+    /**
+     * <p>The <code>Digester</code> instance we will use for parsing.</p>
+     */
+    private Digester digester = null;
+
+
+    // ------------------------------------------------------- Public 
Properties
+
+
+    // ---------------------------------------------------------- Public 
Methods
+
+
+    /**
+     * <p>Parse the specified JavaServer Faces configuration resource, causing
+     * the appropriate JSF artifacts to be registered with the mock object
+     * hierarchy.</p>
+     *
+     * @param url <code>URL</code> of the configuration resource to parse
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception SAXException if a parsing error occurs
+     */
+    public void parse(URL url) throws IOException, SAXException {
+
+        // Acquire and configure the Digester instance we will use
+        Digester digester = digester();
+        ApplicationFactory factory = (ApplicationFactory)
+          FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
+        Application application = factory.getApplication();
+        digester.push(application);
+
+        // Perform the required parsing
+        try {
+            digester.parse(url);
+        } finally {
+            digester.clear();
+        }
+
+    }
+
+
+    /**
+     * <p>Parse the specified set of JavaServer Faces configuration resources,
+     * in the listed order, causing the appropriate JSF artifacts to be 
registered
+     * with the mock object hierarchy.</p>
+     *
+     * @param urls <code>URL</code>s of the configuration resources to parse
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception SAXException if a parsing error occurs
+     */
+    public void parse(URL[] urls) throws IOException, SAXException {
+
+        for (int i = 0; i < urls.length; i++) {
+            parse(urls[i]);
+        }
+
+    }
+
+
+    // --------------------------------------------------------- Private 
Methods
+
+
+    /**
+     * <p>Return the <code>Digester</code> instance we will use for parsing,
+     * creating and configuring a new instance if necessary.</p>
+     */
+    private Digester digester() {
+
+        if (this.digester == null) {
+            this.digester = new Digester();
+            digester.addRule("faces-config/component", new ComponentRule());
+            digester.addCallMethod
+              ("faces-config/component/component-type", "setComponentType", 0);
+            digester.addCallMethod
+              ("faces-config/component/component-class", "setComponentClass", 
0);
+            digester.addRule("faces-config/converter", new ValidatorRule());
+            digester.addCallMethod
+              ("faces-config/converter/converter-id", "setConverterId", 0);
+            digester.addCallMethod
+              ("faces-config/converter/converter-class", "setConverterClass", 
0);
+            digester.addCallMethod
+              ("faces-config/converter/converter-for-class", 
"setConverterForClass", 0);
+            digester.addRule("faces-config/render-kit", new RenderKitRule());
+            digester.addRule("faces-config/render-kit/render-kit-id", new 
RenderKitIdRule());
+            digester.addRule("faces-config/validator", new ValidatorRule());
+            digester.addCallMethod
+              ("faces-config/validator/validator-id", "setValidatorId", 0);
+            digester.addCallMethod
+              ("faces-config/validator/validator-class", "setValidatorClass", 
0);
+        }
+        return this.digester;
+
+    }
+
+
+    // --------------------------------------------------------- Private 
Classes
+
+
+    /**
+     * <p>Data bean that stores information related to a component.</p>
+     */
+    class ComponentBean {
+
+        private String componentClass;
+        public String getComponentClass() {
+            return this.componentClass;
+        }
+        public void setComponentClass(String componentClass) {
+            this.componentClass = componentClass;
+        }
+
+        private String componentType;
+        public String getComponentType() {
+            return this.componentType;
+        }
+        public void setComponentType(String componentType) {
+            this.componentType = componentType;
+        }
+
+    }
+
+
+    /**
+     * <p>Digester <code>Rule</code> for processing components.</p>
+     */
+    class ComponentRule extends Rule {
+
+        public void begin(String namespace, String name, Attributes 
attributes) {
+            getDigester().push(new ComponentBean());
+        }
+
+        public void end(String namespace, String name) {
+            ComponentBean bean = (ComponentBean) getDigester().pop();
+            Application application = (Application) getDigester().peek();
+            application.addComponent(bean.getComponentType(), 
bean.getComponentClass());
+        }
+
+    }
+
+
+    /**
+     * <p>Data bean that stores information related to a converter.</p>
+     */
+    class ConverterBean {
+
+        private String converterClass;
+        public String getConverterClass() {
+            return this.converterClass;
+        }
+        public void setConverterClass(String converterClass) {
+            this.converterClass = converterClass;
+        }
+
+        private String converterForClass;
+        public String getConverterForClass() {
+            return this.converterForClass;
+        }
+        public void setConverterForClass(String converterForClass) {
+            this.converterForClass = converterForClass;
+        }
+
+        private String converterId;
+        public String getConverterId() {
+            return this.converterId;
+        }
+        public void setConverterId(String converterId) {
+            this.converterId = converterId;
+        }
+
+    }
+
+
+    /**
+     * <p>Digester <code>Rule</code> for processing converers.</p>
+     */
+    class ConverterRule extends Rule {
+
+        public void begin(String namespace, String name, Attributes 
attributes) {
+            getDigester().push(new ConverterBean());
+        }
+
+        public void end(String namespace, String name) {
+            ConverterBean bean = (ConverterBean) getDigester().pop();
+            Application application = (Application) getDigester().peek();
+            if (bean.getConverterId() != null) {
+                application.addConverter(bean.getConverterId(), 
bean.getConverterClass());
+            } else {
+                Class clazz = null;
+                try {
+                    clazz = 
this.getClass().getClassLoader().loadClass(bean.getConverterForClass());
+                } catch (ClassNotFoundException e) {
+                    throw new 
IllegalArgumentException(bean.getConverterForClass(), e);
+                }
+                application.addConverter(clazz, bean.getConverterClass());
+            }
+        }
+
+    }
+
+
+    /**
+     * <p>Digester <code>Rule</code> for processing render kits.</p>
+     */
+    class RenderKitRule extends Rule {
+
+        public void begin(String namespace, String name, Attributes 
attributes) {
+            RenderKitFactory factory = (RenderKitFactory)
+              FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+            getDigester().push(factory.getRenderKit(null, 
RenderKitFactory.HTML_BASIC_RENDER_KIT));
+        }
+
+        public void end(String namespace, String name) {
+            getDigester().pop();
+        }
+
+    }
+
+
+    /**
+     * <p>Digester <code>Rule</code> for processing render kit identifiers.</p>
+     */
+    class RenderKitIdRule extends Rule {
+
+        public void body(String namespace, String name, String text) {
+            String renderKitId = text.trim();
+            RenderKitFactory factory = (RenderKitFactory)
+              FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+            RenderKit renderKit = factory.getRenderKit(null, renderKitId);
+            if (renderKit == null) {
+                renderKit = new MockRenderKit();
+                factory.addRenderKit(renderKitId, renderKit);
+            }
+            digester.pop();
+            digester.push(renderKit);
+        }
+
+    }
+
+
+    /**
+     * <p>Data bean that stores information related to a renderer.</p>
+     */
+    class RendererBean {
+
+        private String componentFamily;
+        public String getComponentFamily() {
+            return this.componentFamily;
+        }
+        public void setComponentFamily(String componentFamily) {
+            this.componentFamily = componentFamily;
+        }
+
+        private String rendererClass;
+        public String getRendererClass() {
+            return this.rendererClass;
+        }
+        public void setRendererClass(String rendererClass) {
+            this.rendererClass = rendererClass;
+        }
+
+        private String rendererType;
+        public String getRendererType() {
+            return this.rendererType;
+        }
+        public void setRendererType(String rendererType) {
+            this.rendererType = rendererType;
+        }
+
+    }
+
+
+    /**
+     * <p>Digester <code>Rule</code> for processing renderers.</p>
+     */
+    class RendererRule extends Rule {
+
+        public void begin(String namespace, String name, Attributes 
attributes) {
+            getDigester().push(new RendererBean());
+        }
+
+        public void end(String namespace, String name) {
+            RendererBean bean = (RendererBean) getDigester().pop();
+            RenderKit kit = (RenderKit) getDigester().peek();
+            Renderer renderer = null;
+            Class clazz = null;
+            try {
+                clazz = 
this.getClass().getClassLoader().loadClass(bean.getRendererClass());
+                renderer = (Renderer) clazz.newInstance();
+            } catch (Exception e) {
+                throw new IllegalArgumentException(bean.getRendererClass(), e);
+            }
+            kit.addRenderer(bean.getComponentFamily(), bean.getRendererType(),
+                            renderer);
+        }
+
+    }
+
+
+    /**
+     * <p>Data bean that stores information related to a validator.</p>
+     */
+    class ValidatorBean {
+
+        private String validatorClass;
+        public String getValidatorClass() {
+            return this.validatorClass;
+        }
+        public void setValidatorClass(String validatorClass) {
+            this.validatorClass = validatorClass;
+        }
+
+        private String validatorId;
+        public String getValidatorId() {
+            return this.validatorId;
+        }
+        public void setValidatorId(String validatorId) {
+            this.validatorId = validatorId;
+        }
+
+    }
+
+
+    /**
+     * <p>Digester <code>Rule</code> for processing validators.</p>
+     */
+    class ValidatorRule extends Rule {
+
+        public void begin(String namespace, String name, Attributes 
attributes) {
+            getDigester().push(new ValidatorBean());
+        }
+
+        public void end(String namespace, String name) {
+            ValidatorBean bean = (ValidatorBean) getDigester().pop();
+            Application application = (Application) getDigester().peek();
+            application.addValidator(bean.getValidatorId(), 
bean.getValidatorClass());
+        }
+
+    }
+
+
+}

Propchange: 
shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/config/ConfigParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/config/ConfigParser.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: 
shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/config/package.html
URL: 
http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/config/package.html?view=auto&rev=491897
==============================================================================
--- 
shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/config/package.html
 (added)
+++ 
shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/config/package.html
 Tue Jan  2 11:02:36 2007
@@ -0,0 +1,30 @@
+<body>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<p>This package contains a utility class,
+<a href="ConfigParser.html">ConfigParser</a>, which provides a
+<code>parse()</code> method that can parse JavaServer Faces configuration
+resources.  It supports the registration, in the mock object hierarchy
+set up by an instance of <code>AbstractJsfTestCase</code> or
+<code>AbstractJmockJsfTestCase</code>, of the following JSF artifacts:</p>
+<ul>
+    <li><code>Converter</code> (by-id and by-class)</li>
+    <li><code>RenderKit</code> and <code>Renderer</code></li>
+    <li><code>UIComponent</code></li>
+    <li><code>Validator</code></li>
+</ul>
+</body>

Propchange: 
shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/config/package.html
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/config/package.html
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: 
shale/framework/trunk/shale-test/src/test/java/org/apache/shale/test/config/ConfigParserTestCase.java
URL: 
http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/test/java/org/apache/shale/test/config/ConfigParserTestCase.java?view=auto&rev=491897
==============================================================================
--- 
shale/framework/trunk/shale-test/src/test/java/org/apache/shale/test/config/ConfigParserTestCase.java
 (added)
+++ 
shale/framework/trunk/shale-test/src/test/java/org/apache/shale/test/config/ConfigParserTestCase.java
 Tue Jan  2 11:02:36 2007
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.test.config;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.shale.test.base.AbstractJsfTestCase;
+
+/**
+ * <p>Unit tests for the configuration parser utility class.</p>
+ */
+public class ConfigParserTestCase extends AbstractJsfTestCase {
+
+
+    // ------------------------------------------------------------ 
Constructors
+
+
+    // Construct a new instance of this test case.
+    public ConfigParserTestCase(String name) {
+        super(name);
+    }
+
+
+    // ---------------------------------------------------- Overall Test 
Methods
+
+
+    // Set up instance variables required by this test case.
+    protected void setUp() throws Exception {
+
+        super.setUp();
+        parser = new ConfigParser();
+
+    }
+
+
+    // Return the tests included in this test case.
+    public static Test suite() {
+
+        return (new TestSuite(ConfigParserTestCase.class));
+
+    }
+
+
+    // Tear down instance variables required by this test case.
+    protected void tearDown() throws Exception {
+
+        parser = null;
+        super.tearDown();
+
+    }
+
+
+    // ------------------------------------------------------ Instance 
Variables
+
+
+    // ConfigParser instance under test
+    ConfigParser parser = null;
+
+
+    // ------------------------------------------------- Individual Test 
Methods
+
+
+    // Test a pristine instance
+    public void testPristine() {
+
+        assertNotNull(parser);
+
+    }
+
+
+    // --------------------------------------------------------- Private 
Methods
+
+
+}

Propchange: 
shale/framework/trunk/shale-test/src/test/java/org/apache/shale/test/config/ConfigParserTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
shale/framework/trunk/shale-test/src/test/java/org/apache/shale/test/config/ConfigParserTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL


Reply via email to