com.feilong.lib.digester3.binder.CallMethodBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of feilong Show documentation
Show all versions of feilong Show documentation
feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.
package com.feilong.lib.digester3.binder;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import static java.lang.String.format;
import java.util.Arrays;
import com.feilong.lib.digester3.CallMethodRule;
/**
* Builder chained when invoking {@link LinkedRuleBuilder#callMethod(String)}.
*
* @since 3.0
*/
public final class CallMethodBuilder extends AbstractBackToLinkedRuleBuilder{
private final String methodName;
private final ClassLoader classLoader;
private int targetOffset;
private int paramCount = 0;
private Class>[] paramTypes = new Class>[] {};
private boolean useExactMatch = false;
CallMethodBuilder(String keyPattern, String namespaceURI, RulesBinder mainBinder, LinkedRuleBuilder mainBuilder, String methodName,
ClassLoader classLoader){
super(keyPattern, namespaceURI, mainBinder, mainBuilder);
this.methodName = methodName;
this.classLoader = classLoader;
}
/**
* Sets the location of the target object.
*
* Positive numbers are relative to the top of the digester object stack.
* Negative numbers are relative to the bottom of the stack. Zero implies the top object on the stack.
*
* @param targetOffset
* location of the target object.
* @return this builder instance
*/
public CallMethodBuilder withTargetOffset(int targetOffset){
this.targetOffset = targetOffset;
return this;
}
/**
* Sets the Java class names that represent the parameter types of the method arguments.
*
* If you wish to use a primitive type, specify the corresonding Java wrapper class instead,
* such as {@code java.lang.Boolean.TYPE} for a {@code boolean} parameter.
*
* @param paramTypeNames
* The Java classes names that represent the parameter types of the method arguments
* @return this builder instance
*/
public CallMethodBuilder withParamTypes(String...paramTypeNames){
Class>[] paramTypes = null;
if (paramTypeNames != null){
paramTypes = new Class>[paramTypeNames.length];
for (int i = 0; i < paramTypeNames.length; i++){
try{
paramTypes[i] = classLoader.loadClass(paramTypeNames[i]);
}catch (ClassNotFoundException e){
this.reportError(
format("callMethod( \"%s\" ).withParamTypes( %s )", this.methodName, Arrays.toString(paramTypeNames)),
format("class '%s' cannot be load", paramTypeNames[i]));
}
}
}
return withParamTypes(paramTypes);
}
/**
* Sets the Java classes that represent the parameter types of the method arguments.
*
* If you wish to use a primitive type, specify the corresonding Java wrapper class instead,
* such as {@code java.lang.Boolean.TYPE} for a {@code boolean} parameter.
*
* @param paramTypes
* The Java classes that represent the parameter types of the method arguments
* @return this builder instance
*/
public CallMethodBuilder withParamTypes(Class>...paramTypes){
this.paramTypes = paramTypes;
if (paramTypes != null){
this.paramCount = paramTypes.length;
}else{
paramCount = 0;
}
return this;
}
/**
* Should MethodUtils.invokeExactMethod
be used for the reflection.
*
* @param useExactMatch
* Flag to mark exact matching or not
* @return this builder instance
*/
public CallMethodBuilder useExactMatch(boolean useExactMatch){
this.useExactMatch = useExactMatch;
return this;
}
/**
* The number of parameters to collect, or zero for a single argument from the body of this element.
*
* @param paramCount
* The number of parameters to collect, or zero for a single argument
* from the body of this element.
* @return this builder instance
*/
public CallMethodBuilder withParamCount(int paramCount){
if (paramCount < 0){
this.reportError(format("callMethod(\"%s\").withParamCount(int)", this.methodName), "negative parameters counter not allowed");
}
this.paramCount = paramCount;
if (this.paramCount == 0){
if (this.paramTypes == null || this.paramTypes.length != 1){
this.paramTypes = new Class>[] { String.class };
}
}else{
this.paramTypes = new Class>[this.paramCount];
for (int i = 0; i < paramTypes.length; i++){
this.paramTypes[i] = String.class;
}
}
return this;
}
/**
* Prepare the {@link CallMethodRule} to be invoked using the matching element body as argument.
*
* @return this builder instance
*/
public CallMethodBuilder usingElementBodyAsArgument(){
return withParamCount(0);
}
/**
* {@inheritDoc}
*/
@Override
protected CallMethodRule createRule(){
CallMethodRule callMethodRule = new CallMethodRule(targetOffset, methodName, paramCount, paramTypes);
callMethodRule.setUseExactMatch(useExactMatch);
return callMethodRule;
}
}