001package org.apache.commons.digester3.plugins.strategies;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.util.Properties;
023
024import org.apache.commons.digester3.Digester;
025import org.apache.commons.digester3.plugins.PluginException;
026import org.apache.commons.digester3.plugins.RuleFinder;
027import org.apache.commons.digester3.plugins.RuleLoader;
028
029/**
030 * A rule-finding algorithm which looks for a method with a specific name on a class whose name is derived from the
031 * plugin class name.
032 * 
033 * @since 1.6
034 */
035public class FinderFromDfltClass
036    extends RuleFinder
037{
038    private static final String DFLT_RULECLASS_SUFFIX = "RuleInfo";
039
040    private static final String DFLT_METHOD_NAME = "addRules";
041
042    private final String rulesClassSuffix;
043
044    private final String methodName;
045
046    /** See {@link #findLoader}. */
047    public FinderFromDfltClass()
048    {
049        this( DFLT_RULECLASS_SUFFIX, DFLT_METHOD_NAME );
050    }
051
052    /**
053     * Create a rule-finder which invokes a method on a class whenever dynamic rules for a plugin need to be loaded. See
054     * the findRules method for more info.
055     * 
056     * @param rulesClassSuffix must be non-null.
057     * @param methodName may be null.
058     */
059    public FinderFromDfltClass( String rulesClassSuffix, String methodName )
060    {
061        this.rulesClassSuffix = rulesClassSuffix;
062        this.methodName = methodName;
063    }
064
065    /**
066     * If there exists a class whose name is the plugin class name + the suffix specified to the constructor, then load
067     * that class, locate the appropriate rules-adding method on that class, and return an object encapsulating that
068     * info.
069     * <p>
070     * If there is no such class, then just return null.
071     * <p>
072     * The returned object (when non-null) will invoke the target method on the selected class whenever its addRules
073     * method is invoked. The target method is expected to have the following prototype:
074     * <code> public static void xxxxx(Digester d, String patternPrefix); </code>
075     *
076     * @param digester The digester instance where locating plugin classes
077     * @param pluginClass The plugin Java class
078     * @param p The properties object that holds any xml attributes the user may have specified on the plugin
079     *          declaration in order to indicate how to locate the plugin rules.
080     * @return a source of digester rules for the specified plugin class.
081     * @throws PluginException if the algorithm finds a source of rules, but there is something invalid
082     *         about that source.
083     */
084    @Override
085    public RuleLoader findLoader( Digester digester, Class<?> pluginClass, Properties p )
086        throws PluginException
087    {
088        String rulesClassName = pluginClass.getName() + rulesClassSuffix;
089
090        Class<?> rulesClass = null;
091        try
092        {
093            rulesClass = digester.getClassLoader().loadClass( rulesClassName );
094        }
095        catch ( ClassNotFoundException cnfe )
096        {
097            // nope, no rule-info class in the classpath
098            return null;
099        }
100
101        if ( methodName == null )
102        {
103            return new LoaderFromClass( rulesClass, DFLT_METHOD_NAME );
104        }
105
106        return new LoaderFromClass( rulesClass, methodName );
107    }
108
109}