001    // Copyright 2004, 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry.services.impl;
016    
017    import ognl.OgnlRuntime;
018    import ognl.TypeConverter;
019    import ognl.enhance.ExpressionCompiler;
020    import org.apache.hivemind.ApplicationRuntimeException;
021    import org.apache.tapestry.BaseComponentTestCase;
022    import org.apache.tapestry.Tapestry;
023    import org.apache.tapestry.enhance.ClassFactoryImpl;
024    import org.apache.tapestry.services.ExpressionEvaluator;
025    import org.apache.tapestry.spec.IApplicationSpecification;
026    import static org.easymock.EasyMock.expect;
027    import org.testng.annotations.BeforeMethod;
028    import org.testng.annotations.Test;
029    
030    import java.util.Collections;
031    import java.util.Date;
032    
033    /**
034     */
035    @Test
036    public class TestExpressionEvaluator extends BaseComponentTestCase
037    {
038        private ExpressionEvaluatorImpl create()
039        {
040            ExpressionCacheImpl cache = new ExpressionCacheImpl();
041    
042            ExpressionEvaluatorImpl result = new ExpressionEvaluatorImpl();
043            result.setClassFactory(new ClassFactoryImpl());
044            result.setExpressionCache(cache);
045            
046            cache.setEvaluator(result);
047    
048            return result;
049        }
050    
051        // make sure hivemind compiler isn't configured
052        @BeforeMethod
053        public void setup_Ognl()
054        {
055            if (HiveMindExpressionCompiler.class.isInstance(OgnlRuntime.getCompiler()))
056            {
057                OgnlRuntime.setCompiler(new ExpressionCompiler());
058            }
059        }
060    
061        public static class Fixture
062        {
063            private String _value;
064    
065            public Fixture()
066            {
067            }
068    
069            public Fixture(String value)
070            {
071                _value = value;
072            }
073    
074            public String getValue()
075            {
076                return _value;
077            }
078    
079            public void setValue(String value)
080            {
081                _value = value;
082            }
083        }
084    
085        public void test_Read()
086        {
087            Fixture f = new Fixture("Foo");
088    
089            ExpressionEvaluator ee = create();
090            trainIntialize(ee);
091    
092            assertEquals("Foo", ee.read(f, "value"));
093        }
094    
095        public void test_Read_Fail()
096        {
097            Fixture f = new Fixture();
098            ExpressionEvaluator ee = create();
099    
100            try
101            {
102                ee.read(f, "bar");
103                unreachable();
104            }
105            catch (ApplicationRuntimeException ex)
106            {
107                assertExceptionSubstring(ex, "Unable to read OGNL expression");
108            }
109        }
110    
111        public void test_Write()
112        {
113            Fixture f = new Fixture("Foo");
114    
115            ExpressionEvaluator ee = create();
116            trainIntialize(ee);
117            
118            ee.write(f, "value", "Bar");
119    
120            assertEquals("Bar", f.getValue());
121        }
122    
123        public void test_Write_Fail()
124        {
125            Fixture f = new Fixture();
126            ExpressionEvaluator ee = create();
127    
128            try
129            {
130                ee.write(f, "class", "Foo");
131                unreachable();
132            }
133            catch (ApplicationRuntimeException ex)
134            {
135                assertExceptionSubstring(ex, "Unable to update OGNL expression");
136                assertSame(f, ex.getComponent());
137            }
138        }
139    
140        public void test_Is_Constant()
141        {
142            ExpressionEvaluatorImpl ee = create();
143    
144            ee.setApplicationSpecification(newAppSpec());
145            ee.setContributions(Collections.EMPTY_LIST);
146            ee.setNullHandlerContributions(Collections.EMPTY_LIST);
147    
148            replay();
149    
150            ee.initializeService();
151    
152            assertEquals(true, ee.isConstant("true"));
153            assertEquals(true, ee.isConstant("'OGNL'"));
154            assertEquals(false, ee.isConstant("foo.bar"));
155            assertEquals(false, ee.isConstant("bar()"));
156            assertEquals(true, ee.isConstant("@org.apache.tapestry.Tapestry@HOME_SERVICE"));
157    
158            verify();
159        }
160    
161        private IApplicationSpecification newAppSpec()
162        {
163            IApplicationSpecification spec = newMock(IApplicationSpecification.class);
164    
165            expect(spec.checkExtension(Tapestry.OGNL_TYPE_CONVERTER)).andReturn(false);
166    
167            return spec;
168        }
169    
170        public void test_Is_Constant_Fail()
171        {
172            ExpressionEvaluator ee = create();
173    
174            try
175            {
176                ee.isConstant("@foo@BAR");
177                unreachable();
178            }
179            catch (ApplicationRuntimeException ex)
180            {
181                assertExceptionSubstring(ex, "Error evaluating OGNL expression");
182            }
183    
184        }
185    
186        void trainIntialize(ExpressionEvaluator evaluator)
187        {
188            ExpressionEvaluatorImpl impl = (ExpressionEvaluatorImpl)evaluator;
189            
190            IApplicationSpecification as = newMock(IApplicationSpecification.class);
191    
192            expect(as.checkExtension(Tapestry.OGNL_TYPE_CONVERTER)).andReturn(false);
193    
194            impl.setApplicationSpecification(as);
195            impl.setContributions(Collections.EMPTY_LIST);
196            impl.setNullHandlerContributions(Collections.EMPTY_LIST);
197            impl.setClassFactory(new ClassFactoryImpl());
198    
199            replay();
200    
201            impl.initializeService();
202    
203            verify();
204        }
205    
206        public void test_Type_Converter() throws Exception
207        {
208            IApplicationSpecification as = newMock(IApplicationSpecification.class);
209            
210            TypeConverter tc = newMock(TypeConverter.class);
211    
212            // Training
213    
214            expect(as.checkExtension(Tapestry.OGNL_TYPE_CONVERTER)).andReturn(true);
215    
216            expect(as.getExtension(Tapestry.OGNL_TYPE_CONVERTER, TypeConverter.class)).andReturn(tc);
217    
218            replay();
219    
220            ExpressionCacheImpl cache = new ExpressionCacheImpl();
221    
222            ExpressionEvaluatorImpl ee = new ExpressionEvaluatorImpl();
223            
224            ee.setExpressionCache(cache);
225            ee.setApplicationSpecification(as);
226            ee.setContributions(Collections.EMPTY_LIST);
227            ee.setNullHandlerContributions(Collections.EMPTY_LIST);
228            ee.setClassFactory(new ClassFactoryImpl());
229            
230            ee.initializeService();
231            
232            verify();
233            
234            cache.setEvaluator(ee);
235    
236            Fixture f = new Fixture();
237    
238            Date d = new Date();
239    
240            // Training
241            
242            replay();
243            
244            ee.write(f, "value", d);
245    
246            assertEquals(f.getValue(), d.toString());
247    
248            verify();
249        }
250    }