blob: f481c6cb48eb618ef73f39291f2ae66c8e39e801 [file] [log] [blame]
package org.apache.commons.ognl;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.commons.ognl.enhance.ExpressionCompiler;
import org.apache.commons.ognl.enhance.OgnlExpressionCompiler;
import org.apache.commons.ognl.enhance.UnsupportedCompilationException;
import java.util.ArrayList;
import java.util.List;
/**
* $Id$
*/
public class ASTList
extends SimpleNode
implements NodeType
{
public ASTList( int id )
{
super( id );
}
public ASTList( OgnlParser p, int id )
{
super( p, id );
}
protected Object getValueBody( OgnlContext context, Object source )
throws OgnlException
{
List answer = new ArrayList( jjtGetNumChildren() );
for ( int i = 0; i < jjtGetNumChildren(); ++i )
{
answer.add( children[i].getValue( context, source ) );
}
return answer;
}
public Class getGetterClass()
{
return null;
}
public Class getSetterClass()
{
return null;
}
public String toGetSourceString( OgnlContext context, Object target )
{
StringBuilder result = new StringBuilder();
boolean array = ASTCtor.class.isInstance(parent) && ((ASTCtor) parent).isArray();
context.setCurrentType( List.class );
context.setCurrentAccessor( List.class );
if ( !array )
{
if ( jjtGetNumChildren() < 1 )
{
return "java.util.Arrays.asList( new Object[0])";
}
result.append("java.util.Arrays.asList( new Object[] ");
}
result.append("{ ");
try
{
for ( int i = 0; i < jjtGetNumChildren(); ++i )
{
if ( i > 0 )
{
result.append(", ");
}
Class prevType = context.getCurrentType();
Object objValue = children[i].getValue( context, context.getRoot() );
String value = children[i].toGetSourceString( context, target );
// to undo type setting of constants when used as method parameters
if ( ASTConst.class.isInstance( children[i] ) )
{
context.setCurrentType( prevType );
}
value = ExpressionCompiler.getRootExpression( children[i], target, context ) + value;
String cast = "";
if ( ExpressionCompiler.shouldCast( children[i] ) )
{
cast = (String) context.remove( ExpressionCompiler.PRE_CAST );
}
if ( cast == null )
{
cast = "";
}
if ( !ASTConst.class.isInstance( children[i] ) )
{
value = cast + value;
}
Class ctorClass = (Class) context.get( "_ctorClass" );
if ( array && ctorClass != null && !ctorClass.isPrimitive() )
{
Class valueClass = value != null ? value.getClass() : null;
if ( NodeType.class.isAssignableFrom( children[i].getClass() ) )
{
valueClass = ( (NodeType) children[i] ).getGetterClass();
}
final OgnlExpressionCompiler compiler = OgnlRuntime.getCompiler( context );
if ( valueClass != null && ctorClass.isArray() )
{
value =
compiler
.createLocalReference( context, "(" + ExpressionCompiler.getCastString( ctorClass )
+ ")org.apache.commons.ognl.OgnlOps.toArray(" + value + ", "
+ ctorClass.getComponentType().getName() + ".class, true)", ctorClass );
}
else if ( ctorClass.isPrimitive() )
{
Class wrapClass = OgnlRuntime.getPrimitiveWrapperClass( ctorClass );
value =
compiler
.createLocalReference( context, "((" + wrapClass.getName()
+ ")org.apache.commons.ognl.OgnlOps.convertValue(" + value + ","
+ wrapClass.getName() + ".class, true))." + OgnlRuntime.getNumericValueGetter(
wrapClass ), ctorClass );
}
else if ( ctorClass != Object.class )
{
value =
compiler
.createLocalReference( context, "(" + ctorClass.getName()
+ ")org.apache.commons.ognl.OgnlOps.convertValue(" + value + ","
+ ctorClass.getName() + ".class)", ctorClass );
}
else if ( ( NodeType.class.isInstance( children[i] )
&& ( (NodeType) children[i] ).getGetterClass() != null
&& Number.class.isAssignableFrom( ( (NodeType) children[i] ).getGetterClass() ) )
|| valueClass.isPrimitive() )
{
value = " ($w) (" + value + ")";
}
else if ( valueClass.isPrimitive() )
{
value = "($w) (" + value + ")";
}
}
else if ( ctorClass == null || !ctorClass.isPrimitive() )
{
value = " ($w) (" + value + ")";
}
if ( objValue == null || value.isEmpty() )
{
value = "null";
}
result.append(value);
}
}
catch ( Throwable t )
{
throw OgnlOps.castToRuntime( t );
}
context.setCurrentType( List.class );
context.setCurrentAccessor( List.class );
result.append("}");
if ( !array )
{
result.append(")");
}
return result.toString();
}
public String toSetSourceString( OgnlContext context, Object target )
{
throw new UnsupportedCompilationException( "Can't generate setter for ASTList." );
}
public <R, P> R accept( NodeVisitor<? extends R, ? super P> visitor, P data )
throws OgnlException
{
return visitor.visit( this, data );
}
}