Author: craigmcc
Date: Wed Nov 22 20:23:00 2006
New Revision: 478459

URL: http://svn.apache.org/viewvc?view=rev&rev=478459
Log:
Refactor validator resource configuration into a ServletContextListener that
is called at startup time, for the following reasons:

* Architectural similarity to other Shale modules

* Ability to "fail fast" on invalid configuration resource names

* Ability to clean up the Commons BeanUtils and Commons Logging
  modules that can otherwise result in memory leaks and/or locked
  JAR files on Windows platforms.

SHALE-340


Added:
    
shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/faces/ValidatorLifecycleListener.java
   (with props)
Modified:
    
shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/CommonsValidator.java
    
shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/Globals.java
    shale/framework/trunk/shale-validator/src/main/resources/META-INF/taglib.tld
    
shale/framework/trunk/shale-validator/src/test/java/org/apache/shale/validator/CommonsValidatorTestCase.java
    
shale/framework/trunk/shale-validator/src/test/java/org/apache/shale/validator/ValidatorDefaultTestCase.java

Modified: 
shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/CommonsValidator.java
URL: 
http://svn.apache.org/viewvc/shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/CommonsValidator.java?view=diff&rev=478459&r1=478458&r2=478459
==============================================================================
--- 
shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/CommonsValidator.java
 (original)
+++ 
shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/CommonsValidator.java
 Wed Nov 22 20:23:00 2006
@@ -17,6 +17,7 @@
 
 package org.apache.shale.validator;
 
+import com.sun.org.apache.bcel.internal.classfile.ConstantString;
 import java.io.IOException;
 import java.io.Serializable;
 import java.lang.reflect.InvocationTargetException;
@@ -453,64 +454,18 @@
    }
 
 
-   /**
-    * This method lazily configures validator resources by reading either
-    * the default <code>validalidator-rules.xml</code> file in
-    * shale-core.jar or the list of resources configured using the init
-    * param <code>org.apache.shale.validator.VALIDATOR_RULES</code>.
-    *
-    * @return validator resources loaded from the configuration file.
-    */
+    /**
+     * <p>Return the validator resources that were configured and cached
+     * at application startup time.</p>
+     */
     private static ValidatorResources getValidatorResources() {
-        final String VALIDATOR_RESOURCES_KEY =
-            "org.apache.shale.validator.resources";
+
        FacesContext context = FacesContext.getCurrentInstance();
        ExternalContext external = context.getExternalContext();
        Map applicationMap = external.getApplicationMap();
-       ValidatorResources validatorResources
-          = (ValidatorResources) applicationMap.get(VALIDATOR_RESOURCES_KEY);
-       if (validatorResources == null) {
-          try {
-             String pathnames = 
external.getInitParameter(Globals.VALIDATOR_RULES);
-             if (pathnames == null || pathnames.length() <= 0) {
-                pathnames = Globals.DEFAULT_VALIDATOR_RULES;
-             }
-             StringTokenizer st = new StringTokenizer(pathnames, ",");
-             List urlList = new ArrayList();
-             while (st.hasMoreTokens()) {
-                String validatorRules = st.nextToken().trim();
-                log.info(messages.getMessage("commonsValidator.loadresource",
-                                      new Object[] {validatorRules}));
-                URL input = external.getResource(validatorRules);
-                if (input == null) {
-                   input = CommonsValidator.class.getResource(validatorRules);
-                }
-                if (input != null) {
-                   urlList.add(input);
-                } else {
-                   log.warn(messages.
-                            getMessage("commonsValidator.skipresource",
-                                          new Object[] {validatorRules}));
-                }
-             }
-             int urlSize = urlList.size();
-             String[] urlArray = new String[urlSize];
-             for (int urlIndex = 0; urlIndex < urlSize; urlIndex++) {
-                URL url = (URL) urlList.get(urlIndex);
-                urlArray[urlIndex] = url.toExternalForm();
-             }
-             validatorResources = new ValidatorResources(urlArray);
-             applicationMap.put(VALIDATOR_RESOURCES_KEY, validatorResources);
-          } catch (IOException ex) {
-             log.error(messages.getMessage("commonsValidator.loaderror"), ex);
-             return null;
-          } catch (SAXException ex) {
-             log.error(messages.getMessage("commonsValidator.loaderror"), ex);
-             return null;
-          }
-       }
+       return (ValidatorResources)
+         
context.getExternalContext().getApplicationMap().get(Globals.VALIDATOR_RESOURCES);
 
-       return validatorResources;
     }
 
 

