001 /*
002 * Apache License
003 * Version 2.0, January 2004
004 * http://www.apache.org/licenses/
005 *
006 * Copyright 1996-2008 by Sven Homburg
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 */
014
015 package org.chenillekit.tapestry.core.bindings;
016
017 import java.util.Map;
018
019 import org.apache.tapestry5.internal.bindings.AbstractBinding;
020 import org.apache.tapestry5.ioc.Location;
021 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
022 import org.apache.tapestry5.ioc.internal.util.TapestryException;
023
024 import ognl.Ognl;
025
026 /**
027 * Binding type for OGNL expressions.
028 * This binding called by expression "ognl:".
029 *
030 * @version $Id: OgnlBinding.java 594 2009-12-05 15:17:26Z mlusetti $
031 */
032 public class OgnlBinding extends AbstractBinding
033 {
034 private static final Map<String, Object> _cache = CollectionFactory.newMap();
035
036 private String _expression;
037 private Object _root;
038
039 public OgnlBinding(final Location location, final Object root, final String expression)
040 {
041 super(location);
042 _expression = expression;
043 _root = root;
044 }
045
046 /**
047 * Gets a parsed OGNL expression from the input string.
048 *
049 * @throws TapestryException if the expression can not be parsed.
050 */
051 public synchronized Object getParsedExpression(String expression)
052 {
053 Object result = _cache.get(expression);
054
055 if (result == null)
056 {
057 try
058 {
059 result = Ognl.parseExpression(expression);
060 }
061 catch (Exception ex)
062 {
063 throw new TapestryException(ex.getLocalizedMessage(), getLocation(), ex);
064 }
065
066 _cache.put(expression, result);
067 }
068
069 return result;
070 }
071
072 /**
073 * Reads the current value of the property (or other resource). When reading properties of
074 * objects that are primitive types, this will return an instance of the wrapper type. In some
075 * cases, a binding is read only and this method will throw a runtime exception.
076 */
077 public Object get()
078 {
079 Object ognlExpression = getParsedExpression(_expression);
080
081 try
082 {
083 Map context = Ognl.createDefaultContext(_root);
084 return Ognl.getValue(ognlExpression, context, _root);
085 }
086 catch (Exception ex)
087 {
088 throw new TapestryException(ex.getLocalizedMessage(), getLocation(), ex);
089 }
090 }
091
092 /**
093 * Returns false; these properties are always dynamic.
094 */
095 @Override
096 public boolean isInvariant()
097 {
098 return false;
099 }
100
101 @Override
102 public String toString()
103 {
104 return String.format("OgnlBinding[%s]", _expression);
105 }
106 }