001 /* $Id: LoaderFromClass.java 472842 2006-11-09 10:19:56Z skitching $ 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one or more 004 * contributor license agreements. See the NOTICE file distributed with 005 * this work for additional information regarding copyright ownership. 006 * The ASF licenses this file to You under the Apache License, Version 2.0 007 * (the "License"); you may not use this file except in compliance with 008 * the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package org.apache.commons.digester.plugins.strategies; 020 021 import java.lang.reflect.Method; 022 023 import org.apache.commons.digester.Digester; 024 import org.apache.commons.beanutils.MethodUtils; 025 import org.apache.commons.logging.Log; 026 import org.apache.commons.digester.plugins.RuleLoader; 027 import org.apache.commons.digester.plugins.PluginException; 028 029 /** 030 * A RuleLoader which invokes a static method on a target class, leaving that 031 * method to actually instantiate and add new rules to a Digester instance. 032 * 033 * @since 1.6 034 */ 035 036 public class LoaderFromClass extends RuleLoader { 037 038 private Class rulesClass; 039 private Method rulesMethod; 040 041 /** Constructor. */ 042 public LoaderFromClass(Class rulesClass, Method rulesMethod) { 043 this.rulesClass = rulesClass; 044 this.rulesMethod = rulesMethod; 045 } 046 047 /** Constructor. */ 048 public LoaderFromClass(Class rulesClass, String methodName) 049 throws PluginException { 050 051 Method method = locateMethod(rulesClass, methodName); 052 053 if (method == null) { 054 throw new PluginException( 055 "rule class " + rulesClass.getName() 056 + " does not have method " + methodName 057 + " or that method has an invalid signature."); 058 } 059 060 this.rulesClass = rulesClass; 061 this.rulesMethod = method; 062 } 063 064 /** 065 * Just invoke the target method. 066 */ 067 public void addRules(Digester d, String path) throws PluginException { 068 Log log = d.getLogger(); 069 boolean debug = log.isDebugEnabled(); 070 if (debug) { 071 log.debug( 072 "LoaderFromClass loading rules for plugin at path [" 073 + path + "]"); 074 } 075 076 try { 077 Object[] params = {d, path}; 078 rulesMethod.invoke(null, params); 079 } catch (Exception e) { 080 throw new PluginException( 081 "Unable to invoke rules method " + rulesMethod 082 + " on rules class " + rulesClass, e); 083 } 084 } 085 086 /** 087 * Find a method on the specified class whose name matches methodName, 088 * and whose signature is: 089 * <code> public static void foo(Digester d, String patternPrefix);</code>. 090 * 091 * @return null if no such method exists. 092 */ 093 public static Method locateMethod(Class rulesClass, String methodName) 094 throws PluginException { 095 096 Class[] paramSpec = { Digester.class, String.class }; 097 Method rulesMethod = MethodUtils.getAccessibleMethod( 098 rulesClass, methodName, paramSpec); 099 100 return rulesMethod; 101 } 102 } 103