Modified: 
shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/Globals.java
URL: 
http://svn.apache.org/viewvc/shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/Globals.java?view=diff&rev=478459&r1=478458&r2=478459
==============================================================================
--- 
shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/Globals.java
 (original)
+++ 
shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/Globals.java
 Wed Nov 22 20:23:00 2006
@@ -18,19 +18,12 @@
 package org.apache.shale.validator;
 
 /**
- * <p>Manifest constants that are global to the Validator Support
+ * <p>Manifest constants that are global to the Validator Integration
  * implementation.</p>
  */
 
 public class Globals {
 
-    /**
-     * <p>Context initialization parameter used to specify a comma delimited
-     * list of context relative resource paths to resources containing our
-     * validator configuration information.</p>
-     */
-    public static final String VALIDATOR_RULES =
-      "org.apache.shale.validator.VALIDATOR_RULES";
 
     /**
      * <p>Location of the default Validator configuration file.
@@ -40,5 +33,23 @@
      */
     public static final String DEFAULT_VALIDATOR_RULES =
       "/org/apache/shale/validator/validator-rules.xml";
+
+
+    /**
+     * <p>Application scope attribute under which we store the Commons
+     * Validator resources that have been configured.</p>
+     */
+    public static final String VALIDATOR_RESOURCES =
+      "org.apache.shale.validator.RESOURCES";
+
+
+    /**
+     * <p>Context initialization parameter used to specify a comma delimited
+     * list of context relative resource paths to resources containing our
+     * validator configuration information.</p>
+     */
+    public static final String VALIDATOR_RULES =
+      "org.apache.shale.validator.VALIDATOR_RULES";
+
 
 }

Added: 
shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/faces/ValidatorLifecycleListener.java
URL: 
http://svn.apache.org/viewvc/shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/faces/ValidatorLifecycleListener.java?view=auto&rev=478459
==============================================================================
--- 
shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/faces/ValidatorLifecycleListener.java
 (added)
+++ 
shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/faces/ValidatorLifecycleListener.java
 Wed Nov 22 20:23:00 2006
