001    package org.apache.commons.ognl;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.commons.ognl.enhance.ExpressionCompiler;
023    
024    /**
025     * @author Luke Blanshard (blanshlu@netscape.net)
026     * @author Drew Davidson (drew@ognl.org)
027     */
028    public abstract class ExpressionNode
029        extends SimpleNode
030    {
031    
032        private static final long serialVersionUID = 9076228016268317598L;
033    
034        public ExpressionNode( int i )
035        {
036            super( i );
037        }
038    
039        public ExpressionNode( OgnlParser p, int i )
040        {
041            super( p, i );
042        }
043    
044        /**
045         * Returns true iff this node is constant without respect to the children.
046         */
047        @Override
048        public boolean isNodeConstant( OgnlContext context )
049            throws OgnlException
050        {
051            return false;
052        }
053    
054        @Override
055        public boolean isConstant( OgnlContext context )
056            throws OgnlException
057        {
058            boolean result = isNodeConstant( context );
059    
060            if ( ( children != null ) && ( children.length > 0 ) )
061            {
062                result = true;
063                for ( int i = 0; result && ( i < children.length ); ++i )
064                {
065                    if ( children[i] instanceof SimpleNode )
066                    {
067                        result = ( (SimpleNode) children[i] ).isConstant( context );
068                    }
069                    else
070                    {
071                        result = false;
072                    }
073                }
074            }
075            return result;
076        }
077    
078        public String getExpressionOperator( int index )
079        {
080            throw new RuntimeException( "unknown operator for " + OgnlParserTreeConstants.jjtNodeName[id] );
081        }
082    
083        @Override
084        public String toGetSourceString( OgnlContext context, Object target )
085        {
086            StringBuilder result =
087                new StringBuilder(
088                    ( parent == null || NumericExpression.class.isAssignableFrom( parent.getClass() ) ) ? "" : "(" );
089    
090            if ( ( children != null ) && ( children.length > 0 ) )
091            {
092                for ( int i = 0; i < children.length; ++i )
093                {
094                    if ( i > 0 )
095                    {
096                        result.append( " " ).append( getExpressionOperator( i ) ).append( " " );
097                    }
098    
099                    String value = children[i].toGetSourceString( context, target );
100    
101                    if ( ( ASTProperty.class.isInstance( children[i] ) || ASTMethod.class.isInstance( children[i] )
102                        || ASTSequence.class.isInstance( children[i] ) || ASTChain.class.isInstance( children[i] ) )
103                        && value != null && value.trim().length() > 0 )
104                    {
105    
106                        String pre = null;
107                        if ( ASTMethod.class.isInstance( children[i] ) )
108                        {
109                            pre = (String) context.get( "_currentChain" );
110                        }
111    
112                        if ( pre == null )
113                        {
114                            pre = "";
115                        }
116    
117                        String cast = (String) context.remove( ExpressionCompiler.PRE_CAST );
118                        if ( cast == null )
119                        {
120                            cast = "";
121                        }
122    
123                        value =
124                            cast + ExpressionCompiler.getRootExpression( children[i], context.getRoot(), context ) + pre
125                                + value;
126                    }
127    
128                    result.append( value );
129                }
130            }
131    
132            if ( parent != null && !NumericExpression.class.isAssignableFrom( parent.getClass() ) )
133            {
134                result.append( ")" );
135            }
136    
137            return result.toString();
138        }
139    
140        @Override
141        public String toSetSourceString( OgnlContext context, Object target )
142        {
143            StringBuilder sourceStringBuilder = new StringBuilder( parent == null ? "" : "(" );
144    
145            if ( ( children != null ) && ( children.length > 0 ) )
146            {
147                for ( int i = 0; i < children.length; ++i )
148                {
149                    if ( i > 0 )
150                    {
151                        sourceStringBuilder.append( " " ).append( getExpressionOperator( i ) ).append( ' ' );
152                    }
153    
154                    sourceStringBuilder.append( children[i].toSetSourceString( context, target ) );
155                }
156            }
157            if ( parent != null )
158            {
159                sourceStringBuilder.append( ")" );
160            }
161    
162            return sourceStringBuilder.toString();
163        }
164    }