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.UnsupportedCompilationException;
24  
25  /**
26   * $Id: ASTOr.java 1194869 2011-10-29 11:10:16Z mcucchiara $
27   * @author Luke Blanshard (blanshlu@netscape.net)
28   * @author Drew Davidson (drew@ognl.org)
29   */
30  public class ASTOr
31      extends BooleanExpression
32  {
33      public ASTOr( int id )
34      {
35          super( id );
36      }
37  
38      public ASTOr( OgnlParser p, int id )
39      {
40          super( p, id );
41      }
42  
43      public void jjtClose()
44      {
45          flattenTree();
46      }
47  
48      protected Object getValueBody( OgnlContext context, Object source )
49          throws OgnlException
50      {
51          Object result = null;
52          int last = children.length - 1;
53          for ( int i = 0; i <= last; ++i )
54          {
55              result = children[i].getValue( context, source );
56              if ( i != last && OgnlOps.booleanValue( result ) )
57              {
58                  break;
59              }
60          }
61          return result;
62      }
63  
64      protected void setValueBody( OgnlContext context, Object target, Object value )
65          throws OgnlException
66      {
67          int last = children.length - 1;
68          for ( int i = 0; i < last; ++i )
69          {
70              Object v = children[i].getValue( context, target );
71              if ( OgnlOps.booleanValue( v ) )
72              {
73                  return;
74              }
75          }
76          children[last].setValue( context, target, value );
77      }
78  
79      public String getExpressionOperator( int index )
80      {
81          return "||";
82      }
83  
84      public Class getGetterClass()
85      {
86          return null;
87      }
88  
89      public String toGetSourceString( OgnlContext context, Object target )
90      {
91          if ( children.length != 2 )
92          {
93              throw new UnsupportedCompilationException( "Can only compile boolean expressions with two children." );
94          }
95          
96          String result = "(";
97  
98          try
99          {
100 
101             String first = OgnlRuntime.getChildSource( context, target, children[0] );
102             if ( !OgnlRuntime.isBoolean( first ) )
103             {
104                 first = OgnlRuntime.getCompiler( context ).createLocalReference( context, first, context.getCurrentType() );
105             }
106             
107             Class firstType = context.getCurrentType();
108 
109             String second = OgnlRuntime.getChildSource( context, target, children[1] );
110             if ( !OgnlRuntime.isBoolean( second ) )
111             {
112                 second = OgnlRuntime.getCompiler( context ).createLocalReference( context, second, context.getCurrentType() );
113             }
114             
115             Class secondType = context.getCurrentType();
116 
117             boolean mismatched =
118                 ( firstType.isPrimitive( ) && !secondType.isPrimitive( ) ) || ( !firstType.isPrimitive( )
119                     && secondType.isPrimitive( ) );
120 
121             result += "org.apache.commons.ognl.OgnlOps.booleanValue(" + first + ")";
122 
123             result += " ? ";
124 
125             result += ( mismatched ? " ($w) " : "" ) + first;
126 
127             result += " : ";
128 
129             result += ( mismatched ? " ($w) " : "" ) + second;
130 
131             result += ")";
132 
133             context.setCurrentObject( target );
134             context.setCurrentType( Boolean.TYPE );
135 
136         }
137         catch ( Throwable t )
138         {
139             throw OgnlOps.castToRuntime( t );
140         }
141 
142         return result;
143     }
144 
145     public String toSetSourceString( OgnlContext context, Object target )
146     {
147         if ( children.length != 2 )
148         {
149             throw new UnsupportedCompilationException( "Can only compile boolean expressions with two children." );
150         }
151         
152         String pre = (String) context.get( "_currentChain" );
153         if ( pre == null )
154         {
155             pre = "";
156         }
157         
158         String result = "";
159 
160         try
161         {
162 
163             children[0].getValue( context, target );
164 
165             String first =
166                 ExpressionCompiler.getRootExpression( children[0], context.getRoot(), context ) + pre
167                     + children[0].toGetSourceString( context, target );
168             if ( !OgnlRuntime.isBoolean( first ) )
169             {
170                 first = OgnlRuntime.getCompiler( context ).createLocalReference( context, first, Object.class );
171             }
172             children[1].getValue( context, target );
173 
174             String second =
175                 ExpressionCompiler.getRootExpression( children[1], context.getRoot(), context ) + pre
176                     + children[1].toSetSourceString( context, target );
177             if ( !OgnlRuntime.isBoolean( second ) )
178             {
179                 second = OgnlRuntime.getCompiler( context ).createLocalReference( context, second, context.getCurrentType() );
180             }
181             result += "org.apache.commons.ognl.OgnlOps.booleanValue(" + first + ")";
182 
183             result += " ? ";
184 
185             result += first;
186             result += " : ";
187 
188             result += second;
189 
190             context.setCurrentObject( target );
191 
192             context.setCurrentType( Boolean.TYPE );
193 
194         }
195         catch ( Throwable t )
196         {
197             throw OgnlOps.castToRuntime( t );
198         }
199 
200         return result;
201     }
202     
203     public <R, P> R accept( NodeVisitor<? extends R, ? super P> visitor, P data )
204         throws OgnlException
205     {
206         return visitor.visit( this, data );
207     }
208 }