in src/main/java/org/apache/commons/ognl/ASTProperty.java [146:337]
public String toGetSourceString( OgnlContext context, Object target )
{
if ( context.getCurrentObject() == null )
{
throw new UnsupportedCompilationException( "Current target is null." );
}
String result = "";
Method m = null;
try
{
/*
* System.out.println("astproperty is indexed? : " + isIndexedAccess() + " child: " +
* _children[0].getClass().getName() + " target: " + target.getClass().getName() + " current object: " +
* context.getCurrentObject().getClass().getName());
*/
Node child = children[0];
if ( isIndexedAccess() )
{
Object value = child.getValue( context, context.getRoot() );
if ( value == null || DynamicSubscript.class.isAssignableFrom( value.getClass() ) )
{
throw new UnsupportedCompilationException(
"Value passed as indexed property was null or not supported." );
}
// Get root cast string if the child is a type that needs it (like a nested ASTProperty)
String srcString = getSourceString( context, child );
if ( context.get( "_indexedMethod" ) != null )
{
m = (Method) context.remove( "_indexedMethod" );
getterClass = m.getReturnType();
Object indexedValue = OgnlRuntime.callMethod( context, target, m.getName(), new Object[]{ value } );
context.setCurrentType( getterClass );
context.setCurrentObject( indexedValue );
context.setCurrentAccessor(
OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( m, m.getDeclaringClass() ) );
return "." + m.getName() + "(" + srcString + ")";
}
PropertyAccessor propertyAccessor = OgnlRuntime.getPropertyAccessor( target.getClass() );
// System.out.println("child value : " + _children[0].getValue(context, context.getCurrentObject())
// + " using propaccessor " + p.getClass().getName()
// + " and srcString " + srcString + " on target: " + target);
Object currentObject = context.getCurrentObject();
if ( child instanceof ASTConst && currentObject instanceof Number)
{
context.setCurrentType( OgnlRuntime.getPrimitiveWrapperClass( currentObject.getClass() ) );
}
Object indexValue = propertyAccessor.getProperty( context, target, value );
result = propertyAccessor.getSourceAccessor( context, target, srcString );
getterClass = context.getCurrentType();
context.setCurrentObject( indexValue );
return result;
}
String name = ( (ASTConst) child ).getValue().toString();
target = getTarget( context, target, name );
PropertyDescriptor pd = OgnlRuntime.getPropertyDescriptor( context.getCurrentObject().getClass(), name );
if ( pd != null && pd.getReadMethod() != null && !context.getMemberAccess().isAccessible( context,
context.getCurrentObject(),
pd.getReadMethod(),
name ) )
{
throw new UnsupportedCompilationException( "Member access forbidden for property " + name + " on class "
+ context.getCurrentObject().getClass() );
}
if ( this.getIndexedPropertyType( context, context.getCurrentObject() ) > 0 && pd != null )
{
// if an indexed method accessor need to use special property descriptors to find methods
if ( pd instanceof IndexedPropertyDescriptor )
{
m = ( (IndexedPropertyDescriptor) pd ).getIndexedReadMethod();
}
else
{
if ( !(pd instanceof ObjectIndexedPropertyDescriptor) ) {
throw new OgnlException( "property '" + name + "' is not an indexed property" );
}
m = ( (ObjectIndexedPropertyDescriptor) pd ).getIndexedReadMethod();
}
if ( parent == null )
{
// the above pd will be the wrong result sometimes, such as methods like getValue(int) vs String[]
// getValue()
m = OgnlRuntime.getReadMethod( context.getCurrentObject().getClass(), name );
result = m.getName() + "()";
getterClass = m.getReturnType();
}
else
{
context.put( "_indexedMethod", m );
}
}
else
{
/*
* System.out.println("astproperty trying to get " + name + " on object target: " +
* context.getCurrentObject().getClass().getName() + " current type " + context.getCurrentType() +
* " current accessor " + context.getCurrentAccessor() + " prev type " + context.getPreviousType() +
* " prev accessor " + context.getPreviousAccessor());
*/
PropertyAccessor pa = OgnlRuntime.getPropertyAccessor( context.getCurrentObject().getClass() );
if ( context.getCurrentObject().getClass().isArray() )
{
if ( pd == null )
{
pd = OgnlRuntime.getProperty( context.getCurrentObject().getClass(), name );
if ( pd != null && pd.getReadMethod() != null )
{
m = pd.getReadMethod();
result = pd.getName();
}
else
{
getterClass = int.class;
context.setCurrentAccessor( context.getCurrentObject().getClass() );
context.setCurrentType( int.class );
result = "." + name;
}
}
}
else
{
if ( pd != null && pd.getReadMethod() != null )
{
m = pd.getReadMethod();
result = "." + m.getName() + "()";
}
else if ( pa != null )
{
Object currObj = context.getCurrentObject();
Class currType = context.getCurrentType();
Class prevType = context.getPreviousType();
String srcString = child.toGetSourceString( context, context.getRoot() );
if ( child instanceof ASTConst && context.getCurrentObject() instanceof String)
{
srcString = "\"" + srcString + "\"";
}
context.setCurrentObject( currObj );
context.setCurrentType( currType );
context.setPreviousType( prevType );
result = pa.getSourceAccessor( context, context.getCurrentObject(), srcString );
getterClass = context.getCurrentType();
}
}
}
}
catch ( Throwable t )
{
throw OgnlOps.castToRuntime( t );
}
// set known property types for NodeType interface when possible
if ( m != null )
{
getterClass = m.getReturnType();
context.setCurrentType( m.getReturnType() );
context.setCurrentAccessor(
OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( m, m.getDeclaringClass() ) );
}
context.setCurrentObject( target );
return result;
}