in commons-digester3-core/src/main/java/org/apache/commons/digester3/plugins/PluginCreateRule.java [132:259]
public void begin( final String namespace, final String name, final Attributes attributes )
throws Exception
{
final Log log = getDigester().getLogger();
final boolean debug = log.isDebugEnabled();
if ( debug )
{
log.debug( "PluginCreateRule.begin" + ": pattern=[" + pattern + "]" + " match=[" + getDigester().getMatch()
+ "]" );
}
if ( initException != null )
{
// we had a problem during initialization that we could
// not report then; report it now.
throw initException;
}
// load any custom rules associated with the plugin
final PluginRules oldRules = (PluginRules) getDigester().getRules();
final PluginManager pluginManager = oldRules.getPluginManager();
Declaration currDeclaration;
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( getDigester(), pluginManager );
}
catch ( final 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
final Class<?> pluginClass = currDeclaration.getPluginClass();
final String path = getDigester().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.
final PluginRules newRules = new PluginRules( getDigester(), path, oldRules, pluginClass );
getDigester().setRules( newRules );
if ( debug )
{
log.debug( "PluginCreateRule.begin: installing new plugin: oldrules=" + oldRules + ", newrules=" + newRules );
}
// load up the custom rules
currDeclaration.configure( getDigester(), pattern );
// create an instance of the plugin class
final Object instance = pluginClass.newInstance();
getDigester().push( instance );
if ( debug )
{
log.debug( "PluginCreateRule.begin" + ": pattern=[" + pattern + "]" + " match=[" + getDigester().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.
final List<Rule> rules = newRules.getDecoratedRules().match( namespace, path, name, attributes );
fireBeginMethods( rules, namespace, name, attributes );
}