001 /* $Id: LoaderFromClass.java 992060 2010-09-02 19:09:47Z simonetripodi $ 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 package org.apache.commons.digester.plugins.strategies; 019 020 import java.lang.reflect.Method; 021 022 import org.apache.commons.digester.Digester; 023 import org.apache.commons.beanutils.MethodUtils; 024 import org.apache.commons.logging.Log; 025 import org.apache.commons.digester.plugins.RuleLoader; 026 import org.apache.commons.digester.plugins.PluginException; 027 028 /** 029 * A RuleLoader which invokes a static method on a target class, leaving that 030 * method to actually instantiate and add new rules to a Digester instance. 031 * 032 * @since 1.6 033 */ 034 035 public class LoaderFromClass extends RuleLoader { 036 037 private Class<?> rulesClass; 038 private Method rulesMethod; 039 040 /** Constructor. */ 041 public LoaderFromClass(Class<?> rulesClass, Method rulesMethod) { 042 this.rulesClass = rulesClass; 043 this.rulesMethod = rulesMethod; 044 } 045 046 /** Constructor. */ 047 public LoaderFromClass(Class<?> rulesClass, String methodName) 048 throws PluginException { 049 050 Method method = locateMethod(rulesClass, methodName); 051 052 if (method == null) { 053 throw new PluginException( 054 "rule class " + rulesClass.getName() 055 + " does not have method " + methodName 056 + " or that method has an invalid signature."); 057 } 058 059 this.rulesClass = rulesClass; 060 this.rulesMethod = method; 061 } 062 063 /** 064 * Just invoke the target method. 065 */ 066 @Override 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