You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ibatis.apache.org by cb...@apache.org on 2008/08/10 08:00:22 UTC

svn commit: r684410 [5/16] - in /ibatis/trunk/java/ibatis-3: ./ ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ ibatis-3-core/src/test/java/org/apache/ibatis/ognl/objects/ ibatis-3-core/src/test/j...

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectElementsAccessor.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectElementsAccessor.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectElementsAccessor.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectElementsAccessor.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,65 @@
+//--------------------------------------------------------------------------
+//	Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
+//  All rights reserved.
+//
+//	Redistribution and use in source and binary forms, with or without
+//  modification, are permitted provided that the following conditions are
+//  met:
+//
+//	Redistributions of source code must retain the above copyright notice,
+//  this list of conditions and the following disclaimer.
+//	Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//	Neither the name of the Drew Davidson nor the names of its contributors
+//  may be used to endorse or promote products derived from this software
+//  without specific prior written permission.
+//
+//	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+//  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+//  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+//  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+//  DAMAGE.
+//--------------------------------------------------------------------------
+package org.apache.ibatis.ognl;
+
+import java.util.*;
+
+/**
+ * Implementation of ElementsAccessor that returns a single-element iterator, containing
+ * the original target object.
+ * @author Luke Blanshard (blanshlu@netscape.net)
+ * @author Drew Davidson (drew@ognl.org)
+ */
+public class ObjectElementsAccessor implements ElementsAccessor
+{
+    public Enumeration getElements( Object target )
+    {
+    	final Object		object = target;
+
+        return new Enumeration() {
+        	private boolean seen = false;
+
+	        public boolean hasMoreElements() {
+	            return !seen;
+	        }
+
+	        public Object nextElement() {
+	        	Object		result = null;
+
+	        	if (!seen) {
+	        		result = object;
+	        		seen = true;
+	        	}
+	            return result;
+	        }
+	    };
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectIndexedPropertyDescriptor.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectIndexedPropertyDescriptor.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectIndexedPropertyDescriptor.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectIndexedPropertyDescriptor.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,123 @@
+//--------------------------------------------------------------------------
+//	Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
+//  All rights reserved.
+//
+//	Redistribution and use in source and binary forms, with or without
+//  modification, are permitted provided that the following conditions are
+//  met:
+//
+//	Redistributions of source code must retain the above copyright notice,
+//  this list of conditions and the following disclaimer.
+//	Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//	Neither the name of the Drew Davidson nor the names of its contributors
+//  may be used to endorse or promote products derived from this software
+//  without specific prior written permission.
+//
+//	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+//  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+//  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+//  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+//  DAMAGE.
+//--------------------------------------------------------------------------
+package org.apache.ibatis.ognl;
+
+import java.beans.*;
+import java.lang.reflect.*;
+
+/**
+ * <p>PropertyDescriptor subclass that describes an indexed set of read/write
+ * methods to get a property. Unlike IndexedPropertyDescriptor this allows
+ * the "key" to be an arbitrary object rather than just an int.  Consequently
+ * it does not have a "readMethod" or "writeMethod" because it only expects
+ * a pattern like:</p>
+ *<pre>
+ *    public void set<i>Property</i>(<i>KeyType</i>, <i>ValueType</i>);
+ *    public <i>ValueType</i> get<i>Property</i>(<i>KeyType</i>);
+ *</pre>
+ * <p>and does not require the methods that access it as an array.  OGNL can
+ * get away with this without losing functionality because if the object
+ * does expose the properties they are most probably in a Map and that case
+ * is handled by the normal OGNL property accessors.
+ *</p>
+ *<p>For example, if an object were to have methods that accessed and "attributes"
+ * property it would be natural to index them by String rather than by integer
+ * and expose the attributes as a map with a different property name:
+ *<pre>
+ *    public void setAttribute(String name, Object value);
+ *    public Object getAttribute(String name);
+ *    public Map getAttributes();
+ *</pre>
+ *<p>Note that the index get/set is called get/set <code>Attribute</code>
+ * whereas the collection getter is called <code>Attributes</code>.  This
+ * case is handled unambiguously by the OGNL property accessors because the
+ * set/get<code>Attribute</code> methods are detected by this object and the
+ * "attributes" case is handled by the <code>MapPropertyAccessor</code>.
+ * Therefore OGNL expressions calling this code would be handled in the
+ * following way:
+ *</p>
+ *<table>
+ *  <tr><th>OGNL Expression</th>
+ *      <th>Handling</th>
+ *  </tr>
+ *  <tr>
+ *      <td><code>attribute["name"]</code></td>
+ *      <td>Handled by an index getter, like <code>getAttribute(String)</code>.</td>
+ *  </tr>
+ *  <tr>
+ *      <td><code>attribute["name"] = value</code></td>
+ *      <td>Handled by an index setter, like <code>setAttribute(String, Object)</code>.</td>
+ *  </tr>
+ *  <tr>
+ *      <td><code>attributes["name"]</code></td>
+ *      <td>Handled by <code>MapPropertyAccessor</code> via a <code>Map.get()</code>.  This
+ *          will <b>not</b> go through the index get accessor.
+ *      </td>
+ *  </tr>
+ *  <tr>
+ *      <td><code>attributes["name"] = value</code></td>
+ *      <td>Handled by <code>MapPropertyAccessor</code> via a <code>Map.put()</code>.  This
+ *          will <b>not</b> go through the index set accessor.
+ *      </td>
+ *  </tr>
+ * </table>
+ * @author Luke Blanshard (blanshlu@netscape.net)
+ * @author Drew Davidson (drew@ognl.org)
+ */
+public class ObjectIndexedPropertyDescriptor extends PropertyDescriptor
+{
+    private Method          indexedReadMethod;
+    private Method          indexedWriteMethod;
+    private Class           propertyType;
+
+    public ObjectIndexedPropertyDescriptor(String propertyName, Class propertyType, Method indexedReadMethod, Method indexedWriteMethod) throws IntrospectionException
+    {
+        super(propertyName, null, null);
+        this.propertyType = propertyType;
+        this.indexedReadMethod = indexedReadMethod;
+        this.indexedWriteMethod = indexedWriteMethod;
+    }
+
+    public Method getIndexedReadMethod()
+    {
+        return indexedReadMethod;
+    }
+
+    public Method getIndexedWriteMethod()
+    {
+        return indexedWriteMethod;
+    }
+
+    public Class getPropertyType()
+    {
+        return propertyType;
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectMethodAccessor.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectMethodAccessor.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectMethodAccessor.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectMethodAccessor.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,63 @@
+//--------------------------------------------------------------------------
+//	Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
+//  All rights reserved.
+//
+//	Redistribution and use in source and binary forms, with or without
+//  modification, are permitted provided that the following conditions are
+//  met:
+//
+//	Redistributions of source code must retain the above copyright notice,
+//  this list of conditions and the following disclaimer.
+//	Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//	Neither the name of the Drew Davidson nor the names of its contributors
+//  may be used to endorse or promote products derived from this software
+//  without specific prior written permission.
+//
+//	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+//  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+//  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+//  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+//  DAMAGE.
+//--------------------------------------------------------------------------
+package org.apache.ibatis.ognl;
+
+import java.util.*;
+
+/**
+ * Implementation of PropertyAccessor that uses reflection on the target object's class to
+ * find a field or a pair of set/get methods with the given property name.
+ * @author Luke Blanshard (blanshlu@netscape.net)
+ * @author Drew Davidson (drew@ognl.org)
+ */
+public class ObjectMethodAccessor implements MethodAccessor
+{
+    /* MethodAccessor interface */
+    public Object callStaticMethod( Map context, Class targetClass, String methodName, Object[] args ) throws MethodFailedException
+    {
+        List        methods = OgnlRuntime.getMethods(targetClass, methodName, true);
+
+        return OgnlRuntime.callAppropriateMethod( (OgnlContext)context, targetClass, null, methodName, null, methods, args );
+    }
+
+    public Object callMethod( Map context, Object target, String methodName, Object[] args ) throws MethodFailedException
+    {
+        Class       targetClass = (target == null) ? null : target.getClass();
+        Object      source = target;
+        List        methods = OgnlRuntime.getMethods(targetClass, methodName, false);
+
+        if ((methods == null) || (methods.size() == 0)) {
+            methods = OgnlRuntime.getMethods(targetClass, methodName, true);
+            source = targetClass;
+        }
+        return OgnlRuntime.callAppropriateMethod( (OgnlContext)context, target, target, methodName, null, methods, args );
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectNullHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectNullHandler.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectNullHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectNullHandler.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,53 @@
+//--------------------------------------------------------------------------
+//	Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
+//  All rights reserved.
+//
+//	Redistribution and use in source and binary forms, with or without
+//  modification, are permitted provided that the following conditions are
+//  met:
+//
+//	Redistributions of source code must retain the above copyright notice,
+//  this list of conditions and the following disclaimer.
+//	Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//	Neither the name of the Drew Davidson nor the names of its contributors
+//  may be used to endorse or promote products derived from this software
+//  without specific prior written permission.
+//
+//	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+//  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+//  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+//  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+//  DAMAGE.
+//--------------------------------------------------------------------------
+package org.apache.ibatis.ognl;
+
+import java.util.*;
+
+/**
+ * Implementation of NullHandler that returns null in all cases,
+ * so that NullPointerException will be thrown by the caller.
+ * @author Luke Blanshard (blanshlu@netscape.net)
+ * @author Drew Davidson (drew@ognl.org)
+ */
+public class ObjectNullHandler implements NullHandler
+{
+    /* NullHandler interface */
+    public Object nullMethodResult(Map context, Object target, String methodName, Object[] args)
+    {
+        return null;
+    }
+
+    public Object nullPropertyValue(Map context, Object target, Object property)
+    {
+        return null;
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectPropertyAccessor.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectPropertyAccessor.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectPropertyAccessor.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ObjectPropertyAccessor.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,135 @@
+//--------------------------------------------------------------------------
+//	Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
+//  All rights reserved.
+//
+//	Redistribution and use in source and binary forms, with or without
+//  modification, are permitted provided that the following conditions are
+//  met:
+//
+//	Redistributions of source code must retain the above copyright notice,
+//  this list of conditions and the following disclaimer.
+//	Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//	Neither the name of the Drew Davidson nor the names of its contributors
+//  may be used to endorse or promote products derived from this software
+//  without specific prior written permission.
+//
+//	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+//  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+//  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+//  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+//  DAMAGE.
+//--------------------------------------------------------------------------
+package org.apache.ibatis.ognl;
+
+import java.beans.IntrospectionException;
+import java.util.Map;
+
+/**
+ * Implementation of PropertyAccessor that uses reflection on the target object's class to
+ * find a field or a pair of set/get methods with the given property name.
+ * @author Luke Blanshard (blanshlu@netscape.net)
+ * @author Drew Davidson (drew@ognl.org)
+ */
+public class ObjectPropertyAccessor implements PropertyAccessor
+{
+    /**
+        Returns OgnlRuntime.NotFound if the property does not exist.
+     */
+    public Object getPossibleProperty( Map context, Object target, String name) throws OgnlException
+    {
+        Object          result;
+        OgnlContext     ognlContext = (OgnlContext)context;
+
+        try {
+            if ((result = OgnlRuntime.getMethodValue(ognlContext, target, name, true)) == OgnlRuntime.NotFound) {
+                result = OgnlRuntime.getFieldValue(ognlContext, target, name, true);
+            }
+        } catch (IntrospectionException ex) {
+            throw new OgnlException(name, ex);
+        } catch (OgnlException ex) {
+            throw ex;
+        } catch (Exception ex) {
+            throw new OgnlException(name, ex);
+        }
+        return result;
+    }
+
+    /**
+        Returns OgnlRuntime.NotFound if the property does not exist.
+     */
+    public Object setPossibleProperty( Map context, Object target, String name, Object value) throws OgnlException
+    {
+        Object          result = null;
+        OgnlContext     ognlContext = (OgnlContext)context;
+
+        try {
+            if (!OgnlRuntime.setMethodValue(ognlContext, target, name, value, true)) {
+                result = OgnlRuntime.setFieldValue(ognlContext, target, name, value) ? null : OgnlRuntime.NotFound;
+            }
+        } catch (IntrospectionException ex) {
+            throw new OgnlException(name, ex);
+        } catch (OgnlException ex) {
+            throw ex;
+        } catch (Exception ex) {
+            throw new OgnlException(name, ex);
+        }
+        return result;
+    }
+
+    public boolean hasGetProperty( OgnlContext context, Object target, Object oname ) throws OgnlException
+    {
+        try {
+            return OgnlRuntime.hasGetProperty( context, target, oname );
+        } catch (IntrospectionException ex) {
+            throw new OgnlException("checking if " + target + " has gettable property " + oname, ex);
+        }
+    }
+
+    public boolean hasGetProperty( Map context, Object target, Object oname ) throws OgnlException
+    {
+        return hasGetProperty((OgnlContext)context, target, oname);
+    }
+
+    public boolean hasSetProperty( OgnlContext context, Object target, Object oname ) throws OgnlException
+    {
+        try {
+            return OgnlRuntime.hasSetProperty( context, target, oname );
+        } catch (IntrospectionException ex) {
+            throw new OgnlException("checking if " + target + " has settable property " + oname, ex);
+        }
+    }
+
+    public boolean hasSetProperty( Map context, Object target, Object oname ) throws OgnlException
+    {
+        return hasSetProperty((OgnlContext)context, target, oname);
+    }
+
+    public Object getProperty( Map context, Object target, Object oname ) throws OgnlException
+    {
+        Object              result = null;
+        String              name = oname.toString();
+
+        if ((result = getPossibleProperty(context, target, name)) == OgnlRuntime.NotFound) {
+            throw new NoSuchPropertyException(target, name);
+        }
+        return result;
+    }
+
+    public void setProperty( Map context, Object target, Object oname, Object value ) throws OgnlException
+    {
+        String          name = oname.toString();
+
+        if (setPossibleProperty(context, target, name, value) == OgnlRuntime.NotFound) {
+            throw new NoSuchPropertyException(target, name);
+        }
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/Ognl.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/Ognl.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/Ognl.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/Ognl.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,598 @@
+//--------------------------------------------------------------------------
+//	Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
+//  All rights reserved.
+//
+//	Redistribution and use in source and binary forms, with or without
+//  modification, are permitted provided that the following conditions are
+//  met:
+//
+//	Redistributions of source code must retain the above copyright notice,
+//  this list of conditions and the following disclaimer.
+//	Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//	Neither the name of the Drew Davidson nor the names of its contributors
+//  may be used to endorse or promote products derived from this software
+//  without specific prior written permission.
+//
+//	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+//  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+//  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+//  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+//  DAMAGE.
+//--------------------------------------------------------------------------
+package org.apache.ibatis.ognl;
+
+import java.io.StringReader;
+import java.util.Map;
+
+/**
+ * <P>This class provides static methods for parsing and interpreting OGNL expressions.</P>
+ *
+ * <P>The simplest use of the Ognl class is to get the value of an expression from
+ * an object, without extra context or pre-parsing.</P>
+ *
+ * <PRE>
+ * import ognl.Ognl;
+ * import ognl.OgnlException;
+ *
+ *    try {
+ *        result = Ognl.getValue(expression, root);
+ *    } catch (OgnlException ex) {
+ *       // Report error or recover
+ *    }
+ * </PRE>
+ *
+ * <P>This will parse the expression given and evaluate it against the root object
+ * given, returning the result.  If there is an error in the expression, such
+ * as the property is not found, the exception is encapsulated into an
+ * {@link org.apache.ibatis.ognl.OgnlException OgnlException}.</P>
+ *
+ * <P>Other more sophisticated uses of Ognl can pre-parse expressions.  This
+ * provides two advantages: in the case of user-supplied expressions it
+ * allows you to catch parse errors before evaluation and it allows you to
+ * cache parsed expressions into an AST for better speed during repeated use.
+ * The pre-parsed expression is always returned as an <CODE>Object</CODE>
+ * to simplify use for programs that just wish to store the value for
+ * repeated use and do not care that it is an AST.  If it does care
+ * it can always safely cast the value to an <CODE>AST</CODE> type.</P>
+ *
+ * <P>The Ognl class also takes a <I>context map</I> as one of the parameters
+ * to the set and get methods.  This allows you to put your own variables
+ * into the available namespace for OGNL expressions.  The default context
+ * contains only the <CODE>#root</CODE> and <CODE>#context</CODE> keys,
+ * which are required to be present.  The <CODE>addDefaultContext(Object, Map)</CODE>
+ * method will alter an existing <CODE>Map</CODE> to put the defaults in.
+ * Here is an example that shows how to extract the <CODE>documentName</CODE>
+ * property out of the root object and append a string with the current user
+ * name in parens:</P>
+ *
+ * <PRE>
+ *     private Map	context = new HashMap();
+ *
+ *     public void setUserName(String value)
+ *     {
+ *         context.put("userName", value);
+ *     }
+ *
+ *     try {
+ *        // get value using our own custom context map
+ *        result = Ognl.getValue("documentName + \" (\" + ((#userName == null) ? \"&lt;nobody&gt;\" : #userName) + \")\"", context, root);
+ *     } catch (OgnlException ex) {
+ *         // Report error or recover
+ *     }
+ *
+ * </PRE>
+ *
+ * @author Luke Blanshard (blanshlu@netscape.net)
+ * @author Drew Davidson (drew@ognl.org)
+ * @version 27 June 1999
+ */
+public abstract class Ognl
+{
+      /**
+       * Parses the given OGNL expression and returns a tree representation of the
+       * expression that can be used by <CODE>Ognl</CODE> static methods.
+       *
+       * @param expression the OGNL expression to be parsed
+       * @return a tree representation of the expression
+       * @throws ExpressionSyntaxException if the expression is malformed
+       * @throws OgnlException if there is a pathological environmental problem
+       */
+    public static Object parseExpression( String expression ) throws OgnlException
+    {
+        try {
+            OgnlParser parser = new OgnlParser( new StringReader(expression) );
+            return parser.topLevelExpression();
+        }
+        catch (ParseException e) {
+            throw new ExpressionSyntaxException( expression, e );
+        }
+        catch (TokenMgrError e) {
+            throw new ExpressionSyntaxException( expression, e );
+        }
+    }
+
+      /**
+       * Creates and returns a new standard naming context for evaluating an OGNL
+       * expression.
+       *
+       * @param root the root of the object graph
+       * @return a new Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
+       *         set appropriately
+       */
+    public static Map createDefaultContext( Object root )
+    {
+        return addDefaultContext( root, null, null, null, new OgnlContext() );
+    }
+
+      /**
+       * Creates and returns a new standard naming context for evaluating an OGNL
+       * expression.
+       *
+       * @param root the root of the object graph
+       * @return a new OgnlContext with the keys <CODE>root</CODE> and <CODE>context</CODE>
+       *         set appropriately
+       */
+    public static Map createDefaultContext( Object root, ClassResolver classResolver )
+    {
+        return addDefaultContext( root, classResolver, null, null, new OgnlContext() );
+    }
+
+      /**
+       * Creates and returns a new standard naming context for evaluating an OGNL
+       * expression.
+       *
+       * @param root the root of the object graph
+       * @return a new Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
+       *         set appropriately
+       */
+    public static Map createDefaultContext( Object root, ClassResolver classResolver, TypeConverter converter )
+    {
+        return addDefaultContext( root, classResolver, converter, null, new OgnlContext() );
+    }
+
+      /**
+       * Creates and returns a new standard naming context for evaluating an OGNL
+       * expression.
+       *
+       * @param root the root of the object graph
+       * @return a new Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
+       *         set appropriately
+       */
+    public static Map createDefaultContext( Object root, ClassResolver classResolver, TypeConverter converter, MemberAccess memberAccess )
+    {
+        return addDefaultContext( root, classResolver, converter, memberAccess, new OgnlContext() );
+    }
+
+      /**
+       * Appends the standard naming context for evaluating an OGNL expression
+       * into the context given so that cached maps can be used as a context.
+       *
+       * @param root the root of the object graph
+       * @param context the context to which OGNL context will be added.
+       * @return Context Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
+       *         set appropriately
+       */
+    public static Map addDefaultContext( Object root, Map context )
+    {
+    	return addDefaultContext( root, null, null, null, context );
+    }
+
+      /**
+       * Appends the standard naming context for evaluating an OGNL expression
+       * into the context given so that cached maps can be used as a context.
+       *
+       * @param root the root of the object graph
+       * @param context the context to which OGNL context will be added.
+       * @return Context Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
+       *         set appropriately
+       */
+    public static Map addDefaultContext( Object root, ClassResolver classResolver, Map context )
+    {
+        return addDefaultContext(root, classResolver, null, null, context);
+    }
+
+      /**
+       * Appends the standard naming context for evaluating an OGNL expression
+       * into the context given so that cached maps can be used as a context.
+       *
+       * @param root the root of the object graph
+       * @param context the context to which OGNL context will be added.
+       * @return Context Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
+       *         set appropriately
+       */
+    public static Map addDefaultContext( Object root, ClassResolver classResolver, TypeConverter converter, Map context )
+    {
+        return addDefaultContext(root, classResolver, converter, null, context);
+    }
+
+      /**
+       * Appends the standard naming context for evaluating an OGNL expression
+       * into the context given so that cached maps can be used as a context.
+       *
+       * @param root the root of the object graph
+       * @param context the context to which OGNL context will be added.
+       * @return Context Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
+       *         set appropriately
+       */
+    public static Map addDefaultContext( Object root, ClassResolver classResolver, TypeConverter converter, MemberAccess memberAccess, Map context )
+    {
+        OgnlContext     result;
+
+        if (!(context instanceof OgnlContext)) {
+            result = new OgnlContext();
+            result.setValues(context);
+        } else {
+            result = (OgnlContext)context;
+        }
+        if (classResolver != null) {
+            result.setClassResolver(classResolver);
+        }
+        if (converter != null) {
+            result.setTypeConverter(converter);
+        }
+        if (memberAccess != null) {
+            result.setMemberAccess(memberAccess);
+        }
+        result.setRoot(root);
+        return result;
+    }
+
+    public static void setClassResolver( Map context, ClassResolver classResolver)
+    {
+        context.put(OgnlContext.CLASS_RESOLVER_CONTEXT_KEY, classResolver);
+    }
+
+    public static ClassResolver getClassResolver( Map context )
+    {
+        return (ClassResolver)context.get(OgnlContext.CLASS_RESOLVER_CONTEXT_KEY);
+    }
+
+    public static void setTypeConverter( Map context, TypeConverter converter)
+    {
+        context.put(OgnlContext.TYPE_CONVERTER_CONTEXT_KEY, converter);
+    }
+
+    public static TypeConverter getTypeConverter( Map context )
+    {
+        return (TypeConverter)context.get(OgnlContext.TYPE_CONVERTER_CONTEXT_KEY);
+    }
+
+	public static void setMemberAccess(Map context, MemberAccess memberAccess)
+	{
+	    context.put(OgnlContext.MEMBER_ACCESS_CONTEXT_KEY, memberAccess);
+	}
+
+	public static MemberAccess getMemberAccess(Map context)
+	{
+	    return (MemberAccess)context.get(OgnlContext.MEMBER_ACCESS_CONTEXT_KEY);
+	}
+
+    public static void setRoot( Map context, Object root)
+    {
+        context.put(OgnlContext.ROOT_CONTEXT_KEY, root);
+    }
+
+    public static Object getRoot( Map context )
+    {
+        return context.get(OgnlContext.ROOT_CONTEXT_KEY);
+    }
+
+    public static Evaluation getLastEvaluation( Map context )
+    {
+        return (Evaluation)context.get(OgnlContext.LAST_EVALUATION_CONTEXT_KEY);
+    }
+
+      /**
+       * Evaluates the given OGNL expression tree to extract a value from the given root
+       * object. The default context is set for the given context and root via
+       * <CODE>addDefaultContext()</CODE>.
+       *
+       * @param tree the OGNL expression tree to evaluate, as returned by parseExpression()
+       * @param context the naming context for the evaluation
+       * @param root the root object for the OGNL expression
+       * @return the result of evaluating the expression
+       * @throws MethodFailedException if the expression called a method which failed
+       * @throws NoSuchPropertyException if the expression referred to a nonexistent property
+       * @throws InappropriateExpressionException if the expression can't be used in this context
+       * @throws OgnlException if there is a pathological environmental problem
+       */
+    public static Object getValue( Object tree, Map context, Object root ) throws OgnlException
+    {
+        return getValue( tree, context, root, null );
+    }
+
+      /**
+       * Evaluates the given OGNL expression tree to extract a value from the given root
+       * object. The default context is set for the given context and root via
+       * <CODE>addDefaultContext()</CODE>.
+       *
+       * @param tree the OGNL expression tree to evaluate, as returned by parseExpression()
+       * @param context the naming context for the evaluation
+       * @param root the root object for the OGNL expression
+       * @param resultType the converted type of the resultant object, using the context's type converter
+       * @return the result of evaluating the expression
+       * @throws MethodFailedException if the expression called a method which failed
+       * @throws NoSuchPropertyException if the expression referred to a nonexistent property
+       * @throws InappropriateExpressionException if the expression can't be used in this context
+       * @throws OgnlException if there is a pathological environmental problem
+       */
+    public static Object getValue( Object tree, Map context, Object root, Class resultType ) throws OgnlException
+    {
+        Object          result;
+        OgnlContext     ognlContext = (OgnlContext)addDefaultContext(root, context);
+
+        result = ((Node)tree).getValue( ognlContext, root );
+        if (resultType != null) {
+            result = getTypeConverter( context ).convertValue( context, root, null, null, result, resultType);
+        }
+        return result;
+    }
+
+      /**
+       * Evaluates the given OGNL expression to extract a value from the given root
+       * object in a given context
+       *
+       * @see #parseExpression(String)
+       * @see #getValue(Object,Object)
+       * @param expression the OGNL expression to be parsed
+       * @param context the naming context for the evaluation
+       * @param root the root object for the OGNL expression
+       * @return the result of evaluating the expression
+       * @throws MethodFailedException if the expression called a method which failed
+       * @throws NoSuchPropertyException if the expression referred to a nonexistent property
+       * @throws InappropriateExpressionException if the expression can't be used in this context
+       * @throws OgnlException if there is a pathological environmental problem
+       */
+    public static Object getValue( String expression, Map context, Object root ) throws OgnlException
+    {
+        return getValue( expression, context, root, null );
+    }
+
+      /**
+       * Evaluates the given OGNL expression to extract a value from the given root
+       * object in a given context
+       *
+       * @see #parseExpression(String)
+       * @see #getValue(Object,Object)
+       * @param expression the OGNL expression to be parsed
+       * @param context the naming context for the evaluation
+       * @param root the root object for the OGNL expression
+       * @param resultType the converted type of the resultant object, using the context's type converter
+       * @return the result of evaluating the expression
+       * @throws MethodFailedException if the expression called a method which failed
+       * @throws NoSuchPropertyException if the expression referred to a nonexistent property
+       * @throws InappropriateExpressionException if the expression can't be used in this context
+       * @throws OgnlException if there is a pathological environmental problem
+       */
+    public static Object getValue( String expression, Map context, Object root, Class resultType ) throws OgnlException
+    {
+        return getValue( parseExpression(expression), context, root, resultType );
+    }
+
+      /**
+       * Evaluates the given OGNL expression tree to extract a value from the given root
+       * object.
+       *
+       * @param tree the OGNL expression tree to evaluate, as returned by parseExpression()
+       * @param root the root object for the OGNL expression
+       * @return the result of evaluating the expression
+       * @throws MethodFailedException if the expression called a method which failed
+       * @throws NoSuchPropertyException if the expression referred to a nonexistent property
+       * @throws InappropriateExpressionException if the expression can't be used in this context
+       * @throws OgnlException if there is a pathological environmental problem
+       */
+    public static Object getValue( Object tree, Object root ) throws OgnlException
+    {
+        return getValue( tree, root, null );
+    }
+
+      /**
+       * Evaluates the given OGNL expression tree to extract a value from the given root
+       * object.
+       *
+       * @param tree the OGNL expression tree to evaluate, as returned by parseExpression()
+       * @param root the root object for the OGNL expression
+       * @param resultType the converted type of the resultant object, using the context's type converter
+       * @return the result of evaluating the expression
+       * @throws MethodFailedException if the expression called a method which failed
+       * @throws NoSuchPropertyException if the expression referred to a nonexistent property
+       * @throws InappropriateExpressionException if the expression can't be used in this context
+       * @throws OgnlException if there is a pathological environmental problem
+       */
+    public static Object getValue( Object tree, Object root, Class resultType ) throws OgnlException
+    {
+        return getValue( tree, createDefaultContext(root), root, resultType );
+    }
+
+      /**
+       * Convenience method that combines calls to <code> parseExpression </code> and
+       * <code> getValue</code>.
+       *
+       * @see #parseExpression(String)
+       * @see #getValue(Object,Object)
+       * @param expression the OGNL expression to be parsed
+       * @param root the root object for the OGNL expression
+       * @return the result of evaluating the expression
+       * @throws ExpressionSyntaxException if the expression is malformed
+       * @throws MethodFailedException if the expression called a method which failed
+       * @throws NoSuchPropertyException if the expression referred to a nonexistent property
+       * @throws InappropriateExpressionException if the expression can't be used in this context
+       * @throws OgnlException if there is a pathological environmental problem
+       */
+    public static Object getValue( String expression, Object root ) throws OgnlException
+    {
+        return getValue( expression, root, null );
+    }
+
+      /**
+       * Convenience method that combines calls to <code> parseExpression </code> and
+       * <code> getValue</code>.
+       *
+       * @see #parseExpression(String)
+       * @see #getValue(Object,Object)
+       * @param expression the OGNL expression to be parsed
+       * @param root the root object for the OGNL expression
+       * @param resultType the converted type of the resultant object, using the context's type converter
+       * @return the result of evaluating the expression
+       * @throws ExpressionSyntaxException if the expression is malformed
+       * @throws MethodFailedException if the expression called a method which failed
+       * @throws NoSuchPropertyException if the expression referred to a nonexistent property
+       * @throws InappropriateExpressionException if the expression can't be used in this context
+       * @throws OgnlException if there is a pathological environmental problem
+       */
+    public static Object getValue( String expression, Object root, Class resultType ) throws OgnlException
+    {
+        return getValue( parseExpression(expression), root, resultType );
+    }
+
+      /**
+       * Evaluates the given OGNL expression tree to insert a value into the object graph
+       * rooted at the given root object.  The default context is set for the given
+       * context and root via <CODE>addDefaultContext()</CODE>.
+       *
+       * @param tree the OGNL expression tree to evaluate, as returned by parseExpression()
+       * @param context the naming context for the evaluation
+       * @param root the root object for the OGNL expression
+       * @param value the value to insert into the object graph
+       * @throws MethodFailedException if the expression called a method which failed
+       * @throws NoSuchPropertyException if the expression referred to a nonexistent property
+       * @throws InappropriateExpressionException if the expression can't be used in this context
+       * @throws OgnlException if there is a pathological environmental problem
+       */
+    public static void setValue( Object tree, Map context, Object root, Object value ) throws OgnlException
+    {
+        OgnlContext     ognlContext = (OgnlContext)addDefaultContext(root, context);
+        Node            n = (Node) tree;
+
+        n.setValue( ognlContext, root, value );
+    }
+
+      /**
+       * Evaluates the given OGNL expression to insert a value into the object graph
+       * rooted at the given root object given the context.
+       *
+       * @param expression the OGNL expression to be parsed
+       * @param root the root object for the OGNL expression
+       * @param context the naming context for the evaluation
+       * @param value the value to insert into the object graph
+       * @throws MethodFailedException if the expression called a method which failed
+       * @throws NoSuchPropertyException if the expression referred to a nonexistent property
+       * @throws InappropriateExpressionException if the expression can't be used in this context
+       * @throws OgnlException if there is a pathological environmental problem
+       */
+    public static void setValue( String expression, Map context, Object root, Object value ) throws OgnlException
+    {
+        setValue( parseExpression(expression), context, root, value );
+    }
+
+      /**
+       * Evaluates the given OGNL expression tree to insert a value into the object graph
+       * rooted at the given root object.
+       *
+       * @param tree the OGNL expression tree to evaluate, as returned by parseExpression()
+       * @param root the root object for the OGNL expression
+       * @param value the value to insert into the object graph
+       * @throws MethodFailedException if the expression called a method which failed
+       * @throws NoSuchPropertyException if the expression referred to a nonexistent property
+       * @throws InappropriateExpressionException if the expression can't be used in this context
+       * @throws OgnlException if there is a pathological environmental problem
+       */
+    public static void setValue( Object tree, Object root, Object value ) throws OgnlException
+    {
+        setValue( tree, createDefaultContext(root), root, value );
+    }
+
+      /**
+       * Convenience method that combines calls to <code> parseExpression </code> and
+       * <code> setValue</code>.
+       *
+       * @see #parseExpression(String)
+       * @see #setValue(Object,Object,Object)
+       * @param expression the OGNL expression to be parsed
+       * @param root the root object for the OGNL expression
+       * @param value the value to insert into the object graph
+       * @throws ExpressionSyntaxException if the expression is malformed
+       * @throws MethodFailedException if the expression called a method which failed
+       * @throws NoSuchPropertyException if the expression referred to a nonexistent property
+       * @throws InappropriateExpressionException if the expression can't be used in this context
+       * @throws OgnlException if there is a pathological environmental problem
+       */
+    public static void setValue( String expression, Object root, Object value ) throws OgnlException
+    {
+        setValue( parseExpression(expression), root, value );
+    }
+
+    public static boolean isConstant( Object tree, Map context ) throws OgnlException
+    {
+        return ((SimpleNode)tree).isConstant( (OgnlContext)addDefaultContext( null, context ) );
+    }
+
+    public static boolean isConstant( String expression, Map context ) throws OgnlException
+    {
+        return isConstant(parseExpression(expression), context);
+    }
+
+    public static boolean isConstant( Object tree ) throws OgnlException
+    {
+        return isConstant(tree, createDefaultContext(null));
+    }
+
+    public static boolean isConstant( String expression ) throws OgnlException
+    {
+        return isConstant(parseExpression(expression), createDefaultContext(null));
+    }
+
+    public static boolean isSimpleProperty( Object tree, Map context ) throws OgnlException
+    {
+        return ((SimpleNode)tree).isSimpleProperty( (OgnlContext)addDefaultContext( null, context ) );
+    }
+
+    public static boolean isSimpleProperty( String expression, Map context ) throws OgnlException
+    {
+        return isSimpleProperty(parseExpression(expression), context);
+    }
+
+    public static boolean isSimpleProperty( Object tree ) throws OgnlException
+    {
+        return isSimpleProperty(tree, createDefaultContext(null));
+    }
+
+    public static boolean isSimpleProperty( String expression ) throws OgnlException
+    {
+        return isSimpleProperty(parseExpression(expression), createDefaultContext(null));
+    }
+
+    public static boolean isSimpleNavigationChain( Object tree, Map context ) throws OgnlException
+    {
+        return ((SimpleNode)tree).isSimpleNavigationChain( (OgnlContext)addDefaultContext( null, context ) );
+    }
+
+    public static boolean isSimpleNavigationChain( String expression, Map context ) throws OgnlException
+    {
+        return isSimpleNavigationChain(parseExpression(expression), context);
+    }
+
+    public static boolean isSimpleNavigationChain( Object tree ) throws OgnlException
+    {
+        return isSimpleNavigationChain(tree, createDefaultContext(null));
+    }
+
+    public static boolean isSimpleNavigationChain( String expression ) throws OgnlException
+    {
+        return isSimpleNavigationChain(parseExpression(expression), createDefaultContext(null));
+    }
+
+      /** You can't make one of these. */
+    private Ognl()
+    {
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlContext.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlContext.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlContext.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlContext.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,587 @@
+//--------------------------------------------------------------------------
+//	Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
+//  All rights reserved.
+//
+//	Redistribution and use in source and binary forms, with or without
+//  modification, are permitted provided that the following conditions are
+//  met:
+//
+//	Redistributions of source code must retain the above copyright notice,
+//  this list of conditions and the following disclaimer.
+//	Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//	Neither the name of the Drew Davidson nor the names of its contributors
+//  may be used to endorse or promote products derived from this software
+//  without specific prior written permission.
+//
+//	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+//  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+//  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+//  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+//  DAMAGE.
+//--------------------------------------------------------------------------
+package org.apache.ibatis.ognl;
+
+import java.util.*;
+
+/**
+ * This class defines the execution context for an OGNL expression
+ * @author Luke Blanshard (blanshlu@netscape.net)
+ * @author Drew Davidson (drew@ognl.org)
+ */
+public class OgnlContext extends Object implements Map
+{
+    public static final String          CONTEXT_CONTEXT_KEY = "context";
+    public static final String          ROOT_CONTEXT_KEY = "root";
+    public static final String          THIS_CONTEXT_KEY = "this";
+    public static final String          TRACE_EVALUATIONS_CONTEXT_KEY = "_traceEvaluations";
+    public static final String          LAST_EVALUATION_CONTEXT_KEY = "_lastEvaluation";
+    public static final String          KEEP_LAST_EVALUATION_CONTEXT_KEY = "_keepLastEvaluation";
+    public static final String          CLASS_RESOLVER_CONTEXT_KEY = "_classResolver";
+    public static final String          TYPE_CONVERTER_CONTEXT_KEY = "_typeConverter";
+    public static final String          MEMBER_ACCESS_CONTEXT_KEY = "_memberAccess";
+
+    private static final String         PROPERTY_KEY_PREFIX = "ognl";
+    private static boolean              DEFAULT_TRACE_EVALUATIONS = false;
+    private static boolean              DEFAULT_KEEP_LAST_EVALUATION = false;
+
+    public static final ClassResolver   DEFAULT_CLASS_RESOLVER = new DefaultClassResolver();
+    public static final TypeConverter   DEFAULT_TYPE_CONVERTER = new DefaultTypeConverter();
+    public static final MemberAccess    DEFAULT_MEMBER_ACCESS = new DefaultMemberAccess(false);
+
+    private static Map                  RESERVED_KEYS = new HashMap(11);
+
+    private Object                      root;
+    private Object                      currentObject;
+    private Node                        currentNode;
+    private boolean                     traceEvaluations = DEFAULT_TRACE_EVALUATIONS;
+    private Evaluation                  rootEvaluation;
+    private Evaluation                  currentEvaluation;
+    private Evaluation                  lastEvaluation;
+    private boolean                     keepLastEvaluation = DEFAULT_KEEP_LAST_EVALUATION;
+    private Map                         values = new HashMap(23);
+    private ClassResolver               classResolver = DEFAULT_CLASS_RESOLVER;
+    private TypeConverter               typeConverter = DEFAULT_TYPE_CONVERTER;
+    private MemberAccess                memberAccess = DEFAULT_MEMBER_ACCESS;
+
+    static
+    {
+        String          s;
+
+        RESERVED_KEYS.put(CONTEXT_CONTEXT_KEY, null);
+        RESERVED_KEYS.put(ROOT_CONTEXT_KEY, null);
+        RESERVED_KEYS.put(THIS_CONTEXT_KEY, null);
+        RESERVED_KEYS.put(TRACE_EVALUATIONS_CONTEXT_KEY, null);
+        RESERVED_KEYS.put(LAST_EVALUATION_CONTEXT_KEY, null);
+        RESERVED_KEYS.put(KEEP_LAST_EVALUATION_CONTEXT_KEY, null);
+        RESERVED_KEYS.put(CLASS_RESOLVER_CONTEXT_KEY, null);
+        RESERVED_KEYS.put(TYPE_CONVERTER_CONTEXT_KEY, null);
+        RESERVED_KEYS.put(MEMBER_ACCESS_CONTEXT_KEY, null);
+
+        try {
+            if ((s = System.getProperty(PROPERTY_KEY_PREFIX + ".traceEvaluations")) != null) {
+                DEFAULT_TRACE_EVALUATIONS = Boolean.valueOf(s.trim()).booleanValue();
+            }
+            if ((s = System.getProperty(PROPERTY_KEY_PREFIX + ".keepLastEvaluation")) != null) {
+                DEFAULT_KEEP_LAST_EVALUATION = Boolean.valueOf(s.trim()).booleanValue();
+            }
+        } catch (SecurityException ex) {
+            // restricted access environment, just keep defaults
+        }
+    }
+
+    /**
+        Constructs a new OgnlContext with the default class resolver, type converter and
+        member access.
+     */
+    public OgnlContext()
+    {
+        super();
+    }
+
+    /**
+        Constructs a new OgnlContext with the given class resolver, type converter and
+        member access.  If any of these parameters is null the default will be used.
+     */
+    public OgnlContext(ClassResolver classResolver, TypeConverter typeConverter, MemberAccess memberAccess)
+    {
+        this();
+        if (classResolver != null) {
+            this.classResolver = classResolver;
+        }
+        if (typeConverter != null) {
+            this.typeConverter = typeConverter;
+        }
+        if (memberAccess != null) {
+            this.memberAccess = memberAccess;
+        }
+    }
+
+    public OgnlContext(Map values)
+    {
+        super();
+        this.values = values;
+    }
+
+    public OgnlContext(ClassResolver classResolver, TypeConverter typeConverter, MemberAccess memberAccess, Map values)
+    {
+        this(classResolver, typeConverter, memberAccess);
+        this.values = values;
+    }
+
+    public void setValues(Map value)
+    {
+        for (Iterator it = value.keySet().iterator(); it.hasNext();) {
+            Object      k = it.next();
+
+            values.put(k, value.get(k));
+        }
+    }
+
+    public Map getValues()
+    {
+        return values;
+    }
+
+    public void setClassResolver(ClassResolver value)
+    {
+        if (value == null) {
+            throw new IllegalArgumentException("cannot set ClassResolver to null");
+        }
+        classResolver = value;
+    }
+
+    public ClassResolver getClassResolver()
+    {
+        return classResolver;
+    }
+
+    public void setTypeConverter(TypeConverter value)
+    {
+        if (value == null) {
+            throw new IllegalArgumentException("cannot set TypeConverter to null");
+        }
+        typeConverter = value;
+    }
+
+    public TypeConverter getTypeConverter()
+    {
+        return typeConverter;
+    }
+
+    public void setMemberAccess(MemberAccess value)
+    {
+        if (value == null) {
+            throw new IllegalArgumentException("cannot set MemberAccess to null");
+        }
+        memberAccess = value;
+    }
+
+    public MemberAccess getMemberAccess()
+    {
+        return memberAccess;
+    }
+
+    public void setRoot(Object value)
+    {
+        root = value;
+    }
+
+    public Object getRoot()
+    {
+        return root;
+    }
+
+    public boolean getTraceEvaluations()
+    {
+        return traceEvaluations;
+    }
+
+    public void setTraceEvaluations(boolean value)
+    {
+        traceEvaluations = value;
+    }
+
+    public Evaluation getLastEvaluation()
+    {
+        return lastEvaluation;
+    }
+
+    public void setLastEvaluation(Evaluation value)
+    {
+        lastEvaluation = value;
+    }
+
+    /**
+        This method can be called when the last evaluation has been used
+        and can be returned for reuse in the free pool maintained by the
+        runtime.  This is not a necessary step, but is useful for keeping
+        memory usage down.  This will recycle the last evaluation and then
+        set the last evaluation to null.
+     */
+    public void recycleLastEvaluation()
+    {
+        OgnlRuntime.getEvaluationPool().recycleAll(lastEvaluation);
+        lastEvaluation = null;
+    }
+
+    /**
+        Returns true if the last evaluation that was done on this
+        context is retained and available through <code>getLastEvaluation()</code>.
+        The default is true.
+     */
+    public boolean getKeepLastEvaluation()
+    {
+        return keepLastEvaluation;
+    }
+
+    /**
+        Sets whether the last evaluation that was done on this
+        context is retained and available through <code>getLastEvaluation()</code>.
+        The default is true.
+     */
+    public void setKeepLastEvaluation(boolean value)
+    {
+        keepLastEvaluation = value;
+    }
+
+    public void setCurrentObject(Object value)
+    {
+        currentObject = value;
+    }
+
+    public Object getCurrentObject()
+    {
+        return currentObject;
+    }
+
+    public void setCurrentNode(Node value)
+    {
+        currentNode = value;
+    }
+
+    public Node getCurrentNode()
+    {
+        return currentNode;
+    }
+
+    /**
+        Gets the current Evaluation from the top of the stack.
+        This is the Evaluation that is in process of evaluating.
+     */
+    public Evaluation getCurrentEvaluation()
+    {
+        return currentEvaluation;
+    }
+
+    public void setCurrentEvaluation(Evaluation value)
+    {
+        currentEvaluation = value;
+    }
+
+    /**
+        Gets the root of the evaluation stack.
+        This Evaluation contains the node representing
+        the root expression and the source is the root
+        source object.
+     */
+    public Evaluation getRootEvaluation()
+    {
+        return rootEvaluation;
+    }
+
+    public void setRootEvaluation(Evaluation value)
+    {
+        rootEvaluation = value;
+    }
+
+    /**
+        Returns the Evaluation at the relative index given.  This should be
+        zero or a negative number as a relative reference back up the evaluation
+        stack.  Therefore getEvaluation(0) returns the current Evaluation.
+     */
+    public Evaluation getEvaluation(int relativeIndex)
+    {
+        Evaluation      result = null;
+
+        if (relativeIndex <= 0) {
+            result = currentEvaluation;
+            while ((++relativeIndex < 0) && (result != null)) {
+                result = result.getParent();
+            }
+        }
+        return result;
+    }
+
+    /**
+        Pushes a new Evaluation onto the stack.  This is done
+        before a node evaluates.  When evaluation is complete
+        it should be popped from the stack via <code>popEvaluation()</code>.
+     */
+    public void pushEvaluation(Evaluation value)
+    {
+        if (currentEvaluation != null) {
+            currentEvaluation.addChild(value);
+        } else {
+            setRootEvaluation(value);
+        }
+        setCurrentEvaluation(value);
+    }
+
+    /**
+        Pops the current Evaluation off of the top of the stack.
+        This is done after a node has completed its evaluation.
+     */
+    public Evaluation popEvaluation()
+    {
+        Evaluation      result;
+
+        result = currentEvaluation;
+        setCurrentEvaluation(result.getParent());
+        if (currentEvaluation == null) {
+            setLastEvaluation(getKeepLastEvaluation() ? result : null);
+            setRootEvaluation(null);
+            setCurrentNode(null);
+        }
+        return result;
+    }
+
+    /*================= Map interface =================*/
+    public int size()
+    {
+        return values.size();
+    }
+
+    public boolean isEmpty()
+    {
+        return values.isEmpty();
+    }
+
+    public boolean containsKey(Object key)
+    {
+        return values.containsKey(key);
+    }
+
+    public boolean containsValue(Object value)
+    {
+        return values.containsValue(value);
+    }
+
+    public Object get(Object key)
+    {
+        Object      result;
+
+        if (RESERVED_KEYS.containsKey(key)) {
+            if (key.equals(OgnlContext.THIS_CONTEXT_KEY)) {
+                result = getCurrentObject();
+            } else {
+                if (key.equals(OgnlContext.ROOT_CONTEXT_KEY)) {
+                    result = getRoot();
+                } else {
+                    if (key.equals(OgnlContext.CONTEXT_CONTEXT_KEY)) {
+                        result = this;
+                    } else {
+                        if (key.equals(OgnlContext.TRACE_EVALUATIONS_CONTEXT_KEY)) {
+                            result = getTraceEvaluations() ? Boolean.TRUE : Boolean.FALSE;
+                        } else {
+                            if (key.equals(OgnlContext.LAST_EVALUATION_CONTEXT_KEY)) {
+                                result = getLastEvaluation();
+                            } else {
+                                if (key.equals(OgnlContext.KEEP_LAST_EVALUATION_CONTEXT_KEY)) {
+                                    result = getKeepLastEvaluation() ? Boolean.TRUE : Boolean.FALSE;
+                                } else {
+                                    if (key.equals(OgnlContext.CLASS_RESOLVER_CONTEXT_KEY)) {
+                                        result = getClassResolver();
+                                    } else {
+                                        if (key.equals(OgnlContext.TYPE_CONVERTER_CONTEXT_KEY)) {
+                                            result = getTypeConverter();
+                                        } else {
+                                            if (key.equals(OgnlContext.MEMBER_ACCESS_CONTEXT_KEY)) {
+                                                result = getMemberAccess();
+                                            } else {
+                                                throw new IllegalArgumentException("unknown reserved key '" + key + "'");
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } else {
+            result = values.get(key);
+        }
+        return result;
+    }
+
+    public Object put(Object key, Object value)
+    {
+        Object      result;
+
+        if (RESERVED_KEYS.containsKey(key)) {
+            if (key.equals(OgnlContext.THIS_CONTEXT_KEY)) {
+                result = getCurrentObject();
+                setCurrentObject(value);
+            } else {
+                if (key.equals(OgnlContext.ROOT_CONTEXT_KEY)) {
+                    result = getRoot();
+                    setRoot(value);
+                } else {
+                    if (key.equals(OgnlContext.CONTEXT_CONTEXT_KEY)) {
+                        throw new IllegalArgumentException("can't change " + OgnlContext.CONTEXT_CONTEXT_KEY + " in context");
+                    } else {
+                        if (key.equals(OgnlContext.TRACE_EVALUATIONS_CONTEXT_KEY)) {
+                            result = getTraceEvaluations() ? Boolean.TRUE : Boolean.FALSE;
+                            setTraceEvaluations(OgnlOps.booleanValue(value));
+                        } else {
+                            if (key.equals(OgnlContext.LAST_EVALUATION_CONTEXT_KEY)) {
+                                result = getLastEvaluation();
+                                lastEvaluation = (Evaluation)value;
+                            } else {
+                                if (key.equals(OgnlContext.KEEP_LAST_EVALUATION_CONTEXT_KEY)) {
+                                    result = getKeepLastEvaluation() ? Boolean.TRUE : Boolean.FALSE;
+                                    setKeepLastEvaluation(OgnlOps.booleanValue(value));
+                                } else {
+                                    if (key.equals(OgnlContext.CLASS_RESOLVER_CONTEXT_KEY)) {
+                                        result = getClassResolver();
+                                        setClassResolver((ClassResolver)value);
+                                    } else {
+                                        if (key.equals(OgnlContext.TYPE_CONVERTER_CONTEXT_KEY)) {
+                                            result = getTypeConverter();
+                                            setTypeConverter((TypeConverter)value);
+                                        } else {
+                                            if (key.equals(OgnlContext.MEMBER_ACCESS_CONTEXT_KEY)) {
+                                                result = getMemberAccess();
+                                                setMemberAccess((MemberAccess)value);
+                                            } else {
+                                                throw new IllegalArgumentException("unknown reserved key '" + key + "'");
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } else {
+            result = values.put(key, value);
+        }
+        return result;
+    }
+
+    public Object remove(Object key)
+    {
+        Object      result;
+
+        if (RESERVED_KEYS.containsKey(key)) {
+            if (key.equals(OgnlContext.THIS_CONTEXT_KEY)) {
+                result = getCurrentObject();
+                setCurrentObject(null);
+            } else {
+                if (key.equals(OgnlContext.ROOT_CONTEXT_KEY)) {
+                    result = getRoot();
+                    setRoot(null);
+                } else {
+                    if (key.equals(OgnlContext.CONTEXT_CONTEXT_KEY)) {
+                        throw new IllegalArgumentException("can't remove " + OgnlContext.CONTEXT_CONTEXT_KEY + " from context");
+                    } else {
+                        if (key.equals(OgnlContext.TRACE_EVALUATIONS_CONTEXT_KEY)) {
+                            throw new IllegalArgumentException("can't remove " + OgnlContext.TRACE_EVALUATIONS_CONTEXT_KEY + " from context");
+                        } else {
+                            if (key.equals(OgnlContext.LAST_EVALUATION_CONTEXT_KEY)) {
+                                result = lastEvaluation;
+                                setLastEvaluation(null);
+                            } else {
+                                if (key.equals(OgnlContext.KEEP_LAST_EVALUATION_CONTEXT_KEY)) {
+                                    throw new IllegalArgumentException("can't remove " + OgnlContext.KEEP_LAST_EVALUATION_CONTEXT_KEY + " from context");
+                                } else {
+                                    if (key.equals(OgnlContext.CLASS_RESOLVER_CONTEXT_KEY)) {
+                                        result = getClassResolver();
+                                        setClassResolver(null);
+                                    } else {
+                                        if (key.equals(OgnlContext.TYPE_CONVERTER_CONTEXT_KEY)) {
+                                            result = getTypeConverter();
+                                            setTypeConverter(null);
+                                        } else {
+                                            if (key.equals(OgnlContext.MEMBER_ACCESS_CONTEXT_KEY)) {
+                                                result = getMemberAccess();
+                                                setMemberAccess(null);
+                                            } else {
+                                                throw new IllegalArgumentException("unknown reserved key '" + key + "'");
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } else {
+            result = values.remove(key);
+        }
+        return result;
+    }
+
+    public void putAll(Map t)
+    {
+        for (Iterator it = t.keySet().iterator(); it.hasNext();) {
+            Object      k = it.next();
+
+            put(k, t.get(k));
+        }
+    }
+
+    public void clear()
+    {
+        values.clear();
+        setRoot(null);
+        setCurrentObject(null);
+        setRootEvaluation(null);
+        setCurrentEvaluation(null);
+        setLastEvaluation(null);
+        setCurrentNode(null);
+        setClassResolver(DEFAULT_CLASS_RESOLVER);
+        setTypeConverter(DEFAULT_TYPE_CONVERTER);
+        setMemberAccess(DEFAULT_MEMBER_ACCESS);
+    }
+
+    public Set keySet()
+    {
+        /* Should root, currentObject, classResolver, typeConverter & memberAccess be included here? */
+        return values.keySet();
+    }
+
+    public Collection values()
+    {
+        /* Should root, currentObject, classResolver, typeConverter & memberAccess be included here? */
+        return values.values();
+    }
+
+    public Set entrySet()
+    {
+        /* Should root, currentObject, classResolver, typeConverter & memberAccess be included here? */
+        return values.entrySet();
+    }
+
+    public boolean equals(Object o)
+    {
+        return values.equals(o);
+    }
+
+    public int hashCode()
+    {
+        return values.hashCode();
+    }
+}
+

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlException.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlException.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlException.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlException.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,158 @@
+//--------------------------------------------------------------------------
+//	Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
+//  All rights reserved.
+//
+//	Redistribution and use in source and binary forms, with or without
+//  modification, are permitted provided that the following conditions are
+//  met:
+//
+//	Redistributions of source code must retain the above copyright notice,
+//  this list of conditions and the following disclaimer.
+//	Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//	Neither the name of the Drew Davidson nor the names of its contributors
+//  may be used to endorse or promote products derived from this software
+//  without specific prior written permission.
+//
+//	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+//  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+//  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+//  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+//  DAMAGE.
+//--------------------------------------------------------------------------
+package org.apache.ibatis.ognl;
+
+
+/**
+ * Superclass for OGNL exceptions, incorporating an optional encapsulated exception.
+ * @author Luke Blanshard (blanshlu@netscape.net)
+ * @author Drew Davidson (drew@ognl.org)
+ */
+public class OgnlException extends Exception
+{
+      /**
+       * The root evaluation of the expression when the exception was thrown
+       */
+    private Evaluation  evaluation;
+
+      /**
+       * Why this exception was thrown.
+       * @serial
+       */
+    private Throwable reason;
+
+      /** Constructs an OgnlException with no message or encapsulated exception. */
+    public OgnlException()
+    {
+        this( null, null );
+    }
+
+      /**
+       * Constructs an OgnlException with the given message but no encapsulated exception.
+       * @param msg the exception's detail message
+       */
+    public OgnlException( String msg )
+    {
+        this( msg, null );
+    }
+
+      /**
+       * Constructs an OgnlException with the given message and encapsulated exception.
+       * @param msg     the exception's detail message
+       * @param reason  the encapsulated exception
+       */
+    public OgnlException( String msg, Throwable reason )
+    {
+        super( msg );
+        this.reason = reason;
+    }
+
+      /**
+       * Returns the encapsulated exception, or null if there is none.
+       * @return the encapsulated exception
+       */
+    public Throwable getReason()
+    {
+        return reason;
+    }
+
+    /**
+        Returns the Evaluation that was the root evaluation when the exception was
+        thrown.
+     */
+    public Evaluation getEvaluation()
+    {
+        return evaluation;
+    }
+
+    /**
+        Sets the Evaluation that was current when this exception was thrown.
+     */
+    public void setEvaluation(Evaluation value)
+    {
+        evaluation = value;
+    }
+
+      /**
+       * Returns a string representation of this exception.
+       * @return a string representation of this exception
+       */
+    public String toString()
+    {
+        if ( reason == null )
+            return super.toString();
+        return super.toString() + " [" + reason + "]";
+    }
+
+
+      /**
+       * Prints the stack trace for this (and possibly the encapsulated) exception on
+       * System.err.
+       */
+    public void printStackTrace()
+    {
+        printStackTrace( System.err );
+    }
+
+      /**
+       * Prints the stack trace for this (and possibly the encapsulated) exception on the
+       * given print stream.
+       */
+    public void printStackTrace(java.io.PrintStream s)
+    {
+	synchronized (s)
+          {
+            super.printStackTrace(s);
+            if ( reason != null ) {
+                s.println(  "/-- Encapsulated exception ------------\\" );
+                reason.printStackTrace(s);
+                s.println( "\\--------------------------------------/" );
+            }
+          }
+    }
+
+      /**
+       * Prints the stack trace for this (and possibly the encapsulated) exception on the
+       * given print writer.
+       */
+    public void printStackTrace(java.io.PrintWriter s)
+    {
+	synchronized (s)
+          {
+            super.printStackTrace(s);
+            if ( reason != null ) {
+                s.println(  "/-- Encapsulated exception ------------\\" );
+                reason.printStackTrace(s);
+                s.println( "\\--------------------------------------/" );
+            }
+          }
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlInvokePermission.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlInvokePermission.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlInvokePermission.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlInvokePermission.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,56 @@
+//--------------------------------------------------------------------------
+//	Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
+//  All rights reserved.
+//
+//  Redistribution and use in source and binary forms, with or without
+//  modification, are permitted provided that the following conditions are
+//  met:
+//
+//  Redistributions of source code must retain the above copyright notice,
+//  this list of conditions and the following disclaimer.
+//  Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//  Neither the name of the Drew Davidson nor the names of its contributors
+//  may be used to endorse or promote products derived from this software
+//  without specific prior written permission.
+//
+//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+//  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+//  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+//  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+//  DAMAGE.
+//--------------------------------------------------------------------------
+package org.apache.ibatis.ognl;
+
+import java.security.*;
+
+/**
+ * BasicPermission subclass that defines a permission token for invoking
+ * methods within OGNL.  This does not override any methods (except
+ * constructors) and does not implement actions.  It is similar in spirit
+ * to the {@link java.lang.reflect.ReflectPermission} class in that it
+ * guards access to methods.
+ * @author Luke Blanshard (blanshlu@netscape.net)
+ * @author Drew Davidson (drew@ognl.org)
+ */
+public class OgnlInvokePermission extends BasicPermission
+{
+    public OgnlInvokePermission(String name)
+    {
+        super(name);
+    }
+
+    public OgnlInvokePermission(String name, String actions)
+    {
+        super(name, actions);
+    }
+}
+