@@ -0,0 +1,206 @@
+/*
+ * 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.validator.faces;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import javax.faces.FacesException;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.validator.ValidatorResources;
+import org.apache.shale.validator.Globals;
+import org.xml.sax.SAXException;
+
+/**
+ * <p>ServletContextListener that loads validator configuration resources
+ * at application startup, and cleans up the libraries we depend on at
+ * application shutdown.</p>
+ */
+public class ValidatorLifecycleListener implements ServletContextListener {
+    
+
+    // -------------------------------------------------------- Static 
Variables
+
+
+    // ------------------------------------------------------ Instance 
Variables
+
+
+    /**
+     * <p>The <code>Log</code> instance we will use for this listener.</p>
+     */
+    private Log log = LogFactory.getLog(ValidatorLifecycleListener.class);
+
+
+    // ------------------------------------------ ServletContextListener 
Methods
+
+
+    /**
+     * <p>Process an application shutdown event.</p>
+     *
+     * @param event Shutdown event to be processed
+     */
+    public void contextDestroyed(ServletContextEvent event) {
+
+        if (log.isInfoEnabled()) {
+            log.info("Finalizing Validator Integration");
+        }
+
+        // Clean up our cache of dialog configuration information
+        event.getServletContext().removeAttribute(Globals.VALIDATOR_RESOURCES);
+
+        // Clean up dependency libraries we have used
+        PropertyUtils.clearDescriptors(); // Used by Commons Validator via 
Digester
+        LogFactory.release(Thread.currentThread().getContextClassLoader());
+        log = null;
+
+    }
+
+
+    /**
+     * <p>Process an application startup event.</p>
+     *
+     * @param event Startup event to be processed
+     */
+    public void contextInitialized(ServletContextEvent event) {
+
+        if (log.isInfoEnabled()) {
+            log.info("Initializing Validator Integration");
+        }
+
+        // Configure and cache the validator resources for this application
+        ServletContext context = event.getServletContext();
+        ValidatorResources resources = null;
+        try {
+            resources = validatorResources(context);
+        } catch (IllegalArgumentException e) {
+            throw e;
+        } catch (IOException e) {
+            throw new FacesException(e);
+        } catch (SAXException e) {
+            throw new FacesException(e);
+        }
+        context.setAttribute(Globals.VALIDATOR_RESOURCES, resources);
+
+    }
+
+
+    // --------------------------------------------------------- Private 
Methods
+
+
+   /**
+    * <p>Configure the validator resources to be used by this application,
+    * by reading the list of resources configured on the context init
+    * parameter named by <code>Globals.VALIDATOR_RULES</code> (if any),
+    * followed by reading the default resource named by
+    * <code>Globals.DEFAULT_VALIDATOR_RULES</code> (if it has not already
+    * been processed).</p>
+    *
+    * @param context <code>ServletContext</code> for this application
+    *
+    * @exception IllegalArgumentException if a specified resource cannot
+    *  be located, or if a malformed URL is constructed from the
+    *  specified resource name
+    * @exception IOException if an input/output error occurs while
+    *  processing the specified configuration resources
+    * @exception SAXException if an XML parsing error occurs while
+    *  processing the specified configuration resources
+    */
+    private ValidatorResources validatorResources(ServletContext context)
+      throws IOException, SAXException {
+
+        // Process the explicitly configured resources (if any)
+        List urls = new ArrayList();
+        URL url = null;
+        boolean didDefault = false;
+        String pathnames = context.getInitParameter(Globals.VALIDATOR_RULES);
+        if (pathnames != null) {
+            pathnames = pathnames.trim();
+            while (pathnames.length() > 0) {
+
+                // Identify the next resource pathname to be processed
+                int comma = pathnames.indexOf(',');
+                String pathname = null;
+                if (comma >= 0) {
+                    pathname = pathnames.substring(0, comma).trim();
+                    pathnames = pathnames.substring(comma + 1);
+                } else {
+                    pathname = pathnames.trim();
+                    pathnames = "";
+                }
+                if (pathname.length() < 1) {
+                    break;
+                }
+
+                // Add the corresponding URL to our list
+                try {
+                    url = context.getResource(pathname);
+                } catch (MalformedURLException e) {
+                    throw new IllegalArgumentException(pathname, e);
+                }
+                if (url == null) {
+                    url = 
ValidatorLifecycleListener.class.getResource(pathname);
+                }
+                if (url == null) {
+                    throw new IllegalArgumentException(pathname);
+                }
+                urls.add(url);
+                if (Globals.DEFAULT_VALIDATOR_RULES.equals(pathname)) {
+                    didDefault = true;
+                }
+
+            }
+        }
+
+        // Process the default configuration resources (if not already loaded)
+        if (!didDefault) {
+            try {
+                url = context.getResource(Globals.DEFAULT_VALIDATOR_RULES);
+            } catch (MalformedURLException e) {
+                throw new 
IllegalArgumentException(Globals.DEFAULT_VALIDATOR_RULES, e);
+            }
+            if (url == null) {
+                url = 
ValidatorLifecycleListener.class.getResource(Globals.DEFAULT_VALIDATOR_RULES);
+            }
+            if (url == null) {
+                throw new 
IllegalArgumentException(Globals.DEFAULT_VALIDATOR_RULES);
+            }
+            urls.add(url);
+        }
+
+        // Until <http://issues.apache.org/jira/browse/VALIDATOR-209>
+        // is addressed, we must convert the URLs we have gathered back into
+        // Strings and hope no information is lost in the process
+        String[] array = new String[urls.size()];
+        for (int i = 0; i < array.length; i++) {
+            array[i] = ((URL) urls.get(i)).toExternalForm();
+        }
+        
+        // Construct and return a new ValidatorResources instance
+        return new ValidatorResources(array);
+
+    }
+
+
+}

Propchange: 
shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/faces/ValidatorLifecycleListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
shale/framework/trunk/shale-validator/src/main/java/org/apache/shale/validator/faces/ValidatorLifecycleListener.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: 
shale/framework/trunk/shale-validator/src/main/resources/META-INF/taglib.tld
URL: 
http://svn.apache.org/viewvc/shale/framework/trunk/shale-validator/src/main/resources/META-INF/taglib.tld?view=diff&rev=478459&r1=478458&r2=478459
==============================================================================
--- 
shale/framework/trunk/shale-validator/src/main/resources/META-INF/taglib.tld 
(original)
+++ 
shale/framework/trunk/shale-validator/src/main/resources/META-INF/taglib.tld 
Wed Nov 22 20:23:00 2006
@@ -35,6 +35,14 @@
   </description>
 
 
+  <!-- ===================== Servlet Listeners ============================= 
-->
+
+
+  <listener>
+    
<listener-class>org.apache.shale.validator.faces.ValidatorLifecycleListener</listener-class>
+  </listener>
+  
+
   <!-- ================= JSF Component Tags ================================ 
-->
 
 

