You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sk...@apache.org on 2005/02/20 07:59:48 UTC

svn commit: r154480 - jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/plugins/Declaration.java

Author: skitching
Date: Sat Feb 19 22:59:48 2005
New Revision: 154480

URL: http://svn.apache.org/viewcvs?view=rev&rev=154480
Log:
* more findLoader method to here from PluginDeclarationScope
* perform all initialisation in constructor(s) rather than
  have a separate init method: much cleaner.
* whitespace cleanup.

Modified:
    jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/plugins/Declaration.java

Modified: jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/plugins/Declaration.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/plugins/Declaration.java?view=diff&r1=154479&r2=154480
==============================================================================
--- jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/plugins/Declaration.java (original)
+++ jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/plugins/Declaration.java Sat Feb 19 22:59:48 2005
@@ -1,101 +1,141 @@
 /* $Id$
  *
  * Copyright 2003-2005 The Apache Software Foundation.
- * 
+ *
  * Licensed 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.commons.digester2.plugins;
 
 import java.io.IOException;
 import java.util.Properties;
 import java.util.List;
+import java.util.Iterator;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.digester2.Context;
 
 /**
- * Represents a Class that can be instantiated by a PluginCreateAction, plus
- * info on how to load custom digester rules for mapping xml into that
- * plugged-in class.
+ * Represents info on how to load custom digester rules for mapping xml into
+ * a class instantiated by a PluginCreateRule.
  * <p>
  * Declaration instances are created by either:
  * <ul>
- * <li> PluginCreateAction from method startParse time, in the case where a 
- *  plugin has a default plugin class.
+ * <li> PluginCreateAction from method startParse, in the case where the action
+ *  has a default plugin class.
  * <li> PluginCreateAction from method begin, in the case where the input
  *  xml just declares the plugin class on the matching tag, eg
  *  [widget plugin-class="com.acme.widget" ...]
  * <li> PluginDeclarationAction, in the case where the input xml pre-declares
  *  the plugin class, eg [plugin-declaration id="..." class=".." ..../]
  * </ul>
+ * <p>
+ * Once created, Declaration instances are stored within a
+ * PluginDeclarationScope object. When the scope object is deleted, the
+ * associated Declarations go with it.
  */
 
 public class Declaration {
-   
+
     /** The class of the object to be instantiated. */
     private Class pluginClass;
 
     /** The name of the class of the object to be instantiated. */
     private String pluginClassName;
-    
+
     /** See {@link #setId}. */ 
     private String id;
-    
-    /** See {@link #setProperties}. */
-    private Properties properties = new Properties();
-    
-    /** See {@link #init}. */
-    private boolean initialized = false;
 
     /**
      * Class which is responsible for dynamically loading this
      * plugin's rules on demand.
      */
     private RuleLoader ruleLoader = null;
-    
+
     //---------------------- constructors ----------------------------------
 
     /**
-     * Constructor.
+     * Create an instance whose configure method will load dynamic rules
+     * for a class of the specified name via the classloader returned by
+     * method Context.getClassLoader.
+     * <p>
+     * There can be a difference between this constructor and the one which
+     * takes an explicit class if there are multiple different copies of the
+     * plugin class in the classpath. If that class provides a static method for
+     * adding rules then this constructor will call that method on the class
+     * instance returned by the context.getClassLoader, whereas the alternative
+     * constructor that takes an explicit class will call the method on the
+     * provided class.
+     * <p>
+     * See {@link #init} for more information.
+     *
+     * @param properties is expected to be the set of xml attributes present
+     *  on the declaration. The RuleFinder classes will inspect the available
+     *  properties to help them locate the custom rules associated with the
+     *  plugin class. Must not be null.
      */
-    public Declaration(String pluginClassName) {
-        // We can't load the pluginClass at this time, because we don't
-        // have a digester instance yet to load it through. So just
-        // save the name away, and we'll load the Class object in the
-        // init method.
+    public Declaration(Context context, String pluginClassName, Properties properties) 
+    throws PluginException {
         this.pluginClassName = pluginClassName;
+
+        try {
+            // load the plugin class object
+            this.pluginClass =
+                context.getClassLoader().loadClass(pluginClassName);
+        } catch(ClassNotFoundException cnfe) {
+            throw new PluginException(
+                "Unable to load class " + pluginClassName, cnfe);
+        }
+
+        this.ruleLoader = findLoader(context, pluginClass, properties);
     }
-    
+
     /**
-     * Constructor.
+     * Create an instance whose configure method will load dynamic rules
+     * for a class of the specified name via the specified class.
+     *
+     * @param properties is expected to be the set of xml attributes present
+     *  on the declaration. The RuleFinder classes will inspect the available
+     *  properties to help them locate the custom rules associated with the
+     *  plugin class. Must not be null.
      */
-    public Declaration(Class pluginClass) {
+    public Declaration(Context context, Class pluginClass, Properties properties) 
+    throws PluginException {
         this.pluginClass = pluginClass;
         this.pluginClassName = pluginClass.getName();
+        this.ruleLoader = findLoader(context, pluginClass, properties);
     }
-    
+
     /**
      * Create an instance where a fully-initialised ruleLoader instance
      * is provided by the caller instead of having the PluginManager
      * "discover" an appropriate one.
      */
-    public Declaration(Class pluginClass, RuleLoader ruleLoader) {
+    public Declaration(Context context, Class pluginClass, RuleLoader ruleLoader) {
         this.pluginClass = pluginClass;
         this.pluginClassName = pluginClass.getName();
         this.ruleLoader = ruleLoader;
     }
-    
-    //---------------------- properties -----------------------------------
+
+    //---------------------- methods -----------------------------------
+
+    /**
+     * Return plugin class associated with this declaration.
+     * 
+     * @return The pluginClass.
+     */
+    public Class getPluginClass() {
+        return pluginClass;
+    }
 
     /** 
      * The id that the user associated with a particular plugin declaration
@@ -118,88 +158,60 @@
         return id;
     }
 
-    /** 
-     * Copy all (key,value) pairs in the param into the properties member of
-     * this object.
-     * <p>
-     * The declaration properties cannot be explicit member variables,
-     * because the set of useful properties a user can provide on a declaration
-     * depends on what RuleFinder classes are available - and extra RuleFinders
-     * can be added by the user. So here we keep a map of the settings, and
-     * let the RuleFinder objects look for whatever properties they consider
-     * significant.
-     * <p>
-     * The "id" and "class" properties are treated differently.
-     */
-    public void setProperties(Properties p) {
-        properties.putAll(p);
-    }
-    
-    /**
-     * Return plugin class associated with this declaration.
-     * 
-     * @return The pluginClass.
-     */
-    public Class getPluginClass() {
-        return pluginClass;
-    }
-
-    //---------------------- methods -----------------------------------
-    
     /**
-     * Must be called exactly once, and must be called before any call
-     * to the configure method.
+     * Given a plugin class and some associated properties, scan the
+     * list of known RuleFinder instances until one detects a source of
+     * custom rules for this plugin (aka a RuleLoader).
+     * <p>
+     * If no source of custom rules can be found, null is returned.
      */
-    public void init(Context context, PluginDeclarationScope pds) 
+    private static RuleLoader findLoader(
+    Context context,
+    Class pluginClass, Properties props)
     throws PluginException {
-        Log log = context.getLogger();
+
+        // iterate over the list of RuleFinders, trying each one
+        // until one of them locates a source of dynamic rules given
+        // this specific plugin class and the associated declaration
+        // properties.
+        Log log = LogUtils.getLogger(context);
         boolean debug = log.isDebugEnabled();
-        if (debug) {
-            log.debug("init being called!");
-        }
-        
-        if (initialized) {
-            throw new PluginAssertionFailure("Init called multiple times.");
-        }
+        log.debug("scanning ruleFinders to locate loader..");
 
-        if ((pluginClass == null) && (pluginClassName != null)) {
-            try {
-                // load the plugin class object
-                pluginClass = 
-                    context.getClassLoader().loadClass(pluginClassName);
-            } catch(ClassNotFoundException cnfe) {
-                throw new PluginException(
-                    "Unable to load class " + pluginClassName, cnfe);
-            }
-        }
+        PluginConfiguration pluginConfig =
+            PluginConfiguration.getInstance(context.getSAXHandler());
 
-        if (ruleLoader == null) {
-            // the caller didn't provide a ruleLoader to the constructor,
-            // so get the plugin manager to "discover" one.
-            log.debug("Searching for ruleloader...");
-            ruleLoader = pds.findLoader(context, id, pluginClass, properties);
-        } else {
-            log.debug("This declaration has an explicit ruleLoader.");
-        }
-        
-        if (debug) {
-            if (ruleLoader == null) {
-                log.debug(
-                    "No ruleLoader found for plugin declaration"
-                    + " id [" + id + "]"
-                    + ", class [" + pluginClass.getClass().getName() + "].");
-            } else {
-                log.debug(
-                    "RuleLoader of type [" + ruleLoader.getClass().getName()
-                    + "] associated with plugin declaration"
-                    + " id [" + id + "]"
-                    + ", class [" + pluginClass.getClass().getName() + "].");
+        // try each available RuleFinder object in order until one returns
+        // a non-null value.
+        List ruleFinders = pluginConfig.getRuleFinders();
+        RuleLoader ruleLoader = null;
+        try {
+            for(Iterator i = ruleFinders.iterator();
+                i.hasNext() && ruleLoader == null; ) {
+
+                RuleFinder finder = (RuleFinder) i.next();
+                if (debug) {
+                    log.debug("checking finder of type " + finder.getClass().getName());
+                }
+                ruleLoader = finder.findLoader(context, pluginClass, props);
             }
         }
-        
-        initialized = true;        
+        catch(PluginException e) {
+            throw new PluginException(
+                "Unable to locate plugin rules for plugin"
+                + " with class [" + pluginClass.getName() + "]"
+                + ":" + e.getMessage(), e.getCause());
+        }
+        log.debug("scanned ruleFinders.");
+
+        log.debug(
+            "RuleLoader of type [" + ruleLoader.getClass().getName()
+            + "] associated with plugin declaration for class"
+            + " [" + pluginClass.getClass().getName() + "].");
+
+        return ruleLoader;
     }
-    
+
     /**
      * Attempt to load custom rules for the target class at the specified
      * pattern.
@@ -211,16 +223,12 @@
      * This method is called by PluginCreateAction, after ensuring that
      * the declaration exists and has been initialised.
      */
-     
+
     public void configure(Context context) throws PluginException {
         Log log = context.getLogger();
         boolean debug = log.isDebugEnabled();
         if (debug) {
             log.debug("configure being called!");
-        }
-        
-        if (!initialized) {
-            throw new PluginAssertionFailure("Not initialized.");
         }
 
         if (ruleLoader != null) {



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org