package org.apache.commons.digester; import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.beanutils.MethodUtils; import org.xml.sax.Attributes; public class CallMethodRule extends Rule { protected String bodyText; protected String methodName; protected int paramCount; protected Class[] paramTypes; private String[] paramClassNames; protected boolean useExactMatch; public CallMethodRule(Digester digester, String methodName, int paramCount) { this(methodName, paramCount); } public CallMethodRule(Digester digester, String methodName, int paramCount, String[] paramTypes) { this(methodName, paramCount, paramTypes); } public CallMethodRule(Digester digester, String methodName, int paramCount, Class[] paramTypes) { this(methodName, paramCount, paramTypes); } public CallMethodRule(String methodName, int paramCount) { this.bodyText = null; this.methodName = null; this.paramCount = 0; this.paramTypes = null; this.paramClassNames = null; this.useExactMatch = false; this.methodName = methodName; this.paramCount = paramCount; if (paramCount == 0) { this.paramTypes = new Class[] { String.class }; } else { this.paramTypes = new Class[paramCount]; for (int i = 0; i < this.paramTypes.length; i++) this.paramTypes[i] = String.class; } } public CallMethodRule(String methodName) { this(methodName, 0, (Class[])null); } public CallMethodRule(String methodName, int paramCount, String[] paramTypes) { this.bodyText = null; this.methodName = null; this.paramCount = 0; this.paramTypes = null; this.paramClassNames = null; this.useExactMatch = false; this.methodName = methodName; this.paramCount = paramCount; if (paramTypes == null) { this.paramTypes = new Class[paramCount]; for (int i = 0; i < this.paramTypes.length; i++) this.paramTypes[i] = "abc".getClass(); } else { this.paramClassNames = new String[paramTypes.length]; for (int i = 0; i < this.paramClassNames.length; i++) this.paramClassNames[i] = paramTypes[i]; } } public CallMethodRule(String methodName, int paramCount, Class[] paramTypes) { this.bodyText = null; this.methodName = null; this.paramCount = 0; this.paramTypes = null; this.paramClassNames = null; this.useExactMatch = false; this.methodName = methodName; this.paramCount = paramCount; if (paramTypes == null) { this.paramTypes = new Class[paramCount]; for (int i = 0; i < this.paramTypes.length; i++) this.paramTypes[i] = "abc".getClass(); } else { this.paramTypes = new Class[paramTypes.length]; for (int i = 0; i < this.paramTypes.length; i++) this.paramTypes[i] = paramTypes[i]; } } public boolean getUseExactMatch() { return this.useExactMatch; } public void setUseExactMatch(boolean useExactMatch) { this.useExactMatch = useExactMatch; } public void setDigester(Digester digester) { super.setDigester(digester); if (this.paramClassNames != null) { this.paramTypes = new Class[this.paramClassNames.length]; for (int i = 0; i < this.paramClassNames.length; i++) { try { this.paramTypes[i] = digester.getClassLoader().loadClass(this.paramClassNames[i]); } catch (ClassNotFoundException e) { digester.getLogger().error("(CallMethodRule) Cannot load class " + this.paramClassNames[i], e); this.paramTypes[i] = null; } } } } public void begin(Attributes attributes) throws Exception { if (this.paramCount > 0) { Object[] parameters = new Object[this.paramCount]; for (int i = 0; i < parameters.length; i++) parameters[i] = null; this.digester.pushParams(parameters); } } public void body(String bodyText) throws Exception { if (this.paramCount == 0) this.bodyText = bodyText.trim(); } public void end() throws Exception { Object[] parameters = null; if (this.paramCount > 0) { parameters = (Object[])this.digester.popParams(); if (this.digester.log.isTraceEnabled()) for (int j = 0, size = parameters.length; j < size; j++) this.digester.log.trace("[CallMethodRule](" + j + ")" + parameters[j]); if (this.paramCount == 1 && parameters[0] == null) return; } else if (this.paramTypes != null && this.paramTypes.length != 0) { if (this.bodyText == null) return; parameters = new Object[1]; parameters[0] = this.bodyText; if (this.paramTypes.length == 0) { this.paramTypes = new Class[1]; this.paramTypes[0] = "abc".getClass(); } } Object[] paramValues = new Object[this.paramTypes.length]; for (int i = 0; i < this.paramTypes.length; i++) { if (parameters[i] == null || (parameters[i] instanceof String && !String.class.isAssignableFrom(this.paramTypes[i]))) { paramValues[i] = ConvertUtils.convert((String)parameters[i], this.paramTypes[i]); } else { paramValues[i] = parameters[i]; } } Object top = this.digester.peek(); if (this.digester.log.isDebugEnabled()) { StringBuffer sb = new StringBuffer("[CallMethodRule]{"); sb.append(this.digester.match); sb.append("} Call "); if (top == null) { sb.append("[NULL TOP]"); } else { sb.append(top.getClass().getName()); } sb.append("."); sb.append(this.methodName); sb.append("("); for (int j = 0; j < paramValues.length; j++) { if (j > 0) sb.append(","); if (paramValues[j] == null) { sb.append("null"); } else { sb.append(paramValues[j].toString()); } sb.append("/"); if (this.paramTypes[j] == null) { sb.append("null"); } else { sb.append(this.paramTypes[j].getName()); } } sb.append(")"); this.digester.log.debug(sb.toString()); } if (this.useExactMatch) { MethodUtils.invokeExactMethod(top, this.methodName, paramValues, this.paramTypes); } else { MethodUtils.invokeMethod(top, this.methodName, paramValues, this.paramTypes); } } public void finish() throws Exception { this.bodyText = null; } public String toString() { StringBuffer sb = new StringBuffer("CallMethodRule["); sb.append("methodName="); sb.append(this.methodName); sb.append(", paramCount="); sb.append(this.paramCount); sb.append(", paramTypes={"); if (this.paramTypes != null) for (int i = 0; i < this.paramTypes.length; i++) { if (i > 0) sb.append(", "); sb.append(this.paramTypes[i].getName()); } sb.append("}"); sb.append("]"); return sb.toString(); } }