View Javadoc

1   package org.apache.commons.ognl;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.commons.ognl.enhance.ExpressionCompiler;
23  import org.apache.commons.ognl.enhance.OgnlExpressionCompiler;
24  import org.apache.commons.ognl.enhance.UnsupportedCompilationException;
25  
26  import java.util.ArrayList;
27  import java.util.List;
28  
29  /**
30   * $Id: ASTList.java 1194869 2011-10-29 11:10:16Z mcucchiara $
31   * @author Luke Blanshard (blanshlu@netscape.net)
32   * @author Drew Davidson (drew@ognl.org)
33   */
34  public class ASTList
35      extends SimpleNode
36      implements NodeType
37  {
38      public ASTList( int id )
39      {
40          super( id );
41      }
42  
43      public ASTList( OgnlParser p, int id )
44      {
45          super( p, id );
46      }
47  
48      protected Object getValueBody( OgnlContext context, Object source )
49          throws OgnlException
50      {
51          List answer = new ArrayList( jjtGetNumChildren() );
52          for ( int i = 0; i < jjtGetNumChildren(); ++i )
53          {
54              answer.add( children[i].getValue( context, source ) );
55          }
56          return answer;
57      }
58  
59      public Class getGetterClass()
60      {
61          return null;
62      }
63  
64      public Class getSetterClass()
65      {
66          return null;
67      }
68  
69      public String toGetSourceString( OgnlContext context, Object target )
70      {
71          String result = "";
72          boolean array = false;
73  
74          if ( parent != null && ASTCtor.class.isInstance( parent ) && ( (ASTCtor) parent ).isArray() )
75          {
76  
77              array = true;
78          }
79  
80          context.setCurrentType( List.class );
81          context.setCurrentAccessor( List.class );
82  
83          if ( !array )
84          {
85              if ( jjtGetNumChildren() < 1 )
86              {
87                  return "java.util.Arrays.asList( new Object[0])";
88              }
89              result += "java.util.Arrays.asList( new Object[] ";
90          }
91  
92          result += "{ ";
93  
94          try
95          {
96  
97              for ( int i = 0; i < jjtGetNumChildren(); ++i )
98              {
99                  if ( i > 0 )
100                 {
101                     result = result + ", ";
102                 }
103 
104                 Class prevType = context.getCurrentType();
105 
106                 Object objValue = children[i].getValue( context, context.getRoot() );
107                 String value = children[i].toGetSourceString( context, target );
108 
109                 // to undo type setting of constants when used as method parameters
110                 if ( ASTConst.class.isInstance( children[i] ) )
111                 {
112 
113                     context.setCurrentType( prevType );
114                 }
115 
116                 value = ExpressionCompiler.getRootExpression( children[i], target, context ) + value;
117 
118                 String cast = "";
119                 if ( ExpressionCompiler.shouldCast( children[i] ) )
120                 {
121 
122                     cast = (String) context.remove( ExpressionCompiler.PRE_CAST );
123                 }
124                 if ( cast == null )
125                 {
126                     cast = "";
127                 }
128                 
129                 if ( !ASTConst.class.isInstance( children[i] ) )
130                 {
131                     value = cast + value;
132                 }
133                 Class ctorClass = (Class) context.get( "_ctorClass" );
134                 if ( array && ctorClass != null && !ctorClass.isPrimitive() )
135                 {
136 
137                     Class valueClass = value != null ? value.getClass() : null;
138                     if ( NodeType.class.isAssignableFrom( children[i].getClass() ) )
139                     {
140                         valueClass = ( (NodeType) children[i] ).getGetterClass();
141                     }
142                     final OgnlExpressionCompiler compiler = OgnlRuntime.getCompiler( context );
143                     if ( valueClass != null && ctorClass.isArray() )
144                     {
145 
146                         value =
147                             compiler
148                                 .createLocalReference( context, "(" + ExpressionCompiler.getCastString( ctorClass )
149                                     + ")org.apache.commons.ognl.OgnlOps.toArray(" + value + ", "
150                                     + ctorClass.getComponentType().getName() + ".class, true)", ctorClass );
151 
152                     }
153                     else if ( ctorClass.isPrimitive() )
154                     {
155 
156                         Class wrapClass = OgnlRuntime.getPrimitiveWrapperClass( ctorClass );
157 
158                         value =
159                             compiler
160                                 .createLocalReference( context, "((" + wrapClass.getName()
161                                     + ")org.apache.commons.ognl.OgnlOps.convertValue(" + value + ","
162                                     + wrapClass.getName() + ".class, true))." + OgnlRuntime.getNumericValueGetter(
163                                     wrapClass ), ctorClass );
164                     }
165                     else if ( ctorClass != Object.class )
166                     {
167 
168                         value =
169                             compiler
170                                 .createLocalReference( context, "(" + ctorClass.getName()
171                                     + ")org.apache.commons.ognl.OgnlOps.convertValue(" + value + ","
172                                     + ctorClass.getName() + ".class)", ctorClass );
173 
174                     }
175                     else if ( ( NodeType.class.isInstance( children[i] )
176                         && ( (NodeType) children[i] ).getGetterClass() != null
177                         && Number.class.isAssignableFrom( ( (NodeType) children[i] ).getGetterClass() ) )
178                         || valueClass.isPrimitive() )
179                     {
180 
181                         value = " ($w) (" + value + ")";
182                     }
183                     else if ( valueClass.isPrimitive() )
184                     {
185                         value = "($w) (" + value + ")";
186                     }
187 
188                 }
189                 else if ( ctorClass == null || !ctorClass.isPrimitive() )
190                 {
191 
192                     value = " ($w) (" + value + ")";
193                 }
194 
195                 if ( objValue == null || value.length() <= 0 )
196                 {
197                     value = "null";
198                 }
199                 result += value;
200             }
201 
202         }
203         catch ( Throwable t )
204         {
205             throw OgnlOps.castToRuntime( t );
206         }
207 
208         context.setCurrentType( List.class );
209         context.setCurrentAccessor( List.class );
210 
211         result += "}";
212 
213         if ( !array )
214         {
215             result += ")";
216         }
217         return result;
218     }
219 
220     public String toSetSourceString( OgnlContext context, Object target )
221     {
222         throw new UnsupportedCompilationException( "Can't generate setter for ASTList." );
223     }
224     
225     public <R, P> R accept( NodeVisitor<? extends R, ? super P> visitor, P data )
226         throws OgnlException
227     {
228         return visitor.visit( this, data );
229     }
230 }