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    import org.apache.commons.ognl.enhance.OrderedReturn;
024    
025    /**
026     * $Id: ASTSequence.java 1194869 2011-10-29 11:10:16Z mcucchiara $
027     * @author Luke Blanshard (blanshlu@netscape.net)
028     * @author Drew Davidson (drew@ognl.org)
029     */
030    public class ASTSequence
031        extends SimpleNode
032        implements NodeType, OrderedReturn
033    {
034        private Class getterClass;
035    
036        private String lastExpression;
037    
038        private String coreExpression;
039    
040        public ASTSequence( int id )
041        {
042            super( id );
043        }
044    
045        public ASTSequence( OgnlParser p, int id )
046        {
047            super( p, id );
048        }
049    
050        public void jjtClose()
051        {
052            flattenTree();
053        }
054    
055        protected Object getValueBody( OgnlContext context, Object source )
056            throws OgnlException
057        {
058            Object result = null;
059            for ( int i = 0; i < children.length; ++i )
060            {
061                result = children[i].getValue( context, source );
062            }
063    
064            return result; // The result is just the last one we saw.
065        }
066    
067        protected void setValueBody( OgnlContext context, Object target, Object value )
068            throws OgnlException
069        {
070            int last = children.length - 1;
071            for ( int i = 0; i < last; ++i )
072            {
073                children[i].getValue( context, target );
074            }
075            children[last].setValue( context, target, value );
076        }
077    
078        public Class getGetterClass()
079        {
080            return getterClass;
081        }
082    
083        public Class getSetterClass()
084        {
085            return null;
086        }
087    
088        public String getLastExpression()
089        {
090            return lastExpression;
091        }
092    
093        public String getCoreExpression()
094        {
095            return coreExpression;
096        }
097    
098        public String toSetSourceString( OgnlContext context, Object target )
099        {
100            return "";
101        }
102    
103        public String toGetSourceString( OgnlContext context, Object target )
104        {
105            String result = "";
106    
107            NodeType lastType = null;
108    
109            for ( int i = 0; i < children.length; ++i )
110            {
111                // System.out.println("astsequence child : " + _children[i].getClass().getName());
112                String seqValue = children[i].toGetSourceString( context, target );
113    
114                if ( ( i + 1 ) < children.length && ASTOr.class.isInstance( children[i] ) )
115                {
116                    seqValue = "(" + seqValue + ")";
117                }
118    
119                if ( i > 0 && ASTProperty.class.isInstance( children[i] ) && seqValue != null
120                    && seqValue.trim().length() > 0 )
121                {
122                    String pre = (String) context.get( "_currentChain" );
123                    if ( pre == null )
124                    {
125                        pre = "";
126                    }
127                    
128                    seqValue =
129                        ExpressionCompiler.getRootExpression( children[i], context.getRoot(), context ) + pre + seqValue;
130                    context.setCurrentAccessor( context.getRoot().getClass() );
131                }
132    
133                if ( ( i + 1 ) >= children.length )
134                {
135                    coreExpression = result;
136                    lastExpression = seqValue;
137                }
138    
139                if ( seqValue != null && seqValue.trim().length() > 0 && ( i + 1 ) < children.length )
140                {
141                    result += seqValue + ";";
142                }
143                else if ( seqValue != null && seqValue.trim().length() > 0 )
144                {
145                    result += seqValue;
146                }
147                // set last known type from last child with a type
148    
149                if ( NodeType.class.isInstance( children[i] ) && ( (NodeType) children[i] ).getGetterClass() != null )
150                {
151                    lastType = (NodeType) children[i];
152                }
153            }
154    
155            if ( lastType != null )
156            {
157                getterClass = lastType.getGetterClass();
158            }
159    
160            return result;
161        }
162        
163        public <R, P> R accept( NodeVisitor<? extends R, ? super P> visitor, P data )
164            throws OgnlException
165        {
166            return visitor.visit( this, data );
167        }
168    }