001 package 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
022 import java.util.Properties;
023
024 import org.apache.commons.digester3.Digester;
025 import org.apache.commons.digester3.plugins.PluginException;
026 import org.apache.commons.digester3.plugins.RuleFinder;
027 import 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 */
035 public 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 }