Modified: 
shale/framework/trunk/shale-validator/src/test/java/org/apache/shale/validator/CommonsValidatorTestCase.java
URL: 
http://svn.apache.org/viewvc/shale/framework/trunk/shale-validator/src/test/java/org/apache/shale/validator/CommonsValidatorTestCase.java?view=diff&rev=478459&r1=478458&r2=478459
==============================================================================
--- 
shale/framework/trunk/shale-validator/src/test/java/org/apache/shale/validator/CommonsValidatorTestCase.java
 (original)
+++ 
shale/framework/trunk/shale-validator/src/test/java/org/apache/shale/validator/CommonsValidatorTestCase.java
 Wed Nov 22 20:23:00 2006
@@ -30,12 +30,14 @@
 import javax.faces.component.html.HtmlForm;
 import javax.faces.component.html.HtmlInputText;
 import javax.faces.context.ResponseWriter;
+import javax.servlet.ServletContextEvent;
 
 import junit.framework.Assert;
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
 import org.apache.commons.validator.ValidatorAction;
+import org.apache.shale.validator.faces.ValidatorLifecycleListener;
 import org.apache.shale.validator.faces.ValidatorScript;
 import org.apache.shale.test.base.AbstractJsfTestCase;
 import org.apache.shale.util.Messages;
@@ -90,7 +92,6 @@
     }
    
     
-   
     // ------------------------------------------------------------ 
Constructors
 
 
@@ -100,6 +101,13 @@
     }
 
 
+    // ------------------------------------------------------ Instance 
Variables
+
+
+    // ValidatorLifecycleListener used to load configuration resources
+    ValidatorLifecycleListener listener = null;
+
+
     // ---------------------------------------------------- Overall Test 
Methods
 
 
@@ -111,7 +119,8 @@
             (Globals.VALIDATOR_RULES,
              Globals.DEFAULT_VALIDATOR_RULES +
              ", /org/apache/shale/validator/custom-rules.xml");
-
+        listener = new ValidatorLifecycleListener();
+        listener.contextInitialized(new ServletContextEvent(servletContext));
         
         loadComponents();
         loadConverters();
@@ -131,6 +140,9 @@
 
     // Tear down instance variables required by this test case.
     protected void tearDown() throws Exception {
+
+        listener.contextDestroyed(new ServletContextEvent(servletContext));
+        listener = null;
 
         super.tearDown();
 

Modified: 
shale/framework/trunk/shale-validator/src/test/java/org/apache/shale/validator/ValidatorDefaultTestCase.java
URL: 
http://svn.apache.org/viewvc/shale/framework/trunk/shale-validator/src/test/java/org/apache/shale/validator/ValidatorDefaultTestCase.java?view=diff&rev=478459&r1=478458&r2=478459
==============================================================================
--- 
shale/framework/trunk/shale-validator/src/test/java/org/apache/shale/validator/ValidatorDefaultTestCase.java
 (original)
+++ 
shale/framework/trunk/shale-validator/src/test/java/org/apache/shale/validator/ValidatorDefaultTestCase.java
 Wed Nov 22 20:23:00 2006
@@ -17,10 +17,12 @@
 
 package org.apache.shale.validator;
 
+import javax.servlet.ServletContextEvent;
 import junit.framework.Test;
 import junit.framework.TestSuite;
 import org.apache.commons.validator.ValidatorAction;
 import org.apache.shale.test.base.AbstractJsfTestCase;
+import org.apache.shale.validator.faces.ValidatorLifecycleListener;
 
 /**
  * <p>Test case for <code>CommonsValidator</code>.</p>
@@ -45,6 +47,13 @@
 
         super.setUp();
 
+        servletContext.addInitParameter
+            (Globals.VALIDATOR_RULES,
+             Globals.DEFAULT_VALIDATOR_RULES +
+             ", /org/apache/shale/validator/custom-rules.xml");
+        listener = new ValidatorLifecycleListener();
+        listener.contextInitialized(new ServletContextEvent(servletContext));
+
     }
 
 
@@ -59,12 +68,19 @@
     // Tear down instance variables required by this test case.
     protected void tearDown() throws Exception {
 
+        listener.contextDestroyed(new ServletContextEvent(servletContext));
+        listener = null;
+
         super.tearDown();
 
     }
 
 
     // ------------------------------------------------------ Instance 
Variables
+
+
+    // ValidatorLifecycleListener used to load configuration resources
+    ValidatorLifecycleListener listener = null;
 
 
     // ------------------------------------------------------------ Test 
Methods


Reply via email to