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  1
             _typeConverter = (TypeConverter) _applicationSpecification.getExtension(Tapestry.OGNL_TYPE_CONVERTER,
 74  1
                     TypeConverter.class);
 75  
 
 76  16
         Iterator i = _contributions.iterator();
 77  
 
 78  16
         while (i.hasNext())
 79  
         {
 80  0
             PropertyAccessorContribution c = (PropertyAccessorContribution) i.next();
 81  
             
 82  0
             OgnlRuntime.setPropertyAccessor(c.getSubjectClass(), c.getAccessor());
 83  0
         }
 84  
         
 85  16
         Iterator j = _nullHandlerContributions.iterator();
 86  
         
 87  16
         while (j.hasNext())
 88  
         {
 89  0
             NullHandlerContribution h = (NullHandlerContribution) j.next();
 90  
             
 91  0
             OgnlRuntime.setNullHandler(h.getSubjectClass(), h.getHandler());
 92  0
         }
 93  
         
 94  16
         _defaultContext = Ognl.createDefaultContext(null, _ognlResolver, _typeConverter);
 95  
         
 96  16
         OgnlRuntime.setCompiler(new HiveMindExpressionCompiler(_classFactory));
 97  
         
 98  16
         _contextPool = new GenericObjectPool(new PoolableOgnlContextFactory(_ognlResolver, _typeConverter));
 99  
 
 100  16
         _contextPool.setMaxActive(-1);
 101  16
         _contextPool.setMaxIdle(-1);
 102  16
         _contextPool.setMinEvictableIdleTimeMillis(POOL_MIN_IDLE_TIME);
 103  16
         _contextPool.setTimeBetweenEvictionRunsMillis(POOL_SLEEP_TIME);
 104  16
     }
 105  
 
 106  
     public Object read(Object target, String expression)
 107  
     {
 108  8
         Node node = (Node)_expressionCache.getCompiledExpression(target, expression);
 109  
         
 110  7
         if (node.getAccessor() != null)
 111  7
             return read(target, node.getAccessor());
 112  
         
 113  0
         return readCompiled(target, node);
 114  
     }
 115  
 
 116  
     public Object readCompiled(Object target, Object expression)
 117  
     {
 118  0
         OgnlContext context = null;
 119  
         try
 120  
         {
 121  0
             context = (OgnlContext)_contextPool.borrowObject();
 122  0
             context.setRoot(target);
 123  
 
 124  0
             return Ognl.getValue(expression, context, target);
 125  
         }
 126  0
         catch (Exception ex)
 127  
         {
 128  0
             throw new ApplicationRuntimeException(ImplMessages.unableToReadExpression(ImplMessages
 129  
                     .parsedExpression(), target, ex), target, null, ex);
 130  
         } finally {
 131  0
             try { if (context != null) _contextPool.returnObject(context); } catch (Exception e) {}
 132  
         }
 133  
     }
 134  
     
 135  
     public Object read(Object target, ExpressionAccessor expression)
 136  
     {
 137  7
         OgnlContext context = null;
 138  
         try
 139  
         {
 140  7
             context = (OgnlContext)_contextPool.borrowObject();
 141  
             
 142  7
             return expression.get(context, target);
 143  
         }
 144  0
         catch (Exception ex)
 145  
         {
 146  0
             throw new ApplicationRuntimeException(ImplMessages.unableToReadExpression(ImplMessages
 147  
                     .parsedExpression(), target, ex), target, null, ex);
 148  
         } finally {
 149  7
             try { if (context != null) _contextPool.returnObject(context); } catch (Exception e) {}
 150  
         }
 151  
     }
 152  
     
 153  
     public OgnlContext createContext(Object target)
 154  
     {
 155  11
         OgnlContext result = (OgnlContext)Ognl.createDefaultContext(target, _ognlResolver);
 156  
 
 157  11
         if (_typeConverter != null)
 158  1
             Ognl.setTypeConverter(result, _typeConverter);
 159  
 
 160  11
         return result;
 161  
     }
 162  
 
 163  
     public void write(Object target, String expression, Object value)
 164  
     {
 165  3
         writeCompiled(target, _expressionCache.getCompiledExpression(target, expression), value);
 166  2
     }
 167  
 
 168  
     public void write(Object target, ExpressionAccessor expression, Object value)
 169  
     {
 170  0
         OgnlContext context = null;
 171  
         try
 172  
         {
 173  0
             context = (OgnlContext)_contextPool.borrowObject();
 174  
             
 175  0
             expression.set(context, target, value);
 176  
         }
 177  0
         catch (Exception ex)
 178  
         {
 179  0
             throw new ApplicationRuntimeException(ImplMessages.unableToWriteExpression(ImplMessages
 180  
                     .parsedExpression(), target, value, ex), target, null, ex);
 181  
         } finally {
 182  0
             try { if (context != null) _contextPool.returnObject(context); } catch (Exception e) {}
 183  0
         }
 184  0
     }
 185  
     
 186  
     public void writeCompiled(Object target, Object expression, Object value)
 187  
     {
 188  3
         OgnlContext context = null;
 189  
         try
 190  
         {
 191  3
             context = (OgnlContext)_contextPool.borrowObject();
 192  
 
 193  2
             Ognl.setValue(expression, context, target, value);
 194  
         }
 195  1
         catch (Exception ex)
 196  
         {
 197  1
             throw new ApplicationRuntimeException(ImplMessages.unableToWriteExpression(ImplMessages
 198  
                     .parsedExpression(), target, value, ex), target, null, ex);
 199  
         } finally {
 200  3
             try { if (context != null) _contextPool.returnObject(context); } catch (Exception e) {}
 201  0
         }
 202  2
     }
 203  
     
 204  
     public boolean isConstant(Object target, String expression)
 205  
     {
 206  0
         Object compiled = _expressionCache.getCompiledExpression(target, expression);
 207  
 
 208  
         try
 209  
         {
 210  0
             return Ognl.isConstant(compiled, _defaultContext);
 211  
         }
 212  0
         catch (Exception ex)
 213  
         {
 214  0
             throw new ApplicationRuntimeException(ImplMessages.isConstantExpressionError(
 215  
                     expression,
 216  
                     ex), ex);
 217  
         }
 218  
     }
 219  
     
 220  
     public boolean isConstant(String expression)
 221  
     {
 222  6
         Object compiled = _expressionCache.getCompiledExpression(expression);
 223  
 
 224  
         try
 225  
         {
 226  6
             return Ognl.isConstant(compiled, _defaultContext);
 227  
         }
 228  1
         catch (Exception ex)
 229  
         {
 230  1
             throw new ApplicationRuntimeException(ImplMessages.isConstantExpressionError(
 231  
                     expression,
 232  
                     ex), ex);
 233  
         }
 234  
     }
 235  
 
 236  
     public void registryDidShutdown()
 237  
     {
 238  
         try
 239  
         {
 240  0
             _contextPool.clear();
 241  0
             _contextPool.close();
 242  
 
 243  0
             OgnlRuntime.clearCache();
 244  0
             Introspector.flushCaches();
 245  
             
 246  0
         } catch (Exception et) {
 247  
             // ignore
 248  0
         }
 249  0
     }
 250  
 
 251  
     public void setExpressionCache(ExpressionCache expressionCache)
 252  
     {
 253  24
         _expressionCache = expressionCache;
 254  24
     }
 255  
 
 256  
     public void setContributions(List contributions)
 257  
     {
 258  21
         _contributions = contributions;
 259  21
     }
 260  
     
 261  
     public void setNullHandlerContributions(List nullHandlerContributions)
 262  
     {
 263  21
         _nullHandlerContributions = nullHandlerContributions;
 264  21
     }    
 265  
     
 266  
     public void setClassFactory(ClassFactory classFactory)
 267  
     {
 268  26
         _classFactory = classFactory;
 269  26
     }
 270  
 }