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.UnsupportedCompilationException; 024 025 /** 026 * $Id: ASTAnd.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 ASTAnd 031 extends BooleanExpression 032 { 033 /** Serial */ 034 private static final long serialVersionUID = -4585941425250141812L; 035 036 /** 037 * TODO: javadoc 038 * @param id the id 039 */ 040 public ASTAnd( int id ) 041 { 042 super( id ); 043 } 044 045 /** 046 * TODO: javadoc 047 * @param p the parser 048 * @param id the id 049 */ 050 public ASTAnd( OgnlParser p, int id ) 051 { 052 super( p, id ); 053 } 054 055 /* (non-Javadoc) 056 * @see org.apache.commons.ognl.SimpleNode#jjtClose() 057 */ 058 public void jjtClose() 059 { 060 flattenTree(); 061 } 062 063 /* (non-Javadoc) 064 * @see org.apache.commons.ognl.SimpleNode#getValueBody(org.apache.commons.ognl.OgnlContext, java.lang.Object) 065 */ 066 protected Object getValueBody( OgnlContext context, Object source ) 067 throws OgnlException 068 { 069 Object result = null; 070 int last = children.length - 1; 071 for ( int i = 0; i <= last; ++i ) 072 { 073 result = children[i].getValue( context, source ); 074 075 if ( i != last && !OgnlOps.booleanValue( result ) ) 076 { 077 break; 078 } 079 } 080 081 return result; 082 } 083 084 /* (non-Javadoc) 085 * @see org.apache.commons.ognl.SimpleNode#setValueBody(org.apache.commons.ognl.OgnlContext, java.lang.Object, java.lang.Object) 086 */ 087 protected void setValueBody( OgnlContext context, Object target, Object value ) 088 throws OgnlException 089 { 090 int last = children.length - 1; 091 092 for ( int i = 0; i < last; ++i ) 093 { 094 Object v = children[i].getValue( context, target ); 095 096 if ( !OgnlOps.booleanValue( v ) ) 097 { 098 return; 099 } 100 } 101 102 children[last].setValue( context, target, value ); 103 } 104 105 /* (non-Javadoc) 106 * @see org.apache.commons.ognl.ExpressionNode#getExpressionOperator(int) 107 */ 108 public String getExpressionOperator( int index ) 109 { 110 return "&&"; 111 } 112 113 /* (non-Javadoc) 114 * @see org.apache.commons.ognl.BooleanExpression#getGetterClass() 115 */ 116 public Class getGetterClass() 117 { 118 return null; 119 } 120 121 /* (non-Javadoc) 122 * @see org.apache.commons.ognl.BooleanExpression#toGetSourceString(org.apache.commons.ognl.OgnlContext, java.lang.Object) 123 */ 124 public String toGetSourceString( OgnlContext context, Object target ) 125 { 126 if ( children.length != 2 ) 127 { 128 throw new UnsupportedCompilationException( 129 "Can only compile boolean expressions with two children." ); 130 } 131 132 String result = ""; 133 134 try 135 { 136 137 String first = OgnlRuntime.getChildSource( context, target, children[0] ); 138 if ( !OgnlOps.booleanValue( context.getCurrentObject() ) ) 139 { 140 throw new UnsupportedCompilationException( 141 "And expression can't be compiled until all conditions are true." ); 142 } 143 144 if ( !OgnlRuntime.isBoolean( first ) && !context.getCurrentType().isPrimitive() ) 145 { 146 first = OgnlRuntime.getCompiler( context ).createLocalReference( context, first, context.getCurrentType() ); 147 } 148 149 String second = OgnlRuntime.getChildSource( context, target, children[1] ); 150 if ( !OgnlRuntime.isBoolean( second ) && !context.getCurrentType().isPrimitive() ) 151 { 152 second = OgnlRuntime.getCompiler( context ).createLocalReference( context, second, context.getCurrentType() ); 153 } 154 155 result += "(org.apache.commons.ognl.OgnlOps.booleanValue(" + first + ")"; 156 157 result += " ? "; 158 159 result += " ($w) (" + second + ")"; 160 result += " : "; 161 162 result += " ($w) (" + first + ")"; 163 164 result += ")"; 165 166 context.setCurrentObject( target ); 167 context.setCurrentType( Object.class ); 168 } 169 catch ( NullPointerException e ) 170 { 171 172 throw new UnsupportedCompilationException( "evaluation resulted in null expression." ); 173 } 174 catch ( Throwable t ) 175 { 176 throw OgnlOps.castToRuntime( t ); 177 } 178 179 return result; 180 } 181 182 /* (non-Javadoc) 183 * @see org.apache.commons.ognl.ExpressionNode#toSetSourceString(org.apache.commons.ognl.OgnlContext, java.lang.Object) 184 */ 185 public String toSetSourceString( OgnlContext context, Object target ) 186 { 187 if ( children.length != 2 ) 188 { 189 throw new UnsupportedCompilationException( "Can only compile boolean expressions with two children." ); 190 } 191 192 String pre = (String) context.get( "_currentChain" ); 193 if ( pre == null ) 194 { 195 pre = ""; 196 } 197 198 String result = ""; 199 200 try 201 { 202 203 if ( !OgnlOps.booleanValue( children[0].getValue( context, target ) ) ) 204 { 205 throw new UnsupportedCompilationException( 206 "And expression can't be compiled until all conditions are true." ); 207 } 208 209 String first = 210 ExpressionCompiler.getRootExpression( children[0], context.getRoot(), context ) + pre 211 + children[0].toGetSourceString( context, target ); 212 213 children[1].getValue( context, target ); 214 215 String second = 216 ExpressionCompiler.getRootExpression( children[1], context.getRoot(), context ) + pre 217 + children[1].toSetSourceString( context, target ); 218 219 if ( !OgnlRuntime.isBoolean( first ) ) 220 { 221 result += "if(org.apache.commons.ognl.OgnlOps.booleanValue(" + first + ")){"; 222 } 223 else 224 { 225 result += "if(" + first + "){"; 226 } 227 228 result += second; 229 result += "; } "; 230 231 context.setCurrentObject( target ); 232 context.setCurrentType( Object.class ); 233 234 } 235 catch ( Throwable t ) 236 { 237 throw OgnlOps.castToRuntime( t ); 238 } 239 240 return result; 241 } 242 243 /* (non-Javadoc) 244 * @see org.apache.commons.ognl.Node#accept(org.apache.commons.ognl.NodeVisitor, java.lang.Object) 245 */ 246 public <R, P> R accept( NodeVisitor<? extends R, ? super P> visitor, P data ) 247 throws OgnlException 248 { 249 return visitor.visit( this, data ); 250 } 251 }