View Javadoc

1   package org.apache.commons.digester3.plugins.strategies;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import static org.apache.commons.beanutils.MethodUtils.getAccessibleMethod;
23  
24  import java.lang.reflect.Method;
25  
26  import org.apache.commons.digester3.Digester;
27  import org.apache.commons.digester3.plugins.PluginException;
28  import org.apache.commons.digester3.plugins.RuleLoader;
29  import org.apache.commons.logging.Log;
30  
31  /**
32   * A RuleLoader which invokes a static method on a target class, leaving that method to actually instantiate and add new
33   * rules to a Digester instance.
34   * 
35   * @since 1.6
36   */
37  public class LoaderFromClass
38      extends RuleLoader
39  {
40  
41      private final Class<?> rulesClass;
42  
43      private final Method rulesMethod;
44  
45      /**
46       * Constructor.
47       *
48       * @param rulesClass The target class
49       * @param rulesMethod The method has to be invoked
50       */
51      public LoaderFromClass( Class<?> rulesClass, Method rulesMethod )
52      {
53          this.rulesClass = rulesClass;
54          this.rulesMethod = rulesMethod;
55      }
56  
57      /**
58       * Constructor.
59       *
60       * @param rulesClass The target class
61       * @param methodName The method name has to be invoked
62       * @throws PluginException if input method can't be located inside the given class
63       */
64      public LoaderFromClass( Class<?> rulesClass, String methodName )
65          throws PluginException
66      {
67  
68          Method method = locateMethod( rulesClass, methodName );
69  
70          if ( method == null )
71          {
72              throw new PluginException( "rule class " + rulesClass.getName() + " does not have method " + methodName
73                  + " or that method has an invalid signature." );
74          }
75  
76          this.rulesClass = rulesClass;
77          this.rulesMethod = method;
78      }
79  
80      /**
81       * {@inheritDoc}
82       */
83      @Override
84      public void addRules( Digester d, String path )
85          throws PluginException
86      {
87          Log log = d.getLogger();
88          boolean debug = log.isDebugEnabled();
89          if ( debug )
90          {
91              log.debug( "LoaderFromClass loading rules for plugin at path [" + path + "]" );
92          }
93  
94          try
95          {
96              Object[] params = { d, path };
97              rulesMethod.invoke( null, params );
98          }
99          catch ( Exception e )
100         {
101             throw new PluginException(
102                                        "Unable to invoke rules method " + rulesMethod + " on rules class " + rulesClass,
103                                        e );
104         }
105     }
106 
107     /**
108      * Find a method on the specified class whose name matches methodName, and whose signature is:
109      * <code> public static void foo(Digester d, String patternPrefix);</code>.
110      *
111      * @param rulesClass The target class
112      * @param methodName The method name has to be invoked
113      * @return The method name has to be invoked, or null if no such method exists.
114      * @throws PluginException if any error occurs while discovering the method
115      */
116     public static Method locateMethod( Class<?> rulesClass, String methodName )
117         throws PluginException
118     {
119         Class<?>[] paramSpec = { Digester.class, String.class };
120         Method rulesMethod = getAccessibleMethod( rulesClass, methodName, paramSpec );
121 
122         return rulesMethod;
123     }
124 
125 }