org.apache.camel.util.component.ArgumentSubstitutionParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of camel-core Show documentation
Show all versions of camel-core Show documentation
The Core Camel Java DSL based router
/**
* 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.
*/
package org.apache.camel.util.component;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Adds support for parameter name substitutions.
*/
public class ArgumentSubstitutionParser extends ApiMethodParser {
private final Map>> methodMap;
/**
* Create a parser using regular expressions to adapt parameter names.
* @param proxyType Proxy class.
* @param substitutions an array of ordered Argument adapters.
*/
public ArgumentSubstitutionParser(Class proxyType, Substitution[] substitutions) {
super(proxyType);
Map>> regexMap = new LinkedHashMap>>();
for (Substitution substitution : substitutions) {
substitution.validate();
final NameReplacement nameReplacement = new NameReplacement();
nameReplacement.replacement = substitution.replacement;
if (substitution.argType != null) {
nameReplacement.typePattern = Pattern.compile(substitution.argType);
}
nameReplacement.replaceWithType = substitution.replaceWithType;
Map> replacementMap = regexMap.get(substitution.method);
if (replacementMap == null) {
replacementMap = new LinkedHashMap>();
regexMap.put(substitution.method, replacementMap);
}
List replacements = replacementMap.get(substitution.argName);
if (replacements == null) {
replacements = new ArrayList();
replacementMap.put(substitution.argName, replacements);
}
replacements.add(nameReplacement);
}
// now compile the patterns, all this because Pattern doesn't override equals()!!!
this.methodMap = new LinkedHashMap>>();
for (Map.Entry>> method : regexMap.entrySet()) {
Map> argMap = new LinkedHashMap>();
for (Map.Entry> arg : method.getValue().entrySet()) {
argMap.put(Pattern.compile(arg.getKey()), arg.getValue());
}
methodMap.put(Pattern.compile(method.getKey()), argMap);
}
}
@Override
public List processResults(List parseResult) {
final List result = new ArrayList();
for (ApiMethodModel model : parseResult) {
// look for method name matches
for (Map.Entry>> methodEntry : methodMap.entrySet()) {
// match the whole method name
if (methodEntry.getKey().matcher(model.getName()).matches()) {
// look for arg name matches
final List updatedArguments = new ArrayList();
final Map> argMap = methodEntry.getValue();
for (Argument argument : model.getArguments()) {
final Class argType = argument.getType();
final String typeArgs = argument.getTypeArgs();
final String argTypeName = argType.getCanonicalName();
for (Map.Entry> argEntry : argMap.entrySet()) {
final Matcher matcher = argEntry.getKey().matcher(argument.getName());
// match argument name substring
if (matcher.find()) {
final List adapters = argEntry.getValue();
for (NameReplacement adapter : adapters) {
if (adapter.typePattern == null) {
// no type pattern
final String newName = getJavaArgName(matcher.replaceAll(adapter.replacement));
argument = new Argument(newName, argType, typeArgs);
} else {
final Matcher typeMatcher = adapter.typePattern.matcher(argTypeName);
if (typeMatcher.find()) {
if (!adapter.replaceWithType) {
// replace argument name
final String newName = getJavaArgName(matcher.replaceAll(adapter.replacement));
argument = new Argument(newName, argType, typeArgs);
} else {
// replace name with argument type name
final String newName = getJavaArgName(typeMatcher.replaceAll(adapter.replacement));
argument = new Argument(newName, argType, typeArgs);
}
}
}
}
}
}
updatedArguments.add(argument);
}
model = new ApiMethodModel(model.getUniqueName(), model.getName(), model.getResultType(),
updatedArguments, model.getMethod());
}
}
result.add(model);
}
return result;
}
private String getJavaArgName(String name) {
// make sure the first character is lowercase
// useful for replacement using type names
char firstChar = name.charAt(0);
if (Character.isLowerCase(firstChar)) {
return name;
} else {
return Character.toLowerCase(firstChar) + name.substring(1);
}
}
public static class Substitution {
private String method;
private String argName;
private String argType;
private String replacement;
private boolean replaceWithType;
/**
* Creates a substitution for all argument types.
* @param method regex to match method name
* @param argName regex to match argument name
* @param replacement replacement text for argument name
*/
public Substitution(String method, String argName, String replacement) {
this.method = method;
this.argName = argName;
this.replacement = replacement;
}
/**
* Creates a substitution for a specific argument type.
* @param method regex to match method name
* @param argName regex to match argument name
* @param argType argument type as String
* @param replacement replacement text for argument name
*/
public Substitution(String method, String argName, String argType, String replacement) {
this(method, argName, replacement);
this.argType = argType;
}
/**
* Create a substitution for a specific argument type and flag to indicate whether the replacement uses
* @param method
* @param argName
* @param argType
* @param replacement
* @param replaceWithType
*/
public Substitution(String method, String argName, String argType, String replacement, boolean replaceWithType) {
this(method, argName, argType, replacement);
this.replaceWithType = replaceWithType;
}
public void validate() {
if (method == null || argName == null || replacement == null) {
throw new IllegalArgumentException("Properties method, argName and replacement MUST be provided");
}
}
}
private static class NameReplacement {
private String replacement;
private Pattern typePattern;
private boolean replaceWithType;
}
}