public String toSetSourceString()

in src/main/java/org/apache/commons/ognl/ASTProperty.java [385:617]


    public String toSetSourceString( OgnlContext context, Object target )
    {
        String result = "";
        Method m = null;

        if ( context.getCurrentObject() == null )
        {
            throw new UnsupportedCompilationException( "Current target is null." );
        }
        /*
         * System.out.println("astproperty(setter) is indexed? : " + isIndexedAccess() + " child: " +
         * _children[0].getClass().getName() + " target: " + target.getClass().getName() + " children length: " +
         * _children.length);
         */

        try
        {

            Node child = children[0];
            if ( isIndexedAccess() )
            {
                Object value = child.getValue( context, context.getRoot() );

                if ( value == null )
                {
                    throw new UnsupportedCompilationException(
                        "Value passed as indexed property is null, can't enhance statement to bytecode." );
                }

                String srcString = getSourceString( context, child );

                // System.out.println("astproperty setter using indexed value " + value + " and srcString: " +
                // srcString);

                if ( context.get( "_indexedMethod" ) == null ) {
                    PropertyAccessor propertyAccessor = OgnlRuntime.getPropertyAccessor( target.getClass() );

                    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 = lastChild( context )
                        ? propertyAccessor.getSourceSetter( context, target, srcString )
                        : propertyAccessor.getSourceAccessor( context, target, srcString );

                    /*
                     * System.out.println("ASTProperty using propertyaccessor and isLastChild? " + lastChild(context) +
                     * " generated source of: " + result + " using accessor class: " + p.getClass().getName());
                     */

                    // result = p.getSourceAccessor(context, target, srcString);
                    getterClass = context.getCurrentType();
                    context.setCurrentObject( indexValue );

                    /*
                     * PropertyAccessor p = OgnlRuntime.getPropertyAccessor(target.getClass()); if
                     * (ASTConst.class.isInstance(_children[0]) && Number.class.isInstance(context.getCurrentObject()))
                     * {
                     * context.setCurrentType(OgnlRuntime.getPrimitiveWrapperClass(context.getCurrentObject().getClass(
                     * ))); } result = p.getSourceSetter(context, target, srcString); context.setCurrentObject(value);
                     * context.setCurrentType(getterClass);
                     */
                    return result;
                }
                m = (Method) context.remove( "_indexedMethod" );
                PropertyDescriptor pd = (PropertyDescriptor) context.remove( "_indexedDescriptor" );

                boolean lastChild = lastChild( context );
                if ( lastChild )
                {
                    m = getIndexedWriteMethod( pd );

                    if ( m == null )
                    {
                        throw new UnsupportedCompilationException(
                            "Indexed property has no corresponding write method." );
                    }
                }

                setterClass = m.getParameterTypes()[0];

                Object indexedValue = null;
                if ( !lastChild )
                {
                    indexedValue = OgnlRuntime.callMethod( context, target, m.getName(), new Object[]{ value } );
                }
                context.setCurrentType( setterClass );
                context.setCurrentAccessor(
                    OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( m, m.getDeclaringClass() ) );

                if ( !lastChild )
                {
                    context.setCurrentObject( indexedValue );
                    return "." + m.getName() + "(" + srcString + ")";
                }
                return "." + m.getName() + "(" + srcString + ", $3)";
            }

            String name = ( (ASTConst) child ).getValue().toString();

            // System.out.println(" astprop(setter) : trying to set " + name + " on object target " +
            // context.getCurrentObject().getClass().getName());

            target = getTarget( context, target, name );

            PropertyDescriptor pd = OgnlRuntime.getPropertyDescriptor(
                OgnlRuntime.getCompiler( context ).getInterfaceClass( context.getCurrentObject().getClass() ), name );

            if ( pd != null )
            {
                Method pdMethod = lastChild( context ) ? pd.getWriteMethod() : pd.getReadMethod();

                if ( pdMethod != null && !context.getMemberAccess().isAccessible( context, context.getCurrentObject(),
                                                                                  pdMethod, name ) )
                {
                    throw new UnsupportedCompilationException(
                        "Member access forbidden for property " + name + " on class "
                            + context.getCurrentObject().getClass() );
                }
            }

            if ( pd != null && this.getIndexedPropertyType( context, context.getCurrentObject() ) > 0 )
            {
                // if an indexed method accessor need to use special property descriptors to find methods

                if ( pd instanceof IndexedPropertyDescriptor )
                {
                    IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
                    m = lastChild( context ) ? ipd.getIndexedWriteMethod() : ipd.getIndexedReadMethod();
                }
                else
                {
                    if ( !(pd instanceof ObjectIndexedPropertyDescriptor) ) {
                        throw new OgnlException( "property '" + name + "' is not an indexed property" );
                    }
                    ObjectIndexedPropertyDescriptor opd = (ObjectIndexedPropertyDescriptor) pd;

                    m = lastChild( context ) ? opd.getIndexedWriteMethod() : opd.getIndexedReadMethod();
                }

                if ( parent == null )
                {
                    // the above pd will be the wrong result sometimes, such as methods like getValue(int) vs String[]
                    // getValue()

                    m = OgnlRuntime.getWriteMethod( context.getCurrentObject().getClass(), name );
                    Class parm = m.getParameterTypes()[0];
                    String cast = parm.isArray() ? ExpressionCompiler.getCastString( parm ) : parm.getName();

                    result = m.getName() + "((" + cast + ")$3)";
                    setterClass = parm;
                }
                else
                {
                    context.put( "_indexedMethod", m );
                    context.put( "_indexedDescriptor", pd );
                }

            }
            else
            {
                PropertyAccessor pa = OgnlRuntime.getPropertyAccessor( context.getCurrentObject().getClass() );

                /*
                 * System.out.println("astproperty trying to set " + name + " on object target: " +
                 * context.getCurrentObject().getClass().getName() + " using propertyaccessor type: " + pa);
                 */

                if ( target != null )
                {
                    setterClass = target.getClass();
                }
                if ( parent != null && pd != null && pa == null )
                {
                    m = pd.getReadMethod();
                    result = m.getName() + "()";
                }
                else
                {
                    if ( context.getCurrentObject().getClass().isArray() )
                    {
                        result = "";
                    }
                    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);

                        if ( !lastChild( context ) )
                        {
                            result = pa.getSourceAccessor( context, context.getCurrentObject(), srcString );
                        }
                        else
                        {
                            result = pa.getSourceSetter( context, context.getCurrentObject(), srcString );
                        }

                        getterClass = context.getCurrentType();
                    }
                }
            }

        }
        catch ( Throwable t )
        {
            throw OgnlOps.castToRuntime( t );
        }

        context.setCurrentObject( target );

        if ( m != null )
        {
            context.setCurrentType( m.getReturnType() );
            context.setCurrentAccessor(
                OgnlRuntime.getCompiler( context ).getSuperOrInterfaceClass( m, m.getDeclaringClass() ) );
        }

        return result;
    }