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