// FIXME: make excluded list: 'jsonMessageString'
if (!StringUtils.hasText(className) || propertyName.startsWith("this") ||
(propertyName.indexOf(INDEXED_DELIM_END) != -1 && (propName.length() > (propertyName.indexOf(INDEXED_DELIM_END) + 1))) ||
propertyName.toLowerCase().indexOf("jsonMessageString".toLowerCase()) != -1) {
result = new BeanPropertyFunction(propertyName);
} else {
String classFunctionName = null;
String property = null;
String reflectProperty = null;
String indexedKey = null;
boolean listOrMapProperty = propertyName.indexOf(INDEXED_DELIM_BEGIN) != -1;
if (listOrMapProperty) {
int indexedDelimEnd = propertyName.indexOf(INDEXED_DELIM_END);
indexedKey = propertyName.substring((propertyName.indexOf(INDEXED_DELIM_BEGIN) + 1), indexedDelimEnd);
propertyName = propertyName.substring(0, propertyName.indexOf(INDEXED_DELIM_BEGIN));
}
classFunctionName = className + org.apache.commons.lang.StringUtils.capitalize(propertyName) +
(indexedKey != null ? org.apache.commons.lang.StringUtils.capitalize(indexedKey) : "") +
"BeanPropertyFunction$$Valang";
String key = classFunctionName;
if (hGeneratedBeanFunctions.containsKey(key)) {
result = hGeneratedBeanFunctions.get(key);
} else {
try {
Class<?> clazz = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader());
Class<?> methodReturnType = null;
boolean indexedProperty = propertyName.indexOf(".") != -1;
if (indexedProperty) {
String[] properties = org.apache.commons.lang.StringUtils.split(propertyName, ".");
int count = 1;
StringBuilder sb = new StringBuilder();
Class<?> nestedMethodReturnType = null;
for (String prop : properties) {
reflectProperty = "get" + org.apache.commons.lang.StringUtils.capitalize(prop);
sb.append(reflectProperty);
sb.append("()");
if (count < properties.length) {
sb.append(".");
}
if (nestedMethodReturnType == null) {
Method nestedMethod = ReflectionUtils.findMethod(clazz, reflectProperty);
nestedMethodReturnType = nestedMethod.getReturnType();
} else {
Method nestedMethod = ReflectionUtils.findMethod(nestedMethodReturnType, reflectProperty);
nestedMethodReturnType = nestedMethod.getReturnType();
}
count++;
}
property = sb.toString();
// property = processProperty(propertyName, wrapper); //sb.toString();
methodReturnType = nestedMethodReturnType;
} else {
StringBuilder sb = new StringBuilder();
sb.append("get");
sb.append(org.apache.commons.lang.StringUtils.capitalize(propertyName));
reflectProperty = sb.toString();
sb.append("()");
property = sb.toString();
methodReturnType = ReflectionUtils.findMethod(clazz, reflectProperty).getReturnType();
}
Class<?> primitiveClass = PrimitiveClassUtils.resolvePrimitiveClassName(methodReturnType);
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.makeClass(classFunctionName);
cc.addInterface(pool.get("org.springmodules.validation.valang.functions.Function"));
StringBuilder generatedMethod = new StringBuilder();
generatedMethod.append("public Object getResult(Object target) {");
generatedMethod.append(" return ");
if (primitiveClass != null) {
generatedMethod.append(" new " + primitiveClass.getName() + "(");
}
generatedMethod.append(" ((" + className + ")target).");
generatedMethod.append(property);
if (primitiveClass != null) {
generatedMethod.append(")");
} else if (listOrMapProperty &&
org.apache.commons.lang.ClassUtils.isAssignable(methodReturnType, Map.class)) {
generatedMethod.append(".get(\"" + indexedKey + "\")");
} else if (listOrMapProperty &&
org.apache.commons.lang.ClassUtils.isAssignable(methodReturnType, List.class)) {
generatedMethod.append(".get(" + indexedKey + ")");
} else if (methodReturnType.isArray()) {
int arrayIndex = Integer.parseInt(indexedKey);
generatedMethod.append("[" + arrayIndex + "]");
}
generatedMethod.append(";");
generatedMethod.append("}");
CtMethod m = CtNewMethod.make(generatedMethod.toString(), cc);
cc.addMethod(m);
result = (Function)cc.toClass().newInstance();
hGeneratedBeanFunctions.put(key, result);
logger.info("Generated bytecode for {}.{} as '{}'.",
new Object[] { className,
property + "()" + (indexedKey != null ? "[" + indexedKey + "]" : ""),
classFunctionName });
} catch (Exception e) {
logger.error("Problem generating bytecode for {}.{}. {}",
new Object[] { classFunctionName,
org.apache.commons.lang.StringUtils.capitalize(propertyName),
e.getMessage() });
// fallback to standard bean property function
result = new BeanPropertyFunction(propName);
}
}
}
return result;