Coverage Report - org.apache.tapestry.services.impl.ExpressionEvaluatorImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
ExpressionEvaluatorImpl
59% 
80% 
2.938
 
 1  
 // Copyright 2004, 2005 The Apache Software Foundation
 2  
 //
 3  
 // Licensed under the Apache License, Version 2.0 (the "License");
 4  
 // you may not use this file except in compliance with the License.
 5  
 // You may obtain a copy of the License at
 6  
 //
 7  
 //     http://www.apache.org/licenses/LICENSE-2.0
 8  
 //
 9  
 // Unless required by applicable law or agreed to in writing, software
 10  
 // distributed under the License is distributed on an "AS IS" BASIS,
 11  
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  
 // See the License for the specific language governing permissions and
 13  
 // limitations under the License.
 14  
 
 15  
 package org.apache.tapestry.services.impl;
 16  
 
 17  
 import ognl.*;
 18  
 import ognl.enhance.ExpressionAccessor;
 19  
 import org.apache.commons.pool.impl.GenericObjectPool;
 20  
 import org.apache.hivemind.ApplicationRuntimeException;
 21  
 import org.apache.hivemind.events.RegistryShutdownListener;
 22  
 import org.apache.hivemind.service.ClassFactory;
 23  
 import org.apache.tapestry.Tapestry;
 24  
 import org.apache.tapestry.services.ExpressionCache;
 25  
 import org.apache.tapestry.services.ExpressionEvaluator;
 26  
 import org.apache.tapestry.spec.IApplicationSpecification;
 27  
 
 28  
 import java.beans.Introspector;
 29  
 import java.util.Iterator;
 30  
 import java.util.List;
 31  
 import java.util.Map;
 32  
 
 33  
 /**
 34  
  * @since 4.0
 35  
  */
 36  24
 public class ExpressionEvaluatorImpl implements ExpressionEvaluator, RegistryShutdownListener {
 37  
     
 38  
     private static final long POOL_MIN_IDLE_TIME = 1000 * 60 * 50;
 39  
 
 40  
     private static final long POOL_SLEEP_TIME = 1000 * 60 * 4;
 41  
 
 42  
     // Uses Thread's context class loader
 43  
 
 44  24
     private final ClassResolver _ognlResolver = new OgnlClassResolver();
 45  
 
 46  
     private ExpressionCache _expressionCache;
 47  
 
 48  
     private IApplicationSpecification _applicationSpecification;
 49  
 
 50  
     private TypeConverter _typeConverter;
 51  
 
 52  
     private List _contributions;
 53  
     
 54  
     private List _nullHandlerContributions;
 55  
 
 56  
     // Context, with a root of null, used when evaluating an expression
 57  
     // to see if it is a constant.
 58  
 
 59  
     private Map _defaultContext;
 60  
     
 61  
     private ClassFactory _classFactory;
 62  
 
 63  
     private GenericObjectPool _contextPool;
 64  
 
 65  
     public void setApplicationSpecification(IApplicationSpecification applicationSpecification)
 66  
     {
 67  21
         _applicationSpecification = applicationSpecification;
 68  21
     }
 69  
 
 70  
     public void initializeService()
 71  
     {
 72  16
         if (_applicationSpecification.checkExtension(Tapestry.OGNL_TYPE_CONVERTER))
 73  2
             _typeConverter = (TypeConverter) _applicationSpecification.getExtension(Tapestry.OGNL_TYPE_CONVERTER, TypeConverter.class);
 74  
 
 75  16
         Iterator i = _contributions.iterator();
 76  
 
 77  16
         while (i.hasNext())
 78  
         {
 79  0
             PropertyAccessorContribution c = (PropertyAccessorContribution) i.next();
 80  
             
 81  0
             OgnlRuntime.setPropertyAccessor(c.getSubjectClass(), c.getAccessor());
 82  0
         }
 83  
         
 84  16
         Iterator j = _nullHandlerContributions.iterator();
 85  
         
 86  16
         while (j.hasNext())
 87  
         {
 88  0
             NullHandlerContribution h = (NullHandlerContribution) j.next();
 89  
             
 90  0
             OgnlRuntime.setNullHandler(h.getSubjectClass(), h.getHandler());
 91  0
         }
 92  
         
 93  16
         _defaultContext = Ognl.createDefaultContext(null, _ognlResolver, _typeConverter);
 94  
         
 95  16
         OgnlRuntime.setCompiler(new HiveMindExpressionCompiler(_classFactory));
 96  
         
 97  16
         _contextPool = new GenericObjectPool(new PoolableOgnlContextFactory(_ognlResolver, _typeConverter));
 98  
 
 99  16
         _contextPool.setMaxActive(-1);
 100  16
         _contextPool.setMaxIdle(-1);
 101  16
         _contextPool.setMinEvictableIdleTimeMillis(POOL_MIN_IDLE_TIME);
 102  16
         _contextPool.setTimeBetweenEvictionRunsMillis(POOL_SLEEP_TIME);
 103  16
     }
 104  
 
 105  
     public Object read(Object target, String expression)
 106  
     {
 107  8
         Node node = (Node)_expressionCache.getCompiledExpression(target, expression);
 108  
         
 109  8
         if (node.getAccessor() != null)
 110  8
             return read(target, node.getAccessor());
 111  
         
 112  0
         return readCompiled(target, node);
 113  
     }
 114  
 
 115  
     public Object readCompiled(Object target, Object expression)
 116  
     {
 117  0
         OgnlContext context = null;
 118  
         try
 119  
         {
 120  0
             context = (OgnlContext)_contextPool.borrowObject();
 121  0
             context.setRoot(target);
 122  
 
 123  0
             return Ognl.getValue(expression, context, target);
 124  
         }
 125  0
         catch (Exception ex)
 126  
         {
 127  0
             throw new ApplicationRuntimeException(ImplMessages.unableToReadExpression(ImplMessages
 128  
                     .parsedExpression(), target, ex), target, null, ex);
 129  
         } finally {
 130  0
             try { if (context != null) _contextPool.returnObject(context); } catch (Exception e) {}
 131  
         }
 132  
     }
 133  
     
 134  
     public Object read(Object target, ExpressionAccessor expression)
 135  
     {
 136  8
         OgnlContext context = null;
 137  
         try
 138  
         {
 139  8
             context = (OgnlContext)_contextPool.borrowObject();
 140  
             
 141  7
             return expression.get(context, target);
 142  
         }
 143  1
         catch (Exception ex)
 144  
         {
 145  1
             throw new ApplicationRuntimeException(ImplMessages.unableToReadExpression(ImplMessages.parsedExpression(),
 146  
                                                                                       target, ex), target, null, ex);
 147  
         } finally {
 148  8
             try { if (context != null) _contextPool.returnObject(context); } catch (Exception e) {}
 149  
         }
 150  
     }
 151  
     
 152  
     public OgnlContext createContext(Object target)
 153  
     {
 154  11
         OgnlContext result = (OgnlContext)Ognl.createDefaultContext(target, _ognlResolver);
 155  
 
 156  11
         if (_typeConverter != null)
 157  1
             Ognl.setTypeConverter(result, _typeConverter);
 158  
 
 159  11
         return result;
 160  
     }
 161  
 
 162  
     public void write(Object target, String expression, Object value)
 163  
     {
 164  3
         writeCompiled(target, _expressionCache.getCompiledExpression(target, expression), value);
 165  2
     }
 166  
 
 167  
     public void write(Object target, ExpressionAccessor expression, Object value)
 168  
     {
 169  0
         OgnlContext context = null;
 170  
         try
 171  
         {
 172  0
             context = (OgnlContext)_contextPool.borrowObject();
 173  
 
 174  
             // setup context
 175  
             
 176  0
             context.setRoot(target);
 177  0
             context.setCurrentObject(target);
 178  
 
 179  0
             expression.set(context, target, value);
 180  
         }
 181  0
         catch (Exception ex)
 182  
         {
 183  0
             throw new ApplicationRuntimeException(ImplMessages.unableToWriteExpression(ImplMessages
 184  
                     .parsedExpression(), target, value, ex), target, null, ex);
 185  
         } finally {
 186  0
             try { if (context != null) _contextPool.returnObject(context); } catch (Exception e) {}
 187  0
         }
 188  0
     }
 189  
     
 190  
     public void writeCompiled(Object target, Object expression, Object value)
 191  
     {
 192  3
         OgnlContext context = null;
 193  
         try
 194  
         {
 195  3
             context = (OgnlContext)_contextPool.borrowObject();
 196  
 
 197  2
             Ognl.setValue(expression, context, target, value);
 198  
         }
 199  1
         catch (Exception ex)
 200  
         {
 201  1
             throw new ApplicationRuntimeException(ImplMessages.unableToWriteExpression(ImplMessages
 202  
                     .parsedExpression(), target, value, ex), target, null, ex);
 203  
         } finally {
 204  3
             try { if (context != null) _contextPool.returnObject(context); } catch (Exception e) {}
 205  0
         }
 206  2
     }
 207  
     
 208  
     public boolean isConstant(Object target, String expression)
 209  
     {
 210  0
         Object compiled = _expressionCache.getCompiledExpression(target, expression);
 211  
 
 212  
         try
 213  
         {
 214  0
             return Ognl.isConstant(compiled, _defaultContext);
 215  
         }
 216  0
         catch (Exception ex)
 217  
         {
 218  0
             throw new ApplicationRuntimeException(ImplMessages.isConstantExpressionError(
 219  
                     expression,
 220  
                     ex), ex);
 221  
         }
 222  
     }
 223  
     
 224  
     public boolean isConstant(String expression)
 225  
     {
 226  6
         Object compiled = _expressionCache.getCompiledExpression(expression);
 227  
 
 228  
         try
 229  
         {
 230  6
             return Ognl.isConstant(compiled, _defaultContext);
 231  
         }
 232  1
         catch (Exception ex)
 233  
         {
 234  1
             throw new ApplicationRuntimeException(ImplMessages.isConstantExpressionError(
 235  
                     expression,
 236  
                     ex), ex);
 237  
         }
 238  
     }
 239  
 
 240  
     public void registryDidShutdown()
 241  
     {
 242  
         try
 243  
         {
 244  0
             _contextPool.clear();
 245  0
             _contextPool.close();
 246  
 
 247  0
             OgnlRuntime.clearCache();
 248  0
             Introspector.flushCaches();
 249  
             
 250  0
         } catch (Exception et) {
 251  
             // ignore
 252  0
         }
 253  0
     }
 254  
 
 255  
     public void setExpressionCache(ExpressionCache expressionCache)
 256  
     {
 257  24
         _expressionCache = expressionCache;
 258  24
     }
 259  
 
 260  
     public void setContributions(List contributions)
 261  
     {
 262  21
         _contributions = contributions;
 263  21
     }
 264  
     
 265  
     public void setNullHandlerContributions(List nullHandlerContributions)
 266  
     {
 267  21
         _nullHandlerContributions = nullHandlerContributions;
 268  21
     }    
 269  
     
 270  
     public void setClassFactory(ClassFactory classFactory)
 271  
     {
 272  26
         _classFactory = classFactory;
 273  26
     }
 274  
 }