Here's a small improvement to InvokeParentRule that allows it to invoke
methods with more than 1 argument on the target object.
It takes the last n objects from the stack and use them to find and
invoke a method.
You can specify n with the "args" attribute.
Should I add it to JIRA besides posting it here?
--
Pablo I. Lalloni
Tel�fono +54 (11) 4347-3177
Proyecto Pampa
Direcci�n Inform�tica Tributaria
AFIP
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To fear love is to fear life, and those who fear life are already three
parts dead.
-- Bertrand Russell
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Copyright 2004 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.hivemind.schema.rules;
import java.lang.reflect.Method;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.Element;
import org.apache.hivemind.schema.SchemaProcessor;
/**
* Rule used to connect a child object to its parent by invoking a method on the
* parent, passing the child. The child object is the top object on the stack
* and the parent object is the next object down on the stack. Created from the
* <code><invoke-parent></code> element. Generally, this is the last
* rule in a sequence of rules.
*
* @author Howard Lewis Ship
*/
public class InvokeParentRule extends BaseRule {
private String _methodName;
private int _depth = 1;
private int _args = 1;
public InvokeParentRule() {
}
public InvokeParentRule(String methodName) {
_methodName = methodName;
}
/**
* Invokes the named method on the parent object (using reflection).
*/
public void begin(SchemaProcessor processor, Element element) {
Object parent = processor.peek(_depth);
Object[] params = buildParams(processor, _args);
try {
findMethod(parent, _methodName, classes(params)).invoke(parent, params);
} catch (Exception ex) {
throw new ApplicationRuntimeException(RulesMessages.errorInvokingMethod(_methodName, parent, getLocation(), ex),
getLocation(), ex);
}
}
/**
* @param params
* @return
*/
private Class[] classes(Object[] params) {
Class[] classes = new Class[params.length];
for (int i = 0; i < params.length; i++) {
classes[i] = params[i].getClass();
}
return classes;
}
/**
*
*/
private Object[] buildParams(SchemaProcessor processor, int args) {
Object[] params = new Object[args];
for (int i = 0; i < args; i++) {
params[i] = processor.peek(args - i - 1);
}
return params;
}
public String getMethodName() {
return _methodName;
}
public void setMethodName(String string) {
_methodName = string;
}
/**
* Sets the depth of the parent object. The default is 1.
*/
public void setDepth(int i) {
_depth = i;
}
/**
* Searches for the *first* public method the has the right name, and takes
* a single parameter that is compatible with the parameter type.
*
* @throws NoSuchMethodException
* if a method can't be found
*/
private Method findMethod(Object target, String name, Class[] parameterTypes) throws NoSuchMethodException {
Method[] methods = target.getClass().getMethods();
I : for (int i = 0; i < methods.length; i++) {
Method m = methods[i];
if (m.getParameterTypes().length != parameterTypes.length) continue;
if (!m.getName().equals(name)) continue;
for (int j = 0; j < parameterTypes.length; j++) {
if (m.getParameterTypes()[j].isAssignableFrom(parameterTypes[j])) continue I;
}
return m;
}
throw new NoSuchMethodException(name);
}
public int getArgs() {
return _args;
}
public void setArgs(int args) {
_args = args;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]