type) throws DigesterLoadingException;
+
+}
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/annotations/spi/package-info.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/annotations/spi/package-info.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/annotations/spi/package-info.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,22 @@
+/* $Id: package-info.java 991743 2010-09-01 22:44:15Z simonetripodi $
+ *
+ * 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.
+ */
+
+/**
+ * Contains annotations package SPI definition.
+ */
+package org.apache.commons.digester.annotations.spi;
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/annotations/utils/AnnotationUtils.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/annotations/utils/AnnotationUtils.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/annotations/utils/AnnotationUtils.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,104 @@
+/* $Id: AnnotationUtils.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.annotations.utils;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.commons.beanutils.MethodUtils;
+
+/**
+ * Simple utility class to introspect annotations.
+ *
+ * @since 2.1
+ */
+public class AnnotationUtils {
+
+ /**
+ * The {@code value} string constant.
+ */
+ private static final String VALUE = "value";
+
+ /**
+ * The {@code pattern} string constant.
+ */
+ private static final String PATTERN = "pattern";
+
+ /**
+ * This class can't be instantiated.
+ */
+ private AnnotationUtils() {
+ // this class can' be instantiated
+ }
+
+ /**
+ * Extract the {@code value()} from annotation.
+ *
+ * @param annotation the annotation has to be introspected.
+ * @return the annotation {@code value()}.
+ */
+ public static Object getAnnotationValue(Annotation annotation) {
+ return invokeAnnotationMethod(annotation, VALUE);
+ }
+
+ /**
+ * Extract the {@code pattern()} from annotation.
+ *
+ * @param annotation the annotation has to be introspected.
+ * @return the annotation {@code pattern()}.
+ */
+ public static String getAnnotationPattern(Annotation annotation) {
+ Object ret = invokeAnnotationMethod(annotation, PATTERN);
+ if (ret != null) {
+ return (String) ret;
+ }
+ return null;
+ }
+
+ /**
+ * Extract the Annotations array {@code value()} from annotation if present,
+ * nul otherwise.
+ *
+ * @param annotation the annotation has to be introspected.
+ * @return the annotation {@code value()} as Annotations array.
+ */
+ public static Annotation[] getAnnotationsArrayValue(Annotation annotation) {
+ Object value = getAnnotationValue(annotation);
+ if (value != null
+ && value.getClass().isArray()
+ && Annotation.class.isAssignableFrom(value.getClass().getComponentType())) {
+ return (Annotation[]) value;
+ }
+ return null;
+ }
+
+ /**
+ * Invokes an annotation method.
+ *
+ * @param annotationn the annotation has to be introspected.
+ * @param method the method name to execute.
+ * @return the annotation method value, null if any error occurs.
+ */
+ private static Object invokeAnnotationMethod(Annotation annotation, String method) {
+ try {
+ return MethodUtils.invokeExactMethod(annotation, method, null);
+ } catch (Throwable t) {
+ return null;
+ }
+ }
+
+}
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/annotations/utils/package-info.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/annotations/utils/package-info.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/annotations/utils/package-info.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,22 @@
+/* $Id: package-info.java 991743 2010-09-01 22:44:15Z simonetripodi $
+ *
+ * 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.
+ */
+
+/**
+ * Contains commons utilities classes for Java5 Annotations manipulation.
+ */
+package org.apache.commons.digester.annotations.utils;
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/package-info.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/package-info.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/package-info.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,25 @@
+/* $Id: package-info.java 991743 2010-09-01 22:44:15Z simonetripodi $
+ *
+ * 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.
+ */
+
+/**
+ * The xmlrules
package provides for XML-based definition of
+ * rules for Digester
. This improves maintainability of Java code,
+ * as rules are now defined in XML and read into Digester
+ * at run-time.
+ */
+package org.apache.commons.digester;
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/parser/GenericParser.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/parser/GenericParser.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/parser/GenericParser.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,92 @@
+/* $Id: GenericParser.java 992077 2010-09-02 19:45:22Z simonetripodi $
+ *
+ * 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.commons.digester.parser;
+
+import java.util.Properties;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+
+/**
+ * Create a SAXParser
configured to support XML Schema and DTD.
+ *
+ * @since 1.6
+ * @deprecated Create an XMLParser instance yourself, configure validation
+ * appropriately, and pass it as a parameter to the
+ * {@link org.apache.commons.digester.Digester} constructor, or use
+ * {@link org.apache.commons.digester.Digester#setXMLSchema(javax.xml.validation.Schema)} for validation.
+ */
+
+@Deprecated
+public class GenericParser{
+
+ /**
+ * The Log to which all SAX event related logging calls will be made.
+ */
+ protected static Log log =
+ LogFactory.getLog("org.apache.commons.digester.Digester.sax");
+
+ /**
+ * The JAXP 1.2 property required to set up the schema location.
+ */
+ private static final String JAXP_SCHEMA_SOURCE =
+ "http://java.sun.com/xml/jaxp/properties/schemaSource";
+
+ /**
+ * The JAXP 1.2 property to set up the schemaLanguage used.
+ */
+ protected static String JAXP_SCHEMA_LANGUAGE =
+ "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
+
+ /**
+ * Create a SAXParser
configured to support XML Scheman and DTD
+ * @param properties parser specific properties/features
+ * @return an XML Schema/DTD enabled SAXParser
+ */
+ public static SAXParser newSAXParser(Properties properties)
+ throws ParserConfigurationException,
+ SAXException,
+ SAXNotRecognizedException{
+
+ SAXParserFactory factory =
+ (SAXParserFactory)properties.get("SAXParserFactory");
+ SAXParser parser = factory.newSAXParser();
+ String schemaLocation = (String)properties.get("schemaLocation");
+ String schemaLanguage = (String)properties.get("schemaLanguage");
+
+ try{
+ if (schemaLocation != null) {
+ parser.setProperty(JAXP_SCHEMA_LANGUAGE, schemaLanguage);
+ parser.setProperty(JAXP_SCHEMA_SOURCE, schemaLocation);
+ }
+ } catch (SAXNotRecognizedException e){
+ log.info(parser.getClass().getName() + ": "
+ + e.getMessage() + " not supported.");
+ }
+ return parser;
+ }
+
+}
\ No newline at end of file
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/parser/XercesParser.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/parser/XercesParser.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/parser/XercesParser.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,200 @@
+/* $Id: XercesParser.java 992082 2010-09-02 19:50:06Z simonetripodi $
+ *
+ * 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.commons.digester.parser;
+
+import java.lang.reflect.Method;
+import java.util.Properties;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+
+/**
+ * Create a SAXParser
based on the underlying Xerces version.
+ * Currently, Xerces 2.3 and up doesn't implement schema validation the same way
+ * 2.1 was. In other to support schema validation in a portable way between
+ * parser, some features/properties need to be set.
+ *
+ * @since 1.6
+ * @deprecated Create an XMLParser instance yourself, configure validation
+ * appropriately, and pass it as a parameter to the
+ * {@link org.apache.commons.digester.Digester} constructor, or use
+ * {@link org.apache.commons.digester.Digester#setXMLSchema(javax.xml.validation.Schema)} for validation.
+ */
+
+@Deprecated
+public class XercesParser{
+
+ /**
+ * The Log to which all SAX event related logging calls will be made.
+ */
+ protected static Log log =
+ LogFactory.getLog("org.apache.commons.digester.Digester.sax");
+
+
+ /**
+ * The JAXP 1.2 property required to set up the schema location.
+ */
+ private static final String JAXP_SCHEMA_SOURCE =
+ "http://java.sun.com/xml/jaxp/properties/schemaSource";
+
+
+ /**
+ * The JAXP 1.2 property to set up the schemaLanguage used.
+ */
+ protected static String JAXP_SCHEMA_LANGUAGE =
+ "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
+
+
+ /**
+ * Xerces dynamic validation property
+ */
+ protected static String XERCES_DYNAMIC =
+ "http://apache.org/xml/features/validation/dynamic";
+
+
+ /**
+ * Xerces schema validation property
+ */
+ protected static String XERCES_SCHEMA =
+ "http://apache.org/xml/features/validation/schema";
+
+
+ /**
+ * A float
representing the underlying Xerces version
+ */
+ protected static float version;
+
+
+ /**
+ * The current Xerces version.
+ */
+ protected static String versionNumber = null;
+
+
+ /**
+ * Return the current Xerces version.
+ * @return the current Xerces version.
+ */
+ private static String getXercesVersion() {
+ // If for some reason we can't get the version, set it to 1.0.
+ String versionNumber = "1.0";
+ try{
+ // Use reflection to avoid a build dependency with Xerces.
+ Class> versionClass =
+ Class.forName("org.apache.xerces.impl.Version");
+ // Will return Xerces-J 2.x.0
+ Method method =
+ versionClass.getMethod("getVersion", (Class[])null);
+ String version = (String)method.invoke(null, (Object[])null);
+ versionNumber = version.substring( "Xerces-J".length() ,
+ version.lastIndexOf(".") );
+ } catch (Exception ex){
+ // Do nothing.
+ }
+ return versionNumber;
+ }
+
+
+ /**
+ * Create a SAXParser
based on the underlying
+ * Xerces
version.
+ * @param properties parser specific properties/features
+ * @return an XML Schema/DTD enabled SAXParser
+ */
+ public static SAXParser newSAXParser(Properties properties)
+ throws ParserConfigurationException,
+ SAXException,
+ SAXNotSupportedException {
+
+ SAXParserFactory factory =
+ (SAXParserFactory)properties.get("SAXParserFactory");
+
+ if (versionNumber == null){
+ versionNumber = getXercesVersion();
+ version = new Float( versionNumber ).floatValue();
+ }
+
+ // Note: 2.2 is completely broken (with XML Schema).
+ if (version > 2.1) {
+
+ configureXerces(factory);
+ return factory.newSAXParser();
+ } else {
+ SAXParser parser = factory.newSAXParser();
+ configureOldXerces(parser,properties);
+ return parser;
+ }
+ }
+
+
+ /**
+ * Configure schema validation as recommended by the JAXP 1.2 spec.
+ * The properties
object may contains information about
+ * the schema local and language.
+ * @param properties parser optional info
+ */
+ private static void configureOldXerces(SAXParser parser,
+ Properties properties)
+ throws ParserConfigurationException,
+ SAXNotSupportedException {
+
+ String schemaLocation = (String)properties.get("schemaLocation");
+ String schemaLanguage = (String)properties.get("schemaLanguage");
+
+ try{
+ if (schemaLocation != null) {
+ parser.setProperty(JAXP_SCHEMA_LANGUAGE, schemaLanguage);
+ parser.setProperty(JAXP_SCHEMA_SOURCE, schemaLocation);
+ }
+ } catch (SAXNotRecognizedException e){
+ log.info(parser.getClass().getName() + ": "
+ + e.getMessage() + " not supported.");
+ }
+
+ }
+
+
+ /**
+ * Configure schema validation as recommended by the Xerces spec.
+ * Both DTD and Schema validation will be enabled simultaneously.
+ *
+ * NOTE: This method is broken. It is supposed to set up validation
+ * against the schema specified in property "schemaLocation", but
+ * it doesn't.
+ *
+ * @param factory SAXParserFactory to be configured
+ */
+ private static void configureXerces(SAXParserFactory factory)
+ throws ParserConfigurationException,
+ SAXNotRecognizedException,
+ SAXNotSupportedException {
+
+ factory.setFeature(XERCES_DYNAMIC, true);
+ factory.setFeature(XERCES_SCHEMA, true);
+
+ }
+}
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/parser/package-info.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/parser/package-info.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/parser/package-info.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,25 @@
+/* $Id: package-info.java 991743 2010-09-01 22:44:15Z simonetripodi $
+ *
+ * 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.
+ */
+
+/**
+ * DEPRECATED PACKAGE:
+ * This package contains legacy schema support code used in the v1.x line of
+ * Digester releases. Starting v2.0, the recommended way to use schema
+ * validation is via the javax.xml.validation.Schema
support.
+ */
+package org.apache.commons.digester.parser;
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/Declaration.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/Declaration.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/Declaration.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,216 @@
+/* $Id: Declaration.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins;
+
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.digester.Digester;
+
+/**
+ * Represents a Class that can be instantiated by a PluginCreateRule, plus
+ * info on how to load custom digester rules for mapping xml into that
+ * plugged-in class.
+ *
+ * @since 1.6
+ */
+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.
+ */
+ 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.
+ this.pluginClassName = pluginClassName;
+ }
+
+ /**
+ * Constructor.
+ */
+ public Declaration(Class> pluginClass) {
+ this.pluginClass = pluginClass;
+ this.pluginClassName = pluginClass.getName();
+ }
+
+ /**
+ * 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) {
+ this.pluginClass = pluginClass;
+ this.pluginClassName = pluginClass.getName();
+ this.ruleLoader = ruleLoader;
+ }
+
+ //---------------------- properties -----------------------------------
+
+ /**
+ * The id that the user associated with a particular plugin declaration
+ * in the input xml. This id is later used in the input xml to refer
+ * back to the original declaration.
+ *
+ * For plugins declared "in-line", the id is null.
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * Return the id associated with this declaration. For plugins
+ * declared "inline", null will be returned.
+ *
+ * @return The id value. May be null.
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Copy all (key,value) pairs in the param into the properties member of
+ * this object.
+ *
+ * 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.
+ *
+ * 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.
+ */
+ public void init(Digester digester, PluginManager pm) throws PluginException {
+ Log log = digester.getLogger();
+ boolean debug = log.isDebugEnabled();
+ if (debug) {
+ log.debug("init being called!");
+ }
+
+ if (initialized) {
+ throw new PluginAssertionFailure("Init called multiple times.");
+ }
+
+ if ((pluginClass == null) && (pluginClassName != null)) {
+ try {
+ // load the plugin class object
+ pluginClass =
+ digester.getClassLoader().loadClass(pluginClassName);
+ } catch(ClassNotFoundException cnfe) {
+ throw new PluginException(
+ "Unable to load class " + pluginClassName, cnfe);
+ }
+ }
+
+ 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 = pm.findLoader(digester, 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() + "].");
+ }
+ }
+
+ initialized = true;
+ }
+
+ /**
+ * Attempt to load custom rules for the target class at the specified
+ * pattern.
+ *
+ * On return, any custom rules associated with the plugin class have
+ * been loaded into the Rules object currently associated with the
+ * specified digester object.
+ */
+
+ public void configure(Digester digester, String pattern)
+ throws PluginException {
+ Log log = digester.getLogger();
+ boolean debug = log.isDebugEnabled();
+ if (debug) {
+ log.debug("configure being called!");
+ }
+
+ if (!initialized) {
+ throw new PluginAssertionFailure("Not initialized.");
+ }
+
+ if (ruleLoader != null) {
+ ruleLoader.addRules(digester, pattern);
+ }
+ }
+}
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/InitializableRule.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/InitializableRule.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/InitializableRule.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,43 @@
+/* $Id: InitializableRule.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins;
+
+/**
+ * Defines an interface that a Rule class can implement if it wishes to get an
+ * initialisation callback after the rule has been added to the set of Rules
+ * within a PluginRules instance.
+ *
+ * @since 1.6
+ */
+
+public interface InitializableRule {
+
+ /**
+ * Called after this Rule object has been added to the list of all Rules.
+ * Note that if a single InitializableRule instance is associated with
+ * more than one pattern, then this method will be called more than once.
+ *
+ * @param pattern is the digester match pattern that will trigger this
+ * rule.
+ * @exception
+ * PluginConfigurationException is thrown if the InitializableRule
+ * determines that it cannot correctly initialise itself for any reason.
+ */
+ public void postRegisterInit(String pattern)
+ throws PluginConfigurationException;
+}
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/LogUtils.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/LogUtils.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/LogUtils.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,73 @@
+/* $Id: LogUtils.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.logging.Log;
+
+/**
+ * Simple utility class to assist in logging.
+ *
+ * This class is intended only for the use of the code in the
+ * plugins packages. No "user" code should use this package.
+ *
+ * The Digester module has an interesting approach to logging:
+ * all logging should be done via the Log object stored on the
+ * digester instance that the object *doing* the logging is associated
+ * with.
+ *
+ * This is done because apparently some "container"-type applications
+ * such as Avalon and Tomcat need to be able to configure different logging
+ * for different instances of the Digester class which have been
+ * loaded from the same ClassLoader [info from Craig McClanahan].
+ * Not only the logging of the Digester instance should be affected; all
+ * objects associated with that Digester instance should obey the
+ * reconfiguration of their owning Digester instance's logging. The current
+ * solution is to force all objects to output logging info via a single
+ * Log object stored on the Digester instance they are associated with.
+ *
+ * Of course this causes problems if logging is attempted before an
+ * object has a valid reference to its owning Digester. The
+ * getLogging method provided here resolves this issue by returning a
+ * Log object which silently discards all logging output in this
+ * situation.
+ *
+ * And it also implies that logging filtering can no longer be applied
+ * to subcomponents of the Digester, because all logging is done via
+ * a single Log object (a single Category). C'est la vie...
+ *
+ * @since 1.6
+ */
+
+class LogUtils {
+
+ /**
+ * Get the Log object associated with the specified Digester instance,
+ * or a "no-op" logging object if the digester reference is null.
+ *
+ * You should use this method instead of digester.getLogger() in
+ * any situation where the digester might be null.
+ */
+ static Log getLogger(Digester digester) {
+ if (digester == null) {
+ return new org.apache.commons.logging.impl.NoOpLog();
+ }
+
+ return digester.getLogger();
+ }
+}
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginAssertionFailure.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginAssertionFailure.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginAssertionFailure.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,87 @@
+/* $Id: PluginAssertionFailure.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins;
+
+/**
+ * Thrown when a bug is detected in the plugins code.
+ *
+ * This class is intended to be used in assertion statements, similar to
+ * the way that java 1.4's native assertion mechanism is used. However there
+ * is a difference: when a java 1.4 assertion fails, an AssertionError
+ * is thrown, which is a subclass of Error; here, the PluginAssertionFailure
+ * class extends RuntimeException rather than Error.
+ *
+ * This difference in design is because throwing Error objects is not
+ * good in a container-based architecture.
+ *
+ * Example:
+ *
+ * if (impossibleCondition) {
+ * throw new PluginAssertionFailure(
+ * "internal error: impossible condition is true");
+ * }
+ *
+ *
+ * Note that PluginAssertionFailure should not be thrown when user
+ * input is bad, or when code external to the Digester module passes invalid
+ * parameters to a plugins method. It should be used only in checks for
+ * problems which indicate internal bugs within the plugins module.
+ *
+ * @since 1.6
+ */
+public class PluginAssertionFailure extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+ private Throwable cause = null;
+
+ /**
+ * @param cause underlying exception that caused this to be thrown
+ */
+ public PluginAssertionFailure(Throwable cause) {
+ this(cause.getMessage());
+ this.cause = cause;
+ }
+
+ /**
+ * @param msg describes the reason this exception is being thrown.
+ */
+ public PluginAssertionFailure(String msg) {
+ super(msg);
+ }
+
+ /**
+ * @param msg describes the reason this exception is being thrown.
+ * @param cause underlying exception that caused this to be thrown
+ */
+ public PluginAssertionFailure(String msg, Throwable cause) {
+ this(msg);
+ this.cause = cause;
+ }
+
+ /**
+ * Return the cause of this exception (if any) as specified in the
+ * exception constructor.
+ *
+ * @since 1.8
+ */
+ @Override
+ public Throwable getCause() {
+ return cause;
+ }
+}
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginConfigurationException.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginConfigurationException.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginConfigurationException.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,70 @@
+/* $Id: PluginConfigurationException.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins;
+
+/**
+ * Thrown when an error occurs due to the way the calling application uses
+ * the plugins module. Because the pre-existing Digester API doesn't provide
+ * any option for throwing checked exceptions at some points where Plugins
+ * can potentially fail, this exception extends RuntimeException so that it
+ * can "tunnel" through these points.
+ *
+ * @since 1.6
+ */
+
+public class PluginConfigurationException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+ private Throwable cause = null;
+
+ /**
+ * @param cause underlying exception that caused this to be thrown
+ */
+ public PluginConfigurationException(Throwable cause) {
+ this(cause.getMessage());
+ this.cause = cause;
+ }
+
+ /**
+ * @param msg describes the reason this exception is being thrown.
+ */
+ public PluginConfigurationException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * @param msg describes the reason this exception is being thrown.
+ * @param cause underlying exception that caused this to be thrown
+ */
+ public PluginConfigurationException(String msg, Throwable cause) {
+ this(msg);
+ this.cause = cause;
+ }
+
+ /**
+ * Return the cause of this exception (if any) as specified in the
+ * exception constructor.
+ *
+ * @since 1.8
+ */
+ @Override
+ public Throwable getCause() {
+ return cause;
+ }
+}
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginContext.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginContext.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginContext.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,247 @@
+/* $Id: PluginContext.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins;
+
+import java.util.List;
+import java.util.LinkedList;
+
+import org.apache.commons.digester.plugins.strategies.FinderFromFile;
+import org.apache.commons.digester.plugins.strategies.FinderFromResource;
+import org.apache.commons.digester.plugins.strategies.FinderFromClass;
+import org.apache.commons.digester.plugins.strategies.FinderFromMethod;
+import org.apache.commons.digester.plugins.strategies.FinderFromDfltMethod;
+import org.apache.commons.digester.plugins.strategies.FinderFromDfltClass;
+import org.apache.commons.digester.plugins.strategies.FinderFromDfltResource;
+import org.apache.commons.digester.plugins.strategies.FinderSetProperties;
+
+/**
+ * Provides data and services which should exist only once per digester.
+ *
+ * This class holds a number of useful items which should be shared by all
+ * plugin objects. Such data cannot be stored on the PluginRules or
+ * PluginManager classes, as there can be multiple instances of these at
+ * various times during a parse.
+ *
+ * The name "Context" refers to the similarity between this class and a
+ * ServletContext class in a servlet engine. A ServletContext object provides
+ * access to the container's services such as obtaining global configuration
+ * parameters for the container, or getting access to logging services. For
+ * plugins, a Digester instance can be regarded as "the container".
+ *
+ * @since 1.6
+ */
+
+public class PluginContext {
+
+ // TODO: Consider making following four constants static in 2.0
+ // the xml attribute the user uses on an xml element to specify
+ // the plugin's class
+ public final String DFLT_PLUGIN_CLASS_ATTR_NS = null;
+ public final String DFLT_PLUGIN_CLASS_ATTR = "plugin-class";
+
+ // the xml attribute the user uses on an xml element to specify
+ // the plugin's class
+ public final String DFLT_PLUGIN_ID_ATTR_NS = null;
+ public final String DFLT_PLUGIN_ID_ATTR = "plugin-id";
+
+ /** See {@link #setPluginClassAttribute}. */
+ private String pluginClassAttrNs = DFLT_PLUGIN_CLASS_ATTR_NS;
+
+ /** See {@link #setPluginClassAttribute}. */
+ private String pluginClassAttr = DFLT_PLUGIN_CLASS_ATTR;
+
+ /** See {@link #setPluginClassAttribute}. */
+ private String pluginIdAttrNs = DFLT_PLUGIN_ID_ATTR_NS;
+
+ /** See {@link #setPluginClassAttribute}. */
+ private String pluginIdAttr = DFLT_PLUGIN_ID_ATTR;
+
+ /**
+ * A list of RuleFinder objects used by all Declarations (and thus
+ * indirectly by all PluginCreateRules to locate the custom rules
+ * for plugin classes.
+ */
+ private List ruleFinders;
+
+ //------------------- constructors ---------------------------------------
+
+ public PluginContext() {
+ }
+
+ //------------------- methods ---------------------------------------
+
+ /**
+ * Return the list of RuleFinder objects. Under normal circumstances
+ * this method creates a default list of these objects when first called
+ * (ie "on-demand" or "lazy initialization"). However if setRuleFinders
+ * has been called first, then the list specified there is returned.
+ *
+ * It is explicitly permitted for the caller to modify this list
+ * by inserting or removing RuleFinder objects.
+ */
+ public List getRuleFinders() {
+ if (ruleFinders == null) {
+ // when processing a plugin declaration, attempts are made to
+ // find custom rules in the order in which the Finder objects
+ // are added below. However this list can be modified
+ ruleFinders = new LinkedList();
+ ruleFinders.add(new FinderFromFile());
+ ruleFinders.add(new FinderFromResource());
+ ruleFinders.add(new FinderFromClass());
+ ruleFinders.add(new FinderFromMethod());
+ ruleFinders.add(new FinderFromDfltMethod());
+ ruleFinders.add(new FinderFromDfltClass());
+ ruleFinders.add(new FinderFromDfltResource());
+ ruleFinders.add(new FinderFromDfltResource(".xml"));
+ ruleFinders.add(new FinderSetProperties());
+ }
+ return ruleFinders;
+ }
+
+ /**
+ * Set the list of RuleFinder objects. This may be useful if working
+ * in a non-english language, allowing the application developer to
+ * replace the standard list with a list of objects which look for xml
+ * attributes in the local language.
+ *
+ * If the intent is just to add an additional rule-finding algorithm, then
+ * it may be better to call #getRuleFinders, and insert a new object into
+ * the start of the list.
+ */
+ public void setRuleFinders(List ruleFinders) {
+ this.ruleFinders = ruleFinders;
+ }
+
+ /**
+ * Sets the xml attribute which the input xml uses to indicate to a
+ * PluginCreateRule which class should be instantiated.
+ *
+ * Example:
+ *
+ * setPluginClassAttribute(null, "class");
+ *
+ * will allow this in the input xml:
+ *
+ * <root>
+ * <some-plugin class="com.acme.widget"> ......
+ *
+ * instead of the default syntax:
+ *
+ * <root>
+ * <some-plugin plugin-class="com.acme.widget"> ......
+ *
+ * This is particularly useful if the input xml document is not in
+ * English.
+ *
+ * Note that the xml attributes used by PluginDeclarationRules are not
+ * affected by this method.
+ *
+ * @param namespaceUri is the namespace uri that the specified attribute
+ * is in. If the attribute is in no namespace, then this should be null.
+ * Note that if a namespace is used, the attrName value should not
+ * contain any kind of namespace-prefix. Note also that if you are using
+ * a non-namespace-aware parser, this parameter must be null.
+ *
+ * @param attrName is the attribute whose value contains the name of the
+ * class to be instantiated.
+ */
+ public void setPluginClassAttribute(String namespaceUri,
+ String attrName) {
+ pluginClassAttrNs = namespaceUri;
+ pluginClassAttr = attrName;
+ }
+
+ /**
+ * Sets the xml attribute which the input xml uses to indicate to a
+ * PluginCreateRule which plugin declaration is being referenced.
+ *
+ * Example:
+ *
+ * setPluginIdAttribute(null, "id");
+ *
+ * will allow this in the input xml:
+ *
+ * <root>
+ * <some-plugin id="widget"> ......
+ *
+ * rather than the default behaviour:
+ *
+ * <root>
+ * <some-plugin plugin-id="widget"> ......
+ *
+ * This is particularly useful if the input xml document is not in
+ * English.
+ *
+ * Note that the xml attributes used by PluginDeclarationRules are not
+ * affected by this method.
+ *
+ * @param namespaceUri is the namespace uri that the specified attribute
+ * is in. If the attribute is in no namespace, then this should be null.
+ * Note that if a namespace is used, the attrName value should not
+ * contain any kind of namespace-prefix. Note also that if you are using
+ * a non-namespace-aware parser, this parameter must be null.
+ *
+ * @param attrName is the attribute whose value contains the id of the
+ * plugin declaration to be used when instantiating an object.
+ */
+ public void setPluginIdAttribute(String namespaceUri,
+ String attrName) {
+ pluginIdAttrNs = namespaceUri;
+ pluginIdAttr = attrName;
+ }
+
+ /**
+ * Get the namespace for the xml attribute which indicates to a
+ * PluginCreateRule which class is to be plugged in.
+ *
+ * May be null (in fact, normally will be).
+ */
+ public String getPluginClassAttrNs() {
+ return pluginClassAttrNs;
+ }
+
+ /**
+ * Get the namespace for the xml attribute which indicates to a
+ * PluginCreateRule which class is to be plugged in.
+ *
+ * The return value is never null.
+ */
+ public String getPluginClassAttr() {
+ return pluginClassAttr;
+ }
+
+ /**
+ * Get the namespace for the xml attribute which indicates to a
+ * PluginCreateRule which previous plugin declaration should be used.
+ *
+ * May be null (in fact, normally will be).
+ */
+ public String getPluginIdAttrNs() {
+ return pluginIdAttrNs;
+ }
+
+ /**
+ * Get the namespace for the xml attribute which indicates to a
+ * PluginCreateRule which previous plugin declaration should be used.
+ *
+ * The return value is never null.
+ */
+ public String getPluginIdAttr() {
+ return pluginIdAttr;
+ }
+}
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginCreateRule.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginCreateRule.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginCreateRule.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,584 @@
+/* $Id: PluginCreateRule.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins;
+
+import java.util.List;
+
+import org.apache.commons.digester.Rule;
+import org.apache.commons.logging.Log;
+
+/**
+ * Allows the original rules for parsing the configuration file to define
+ * points at which plugins are allowed, by configuring a PluginCreateRule
+ * with the appropriate pattern.
+ *
+ * @since 1.6
+ */
+public class PluginCreateRule extends Rule implements InitializableRule {
+
+ // see setPluginClassAttribute
+ private String pluginClassAttrNs = null;
+ private String pluginClassAttr = null;
+
+ // see setPluginIdAttribute
+ private String pluginIdAttrNs = null;
+ private String pluginIdAttr = null;
+
+ /**
+ * In order to invoke the addRules method on the plugin class correctly,
+ * we need to know the pattern which this rule is matched by.
+ */
+ private String pattern;
+
+ /** A base class that any plugin must derive from. */
+ private Class> baseClass = null;
+
+ /**
+ * Info about optional default plugin to be used if no plugin-id is
+ * specified in the input data. This can simplify the syntax where one
+ * particular plugin is usually used.
+ */
+ private Declaration defaultPlugin;
+
+ /**
+ * Currently, none of the Rules methods allow exceptions to be thrown.
+ * Therefore if this class cannot initialise itself properly, it cannot
+ * cause the digester to stop. Instead, we cache the exception and throw
+ * it the first time the begin() method is called.
+ */
+ private PluginConfigurationException initException;
+
+ //-------------------- constructors -------------------------------------
+
+ /**
+ * Create a plugin rule where the user must specify a plugin-class
+ * or plugin-id.
+ *
+ * @param baseClass is the class which any specified plugin must be
+ * descended from.
+ */
+ public PluginCreateRule(Class> baseClass) {
+ this.baseClass = baseClass;
+ }
+
+ /**
+ * Create a plugin rule where the user may specify a plugin.
+ * If the user doesn't specify a plugin, then the default class specified
+ * in this constructor is used.
+ *
+ * @param baseClass is the class which any specified plugin must be
+ * descended from.
+ * @param dfltPluginClass is the class which will be used if the user
+ * doesn't specify any plugin-class or plugin-id. This class will have
+ * custom rules installed for it just like a declared plugin.
+ */
+ public PluginCreateRule(Class> baseClass, Class> dfltPluginClass) {
+ this.baseClass = baseClass;
+ if (dfltPluginClass != null) {
+ defaultPlugin = new Declaration(dfltPluginClass);
+ }
+ }
+
+ /**
+ * Create a plugin rule where the user may specify a plugin.
+ * If the user doesn't specify a plugin, then the default class specified
+ * in this constructor is used.
+ *
+ * @param baseClass is the class which any specified plugin must be
+ * descended from.
+ * @param dfltPluginClass is the class which will be used if the user
+ * doesn't specify any plugin-class or plugin-id. This class will have
+ * custom rules installed for it just like a declared plugin.
+ * @param dfltPluginRuleLoader is a RuleLoader instance which knows how
+ * to load the custom rules associated with this default plugin.
+ */
+ public PluginCreateRule(Class> baseClass, Class> dfltPluginClass,
+ RuleLoader dfltPluginRuleLoader) {
+
+ this.baseClass = baseClass;
+ if (dfltPluginClass != null) {
+ defaultPlugin =
+ new Declaration(dfltPluginClass, dfltPluginRuleLoader);
+ }
+ }
+
+ //------------------- properties ---------------------------------------
+
+ /**
+ * Sets the xml attribute which the input xml uses to indicate to a
+ * PluginCreateRule which class should be instantiated.
+ *
+ * See {@link PluginRules#setPluginClassAttribute} for more info.
+ */
+ public void setPluginClassAttribute(String namespaceUri, String attrName) {
+ pluginClassAttrNs = namespaceUri;
+ pluginClassAttr = attrName;
+ }
+
+ /**
+ * Sets the xml attribute which the input xml uses to indicate to a
+ * PluginCreateRule which plugin declaration is being referenced.
+ *
+ * See {@link PluginRules#setPluginIdAttribute} for more info.
+ */
+ public void setPluginIdAttribute(String namespaceUri, String attrName) {
+ pluginIdAttrNs = namespaceUri;
+ pluginIdAttr = attrName;
+ }
+
+ //------------------- methods --------------------------------------------
+
+ /**
+ * Invoked after this rule has been added to the set of digester rules,
+ * associated with the specified pattern. Check all configuration data is
+ * valid and remember the pattern for later.
+ *
+ * @param matchPattern is the digester match pattern that is associated
+ * with this rule instance, eg "root/widget".
+ * @exception PluginConfigurationException
+ */
+ public void postRegisterInit(String matchPattern)
+ throws PluginConfigurationException {
+ Log log = LogUtils.getLogger(digester);
+ boolean debug = log.isDebugEnabled();
+ if (debug) {
+ log.debug("PluginCreateRule.postRegisterInit" +
+ ": rule registered for pattern [" + matchPattern + "]");
+ }
+
+ if (digester == null) {
+ // We require setDigester to be called before this method.
+ // Note that this means that PluginCreateRule cannot be added
+ // to a Rules object which has not yet been added to a
+ // Digester object.
+ initException = new PluginConfigurationException(
+ "Invalid invocation of postRegisterInit" +
+ ": digester not set.");
+ throw initException;
+ }
+
+ if (pattern != null) {
+ // We have been called twice, ie a single instance has been
+ // associated with multiple patterns.
+ //
+ // Generally, Digester Rule instances can be associated with
+ // multiple patterns. However for plugins, this creates some
+ // complications. Some day this may be supported; however for
+ // now we just reject this situation.
+ initException = new PluginConfigurationException(
+ "A single PluginCreateRule instance has been mapped to" +
+ " multiple patterns; this is not supported.");
+ throw initException;
+ }
+
+ if (matchPattern.indexOf('*') != -1) {
+ // having wildcards in patterns is extremely difficult to
+ // deal with. For now, we refuse to allow this.
+ //
+ // TODO: check for any chars not valid in xml element name
+ // rather than just *.
+ //
+ // Reasons include:
+ // (a) handling recursive plugins, and
+ // (b) determining whether one pattern is "below" another,
+ // as done by PluginRules. Without wildcards, "below"
+ // just means startsWith, which is easy to check.
+ initException = new PluginConfigurationException(
+ "A PluginCreateRule instance has been mapped to" +
+ " pattern [" + matchPattern + "]." +
+ " This pattern includes a wildcard character." +
+ " This is not supported by the plugin architecture.");
+ throw initException;
+ }
+
+ if (baseClass == null) {
+ baseClass = Object.class;
+ }
+
+ PluginRules rules = (PluginRules) digester.getRules();
+ PluginManager pm = rules.getPluginManager();
+
+ // check default class is valid
+ if (defaultPlugin != null) {
+ if (!baseClass.isAssignableFrom(defaultPlugin.getPluginClass())) {
+ initException = new PluginConfigurationException(
+ "Default class [" +
+ defaultPlugin.getPluginClass().getName() +
+ "] does not inherit from [" +
+ baseClass.getName() + "].");
+ throw initException;
+ }
+
+ try {
+ defaultPlugin.init(digester, pm);
+
+ } catch(PluginException pwe) {
+
+ throw new PluginConfigurationException(
+ pwe.getMessage(), pwe.getCause());
+ }
+ }
+
+ // remember the pattern for later
+ pattern = matchPattern;
+
+ if (pluginClassAttr == null) {
+ // the user hasn't set explicit xml attr names on this rule,
+ // so fetch the default values
+ pluginClassAttrNs = rules.getPluginClassAttrNs();
+ pluginClassAttr = rules.getPluginClassAttr();
+
+ if (debug) {
+ log.debug(
+ "init: pluginClassAttr set to per-digester values ["
+ + "ns=" + pluginClassAttrNs
+ + ", name=" + pluginClassAttr + "]");
+ }
+ } else {
+ if (debug) {
+ log.debug(
+ "init: pluginClassAttr set to rule-specific values ["
+ + "ns=" + pluginClassAttrNs
+ + ", name=" + pluginClassAttr + "]");
+ }
+ }
+
+ if (pluginIdAttr == null) {
+ // the user hasn't set explicit xml attr names on this rule,
+ // so fetch the default values
+ pluginIdAttrNs = rules.getPluginIdAttrNs();
+ pluginIdAttr = rules.getPluginIdAttr();
+
+ if (debug) {
+ log.debug(
+ "init: pluginIdAttr set to per-digester values ["
+ + "ns=" + pluginIdAttrNs
+ + ", name=" + pluginIdAttr + "]");
+ }
+ } else {
+ if (debug) {
+ log.debug(
+ "init: pluginIdAttr set to rule-specific values ["
+ + "ns=" + pluginIdAttrNs
+ + ", name=" + pluginIdAttr + "]");
+ }
+ }
+ }
+
+ /**
+ * Invoked when the Digester matches this rule against an xml element.
+ *
+ * A new instance of the target class is created, and pushed onto the
+ * stack. A new "private" PluginRules object is then created and set as
+ * the digester's default Rules object. Any custom rules associated with
+ * the plugin class are then loaded into that new Rules object.
+ * Finally, any custom rules that are associated with the current pattern
+ * (such as SetPropertiesRules) have their begin methods executed.
+ *
+ * @param namespace
+ * @param name
+ * @param attributes
+ *
+ * @throws ClassNotFoundException
+ * @throws PluginInvalidInputException
+ * @throws PluginConfigurationException
+ */
+ @Override
+ public void begin(String namespace, String name,
+ org.xml.sax.Attributes attributes)
+ throws java.lang.Exception {
+ Log log = digester.getLogger();
+ boolean debug = log.isDebugEnabled();
+ if (debug) {
+ log.debug("PluginCreateRule.begin" + ": pattern=[" + pattern + "]" +
+ " match=[" + digester.getMatch() + "]");
+ }
+
+ if (initException != null) {
+ // we had a problem during initialisation that we could
+ // not report then; report it now.
+ throw initException;
+ }
+
+ // load any custom rules associated with the plugin
+ PluginRules oldRules = (PluginRules) digester.getRules();
+ PluginManager pluginManager = oldRules.getPluginManager();
+ Declaration currDeclaration = null;
+
+ String pluginClassName;
+ if (pluginClassAttrNs == null) {
+ // Yep, this is ugly.
+ //
+ // In a namespace-aware parser, the one-param version will
+ // return attributes with no namespace.
+ //
+ // In a non-namespace-aware parser, the two-param version will
+ // never return any attributes, ever.
+ pluginClassName = attributes.getValue(pluginClassAttr);
+ } else {
+ pluginClassName =
+ attributes.getValue(pluginClassAttrNs, pluginClassAttr);
+ }
+
+ String pluginId;
+ if (pluginIdAttrNs == null) {
+ pluginId = attributes.getValue(pluginIdAttr);
+ } else {
+ pluginId =
+ attributes.getValue(pluginIdAttrNs, pluginIdAttr);
+ }
+
+ if (pluginClassName != null) {
+ // The user is using a plugin "inline", ie without a previous
+ // explicit declaration. If they have used the same plugin class
+ // before, we have already gone to the effort of creating a
+ // Declaration object, so retrieve it. If there is no existing
+ // declaration object for this class, then create one.
+
+ currDeclaration = pluginManager.getDeclarationByClass(
+ pluginClassName);
+
+ if (currDeclaration == null) {
+ currDeclaration = new Declaration(pluginClassName);
+ try {
+ currDeclaration.init(digester, pluginManager);
+ } catch(PluginException pwe) {
+ throw new PluginInvalidInputException(
+ pwe.getMessage(), pwe.getCause());
+ }
+ pluginManager.addDeclaration(currDeclaration);
+ }
+ } else if (pluginId != null) {
+ currDeclaration = pluginManager.getDeclarationById(pluginId);
+
+ if (currDeclaration == null) {
+ throw new PluginInvalidInputException(
+ "Plugin id [" + pluginId + "] is not defined.");
+ }
+ } else if (defaultPlugin != null) {
+ currDeclaration = defaultPlugin;
+ } else {
+ throw new PluginInvalidInputException(
+ "No plugin class specified for element " +
+ pattern);
+ }
+
+ // get the class of the user plugged-in type
+ Class> pluginClass = currDeclaration.getPluginClass();
+
+ String path = digester.getMatch();
+
+ // create a new Rules object and effectively push it onto a stack of
+ // rules objects. The stack is actually a linked list; using the
+ // PluginRules constructor below causes the new instance to link
+ // to the previous head-of-stack, then the Digester.setRules() makes
+ // the new instance the new head-of-stack.
+ PluginRules newRules = new PluginRules(digester, path, oldRules, pluginClass);
+ digester.setRules(newRules);
+
+ if (debug) {
+ log.debug("PluginCreateRule.begin: installing new plugin: " +
+ "oldrules=" + oldRules.toString() +
+ ", newrules=" + newRules.toString());
+ }
+
+ // load up the custom rules
+ currDeclaration.configure(digester, pattern);
+
+ // create an instance of the plugin class
+ Object instance = pluginClass.newInstance();
+ getDigester().push(instance);
+ if (debug) {
+ log.debug(
+ "PluginCreateRule.begin" + ": pattern=[" + pattern + "]" +
+ " match=[" + digester.getMatch() + "]" +
+ " pushed instance of plugin [" + pluginClass.getName() + "]");
+ }
+
+ // and now we have to fire any custom rules which would have
+ // been matched by the same path that matched this rule, had
+ // they been loaded at that time.
+ List rules = newRules.getDecoratedRules().match(namespace, path);
+ fireBeginMethods(rules, namespace, name, attributes);
+ }
+
+ /**
+ * Process the body text of this element.
+ *
+ * @param text The body text of this element
+ */
+ @Override
+ public void body(String namespace, String name, String text)
+ throws Exception {
+
+ // While this class itself has no work to do in the body method,
+ // we do need to fire the body methods of all dynamically-added
+ // rules matching the same path as this rule. During begin, we had
+ // to manually execute the dynamic rules' begin methods because they
+ // didn't exist in the digester's Rules object when the match begin.
+ // So in order to ensure consistent ordering of rule execution, the
+ // PluginRules class deliberately avoids returning any such rules
+ // in later calls to the match method, instead relying on this
+ // object to execute them at the appropriate time.
+ //
+ // Note that this applies only to rules matching exactly the path
+ // which is also matched by this PluginCreateRule.
+
+ String path = digester.getMatch();
+ PluginRules newRules = (PluginRules) digester.getRules();
+ List rules = newRules.getDecoratedRules().match(namespace, path);
+ fireBodyMethods(rules, namespace, name, text);
+ }
+
+ /**
+ * Invoked by the digester when the closing tag matching this Rule's
+ * pattern is encountered.
+ *
+ *
+ * @param namespace Description of the Parameter
+ * @param name Description of the Parameter
+ * @exception Exception Description of the Exception
+ *
+ * @see #begin
+ */
+ @Override
+ public void end(String namespace, String name)
+ throws Exception {
+
+
+ // see body method for more info
+ String path = digester.getMatch();
+ PluginRules newRules = (PluginRules) digester.getRules();
+ List rules = newRules.getDecoratedRules().match(namespace, path);
+ fireEndMethods(rules, namespace, name);
+
+ // pop the stack of PluginRules instances, which
+ // discards all custom rules associated with this plugin
+ digester.setRules(newRules.getParent());
+
+ // and get rid of the instance of the plugin class from the
+ // digester object stack.
+ digester.pop();
+ }
+
+ /**
+ * Return the pattern that this Rule is associated with.
+ *
+ * In general, Rule instances can be associated with multiple
+ * patterns. A PluginCreateRule, however, will only function correctly
+ * when associated with a single pattern. It is possible to fix this, but
+ * I can't be bothered just now because this feature is unlikely to be
+ * used.
+ *
+ *
+ * @return The pattern value
+ */
+ public String getPattern() {
+ return pattern;
+ }
+
+ /**
+ * Duplicate the processing that the Digester does when firing the
+ * begin methods of rules. It would be really nice if the Digester
+ * class provided a way for this functionality to just be invoked
+ * directly.
+ */
+ public void fireBeginMethods(List rules,
+ String namespace, String name,
+ org.xml.sax.Attributes list)
+ throws java.lang.Exception {
+
+ if ((rules != null) && (rules.size() > 0)) {
+ Log log = digester.getLogger();
+ boolean debug = log.isDebugEnabled();
+ for (int i = 0; i < rules.size(); i++) {
+ try {
+ Rule rule = rules.get(i);
+ if (debug) {
+ log.debug(" Fire begin() for " + rule);
+ }
+ rule.begin(namespace, name, list);
+ } catch (Exception e) {
+ throw digester.createSAXException(e);
+ } catch (Error e) {
+ throw e;
+ }
+ }
+ }
+ }
+
+ /**
+ * Duplicate the processing that the Digester does when firing the
+ * body methods of rules. It would be really nice if the Digester
+ * class provided a way for this functionality to just be invoked
+ * directly.
+ */
+ private void fireBodyMethods(List rules,
+ String namespaceURI, String name,
+ String text) throws Exception {
+
+ if ((rules != null) && (rules.size() > 0)) {
+ Log log = digester.getLogger();
+ boolean debug = log.isDebugEnabled();
+ for (int i = 0; i < rules.size(); i++) {
+ try {
+ Rule rule = rules.get(i);
+ if (debug) {
+ log.debug(" Fire body() for " + rule);
+ }
+ rule.body(namespaceURI, name, text);
+ } catch (Exception e) {
+ throw digester.createSAXException(e);
+ } catch (Error e) {
+ throw e;
+ }
+ }
+ }
+ }
+
+ /**
+ * Duplicate the processing that the Digester does when firing the
+ * end methods of rules. It would be really nice if the Digester
+ * class provided a way for this functionality to just be invoked
+ * directly.
+ */
+ public void fireEndMethods(List rules,
+ String namespaceURI, String name)
+ throws Exception {
+
+ // Fire "end" events for all relevant rules in reverse order
+ if (rules != null) {
+ Log log = digester.getLogger();
+ boolean debug = log.isDebugEnabled();
+ for (int i = 0; i < rules.size(); i++) {
+ int j = (rules.size() - i) - 1;
+ try {
+ Rule rule = rules.get(j);
+ if (debug) {
+ log.debug(" Fire end() for " + rule);
+ }
+ rule.end(namespaceURI, name);
+ } catch (Exception e) {
+ throw digester.createSAXException(e);
+ } catch (Error e) {
+ throw e;
+ }
+ }
+ }
+ }
+}
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginDeclarationRule.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginDeclarationRule.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginDeclarationRule.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,121 @@
+/* $Id: PluginDeclarationRule.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins;
+
+import java.util.Properties;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.Rule;
+
+/**
+ * A Digester rule which allows the user to pre-declare a class which is to
+ * be referenced later at a plugin point by a PluginCreateRule.
+ *
+ * Normally, a PluginDeclarationRule is added to a Digester instance with
+ * the pattern "{root}/plugin" or "* /plugin" where {root} is the name of
+ * the root tag in the input document.
+ *
+ * @since 1.6
+ */
+
+public class PluginDeclarationRule extends Rule {
+
+ //------------------- constructors ---------------------------------------
+
+ /** constructor */
+ public PluginDeclarationRule() {
+ super();
+ }
+
+ //------------------- methods --------------------------------------------
+
+ /**
+ * Invoked upon reading a tag defining a plugin declaration. The tag
+ * must have the following mandatory attributes:
+ *
+ *
+ *@param namespace The xml namespace in which the xml element which
+ * triggered this rule resides.
+ *@param name The name of the xml element which triggered this rule.
+ *@param attributes The set of attributes on the xml element which
+ * triggered this rule.
+ *@exception java.lang.Exception
+ */
+
+ @Override
+ public void begin(String namespace, String name,
+ org.xml.sax.Attributes attributes)
+ throws java.lang.Exception {
+
+ int nAttrs = attributes.getLength();
+ Properties props = new Properties();
+ for(int i=0; i
+ * One instance of this class exists per PluginRules instance.
+ *
+ * @since 1.6
+ */
+
+public class PluginManager {
+
+ /** Map of classname->Declaration */
+ private HashMap declarationsByClass = new HashMap();
+
+ /** Map of id->Declaration */
+ private HashMap declarationsById = new HashMap();
+
+ /** the parent manager to which this one may delegate lookups. */
+ private PluginManager parent;
+
+ /**
+ * The object containing data that should only exist once for each
+ * Digester instance.
+ */
+ private PluginContext pluginContext;
+
+ //------------------- constructors ---------------------------------------
+
+ /** Construct a "root" PluginManager, ie one with no parent. */
+ public PluginManager(PluginContext r) {
+ pluginContext = r;
+ }
+
+ /**
+ * Construct a "child" PluginManager. When declarations are added to
+ * a "child", they are stored within the child and do not modify the
+ * parent, so when the child goes out of scope, those declarations
+ * disappear. When asking a "child" to retrieve a declaration, it
+ * delegates the search to its parent if it does not hold a matching
+ * entry itself.
+ *
+ * @param parent must be non-null.
+ */
+ public PluginManager(PluginManager parent) {
+ this.parent = parent;
+ this.pluginContext = parent.pluginContext;
+ }
+
+ //------------------- methods --------------------------------------------
+
+ /**
+ * Add the declaration to the set of known declarations.
+ *
+ * TODO: somehow get a reference to a Digester object
+ * so that we can really log here. Currently, all
+ * logging is disabled from this method.
+ *
+ *@param decl an object representing a plugin class.
+ */
+ public void addDeclaration(Declaration decl) {
+ Log log = LogUtils.getLogger(null);
+ boolean debug = log.isDebugEnabled();
+
+ Class> pluginClass = decl.getPluginClass();
+ String id = decl.getId();
+
+ declarationsByClass.put(pluginClass.getName(), decl);
+
+ if (id != null) {
+ declarationsById.put(id, decl);
+ if (debug) {
+ log.debug(
+ "Indexing plugin-id [" + id + "]" +
+ " -> class [" + pluginClass.getName() + "]");
+ }
+ }
+ }
+
+ /**
+ * Return the declaration object with the specified class.
+ * If no such plugin is known, null is returned.
+ */
+ public Declaration getDeclarationByClass(String className) {
+ Declaration decl =
+ declarationsByClass.get(className);
+
+ if ((decl == null) && (parent != null)) {
+ decl = parent.getDeclarationByClass(className);
+ }
+
+ return decl;
+ }
+
+ /**
+ * Return the declaration object with the specified id.
+ * If no such plugin is known, null is returned.
+ *
+ *@param id Description of the Parameter
+ *@return The declaration value
+ */
+ public Declaration getDeclarationById(String id) {
+ Declaration decl = declarationsById.get(id);
+
+ if ((decl == null) && (parent != null)) {
+ decl = parent.getDeclarationById(id);
+ }
+
+ return decl;
+ }
+
+ /**
+ * 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).
+ *
+ * If no source of custom rules can be found, null is returned.
+ */
+ public RuleLoader findLoader(Digester digester, String id,
+ Class> pluginClass, Properties props)
+ throws PluginException {
+
+ // 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(digester);
+ boolean debug = log.isDebugEnabled();
+ log.debug("scanning ruleFinders to locate loader..");
+
+ List ruleFinders = pluginContext.getRuleFinders();
+ RuleLoader ruleLoader = null;
+ try {
+ for(Iterator i = ruleFinders.iterator();
+ i.hasNext() && ruleLoader == null; ) {
+
+ RuleFinder finder = i.next();
+ if (debug) {
+ log.debug("checking finder of type " + finder.getClass().getName());
+ }
+ ruleLoader = finder.findLoader(digester, pluginClass, props);
+ }
+ }
+ catch(PluginException e) {
+ throw new PluginException(
+ "Unable to locate plugin rules for plugin"
+ + " with id [" + id + "]"
+ + ", and class [" + pluginClass.getName() + "]"
+ + ":" + e.getMessage(), e.getCause());
+ }
+ log.debug("scanned ruleFinders.");
+
+ return ruleLoader;
+ }
+}
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginRules.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginRules.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/PluginRules.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,429 @@
+/* $Id: PluginRules.java 992104 2010-09-02 20:24:31Z simonetripodi $
+ *
+ * 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.commons.digester.plugins;
+
+import java.util.List;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.Rule;
+import org.apache.commons.digester.Rules;
+import org.apache.commons.digester.RulesBase;
+import org.apache.commons.logging.Log;
+
+/**
+ * A custom digester Rules manager which must be used as the Rules object
+ * when using the plugins module functionality.
+ *
+ * During parsing, a linked list of PluginCreateRule instances develop, and
+ * this list also acts like a stack. The original instance that was set before
+ * the Digester started parsing is always at the tail of the list, and the
+ * Digester always holds a reference to the instance at the head of the list
+ * in the rules member. Initially, this list/stack holds just one instance,
+ * ie head and tail are the same object.
+ *
+ * When the start of an xml element causes a PluginCreateRule to fire, a new
+ * PluginRules instance is created and inserted at the head of the list (ie
+ * pushed onto the stack of Rules objects). Digester.getRules() therefore
+ * returns this new Rules object, and any custom rules associated with that
+ * plugin are added to that instance.
+ *
+ * When the end of the xml element is encountered (and therefore the
+ * PluginCreateRule end method fires), the stack of Rules objects is popped,
+ * so that Digester.getRules returns the previous Rules object.
+ *
+ * @since 1.6
+ */
+
+public class PluginRules implements Rules {
+
+ /**
+ * The Digester instance with which this Rules instance is associated.
+ */
+ protected Digester digester = null;
+
+ /**
+ * The (optional) object which generates new rules instances.
+ */
+ private RulesFactory rulesFactory;
+
+ /**
+ * The rules implementation that we are "enhancing" with plugins
+ * functionality, as per the Decorator pattern.
+ */
+ private Rules decoratedRules;
+
+ /** Object which contains information about all known plugins. */
+ private PluginManager pluginManager;
+
+ /**
+ * The path below which this rules object has responsibility.
+ * For paths shorter than or equal the mountpoint, the parent's
+ * match is called.
+ */
+ private String mountPoint = null;
+
+ /**
+ * The Rules object that holds rules applying "above" the mountpoint,
+ * ie the next Rules object down in the stack.
+ */
+ private PluginRules parent = null;
+
+ /**
+ * A reference to the object that holds all data which should only
+ * exist once per digester instance.
+ */
+ private PluginContext pluginContext = null;
+
+ // ------------------------------------------------------------- Constructor
+
+ /**
+ * Constructor for top-level Rules objects. Exactly one of these must
+ * be created and installed into the Digester instance as the Rules
+ * object before parsing starts.
+ */
+ public PluginRules() {
+ this(new RulesBase());
+ }
+
+ /**
+ * Constructor for top-level Rules object which handles rule-matching
+ * using the specified implementation.
+ */
+ public PluginRules(Rules decoratedRules) {
+ this.decoratedRules = decoratedRules;
+
+ pluginContext = new PluginContext();
+ pluginManager = new PluginManager(pluginContext);
+ }
+
+ /**
+ * Constructs a Rules instance which has a parent Rules object
+ * (which is different from having a delegate rules object).
+ *
+ * One of these is created each time a PluginCreateRule's begin method
+ * fires, in order to manage the custom rules associated with whatever
+ * concrete plugin class the user has specified.
+ *
+ * @param digester is the object this rules will be associated with.
+ * @param mountPoint is the digester match path for the element
+ * matching a PluginCreateRule which caused this "nested parsing scope"
+ * to begin. This is expected to be equal to digester.getMatch().
+ * @param parent must be non-null.
+ * @param pluginClass is the plugin class whose custom rules will be
+ * loaded into this new PluginRules object.
+ */
+ PluginRules(
+ Digester digester,
+ String mountPoint,
+ PluginRules parent,
+ Class> pluginClass)
+ throws PluginException {
+ // no need to set digester or decoratedRules.digester,
+ // because when Digester.setRules is called, the setDigester
+ // method on this object will be called.
+
+ this.digester = digester;
+ this.mountPoint = mountPoint;
+ this.parent = parent;
+ this.rulesFactory = parent.rulesFactory;
+
+ if (rulesFactory == null) {
+ decoratedRules = new RulesBase();
+ } else {
+ decoratedRules = rulesFactory.newRules(digester, pluginClass);
+ }
+
+ pluginContext = parent.pluginContext;
+ pluginManager = new PluginManager(parent.pluginManager);
+ }
+
+ // ------------------------------------------------------------- Properties
+
+ /**
+ * Return the parent Rules object.
+ */
+ public Rules getParent() {
+ return parent;
+ }
+
+ /**
+ * Return the Digester instance with which this instance is associated.
+ */
+ public Digester getDigester() {
+ return digester;
+ }
+
+ /**
+ * Set the Digester instance with which this Rules instance is associated.
+ *
+ * @param digester The newly associated Digester instance
+ */
+ public void setDigester(Digester digester) {
+ this.digester = digester;
+ decoratedRules.setDigester(digester);
+ }
+
+ /**
+ * Return the namespace URI that will be applied to all subsequently
+ * added Rule
objects.
+ */
+ public String getNamespaceURI() {
+ return decoratedRules.getNamespaceURI();
+ }
+
+ /**
+ * Set the namespace URI that will be applied to all subsequently
+ * added Rule
objects.
+ *
+ * @param namespaceURI Namespace URI that must match on all
+ * subsequently added rules, or null
for matching
+ * regardless of the current namespace URI
+ */
+ public void setNamespaceURI(String namespaceURI) {
+ decoratedRules.setNamespaceURI(namespaceURI);
+ }
+
+ /**
+ * Return the object which "knows" about all declared plugins.
+ *
+ * @return The pluginManager value
+ */
+ public PluginManager getPluginManager() {
+ return pluginManager;
+ }
+
+ /**
+ * See {@link PluginContext#getRuleFinders}.
+ */
+ public List getRuleFinders() {
+ return pluginContext.getRuleFinders();
+ }
+
+ /**
+ * See {@link PluginContext#setRuleFinders}.
+ */
+ public void setRuleFinders(List ruleFinders) {
+ pluginContext.setRuleFinders(ruleFinders);
+ }
+
+ /**
+ * Return the rules factory object (or null if one has not been specified).
+ */
+ public RulesFactory getRulesFactory() {
+ return rulesFactory;
+ }
+
+ /**
+ * Set the object which is used to generate the new Rules instances created
+ * to hold and process the rules associated with each plugged-in class.
+ */
+ public void setRulesFactory(RulesFactory factory) {
+ rulesFactory = factory;
+ }
+
+ // --------------------------------------------------------- Public Methods
+
+ /**
+ * This package-scope method is used by the PluginCreateRule class to
+ * get direct access to the rules that were dynamically added by the
+ * plugin. No other class should need access to this object.
+ */
+ Rules getDecoratedRules() {
+ return decoratedRules;
+ }
+
+ /**
+ * Return the list of rules registered with this object, in the order
+ * they were registered with this object.
+ *
+ * Note that Rule objects stored in parent Rules objects are not
+ * returned by this method.
+ *
+ * @return list of all Rule objects known to this Rules instance.
+ */
+ public List rules() {
+ return decoratedRules.rules();
+ }
+
+ /**
+ * Register a new Rule instance matching the specified pattern.
+ *
+ * @param pattern Nesting pattern to be matched for this Rule.
+ * This parameter treats equally patterns that begin with and without
+ * a leading slash ('/').
+ * @param rule Rule instance to be registered
+ */
+ public void add(String pattern, Rule rule) {
+ Log log = LogUtils.getLogger(digester);
+ boolean debug = log.isDebugEnabled();
+
+ if (debug) {
+ log.debug("add entry" + ": mapping pattern [" + pattern + "]" +
+ " to rule of type [" + rule.getClass().getName() + "]");
+ }
+
+ // allow patterns with a leading slash character
+ if (pattern.startsWith("/"))
+ {
+ pattern = pattern.substring(1);
+ }
+
+ if (mountPoint != null
+ && !pattern.equals(mountPoint)
+ && !pattern.startsWith(mountPoint + "/")) {
+ // This can only occur if a plugin attempts to add a
+ // rule with a pattern that doesn't start with the
+ // prefix passed to the addRules method. Plugins mustn't
+ // add rules outside the scope of the tag they were specified
+ // on, so refuse this.
+
+ // alas, can't throw exception
+ log.warn(
+ "An attempt was made to add a rule with a pattern that"
+ + "is not at or below the mountpoint of the current"
+ + " PluginRules object."
+ + " Rule pattern: " + pattern
+ + ", mountpoint: " + mountPoint
+ + ", rule type: " + rule.getClass().getName());
+ return;
+ }
+
+ decoratedRules.add(pattern, rule);
+
+ if (rule instanceof InitializableRule) {
+ try {
+ ((InitializableRule)rule).postRegisterInit(pattern);
+ } catch (PluginConfigurationException e) {
+ // Currently, Digester doesn't handle exceptions well
+ // from the add method. The workaround is for the
+ // initialisable rule to remember that its initialisation
+ // failed, and to throw the exception when begin is
+ // called for the first time.
+ if (debug) {
+ log.debug("Rule initialisation failed", e);
+ }
+ // throw e; -- alas, can't do this
+ return;
+ }
+ }
+
+ if (debug) {
+ log.debug("add exit" + ": mapped pattern [" + pattern + "]" +
+ " to rule of type [" + rule.getClass().getName() + "]");
+ }
+ }
+
+ /**
+ * Clear all rules.
+ */
+ public void clear() {
+ decoratedRules.clear();
+ }
+
+ /**
+ * Return a List of all registered Rule instances that match the specified
+ * nesting pattern, or a zero-length List if there are no matches. If more
+ * than one Rule instance matches, they must be returned
+ * in the order originally registered through the add()
+ * method.
+ *
+ * @param path the path to the xml nodes to be matched.
+ *
+ * @deprecated Call match(namespaceURI,pattern) instead.
+ */
+ @Deprecated
+ public List match(String path) {
+ return (match(null, path));
+ }
+
+ /**
+ * Return a List of all registered Rule instances that match the specified
+ * nodepath, or a zero-length List if there are no matches. If more
+ * than one Rule instance matches, they must be returned
+ * in the order originally registered through the add()
+ * method.
+ *
+ * @param namespaceURI Namespace URI for which to select matching rules,
+ * or null
to match regardless of namespace URI
+ * @param path the path to the xml nodes to be matched.
+ */
+ public List match(String namespaceURI, String path) {
+ Log log = LogUtils.getLogger(digester);
+ boolean debug = log.isDebugEnabled();
+
+ if (debug) {
+ log.debug(
+ "Matching path [" + path +
+ "] on rules object " + this.toString());
+ }
+
+ List matches;
+ if ((mountPoint != null) &&
+ (path.length() <= mountPoint.length())) {
+ if (debug) {
+ log.debug(
+ "Path [" + path + "] delegated to parent.");
+ }
+
+ matches = parent.match(namespaceURI, path);
+
+ // Note that in the case where path equals mountPoint,
+ // we deliberately return only the rules from the parent,
+ // even though this object may hold some rules matching
+ // this same path. See PluginCreateRule's begin, body and end
+ // methods for the reason.
+ } else {
+ log.debug("delegating to decorated rules.");
+ matches = decoratedRules.match(namespaceURI, path);
+ }
+
+ return matches;
+ }
+
+ /** See {@link PluginContext#setPluginClassAttribute}. */
+ public void setPluginClassAttribute(String namespaceUri,
+ String attrName) {
+ pluginContext.setPluginClassAttribute(namespaceUri, attrName);
+ }
+
+ /** See {@link PluginContext#setPluginIdAttribute}. */
+ public void setPluginIdAttribute(String namespaceUri,
+ String attrName) {
+ pluginContext.setPluginIdAttribute(namespaceUri, attrName);
+ }
+
+ /** See {@link PluginContext#getPluginClassAttrNs}. */
+ public String getPluginClassAttrNs() {
+ return pluginContext.getPluginClassAttrNs();
+ }
+
+ /** See {@link PluginContext#getPluginClassAttr}. */
+ public String getPluginClassAttr() {
+ return pluginContext.getPluginClassAttr();
+ }
+
+ /** See {@link PluginContext#getPluginIdAttrNs}. */
+ public String getPluginIdAttrNs() {
+ return pluginContext.getPluginIdAttrNs();
+ }
+
+ /** See {@link PluginContext#getPluginIdAttr}. */
+ public String getPluginIdAttr() {
+ return pluginContext.getPluginIdAttr();
+ }
+}
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/RuleFinder.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/RuleFinder.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/RuleFinder.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,75 @@
+/* $Id: RuleFinder.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins;
+
+import java.util.Properties;
+import org.apache.commons.digester.Digester;
+
+/**
+ * Each concrete implementation of RuleFinder is an algorithm for
+ * locating a source of digester rules for a plugin. The algorithm may
+ * use info explicitly provided by the user as part of the plugin
+ * declaration, or not (in which case the concrete RuleFinder subclass
+ * typically has Dflt as part of its name).
+ *
+ * Instances of this class can also be regarded as a Factory for RuleLoaders,
+ * except that an instance of a RuleLoader is only created if the particular
+ * finder algorithm can locate a suitable source of rules given the plugin
+ * class and associated properties.
+ *
+ * This is an abstract class rather than an interface in order to make
+ * it possible to enhance this class in future without breaking binary
+ * compatibility; it is possible to add methods to an abstract class, but
+ * not to an interface.
+ *
+ * @since 1.6
+ */
+
+public abstract class RuleFinder {
+
+ /**
+ * Apply the finder algorithm to attempt to locate a source of
+ * digester rules for the specified plugin class.
+ *
+ * This method is invoked when a plugin is declared by the user, either
+ * via an explicit use of PluginDeclarationRule, or implicitly via an
+ * "inline declaration" where the declaration and use are simultaneous.
+ *
+ * If dynamic rules for the specified plugin class are located, then
+ * the RuleFinder will return a RuleLoader object encapsulating those
+ * rules, and this object will be invoked each time the user actually
+ * requests an instance of the declared plugin class, to load the
+ * custom rules associated with that plugin instance.
+ *
+ * If no dynamic rules can be found, null is returned. This is not an
+ * error; merely an indication that this particular algorithm found
+ * no matches.
+ *
+ * The properties object holds any xml attributes the user may have
+ * specified on the plugin declaration in order to indicate how to locate
+ * the plugin rules.
+ *
+ * @throws PluginConfigurationException if the algorithm finds a source
+ * of rules, but there is something invalid about that source.
+ */
+
+ public abstract RuleLoader findLoader(
+ Digester d, Class> pluginClass,
+ Properties p) throws PluginException;
+}
+
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/RuleLoader.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/RuleLoader.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/RuleLoader.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,49 @@
+/* $Id: RuleLoader.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins;
+
+import org.apache.commons.digester.Digester;
+
+/**
+ * Interface for classes which can dynamically load custom
+ * plugin rules associated with a user's plugin class.
+ *
+ * Each plugin declaration has an associated RuleLoader instance, and that
+ * instance's addRules method is invoked each time the input xml specifies
+ * that an instance of that plugged-in class is to be created.
+ *
+ * This is an abstract class rather than an interface in order to make
+ * it possible to enhance this class in future without breaking binary
+ * compatibility; it is possible to add methods to an abstract class, but
+ * not to an interface.
+ *
+ * @since 1.6
+ */
+
+public abstract class RuleLoader {
+
+ /**
+ * Configures the digester with custom rules for some plugged-in
+ * class.
+ *
+ * This method is invoked when the start of an xml tag is encountered
+ * which maps to a PluginCreateRule. Any rules added here are removed
+ * from the digester when the end of that xml tag is encountered.
+ */
+ public abstract void addRules(Digester d, String path) throws PluginException;
+}
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/RulesFactory.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/RulesFactory.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/RulesFactory.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,55 @@
+/* $Id: RulesFactory.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.Rules;
+
+/**
+ * Whenever the scope of a plugin tag is entered, the PluginRules class
+ * creates a new Rules instance and configures it with the appropriate
+ * parsing rules for the plugged-in class.
+ *
+ * Users of the plugins module can specify a subclass of this one to
+ * control the creation of that Rules object. In particular, it can
+ * set up default rules within the returned instance which are applicable
+ * to all plugged-in classes.
+ *
+ * @since 1.6
+ */
+
+public abstract class RulesFactory {
+
+ /**
+ * Return an instance of some Rules implementation that the plugged-in
+ * class shall use to match its private parsing rules.
+ *
+ * @param d is the digester that the returned rules object will be
+ * associated with.
+ *
+ * @param pluginClass is the class that is to be configured using rules
+ * added to the returnedobject.
+ *
+ * @throws PluginException if the algorithm finds a source
+ * of rules, but there is something invalid about that source.
+ */
+
+ public abstract Rules newRules(Digester d, Class> pluginClass)
+ throws PluginException;
+}
+
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/package-info.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/package-info.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/package-info.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,23 @@
+/* $Id: package-info.java 991743 2010-09-01 22:44:15Z simonetripodi $
+ *
+ * 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.
+ */
+
+/**
+ * The plugins
package provides an easy mechanism whereby new
+ * digestion rules can be added dynamically during a digestion.
+ */
+package org.apache.commons.digester.plugins;
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromClass.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromClass.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromClass.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,128 @@
+/* $Id: FinderFromClass.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins.strategies;
+
+import java.util.Properties;
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.plugins.RuleFinder;
+import org.apache.commons.digester.plugins.RuleLoader;
+import org.apache.commons.digester.plugins.PluginException;
+
+/**
+ * A rule-finding algorithm which expects the caller to specify a classname and
+ * methodname as plugin properties.
+ *
+ * @since 1.6
+ */
+
+public class FinderFromClass extends RuleFinder {
+ public static String DFLT_RULECLASS_ATTR = "ruleclass";
+ public static String DFLT_METHOD_ATTR = "method";
+ public static String DFLT_METHOD_NAME = "addRules";
+
+ private String ruleClassAttr;
+ private String methodAttr;
+ private String dfltMethodName;
+
+ /**
+ * See {@link #findLoader}.
+ */
+ public FinderFromClass() {
+ this(DFLT_RULECLASS_ATTR, DFLT_METHOD_ATTR, DFLT_METHOD_NAME);
+ }
+
+ /**
+ * Create a rule-finder which invokes a user-specified method on a
+ * user-specified class whenever dynamic rules for a plugin need to be
+ * loaded. See the findRules method for more info.
+ *
+ * @param ruleClassAttr must be non-null.
+ * @param methodAttr may be null.
+ * @param dfltMethodName may be null.
+ */
+ public FinderFromClass(String ruleClassAttr, String methodAttr,
+ String dfltMethodName) {
+ this.ruleClassAttr = ruleClassAttr;
+ this.methodAttr = methodAttr;
+ this.dfltMethodName = dfltMethodName;
+ }
+
+ /**
+ * If there exists a property with the name matching constructor param
+ * ruleClassAttr, then load the specified class, locate the appropriate
+ * rules-adding method on that class, and return an object encapsulating
+ * that info.
+ *
+ * If there is no matching property provided, then just return null.
+ *
+ * The returned object (when non-null) will invoke the target method
+ * on the selected class whenever its addRules method is invoked. The
+ * target method is expected to have the following prototype:
+ * public static void xxxxx(Digester d, String patternPrefix);
+ *
+ * The target method can be specified in several ways. If this object's
+ * constructor was passed a non-null methodAttr parameter, and the
+ * properties defines a value with that key, then that is taken as the
+ * target method name. If there is no matching property, or the constructor
+ * was passed null for methodAttr, then the dfltMethodName passed to the
+ * constructor is used as the name of the method on the target class. And
+ * if that was null, then DFLT_METHOD_NAME will be used.
+ *
+ * When the user explicitly declares a plugin in the input xml, the
+ * xml attributes on the declaration tag are passed here as properties,
+ * so the user can select any class in the classpath (and any method on
+ * that class provided it has the correct prototype) as the source of
+ * dynamic rules for the plugged-in class.
+ */
+ @Override
+ public RuleLoader findLoader(Digester digester, Class> pluginClass,
+ Properties p) throws PluginException {
+
+ String ruleClassName = p.getProperty(ruleClassAttr);
+ if (ruleClassName == null) {
+ // nope, user hasn't requested dynamic rules to be loaded
+ // from a specific class.
+ return null;
+ }
+
+ // ok, we are in business
+ String methodName = null;
+ if (methodAttr != null) {
+ methodName = p.getProperty(methodAttr);
+ }
+ if (methodName == null) {
+ methodName = dfltMethodName;
+ }
+ if (methodName == null) {
+ methodName = DFLT_METHOD_NAME;
+ }
+
+ Class> ruleClass;
+ try {
+ // load the plugin class object
+ ruleClass =
+ digester.getClassLoader().loadClass(ruleClassName);
+ } catch(ClassNotFoundException cnfe) {
+ throw new PluginException(
+ "Unable to load class " + ruleClassName, cnfe);
+ }
+
+ return new LoaderFromClass(ruleClass, methodName);
+ }
+}
+
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromDfltClass.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromDfltClass.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromDfltClass.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,92 @@
+/* $Id: FinderFromDfltClass.java 992106 2010-09-02 20:29:25Z simonetripodi $
+ *
+ * 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.commons.digester.plugins.strategies;
+
+import java.util.Properties;
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.plugins.RuleFinder;
+import org.apache.commons.digester.plugins.RuleLoader;
+import org.apache.commons.digester.plugins.PluginException;
+
+/**
+ * A rule-finding algorithm which looks for a method with a specific name
+ * on a class whose name is derived from the plugin class name.
+ *
+ * @since 1.6
+ */
+
+public class FinderFromDfltClass extends RuleFinder {
+ public static String DFLT_RULECLASS_SUFFIX = "RuleInfo";
+ public static String DFLT_METHOD_NAME = "addRules";
+
+ private String rulesClassSuffix;
+ private String methodName;
+
+ /** See {@link #findLoader}. */
+ public FinderFromDfltClass() {
+ this(DFLT_RULECLASS_SUFFIX, DFLT_METHOD_NAME);
+ }
+
+ /**
+ * Create a rule-finder which invokes a method on a class whenever
+ * dynamic rules for a plugin need to be loaded. See the findRules
+ * method for more info.
+ *
+ * @param rulesClassSuffix must be non-null.
+ * @param methodName may be null.
+ */
+ public FinderFromDfltClass(String rulesClassSuffix, String methodName) {
+ this.rulesClassSuffix = rulesClassSuffix;
+ this.methodName = methodName;
+ }
+
+ /**
+ * If there exists a class whose name is the plugin class name + the
+ * suffix specified to the constructor, then load that class, locate
+ * the appropriate rules-adding method on that class, and return an
+ * object encapsulating that info.
+ *
+ * If there is no such class, then just return null.
+ *
+ * The returned object (when non-null) will invoke the target method
+ * on the selected class whenever its addRules method is invoked. The
+ * target method is expected to have the following prototype:
+ * public static void xxxxx(Digester d, String patternPrefix);
+ */
+ @Override
+ public RuleLoader findLoader(Digester digester, Class> pluginClass, Properties p)
+ throws PluginException {
+
+ String rulesClassName = pluginClass.getName() + rulesClassSuffix;
+
+ Class> rulesClass = null;
+ try {
+ rulesClass = digester.getClassLoader().loadClass(rulesClassName);
+ } catch(ClassNotFoundException cnfe) {
+ // nope, no rule-info class in the classpath
+ return null;
+ }
+
+ if (methodName == null) {
+ methodName = DFLT_METHOD_NAME;
+ }
+
+ return new LoaderFromClass(rulesClass, methodName);
+ }
+}
+
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromDfltMethod.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromDfltMethod.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromDfltMethod.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,80 @@
+/* $Id: FinderFromDfltMethod.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins.strategies;
+
+import java.util.Properties;
+import java.lang.reflect.Method;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.plugins.RuleFinder;
+import org.apache.commons.digester.plugins.RuleLoader;
+import org.apache.commons.digester.plugins.PluginException;
+
+/**
+ * A rule-finding algorithm which looks for a method with a specific name
+ * on the plugin class.
+ *
+ * @since 1.6
+ */
+
+public class FinderFromDfltMethod extends RuleFinder {
+ public static String DFLT_METHOD_NAME = "addRules";
+
+ private String methodName;
+
+ /** See {@link #findLoader}. */
+ public FinderFromDfltMethod() {
+ this(DFLT_METHOD_NAME);
+ }
+
+ /**
+ * Create a rule-finder which invokes a specific method on the plugin
+ * class whenever dynamic rules for a plugin need to be loaded. See the
+ * findRules method for more info.
+ *
+ * @param methodName must be non-null.
+ */
+ public FinderFromDfltMethod(String methodName) {
+ this.methodName = methodName;
+ }
+
+ /**
+ * If there exists on the plugin class a method with name matching the
+ * constructor's methodName value then locate the appropriate Method on
+ * the plugin class and return an object encapsulating that info.
+ *
+ * If there is no matching method then just return null.
+ *
+ * The returned object (when non-null) will invoke the target method
+ * on the plugin class whenever its addRules method is invoked. The
+ * target method is expected to have the following prototype:
+ * public static void xxxxx(Digester d, String patternPrefix);
+ */
+ @Override
+ public RuleLoader findLoader(Digester d, Class> pluginClass, Properties p)
+ throws PluginException {
+
+ Method rulesMethod = LoaderFromClass.locateMethod(pluginClass, methodName);
+ if (rulesMethod == null) {
+ return null;
+ }
+
+ return new LoaderFromClass(pluginClass, rulesMethod);
+ }
+}
+
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromDfltResource.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromDfltResource.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromDfltResource.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,90 @@
+/* $Id: FinderFromDfltResource.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins.strategies;
+
+import java.io.InputStream;
+import java.util.Properties;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.plugins.RuleFinder;
+import org.apache.commons.digester.plugins.RuleLoader;
+import org.apache.commons.digester.plugins.PluginException;
+
+/**
+ * A rule-finding algorithm which looks for a resource file in the classpath
+ * whose name is derived from the plugin class name plus a specified suffix.
+ *
+ * If the resource-file is found, then it is expected to define a set of
+ * Digester rules in xmlrules format.
+ *
+ * @since 1.6
+ */
+
+public class FinderFromDfltResource extends RuleFinder {
+ public static String DFLT_RESOURCE_SUFFIX = "RuleInfo.xml";
+
+ private String resourceSuffix;
+
+ /** See {@link #findLoader}. */
+ public FinderFromDfltResource() {
+ this(DFLT_RESOURCE_SUFFIX);
+ }
+
+ /**
+ * Create a rule-finder which can load an xmlrules file, cache
+ * the rules away, and later add them as a plugin's custom rules
+ * when that plugin is referenced.
+ *
+ * @param resourceSuffix must be non-null.
+ */
+ public FinderFromDfltResource(String resourceSuffix) {
+ this.resourceSuffix = resourceSuffix;
+ }
+
+ /**
+ * If there exists a resource file whose name is equal to the plugin
+ * class name + the suffix specified in the constructor, then
+ * load that file, run it through the xmlrules module and return an object
+ * encapsulating those rules.
+ *
+ * If there is no such resource file, then just return null.
+ *
+ * The returned object (when non-null) will add the selected rules to
+ * the digester whenever its addRules method is invoked.
+ */
+ @Override
+ public RuleLoader findLoader(Digester d, Class> pluginClass, Properties p)
+ throws PluginException {
+
+ String resourceName =
+ pluginClass.getName().replace('.', '/')
+ + resourceSuffix;
+
+ InputStream is =
+ pluginClass.getClassLoader().getResourceAsStream(
+ resourceName);
+
+ if (is == null) {
+ // ok, no such resource
+ return null;
+ }
+
+ return FinderFromResource.loadRules(d, pluginClass, is, resourceName);
+ }
+}
+
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromFile.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromFile.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromFile.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,106 @@
+/* $Id: FinderFromFile.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins.strategies;
+
+import java.util.Properties;
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.plugins.RuleFinder;
+import org.apache.commons.digester.plugins.RuleLoader;
+import org.apache.commons.digester.plugins.PluginException;
+
+/**
+ * A rule-finding algorithm which expects the user to specify an absolute
+ * or relative path in the plugin declaration.
+ *
+ * The file is expected to contain Digester rules in xmlrules format.
+ *
+ * @since 1.6
+ */
+
+public class FinderFromFile extends RuleFinder {
+ /**
+ * Xml attribute that needs to be present on a plugin declaration
+ * in order to specify the file to load rules from.
+ */
+ public static String DFLT_FILENAME_ATTR = "file";
+
+ /** See {@link #findLoader}. */
+ private String filenameAttr;
+
+ /** See {@link #findLoader}. */
+ public FinderFromFile() {
+ this(DFLT_FILENAME_ATTR);
+ }
+
+ /** See {@link #findLoader}. */
+ public FinderFromFile(String filenameAttr) {
+ this.filenameAttr = filenameAttr;
+ }
+
+ /**
+ * If there exists a property with the name specified in the constructor,
+ * then load that file, run it through the xmlrules module and return an
+ * object encapsulating those rules.
+ *
+ * If there is no matching property provided, then just return null.
+ *
+ * The returned object (when non-null) will add the selected rules to
+ * the digester whenever its addRules method is invoked.
+ */
+ @Override
+ public RuleLoader findLoader(Digester d, Class> pluginClass, Properties p)
+ throws PluginException {
+
+ String rulesFileName = p.getProperty(filenameAttr);
+ if (rulesFileName == null) {
+ // nope, user hasn't requested dynamic rules to be loaded
+ // from a specific file.
+ return null;
+ }
+
+ InputStream is = null;
+ try {
+ is = new FileInputStream(rulesFileName);
+ } catch(IOException ioe) {
+ throw new PluginException(
+ "Unable to process file [" + rulesFileName + "]", ioe);
+ }
+
+ try {
+ RuleLoader loader = new LoaderFromStream(is);
+ return loader;
+ } catch(Exception e) {
+ throw new PluginException(
+ "Unable to load xmlrules from file [" +
+ rulesFileName + "]", e);
+ } finally {
+ try {
+ is.close();
+ } catch(java.io.IOException ioe) {
+ throw new PluginException(
+ "Unable to close stream for file [" +
+ rulesFileName + "]", ioe);
+ }
+ }
+ }
+}
+
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromMethod.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromMethod.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromMethod.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,79 @@
+/* $Id: FinderFromMethod.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins.strategies;
+
+import java.util.Properties;
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.plugins.RuleFinder;
+import org.apache.commons.digester.plugins.RuleLoader;
+import org.apache.commons.digester.plugins.PluginException;
+
+/**
+ * A rule-finding algorithm which expects the caller to specify a methodname
+ * as a plugin property, where the method exists on the plugin class.
+ *
+ * @since 1.6
+ */
+
+public class FinderFromMethod extends RuleFinder {
+ /**
+ * Xml attribute that needs to be present on a plugin declaration
+ * in order to specify the method to load rules from.
+ */
+ public static String DFLT_METHOD_ATTR = "method";
+
+ /** See {@link #findLoader}. */
+ private String methodAttr;
+
+ /** Constructor. */
+ public FinderFromMethod() {
+ this(DFLT_METHOD_ATTR);
+ }
+
+ /** See {@link #findLoader}. */
+ public FinderFromMethod(String methodAttr) {
+ this.methodAttr = methodAttr;
+ }
+
+ /**
+ * If there exists a property with the name matching constructor param
+ * methodAttr, then locate the appropriate Method on the plugin class
+ * and return an object encapsulating that info.
+ *
+ * If there is no matching property provided, then just return null.
+ *
+ * The returned object (when non-null) will invoke the target method
+ * on the plugin class whenever its addRules method is invoked. The
+ * target method is expected to have the following prototype:
+ * public static void xxxxx(Digester d, String patternPrefix);
+ */
+ @Override
+ public RuleLoader findLoader(Digester d, Class> pluginClass, Properties p)
+ throws PluginException {
+
+ String methodName = p.getProperty(methodAttr);
+ if (methodName == null) {
+ // nope, user hasn't requested dynamic rules to be loaded
+ // from a specific class.
+ return null;
+ }
+
+ return new LoaderFromClass(pluginClass, methodName);
+ }
+}
+
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromResource.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromResource.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderFromResource.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,122 @@
+/* $Id: FinderFromResource.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins.strategies;
+
+import java.util.Properties;
+import java.io.InputStream;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.plugins.RuleFinder;
+import org.apache.commons.digester.plugins.RuleLoader;
+import org.apache.commons.digester.plugins.PluginException;
+
+/**
+ * A rule-finding algorithm which expects the user to specify a resource
+ * name (ie a file in the classpath). The file is expected to contain Digester
+ * rules in xmlrules format.
+ *
+ * @since 1.6
+ */
+
+public class FinderFromResource extends RuleFinder {
+ /**
+ * Name of xml attribute on the plugin declaration which is used
+ * to configure rule-loading for that declaration.
+ */
+ public static String DFLT_RESOURCE_ATTR = "resource";
+
+ /** See {@link #findLoader}. */
+ private String resourceAttr;
+
+ /** Constructor. */
+ public FinderFromResource() {
+ this(DFLT_RESOURCE_ATTR);
+ }
+
+ /** See {@link #findLoader}. */
+ public FinderFromResource(String resourceAttr) {
+ this.resourceAttr = resourceAttr;
+ }
+
+ /**
+ * If there exists a property with the name matching constructor param
+ * resourceAttr, then load that file, run it through the xmlrules
+ * module and return an object encapsulating those rules.
+ *
+ * If there is no matching property provided, then just return null.
+ *
+ * The returned object (when non-null) will add the selected rules to
+ * the digester whenever its addRules method is invoked.
+ */
+ @Override
+ public RuleLoader findLoader(Digester d, Class> pluginClass, Properties p)
+ throws PluginException {
+
+ String resourceName = p.getProperty(resourceAttr);
+ if (resourceName == null) {
+ // nope, user hasn't requested dynamic rules to be loaded
+ // from a specific file.
+ return null;
+ }
+
+ InputStream is =
+ pluginClass.getClassLoader().getResourceAsStream(
+ resourceName);
+
+ if (is == null) {
+ throw new PluginException(
+ "Resource " + resourceName + " not found.");
+ }
+
+ return loadRules(d, pluginClass, is, resourceName);
+ }
+
+ /**
+ * Open the specified resource file (ie a file in the classpath,
+ * including being within a jar in the classpath), run it through
+ * the xmlrules module and return an object encapsulating those rules.
+ *
+ * @param d is the digester into which rules will eventually be loaded.
+ * @param pluginClass is the class whose xml params the rules are parsing.
+ * @param is is where the xmlrules will be read from, and must be non-null.
+ * @param resourceName is a string describing the source of the xmlrules,
+ * for use in generating error messages.
+ */
+ public static RuleLoader loadRules(Digester d, Class> pluginClass,
+ InputStream is, String resourceName)
+ throws PluginException {
+
+ try {
+ RuleLoader loader = new LoaderFromStream(is);
+ return loader;
+ } catch(Exception e) {
+ throw new PluginException(
+ "Unable to load xmlrules from resource [" +
+ resourceName + "]", e);
+ } finally {
+ try {
+ is.close();
+ } catch(java.io.IOException ioe) {
+ throw new PluginException(
+ "Unable to close stream for resource [" +
+ resourceName + "]", ioe);
+ }
+ }
+ }
+}
+
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderSetProperties.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderSetProperties.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/FinderSetProperties.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,98 @@
+/* $Id: FinderSetProperties.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins.strategies;
+
+import java.util.Properties;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.plugins.RuleFinder;
+import org.apache.commons.digester.plugins.RuleLoader;
+
+/**
+ * A rule-finding algorithm which expects the user to specify whether
+ * "automatic property setting" is desired. If this class discovers that
+ * this is in fact the case for a declaration, then a RuleLoader is returned
+ * which, when invoked, adds a single SetPropertiesRule instance to the
+ * digester.
+ *
+ * This allows ordinary JavaBean classes to be used as plugins, and have
+ * xml attributes be mapped to bean properties of the same name, without
+ * any custom plugin rules being created for them.
+ *
+ * This RuleFinder is typically used as the last RuleFinder, so that
+ * automatic property setting only occurs if there is no other source of
+ * custom rules available.
+ *
+ * @since 1.6
+ */
+
+public class FinderSetProperties extends RuleFinder {
+ public static String DFLT_PROPS_ATTR = "setprops";
+ public static String DFLT_FALSEVAL = "false";
+
+ private String propsAttr;
+ private String falseval;
+
+ /** See {@link #findLoader}. */
+ public FinderSetProperties() {
+ this(DFLT_PROPS_ATTR, DFLT_FALSEVAL);
+ }
+
+ /**
+ * Create a rule-finder which will arrange for a SetPropertiesRule to
+ * be defined for each instance of a plugin, so that xml attributes
+ * map to bean properties.
+ *
+ * Param falseval will commonly be the string "false" for config files
+ * written in English.
+ *
+ * @param propsAttr must be non-null.
+ * @param falseval must be non-null.
+ */
+ public FinderSetProperties(String propsAttr, String falseval) {
+ this.propsAttr = propsAttr;
+ this.falseval = falseval;
+ }
+
+ /**
+ * Returns a RuleLoader unless the properties contain an entry
+ * with the name matching constructor param propsAttr, and the value
+ * matching what is in falseval.
+ *
+ * If no custom source of rules for a plugin is found, then the user
+ * almost always wants xml attributes to map to java bean properties,
+ * so this is the default behaviour unless the user explicitly indicates
+ * that they do not want a SetPropertiesRule to be provided for
+ * the plugged-in class.
+ *
+ * The returned object (when non-null) will add a SetPropertiesRule to
+ * the digester whenever its addRules method is invoked.
+ */
+ @Override
+ public RuleLoader findLoader(Digester d, Class> pluginClass, Properties p) {
+ String state = p.getProperty(propsAttr);
+ if ((state != null) && state.equals(falseval)) {
+ // user has explicitly disabled automatic setting of properties.
+ // this is not expected to be common, but allowed.
+ return null;
+ }
+
+ return new LoaderSetProperties();
+ }
+}
+
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/LoaderFromClass.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/LoaderFromClass.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/LoaderFromClass.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,103 @@
+/* $Id: LoaderFromClass.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins.strategies;
+
+import java.lang.reflect.Method;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.beanutils.MethodUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.digester.plugins.RuleLoader;
+import org.apache.commons.digester.plugins.PluginException;
+
+/**
+ * A RuleLoader which invokes a static method on a target class, leaving that
+ * method to actually instantiate and add new rules to a Digester instance.
+ *
+ * @since 1.6
+ */
+
+public class LoaderFromClass extends RuleLoader {
+
+ private Class> rulesClass;
+ private Method rulesMethod;
+
+ /** Constructor. */
+ public LoaderFromClass(Class> rulesClass, Method rulesMethod) {
+ this.rulesClass = rulesClass;
+ this.rulesMethod = rulesMethod;
+ }
+
+ /** Constructor. */
+ public LoaderFromClass(Class> rulesClass, String methodName)
+ throws PluginException {
+
+ Method method = locateMethod(rulesClass, methodName);
+
+ if (method == null) {
+ throw new PluginException(
+ "rule class " + rulesClass.getName()
+ + " does not have method " + methodName
+ + " or that method has an invalid signature.");
+ }
+
+ this.rulesClass = rulesClass;
+ this.rulesMethod = method;
+ }
+
+ /**
+ * Just invoke the target method.
+ */
+ @Override
+ public void addRules(Digester d, String path) throws PluginException {
+ Log log = d.getLogger();
+ boolean debug = log.isDebugEnabled();
+ if (debug) {
+ log.debug(
+ "LoaderFromClass loading rules for plugin at path ["
+ + path + "]");
+ }
+
+ try {
+ Object[] params = {d, path};
+ rulesMethod.invoke(null, params);
+ } catch (Exception e) {
+ throw new PluginException(
+ "Unable to invoke rules method " + rulesMethod
+ + " on rules class " + rulesClass, e);
+ }
+ }
+
+ /**
+ * Find a method on the specified class whose name matches methodName,
+ * and whose signature is:
+ * public static void foo(Digester d, String patternPrefix);
.
+ *
+ * @return null if no such method exists.
+ */
+ public static Method locateMethod(Class> rulesClass, String methodName)
+ throws PluginException {
+
+ Class>[] paramSpec = { Digester.class, String.class };
+ Method rulesMethod = MethodUtils.getAccessibleMethod(
+ rulesClass, methodName, paramSpec);
+
+ return rulesMethod;
+ }
+}
+
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/LoaderFromStream.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/LoaderFromStream.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/LoaderFromStream.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,93 @@
+/* $Id: LoaderFromStream.java 992107 2010-09-02 20:31:00Z simonetripodi $
+ *
+ * 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.commons.digester.plugins.strategies;
+
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import org.xml.sax.InputSource;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.plugins.RuleLoader;
+import org.apache.commons.digester.plugins.PluginException;
+import org.apache.commons.digester.xmlrules.FromXmlRuleSet;
+import org.apache.commons.logging.Log;
+
+/**
+ * A rule-finding algorithm which loads an xmlplugins-format file.
+ *
+ * Note that the "include" feature of xmlrules is not supported.
+ *
+ * @since 1.6
+ */
+
+public class LoaderFromStream extends RuleLoader {
+
+ private byte[] input;
+
+ /** See {@link #load}. */
+ public LoaderFromStream(InputStream s) throws Exception {
+ load(s);
+ }
+
+ /**
+ * The contents of the input stream are loaded into memory, and
+ * cached for later use.
+ *
+ * The caller is responsible for closing the input stream after this
+ * method has returned.
+ */
+ private void load(InputStream s) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buf = new byte[256];
+ for(;;) {
+ int i = s.read(buf);
+ if (i == -1)
+ break;
+ baos.write(buf, 0, i);
+ }
+ input = baos.toByteArray();
+ }
+
+ /**
+ * Add the rules previously loaded from the input stream into the
+ * specified digester.
+ */
+ @Override
+ public void addRules(Digester d, String path) throws PluginException {
+ Log log = d.getLogger();
+ boolean debug = log.isDebugEnabled();
+ if (debug) {
+ log.debug(
+ "LoaderFromStream: loading rules for plugin at path ["
+ + path + "]");
+ }
+
+ // Note that this input-source doesn't have any idea of its
+ // system id, so it has no way of resolving relative URLs
+ // such as the "include" feature of xmlrules. This is ok,
+ // because that doesn't work well with our approach of
+ // caching the input data in memory anyway.
+
+ InputSource source = new InputSource(new ByteArrayInputStream(input));
+ FromXmlRuleSet ruleSet = new FromXmlRuleSet(source);
+ ruleSet.addRuleInstances(d, path);
+ }
+}
+
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/LoaderSetProperties.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/LoaderSetProperties.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/LoaderSetProperties.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,54 @@
+/* $Id: LoaderSetProperties.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.plugins.strategies;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.logging.Log;
+import org.apache.commons.digester.plugins.RuleLoader;
+
+/**
+ * A RuleLoader which creates a single SetPropertiesRule and adds it to the
+ * digester when its addRules() method is invoked.
+ *
+ * This loader ensures that any xml attributes on the plugin tag get
+ * mapped to equivalent properties on a javabean. This allows JavaBean
+ * classes to be used as plugins without any requirement to create custom
+ * plugin rules.
+ *
+ * @since 1.6
+ */
+
+public class LoaderSetProperties extends RuleLoader {
+
+ /**
+ * Just add a SetPropertiesRule at the specified path.
+ */
+ @Override
+ public void addRules(Digester digester, String path) {
+ Log log = digester.getLogger();
+ boolean debug = log.isDebugEnabled();
+ if (debug) {
+ log.debug(
+ "LoaderSetProperties loading rules for plugin at path ["
+ + path + "]");
+ }
+
+ digester.addSetProperties(path);
+ }
+}
+
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/package-info.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/package-info.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/plugins/strategies/package-info.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,23 @@
+/* $Id: package-info.java 991743 2010-09-01 22:44:15Z simonetripodi $
+ *
+ * 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.
+ */
+
+/**
+ * The plugins.strategies
package contains "rule-finding" strategy
+ * classes, and their associated "helper" loader classes.
+ */
+package org.apache.commons.digester.plugins.strategies;
Index: 3rdParty_sources/commons-digester/org/apache/commons/digester/substitution/MultiVariableExpander.java
===================================================================
diff -u
--- 3rdParty_sources/commons-digester/org/apache/commons/digester/substitution/MultiVariableExpander.java (revision 0)
+++ 3rdParty_sources/commons-digester/org/apache/commons/digester/substitution/MultiVariableExpander.java (revision ae060b7e61e715d667e47c7ee61f04fa2f2a0fbc)
@@ -0,0 +1,116 @@
+/* $Id: MultiVariableExpander.java 992060 2010-09-02 19:09:47Z simonetripodi $
+ *
+ * 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.commons.digester.substitution;
+
+import java.util.Map;
+import java.util.ArrayList;
+
+/**
+ *
Expands variable references from multiple sources.
+ *
+ * @since 1.6
+ */
+
+public class MultiVariableExpander implements VariableExpander {
+ private int nEntries = 0;
+ private ArrayList markers = new ArrayList(2);
+ private ArrayList