in src/main/java/org/apache/commons/ognl/ASTCtor.java [142:348]
public String toGetSourceString( OgnlContext context, Object target )
{
StringBuilder result = new StringBuilder("new " + className);
Class clazz = null;
Object ctorValue = null;
try
{
clazz = OgnlRuntime.classForName( context, className );
ctorValue = this.getValueBody( context, target );
context.setCurrentObject( ctorValue );
if ( ctorValue != null )
{
context.setCurrentType( ctorValue.getClass() );
context.setCurrentAccessor( ctorValue.getClass() );
}
if ( isArray )
{
context.put( "_ctorClass", clazz );
}
}
catch ( Throwable t )
{
throw OgnlOps.castToRuntime( t );
}
try
{
if ( isArray )
{
if ( children[0] instanceof ASTConst )
{
result.append("[").append(children[0].toGetSourceString(context, target)).append("]");
}
else if (children[0] instanceof ASTProperty)
{
result.append("[").append(ExpressionCompiler.getRootExpression(children[0], target, context)).append(children[0].toGetSourceString(context, target)).append("]");
}
else if (children[0] instanceof ASTChain)
{
result.append("[").append(children[0].toGetSourceString(context, target)).append("]");
}
else
{
result.append("[] ").append(children[0].toGetSourceString(context, target));
}
}
else
{
result.append("(");
if ( ( children != null ) && ( children.length > 0 ) )
{
Object[] values = new Object[children.length];
String[] expressions = new String[children.length];
Class[] types = new Class[children.length];
// first populate arrays with child values
for ( int i = 0; i < children.length; i++ )
{
Object objValue = children[i].getValue( context, context.getRoot() );
String value = children[i].toGetSourceString( context, target );
if ( !(children[i] instanceof ASTRootVarRef))
{
value = ExpressionCompiler.getRootExpression( children[i], target, context ) + value;
}
String cast = "";
if ( ExpressionCompiler.shouldCast( children[i] ) )
{
cast = (String) context.remove( ExpressionCompiler.PRE_CAST );
}
if ( cast == null )
{
cast = "";
}
if ( !(children[i] instanceof ASTConst))
{
value = cast + value;
}
values[i] = objValue;
expressions[i] = value;
types[i] = context.getCurrentType();
}
// now try and find a matching constructor
Constructor[] cons = clazz.getConstructors();
Constructor ctor = null;
Class[] ctorParamTypes = null;
for (Constructor con : cons) {
Class[] ctorTypes = con.getParameterTypes();
if ( OgnlRuntime.areArgsCompatible( values, ctorTypes )
&& ( ctor == null || OgnlRuntime.isMoreSpecific( ctorTypes, ctorParamTypes ) ) )
{
ctor = con;
ctorParamTypes = ctorTypes;
}
}
if ( ctor == null )
{
ctor =
OgnlRuntime.getConvertedConstructorAndArgs( context, clazz,
OgnlRuntime.getConstructors( clazz ), values,
new Object[values.length] );
}
if ( ctor == null )
{
throw new NoSuchMethodException(
"Unable to find constructor appropriate for arguments in class: " + clazz );
}
ctorParamTypes = ctor.getParameterTypes();
// now loop over child values again and build up the actual source string
for ( int i = 0; i < children.length; i++ )
{
if ( i > 0 )
{
result.append(", ");
}
String value = expressions[i];
if ( types[i].isPrimitive() )
{
String literal = OgnlRuntime.getNumericLiteral( types[i] );
if ( literal != null )
{
value += literal;
}
}
if ( ctorParamTypes[i] != types[i] )
{
if ( values[i] != null && !types[i].isPrimitive() && !values[i].getClass().isArray()
&& !(children[i] instanceof ASTConst))
{
value =
"(" + OgnlRuntime.getCompiler( context ).getInterfaceClass( values[i].getClass() ).getName()
+ ")" + value;
}
else if ( !(children[i] instanceof ASTConst)
|| ( children[i] instanceof ASTConst && !types[i].isPrimitive() ) )
{
if ( !types[i].isArray() && types[i].isPrimitive() && !ctorParamTypes[i].isPrimitive() )
{
value =
"new "
+ ExpressionCompiler.getCastString(
OgnlRuntime.getPrimitiveWrapperClass( types[i] ) )
+ "(" + value + ")";
}
else
{
value = " ($w) " + value;
}
}
}
result.append(value);
}
}
result.append(")");
}
context.setCurrentType( ctorValue != null ? ctorValue.getClass() : clazz );
context.setCurrentAccessor( clazz );
context.setCurrentObject( ctorValue );
}
catch ( Throwable t )
{
throw OgnlOps.castToRuntime( t );
}
context.remove( "_ctorClass" );
return result.toString();
}