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 [12/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/...

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ognl.jjt
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ognl.jjt?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ognl.jjt (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/ognl.jjt Sat Aug  9 23:00:18 2008
@@ -0,0 +1,687 @@
+//--------------------------------------------------------------------------
+//	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.
+//--------------------------------------------------------------------------
+
+/*
+ * This file defines the syntax of OGNL, the Object-Graph Navigation Language.  This
+ * language was devised by Drew Davidson, who called it Key-Value Coding Language.  Luke
+ * Blanshard then made up the new name and reimplemented it using ANTLR, refining and
+ * polishing the language a bit on the way.  Drew maintained the system for a couple of
+ * years; then Luke converted the ANTLR grammar to JavaCC, to eliminate the run-time
+ * dependency on ANTLR.
+ *
+ * See package.html for a description of the language.
+ */
+
+options {
+      // Parser options
+    LOOKAHEAD           = 1;
+    STATIC              = false;
+    JAVA_UNICODE_ESCAPE = true;
+    UNICODE_INPUT       = true;
+
+      // Tree options
+    MULTI             = true;
+    NODE_DEFAULT_VOID = true;
+}
+
+PARSER_BEGIN(OgnlParser)
+
+package ognl;
+
+import java.math.*;
+
+/**
+ * OgnlParser is a JavaCC parser class; it translates OGNL expressions into abstract
+ * syntax trees (ASTs) that can then be interpreted by the getValue and setValue methods.
+ */
+public class OgnlParser
+{
+}
+
+PARSER_END(OgnlParser)
+
+
+
+
+/**
+ * This is the top-level construct of OGNL.
+ */
+Node topLevelExpression() : {}
+{
+    expression() <EOF> { return jjtree.rootNode(); }
+}
+
+// sequence (level 14)
+void expression() : {}
+{
+    assignmentExpression() ( "," assignmentExpression() #Sequence(2) )*
+}
+
+// assignment expression (level 13)
+void assignmentExpression() : {}
+{
+    conditionalTestExpression() [ "=" assignmentExpression() #Assign(2) ]
+}
+
+// conditional test (level 12)
+void conditionalTestExpression() : {}
+{
+    logicalOrExpression()
+        [ "?" conditionalTestExpression() ":" conditionalTestExpression() #Test(3) ]
+}
+
+// logical or (||)  (level 11)
+void logicalOrExpression() : {}
+{
+    logicalAndExpression() (("||" | "or") logicalAndExpression() #Or(2) )*
+}
+
+
+// logical and (&&)  (level 10)
+void logicalAndExpression() : {}
+{
+    inclusiveOrExpression() (("&&" | "and") inclusiveOrExpression() #And(2) )*
+}
+
+
+// bitwise or non-short-circuiting or (|)  (level 9)
+void inclusiveOrExpression() : {}
+{
+    exclusiveOrExpression() (("|" | "bor") exclusiveOrExpression() #BitOr(2) )*
+}
+
+
+// exclusive or (^)  (level 8)
+void exclusiveOrExpression() : {}
+{
+    andExpression() (("^" | "xor") andExpression() #Xor(2) )*
+}
+
+
+// bitwise or non-short-circuiting and (&)  (level 7)
+void andExpression() : {}
+{
+    equalityExpression() (("&" | "band") equalityExpression() #BitAnd(2) )*
+}
+
+
+// equality/inequality (==/!=) (level 6)
+void equalityExpression() : {}
+{
+    relationalExpression()
+    (
+        ("==" | "eq") relationalExpression() #Eq(2)
+     |
+        ("!=" | "neq") relationalExpression() #NotEq(2)
+    )*
+}
+
+
+// boolean relational expressions (level 5)
+void relationalExpression() : {}
+{
+    shiftExpression()
+    (
+        ("<" | "lt") shiftExpression() #Less(2)
+     |
+        (">" | "gt") shiftExpression() #Greater(2)
+     |
+        ("<=" | "lte") shiftExpression() #LessEq(2)
+     |
+        (">=" | "gte") shiftExpression() #GreaterEq(2)
+     |
+        "in" shiftExpression() #In(2)
+     |
+        "not" "in" shiftExpression() #NotIn(2)
+    )*
+}
+
+
+// bit shift expressions (level 4)
+void shiftExpression() : {}
+{
+    additiveExpression()
+    (
+        ("<<" | "shl") additiveExpression() #ShiftLeft(2)
+     |
+        (">>" | "shr") additiveExpression() #ShiftRight(2)
+     |
+        (">>>" | "ushr") additiveExpression() #UnsignedShiftRight(2)
+    )*
+}
+
+
+// binary addition/subtraction (level 3)
+void additiveExpression() : {}
+{
+    multiplicativeExpression()
+    (
+        "+" multiplicativeExpression() #Add(2)
+     |
+        "-" multiplicativeExpression() #Subtract(2)
+    )*
+}
+
+
+// multiplication/division/remainder (level 2)
+void multiplicativeExpression() : {}
+{
+    unaryExpression()
+    (
+        "*" unaryExpression() #Multiply(2)
+     |
+        "/" unaryExpression() #Divide(2)
+     |
+        "%" unaryExpression() #Remainder(2)
+    )*
+}
+
+// unary (level 1)
+void unaryExpression() : {
+    StringBuffer sb;
+    Token t;
+    ASTInstanceof ionode;
+}
+{
+    (
+        "-" unaryExpression() #Negate(1)
+     |
+        "+" unaryExpression() // Just leave it there
+     |
+        "~" unaryExpression() #BitNegate(1)
+     |
+        ("!" | "not") unaryExpression() #Not(1)
+     |
+        navigationChain()
+        [
+            "instanceof"
+            t = <IDENT>  { sb = new StringBuffer(t.image); ionode = jjtThis; } #Instanceof(1)
+            (   "." t = <IDENT>         { sb.append('.').append( t.image ); }
+            )*                          { ionode.setTargetType( new String(sb) ); }
+        ]
+    )
+}
+
+
+// navigation chain: property references, method calls, projections, selections, etc.
+void navigationChain() : {}
+{
+    primaryExpression()
+    (   "."
+        ( /* Prevent the "eval" ambiguity from issuing a warning; see discussion below. */
+            ( LOOKAHEAD(2) methodCall() | propertyName() )
+              // Also handle "{", which requires a lookahead of 2.
+        |   ( LOOKAHEAD(2) projection() | selection() )
+        |   "(" expression() ")"
+        ) #Chain(2)
+
+    |   index() #Chain(2)
+
+    |   "(" expression() ")" #Eval(2)
+
+            /* Using parentheses to indicate evaluation of the current
+               object makes this language ambiguous, because the
+               expression "ident(args)" could be seen as a single
+               method call or as a property name followed by an
+               evaluation.  We always put the method call first and
+               turn off the ambiguity warning; we always want to
+               interpret this as a method call. */
+
+    )*
+}
+
+
+void primaryExpression() : {
+    Token   t;
+    String  className = null;
+}
+{
+    (
+        (<CHAR_LITERAL> | <BACK_CHAR_LITERAL> | <STRING_LITERAL> | <INT_LITERAL> | <FLT_LITERAL>)
+                                                { jjtThis.setValue( token_source.literalValue ); } #Const(0)
+     |
+        "true"                                  { jjtThis.setValue( Boolean.TRUE ); }  #Const(0)
+     |
+        "false"                                 { jjtThis.setValue( Boolean.FALSE ); } #Const(0)
+     |
+        "null" #Const(0)                        // Null is the default value in an ASTConst
+     |
+        LOOKAHEAD(2) "#this"                 { jjtThis.setName( "this" ); } #ThisVarRef(0)
+     |
+        LOOKAHEAD(2) "#root"                 { jjtThis.setName( "root" ); } #RootVarRef(0)
+     |
+        LOOKAHEAD(2) "#" t=<IDENT>              { jjtThis.setName( t.image ); } #VarRef(0)
+     |
+        LOOKAHEAD(2) ":" "[" expression() "]"   { jjtThis.setValue( jjtThis.jjtGetChild(0) ); } #Const(1)
+     |
+        staticReference()
+     |
+        LOOKAHEAD(2) constructorCall()
+     |
+          // Prevent the "eval" ambiguity from issuing a warning; see discussion elsewhere.
+        ( LOOKAHEAD(2) methodCall() | propertyName() )
+     |
+        index()
+     |
+        "(" expression() ")"
+     |
+        "{" [assignmentExpression() ("," assignmentExpression())*] #List "}"
+     |
+        LOOKAHEAD(2) ( "#" (className=classReference())? "{" [keyValueExpression() ("," keyValueExpression())*] { jjtThis.setClassName(className); } "}" ) #Map
+    )
+}
+
+void keyValueExpression() : {}
+{
+        ( assignmentExpression() (":" assignmentExpression())? ) #KeyValue
+}
+
+void staticReference() : {
+    String className = "java.lang.Math";
+    Token t;
+}
+{
+    className=classReference()
+        ( // Prevent the "eval" ambiguity from issuing a warning; see discussion elsewhere.
+            LOOKAHEAD(2)
+            staticMethodCall( className )
+         |
+            t=<IDENT>               { jjtThis.init( className, t.image ); } #StaticField(0)
+        )
+}
+
+String classReference(): {
+    String      result = "java.lang.Math";
+}
+{
+    "@" ( result=className() )? "@" { return result; }
+}
+
+String className(): {
+    Token t;
+    StringBuffer result;
+}
+{
+    t=<IDENT>               { result = new StringBuffer( t.image ); }
+    ( "." t=<IDENT>         { result.append('.').append( t.image ); }
+    )*                      { return new String(result); }
+}
+
+void constructorCall() #Ctor : {
+    String className;
+    Token t;
+    StringBuffer sb;
+}
+{
+    "new" className=className()
+        (
+            LOOKAHEAD(2) (
+                "(" [ assignmentExpression() ( "," assignmentExpression() )* ] ")"
+                    {
+                        jjtThis.setClassName(className);
+                    }
+            )
+            |
+            LOOKAHEAD(2) (
+                "[" "]" "{" [assignmentExpression() ("," assignmentExpression())*] #List "}"
+                    {
+                        jjtThis.setClassName(className);
+                        jjtThis.setArray(true);
+                    }
+            )
+            |
+            LOOKAHEAD(2) (
+                "[" assignmentExpression() "]"
+                    {
+                        jjtThis.setClassName(className);
+                        jjtThis.setArray(true);
+                    }
+            )
+        )
+}
+
+void propertyName() #Property : {
+    Token t;
+}
+{
+    t=<IDENT> { jjtThis.setValue( t.image ); } #Const
+}
+
+void staticMethodCall( String className ) #StaticMethod : {
+    Token t;
+}
+{
+    t=<IDENT> "(" [ assignmentExpression() ( "," assignmentExpression() )* ] ")"
+                                        { jjtThis.init( className, t.image ); }
+}
+
+void methodCall() #Method : {
+    Token t;
+}
+{
+    t=<IDENT> "(" [ assignmentExpression() ( "," assignmentExpression() )* ] ")"
+                                        { jjtThis.setMethodName( t.image ); }
+}
+
+/**
+ * Apply an expression to all elements of a collection, creating a new collection
+ * as the result.
+ */
+void projection() #Project : {}
+{
+    "{" expression() "}"
+}
+
+void selection() : {}
+{
+        LOOKAHEAD(2) selectAll()
+    |
+        LOOKAHEAD(2) selectFirst()
+    |
+        LOOKAHEAD(2) selectLast()
+}
+
+/**
+ * Apply a boolean expression to all elements of a collection, creating a new collection
+ * containing those elements for which the expression returned true.
+ */
+void selectAll() #Select : {}
+{
+    "{" "?" expression() "}"
+}
+
+/**
+ * Apply a boolean expression to all elements of a collection, creating a new collection
+ * containing those elements for the first element for which the expression returned true.
+ */
+void selectFirst() #SelectFirst : {}
+{
+    "{" "^" expression() "}"
+}
+
+/**
+ * Apply a boolean expression to all elements of a collection, creating a new collection
+ * containing those elements for the first element for which the expression returned true.
+ */
+void selectLast() #SelectLast : {}
+{
+    "{" "$" expression() "}"
+}
+
+void index() #Property : {}
+{
+    "[" expression() "]" { jjtThis.setIndexedAccess(true); }
+ |
+    <DYNAMIC_SUBSCRIPT> { jjtThis.setValue( token_source.literalValue ); } #Const
+    {
+        jjtThis.setIndexedAccess(true);
+    }
+}
+
+// LEXER PRODUCTIONS
+
+TOKEN_MGR_DECLS:
+{
+      /** Holds the last value computed by a constant token. */
+    Object literalValue;
+      /** Holds the last character escaped or in a character literal. */
+    private char charValue;
+      /** Holds char literal start token. */
+    private char charLiteralStartQuote;
+      /** Holds the last string literal parsed. */
+    private StringBuffer stringBuffer;
+
+      /** Converts an escape sequence into a character value. */
+    private char escapeChar()
+    {
+        int ofs = image.length() - 1;
+        switch ( image.charAt(ofs) ) {
+            case 'n':   return '\n';
+            case 'r':   return '\r';
+            case 't':   return '\t';
+            case 'b':   return '\b';
+            case 'f':   return '\f';
+            case '\\':  return '\\';
+            case '\'':  return '\'';
+            case '\"':  return '\"';
+        }
+
+          // Otherwise, it's an octal number.  Find the backslash and convert.
+        while ( image.charAt(--ofs) != '\\' )
+          {}
+        int value = 0;
+        while ( ++ofs < image.length() )
+            value = (value << 3) | (image.charAt(ofs) - '0');
+        return (char) value;
+    }
+
+    private Object makeInt()
+    {
+        Object  result;
+        String  s = image.toString();
+        int     base = 10;
+
+        if ( s.charAt(0) == '0' )
+            base = (s.length() > 1 && (s.charAt(1) == 'x' || s.charAt(1) == 'X'))? 16 : 8;
+        if ( base == 16 )
+            s = s.substring(2); // Trim the 0x off the front
+        switch ( s.charAt(s.length()-1) ) {
+            case 'l': case 'L':
+                result = Long.valueOf( s.substring(0,s.length()-1), base );
+                break;
+
+            case 'h': case 'H':
+                result = new BigInteger( s.substring(0,s.length()-1), base );
+                break;
+
+            default:
+                result = Integer.valueOf( s, base );
+                break;
+        }
+        return result;
+    }
+
+    private Object makeFloat()
+    {
+        String s = image.toString();
+        switch ( s.charAt(s.length()-1) ) {
+            case 'f': case 'F':
+                return Float.valueOf( s );
+
+            case 'b': case 'B':
+                return new BigDecimal( s.substring(0,s.length()-1) );
+
+            case 'd': case 'D':
+            default:
+                return Double.valueOf( s );
+        }
+    }
+}
+
+// Whitespace -- ignored
+SKIP:
+{  " " | "\t" | "\f" | "\r" | "\n" }
+
+// An identifier.
+TOKEN:
+{
+    < IDENT: <LETTER> (<LETTER>|<DIGIT>)* >
+ |
+    < #LETTER: [
+       "\u0024",
+       "\u0041"-"\u005a",
+       "\u005f",
+       "\u0061"-"\u007a",
+       "\u00c0"-"\u00d6",
+       "\u00d8"-"\u00f6",
+       "\u00f8"-"\u00ff",
+       "\u0100"-"\u1fff",
+       "\u3040"-"\u318f",
+       "\u3300"-"\u337f",
+       "\u3400"-"\u3d2d",
+       "\u4e00"-"\u9fff",
+       "\uf900"-"\ufaff"
+      ] >
+ |
+    < #DIGIT:
+      [
+       "\u0030"-"\u0039",
+       "\u0660"-"\u0669",
+       "\u06f0"-"\u06f9",
+       "\u0966"-"\u096f",
+       "\u09e6"-"\u09ef",
+       "\u0a66"-"\u0a6f",
+       "\u0ae6"-"\u0aef",
+       "\u0b66"-"\u0b6f",
+       "\u0be7"-"\u0bef",
+       "\u0c66"-"\u0c6f",
+       "\u0ce6"-"\u0cef",
+       "\u0d66"-"\u0d6f",
+       "\u0e50"-"\u0e59",
+       "\u0ed0"-"\u0ed9",
+       "\u1040"-"\u1049"
+      ] >
+}
+
+/**
+ * Token for "dynamic subscripts", which are one of: [^], [|], [$], and [*].  The
+ * appropriate constant from the DynamicSubscript class is stored in the token manager's
+ * "value" field.
+ */
+TOKEN:
+{
+    < DYNAMIC_SUBSCRIPT: "[" ["^","|","$","*"] "]" >
+        {
+            switch (image.charAt(1)) {
+              case '^': literalValue = DynamicSubscript.first; break;
+              case '|': literalValue = DynamicSubscript.mid;   break;
+              case '$': literalValue = DynamicSubscript.last;  break;
+              case '*': literalValue = DynamicSubscript.all;   break;
+          }
+        }
+}
+
+/**
+ * Character and string literals, whose object value is stored in the token manager's
+ * "literalValue" field.
+ */
+MORE:
+{
+    "`"     : WithinBackCharLiteral
+ |
+    "'"     { stringBuffer = new StringBuffer(); }: WithinCharLiteral
+ |
+    "\""    { stringBuffer = new StringBuffer(); }: WithinStringLiteral
+}
+
+<WithinCharLiteral> MORE:
+{
+    < ESC: "\\" ( ["n","r","t","b","f","\\","'","`","\""]
+                | (["0"-"3"])? ["0"-"7"] (["0"-"7"])?
+                )
+    >
+        { charValue = escapeChar(); stringBuffer.append(charValue); }
+ |
+    < (~["'","\\"]) >
+        { charValue = image.charAt( image.length()-1 ); stringBuffer.append(charValue); }
+}
+
+<WithinCharLiteral> TOKEN:
+{
+    < CHAR_LITERAL: "'">
+        {
+            if (stringBuffer.length() == 1) {
+                literalValue = new Character( charValue );
+            } else {
+                literalValue = new String( stringBuffer );
+            }
+        }
+        : DEFAULT
+}
+
+<WithinBackCharLiteral> MORE:
+{
+    < BACK_CHAR_ESC: <ESC> >
+        { charValue = escapeChar(); }
+ |
+    < (~["`","\\"]) >
+        { charValue = image.charAt( image.length()-1 ); }
+}
+
+<WithinBackCharLiteral> TOKEN:
+{
+    < BACK_CHAR_LITERAL: "`">
+        { literalValue = new Character( charValue ); }: DEFAULT
+}
+
+<WithinStringLiteral> MORE:
+{
+    < STRING_ESC: <ESC> >
+        { stringBuffer.append( escapeChar() ); }
+ |
+    < (~["\"","\\"]) >
+        { stringBuffer.append( image.charAt(image.length()-1) ); }
+}
+
+<WithinStringLiteral> TOKEN:
+{
+    <STRING_LITERAL: "\"">
+        { literalValue = new String( stringBuffer ); }
+        : DEFAULT
+}
+
+/**
+ * Integer or real Numeric literal, whose object value is stored in the token manager's
+ * "literalValue" field.
+ */
+TOKEN:
+{
+    < INT_LITERAL:
+        ( "0" (["0"-"7"])* | ["1"-"9"] (["0"-"9"])* | "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ )
+        (["l","L","h","H"])?
+    >
+        { literalValue =
+        makeInt(); }
+ |
+    < FLT_LITERAL:
+        ( <DEC_FLT> (<EXPONENT>)? (<FLT_SUFF>)?
+        | <DEC_DIGITS> <EXPONENT> (<FLT_SUFF>)?
+        | <DEC_DIGITS> <FLT_SUFF>
+        )
+    >
+        { literalValue = makeFloat(); }
+
+ |  < #DEC_FLT: (["0"-"9"])+ "." (["0"-"9"])* | "." (["0"-"9"])+ >
+ |  < #DEC_DIGITS: (["0"-"9"])+ >
+ |  < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
+ |  < #FLT_SUFF: ["d","D","f","F","b","B"] >
+}
+

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/package.html
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/package.html?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/package.html (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/package.html Sat Aug  9 23:00:18 2008
@@ -0,0 +1,52 @@
+<html>
+<!--
+
+      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.
+
+-->
+<head>
+<title>OGNL Overview</title>
+<body>
+    <p>OGNL stands for Object-Graph Navigation Language; it is an expression language
+    for getting and setting properties of Java objects. You use the same expression
+    for both getting and setting the value of a property.</p>
+
+    <p>OGNL started out as a way to set up associations between UI
+    components and controllers using property names.  As the desire for
+    more complicated associations grew, Drew Davidson created what he
+    called KVCL, for Key-Value Coding Language, egged on by Luke
+    Blanshard.  Luke then reimplemented the language using ANTLR, came up
+    with the new name, and, egged on by Drew, filled it out to its current
+    state.</p>
+
+    <p>We pronounce OGNL as a word, like the last syllables of a drunken
+    pronunciation of "orthogonal" or like "ogg-null".</p>
+</body>
+</html>

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ArithmeticAndLogicalOperatorsTest.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ArithmeticAndLogicalOperatorsTest.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ArithmeticAndLogicalOperatorsTest.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ArithmeticAndLogicalOperatorsTest.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,217 @@
+//--------------------------------------------------------------------------
+//  Copyright (c) 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.math.BigDecimal;
+import java.math.BigInteger;
+import junit.framework.TestSuite;
+
+public class ArithmeticAndLogicalOperatorsTest extends OgnlTestCase
+{
+    private static Object[][]       TESTS = {
+                                          // Double-valued arithmetic expressions
+                                        { "-1d", new Double(-1) },
+                                        { "+1d", new Double(1) },
+                                        { "--1f", new Float(1) },
+                                        { "2*2.0", new Double(4) },
+                                        { "5/2.", new Double(2.5) },
+                                        { "5+2D", new Double(7) },
+                                        { "5f-2F", new Float(3) },
+                                        { "5.+2*3", new Double(11) },
+                                        { "(5.+2)*3", new Double(21) },
+
+                                          // BigDecimal-valued arithmetic expressions
+                                        { "-1b", new BigDecimal(-1) },
+                                        { "+1b", new BigDecimal(1) },
+                                        { "--1b", new BigDecimal(1) },
+                                        { "2*2.0b", new BigDecimal("4.0") },
+                                        { "5/2.B", new BigDecimal(2) },
+                                        { "5.0B/2", new BigDecimal(2.5) },
+                                        { "5+2b", new BigDecimal(7) },
+                                        { "5-2B", new BigDecimal(3) },
+                                        { "5.+2b*3", new BigDecimal(11) },
+                                        { "(5.+2b)*3", new BigDecimal(21) },
+
+                                          // Integer-valued arithmetic expressions
+                                        { "-1", new Integer(-1) },
+                                        { "+1", new Integer(1) },
+                                        { "--1", new Integer(1) },
+                                        { "2*2", new Integer(4) },
+                                        { "5/2", new Integer(2) },
+                                        { "5+2", new Integer(7) },
+                                        { "5-2", new Integer(3) },
+                                        { "5+2*3", new Integer(11) },
+                                        { "(5+2)*3", new Integer(21) },
+                                        { "~1", new Integer(~1) },
+                                        { "5%2", new Integer(1) },
+                                        { "5<<2", new Integer(20) },
+                                        { "5>>2", new Integer(1) },
+                                        { "5>>1+1", new Integer(1) },
+                                        { "-5>>>2", new Integer(-5>>>2) },
+                                        { "-5L>>>2", new Long(-5L>>>2) },
+                                        { "5. & 3", new Double(1) },
+                                        { "5 ^3", new Integer(6) },
+                                        { "5l&3|5^3", new Long(7) },
+                                        { "5&(3|5^3)", new Integer(5) },
+
+                                          // BigInteger-valued arithmetic expressions
+                                        { "-1h", BigInteger.valueOf(-1) },
+                                        { "+1H", BigInteger.valueOf(1) },
+                                        { "--1h", BigInteger.valueOf(1) },
+                                        { "2h*2", BigInteger.valueOf(4) },
+                                        { "5/2h", BigInteger.valueOf(2) },
+                                        { "5h+2", BigInteger.valueOf(7) },
+                                        { "5-2h", BigInteger.valueOf(3) },
+                                        { "5+2H*3", BigInteger.valueOf(11) },
+                                        { "(5+2H)*3", BigInteger.valueOf(21) },
+                                        { "~1h", BigInteger.valueOf(~1) },
+                                        { "5h%2", BigInteger.valueOf(1) },
+                                        { "5h<<2", BigInteger.valueOf(20) },
+                                        { "5h>>2", BigInteger.valueOf(1) },
+                                        { "5h>>1+1", BigInteger.valueOf(1) },
+                                        { "-5h>>>2", BigInteger.valueOf(-2) },
+                                        { "5.b & 3", BigInteger.valueOf(1) },
+                                        { "5h ^3", BigInteger.valueOf(6) },
+                                        { "5h&3|5^3", BigInteger.valueOf(7) },
+                                        { "5H&(3|5^3)", BigInteger.valueOf(5) },
+
+                                          // Logical expressions
+                                        { "!1", Boolean.FALSE },
+                                        { "!null", Boolean.TRUE },
+                                        { "5<2", Boolean.FALSE },
+                                        { "5>2", Boolean.TRUE },
+                                        { "5<=5", Boolean.TRUE },
+                                        { "5>=3", Boolean.TRUE },
+                                        { "5<-5>>>2", Boolean.TRUE },
+                                        { "5==5.0", Boolean.TRUE },
+                                        { "5!=5.0", Boolean.FALSE },
+                                        { "null in {true,false,null}", Boolean.TRUE },
+                                        { "null not in {true,false,null}", Boolean.FALSE },
+                                        { "null in {true,false,null}.toArray()", Boolean.TRUE },
+                                        { "5 in {true,false,null}", Boolean.FALSE },
+                                        { "5 not in {true,false,null}", Boolean.TRUE },
+                                        { "5 instanceof java.lang.Integer", Boolean.TRUE },
+                                        { "5. instanceof java.lang.Integer", Boolean.FALSE },
+
+                                          // Logical expressions (string versions)
+                                        { "2 or 0", new Integer(2) },
+                                        { "1 and 0", new Integer(0) },
+                                        { "1 bor 0", new Integer(1) },
+                                        { "1 xor 0", new Integer(1) },
+                                        { "1 band 0", new Integer(0) },
+                                        { "1 eq 1", Boolean.TRUE },
+                                        { "1 neq 1", Boolean.FALSE },
+                                        { "1 lt 5", Boolean.TRUE },
+                                        { "1 lte 5", Boolean.TRUE },
+                                        { "1 gt 5", Boolean.FALSE },
+                                        { "1 gte 5", Boolean.FALSE },
+                                        { "1 lt 5", Boolean.TRUE },
+                                        { "1 shl 2", new Integer(4) },
+                                        { "4 shr 2", new Integer(1) },
+                                        { "4 ushr 2", new Integer(1) },
+                                        { "not null", Boolean.TRUE },
+                                        { "not 1", Boolean.FALSE },
+
+                                        { "#x > 0", Boolean.TRUE },
+                                        { "#x < 0", Boolean.FALSE },
+                                        { "#x == 0", Boolean.FALSE },
+                                        { "#x == 1", Boolean.TRUE },
+                                        { "0 > #x", Boolean.FALSE },
+                                        { "0 < #x", Boolean.TRUE },
+                                        { "0 == #x", Boolean.FALSE },
+                                        { "1 == #x", Boolean.TRUE },
+                                        { "\"1\" > 0", Boolean.TRUE },
+                                        { "\"1\" < 0", Boolean.FALSE },
+                                        { "\"1\" == 0", Boolean.FALSE },
+                                        { "\"1\" == 1", Boolean.TRUE },
+                                        { "0 > \"1\"", Boolean.FALSE },
+                                        { "0 < \"1\"", Boolean.TRUE },
+                                        { "0 == \"1\"", Boolean.FALSE },
+                                        { "1 == \"1\"", Boolean.TRUE },
+                                        { "#x + 1", "11" },
+                                        { "1 + #x", "11" },
+                                        { "#y == 1", Boolean.TRUE },
+                                        { "#y == \"1\"", Boolean.TRUE },
+                                        { "#y + \"1\"", "11" },
+                                        { "\"1\" + #y", "11" }
+                                    };
+
+    /*===================================================================
+        Public static methods
+      ===================================================================*/
+    public static TestSuite suite()
+    {
+        TestSuite       result = new TestSuite();
+
+        for (int i = 0; i < TESTS.length; i++) {
+            result.addTest(new ArithmeticAndLogicalOperatorsTest((String)TESTS[i][0] + " (" + TESTS[i][1] + ")", null, (String)TESTS[i][0], TESTS[i][1]));
+        }
+        return result;
+    }
+
+    /*===================================================================
+        Constructors
+      ===================================================================*/
+    public ArithmeticAndLogicalOperatorsTest()
+    {
+        super();
+    }
+
+    public ArithmeticAndLogicalOperatorsTest(String name)
+    {
+        super(name);
+    }
+
+    public ArithmeticAndLogicalOperatorsTest(String name, Object root, String expressionString, Object expectedResult, Object setValue, Object expectedAfterSetResult)
+    {
+        super(name, root, expressionString, expectedResult, setValue, expectedAfterSetResult);
+    }
+
+    public ArithmeticAndLogicalOperatorsTest(String name, Object root, String expressionString, Object expectedResult, Object setValue)
+    {
+        super(name, root, expressionString, expectedResult, setValue);
+    }
+
+    public ArithmeticAndLogicalOperatorsTest(String name, Object root, String expressionString, Object expectedResult)
+    {
+        super(name, root, expressionString, expectedResult);
+    }
+
+    /*===================================================================
+        Overridden methods
+      ===================================================================*/
+    protected void setUp()
+    {
+        super.setUp();
+        context.put("x", "1");
+        context.put("y", new BigDecimal(1));
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ArrayCreationTest.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ArrayCreationTest.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ArrayCreationTest.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ArrayCreationTest.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,109 @@
+//--------------------------------------------------------------------------
+//  Copyright (c) 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 junit.framework.TestSuite;
+import org.apache.ibatis.ognl.ExpressionSyntaxException;
+import org.apache.ibatis.ognl.objects.Root;
+import org.apache.ibatis.ognl.objects.Simple;
+
+public class ArrayCreationTest extends OgnlTestCase
+{
+    private static Root             ROOT = new Root();
+
+    private static Object[][]       TESTS = {
+                                        // Array creation
+                                        { ROOT, "new String[] { \"one\", \"two\" }", new String[] { "one", "two" } },
+                                        { ROOT, "new String[] { 1, 2 }", new String[] { "1", "2" } },
+                                        { ROOT, "new Integer[] { \"1\", 2, \"3\" }", new Integer[] { new Integer(1), new Integer(2), new Integer(3) } },
+                                        { ROOT, "new String[10]", new String[10] },
+                                        { ROOT, "new Object[4] { #root, #this }", ExpressionSyntaxException.class },
+                                        { ROOT, "new Object[4]", new Object[4] },
+                                        { ROOT, "new Object[] { #root, #this }", new Object[] { ROOT, ROOT } },
+                                        { ROOT, "new org.apache.ibatis.ognl.objects.Simple[] { new org.apache.ibatis.ognl.objects.Simple(), new org.apache.ibatis.ognl.objects.Simple(\"foo\", 1.0, 2) }", new Simple[] { new Simple(), new Simple("foo", 1.0f, 2) } },
+                                        { ROOT, "new org.apache.ibatis.ognl.objects.Simple[5]", new Simple[5] },
+                                        { ROOT, "new org.apache.ibatis.ognl.objects.Simple(new Object[5])", new Simple(new Object[5]) },
+                                        { ROOT, "new org.apache.ibatis.ognl.objects.Simple(new String[5])", new Simple(new String[5]) },
+                                    };
+
+    /*===================================================================
+        Public static methods
+      ===================================================================*/
+    public static TestSuite suite()
+    {
+        TestSuite       result = new TestSuite();
+
+        for (int i = 0; i < TESTS.length; i++) {
+            if (TESTS[i].length == 3) {
+                result.addTest(new ArrayCreationTest((String)TESTS[i][1], TESTS[i][0], (String)TESTS[i][1], TESTS[i][2]));
+            } else {
+                if (TESTS[i].length == 4) {
+                    result.addTest(new ArrayCreationTest((String)TESTS[i][1], TESTS[i][0], (String)TESTS[i][1], TESTS[i][2], TESTS[i][3]));
+                } else {
+                    if (TESTS[i].length == 5) {
+                        result.addTest(new ArrayCreationTest((String)TESTS[i][1], TESTS[i][0], (String)TESTS[i][1], TESTS[i][2], TESTS[i][3], TESTS[i][4]));
+                    } else {
+                        throw new RuntimeException("don't understand TEST format");
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /*===================================================================
+        Constructors
+      ===================================================================*/
+    public ArrayCreationTest()
+    {
+        super();
+    }
+
+    public ArrayCreationTest(String name)
+    {
+        super(name);
+    }
+
+    public ArrayCreationTest(String name, Object root, String expressionString, Object expectedResult, Object setValue, Object expectedAfterSetResult)
+    {
+        super(name, root, expressionString, expectedResult, setValue, expectedAfterSetResult);
+    }
+
+    public ArrayCreationTest(String name, Object root, String expressionString, Object expectedResult, Object setValue)
+    {
+        super(name, root, expressionString, expectedResult, setValue);
+    }
+
+    public ArrayCreationTest(String name, Object root, String expressionString, Object expectedResult)
+    {
+        super(name, root, expressionString, expectedResult);
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ArrayElementsTest.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ArrayElementsTest.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ArrayElementsTest.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ArrayElementsTest.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,135 @@
+//--------------------------------------------------------------------------
+//  Copyright (c) 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.lang.reflect.*;
+import java.util.*;
+import junit.framework.TestSuite;
+import org.apache.ibatis.ognl.DefaultTypeConverter;
+import org.apache.ibatis.ognl.TypeConverter;
+import org.apache.ibatis.ognl.objects.Root;
+
+public class ArrayElementsTest extends OgnlTestCase
+{
+    private static String[]         STRING_ARRAY = new String[] { "hello", "world" };
+    private static int[]            INT_ARRAY = new int[] { 10, 20 };
+    private static Root             ROOT = new Root();
+
+    private static Object[][]       TESTS = {
+                                          // Array elements test
+                                        { STRING_ARRAY,     "length",       new Integer(2) },
+                                        { STRING_ARRAY,     "#root[1]",     "world" },
+                                        { INT_ARRAY,        "#root[1]",     new Integer(20) },
+                                        { INT_ARRAY,        "#root[1]",     new Integer(20), "50", new Integer(50) },
+                                        { INT_ARRAY,        "#root[1]",     new Integer(50), new String[] { "50", "100" }, new Integer(50) },
+                                        { ROOT,             "intValue",     new Integer(0), new String[] { "50", "100" }, new Integer(50) },
+                                        { ROOT,             "array",        ROOT.getArray(), new String[] { "50", "100" }, new int[] { 50, 100 } },
+                                    };
+
+	/*===================================================================
+		Private static methods
+	  ===================================================================*/
+	/*===================================================================
+		Public static methods
+	  ===================================================================*/
+    public static TestSuite suite()
+    {
+        TestSuite       result = new TestSuite();
+
+        for (int i = 0; i < TESTS.length; i++) {
+            if (TESTS[i].length == 3) {
+                result.addTest(new ArrayElementsTest((String)TESTS[i][1], TESTS[i][0], (String)TESTS[i][1], TESTS[i][2]));
+            } else {
+                if (TESTS[i].length == 4) {
+                    result.addTest(new ArrayElementsTest((String)TESTS[i][1], TESTS[i][0], (String)TESTS[i][1], TESTS[i][2], TESTS[i][3]));
+                } else {
+                    if (TESTS[i].length == 5) {
+                        result.addTest(new ArrayElementsTest((String)TESTS[i][1], TESTS[i][0], (String)TESTS[i][1], TESTS[i][2], TESTS[i][3], TESTS[i][4]));
+                    } else {
+                        throw new RuntimeException("don't understand TEST format");
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+	/*===================================================================
+		Constructors
+	  ===================================================================*/
+	public ArrayElementsTest()
+	{
+	    super();
+	}
+
+	public ArrayElementsTest(String name)
+	{
+	    super(name);
+	}
+
+    public ArrayElementsTest(String name, Object root, String expressionString, Object expectedResult, Object setValue, Object expectedAfterSetResult)
+    {
+        super(name, root, expressionString, expectedResult, setValue, expectedAfterSetResult);
+    }
+
+    public ArrayElementsTest(String name, Object root, String expressionString, Object expectedResult, Object setValue)
+    {
+        super(name, root, expressionString, expectedResult, setValue);
+    }
+
+    public ArrayElementsTest(String name, Object root, String expressionString, Object expectedResult)
+    {
+        super(name, root, expressionString, expectedResult);
+    }
+
+	/*===================================================================
+		Overridden methods
+	  ===================================================================*/
+    protected void setUp()
+    {
+        TypeConverter       arrayConverter;
+
+        super.setUp();
+        arrayConverter = new DefaultTypeConverter()
+            {
+                public Object convertValue(Map context, Object target, Member member, String propertyName, Object value, Class toType)
+                {
+                    if (value.getClass().isArray()) {
+                        if (!toType.isArray()) {
+                            value = Array.get(value, 0);
+                        }
+                    }
+                    return super.convertValue(context, target, member, propertyName, value, toType);
+                }
+            };
+        context.setTypeConverter(arrayConverter);
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ClassMethodTest.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ClassMethodTest.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ClassMethodTest.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ClassMethodTest.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,91 @@
+//--------------------------------------------------------------------------
+//  Copyright (c) 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 junit.framework.TestSuite;
+import org.apache.ibatis.ognl.objects.CorrectedObject;
+
+public class ClassMethodTest extends OgnlTestCase
+{
+    private static CorrectedObject  CORRECTED = new CorrectedObject();
+
+    private static Object[][]       TESTS = {
+                                          // Methods on Class
+                                        { CORRECTED, "getClass().getName()", CORRECTED.getClass().getName() },
+                                        { CORRECTED, "getClass().getInterfaces()", CORRECTED.getClass().getInterfaces() },
+                                        { CORRECTED, "getClass().getInterfaces().length", new Integer(CORRECTED.getClass().getInterfaces().length) },
+                                        { null, "@System@class.getInterfaces()", System.class.getInterfaces() },
+                                        { null, "@Class@class.getName()", Class.class.getName() },
+                                        { null, "@java.awt.image.ImageObserver@class.getName()", java.awt.image.ImageObserver.class.getName() },
+
+                                    };
+
+	/*===================================================================
+		Public static methods
+	  ===================================================================*/
+    public static TestSuite suite()
+    {
+        TestSuite       result = new TestSuite();
+
+        for (int i = 0; i < TESTS.length; i++) {
+            result.addTest(new ClassMethodTest((String)TESTS[i][1], TESTS[i][0], (String)TESTS[i][1], TESTS[i][2]));
+        }
+        return result;
+    }
+
+	/*===================================================================
+		Constructors
+	  ===================================================================*/
+	public ClassMethodTest()
+	{
+	    super();
+	}
+
+	public ClassMethodTest(String name)
+	{
+	    super(name);
+	}
+
+    public ClassMethodTest(String name, Object root, String expressionString, Object expectedResult, Object setValue, Object expectedAfterSetResult)
+    {
+        super(name, root, expressionString, expectedResult, setValue, expectedAfterSetResult);
+    }
+
+    public ClassMethodTest(String name, Object root, String expressionString, Object expectedResult, Object setValue)
+    {
+        super(name, root, expressionString, expectedResult, setValue);
+    }
+
+    public ClassMethodTest(String name, Object root, String expressionString, Object expectedResult)
+    {
+        super(name, root, expressionString, expectedResult);
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/CollectionDirectPropertyTest.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/CollectionDirectPropertyTest.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/CollectionDirectPropertyTest.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/CollectionDirectPropertyTest.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,113 @@
+//--------------------------------------------------------------------------
+//  Copyright (c) 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.*;
+import junit.framework.TestSuite;
+import org.apache.ibatis.ognl.objects.Root;
+
+public class CollectionDirectPropertyTest extends OgnlTestCase
+{
+    private static Root             ROOT = new Root();
+
+    private static Object[][]       TESTS = {
+                                          // Collection direct properties
+                                        { Arrays.asList(new String[]{"hello", "world"}), "size", new Integer(2) },
+                                        { Arrays.asList(new String[]{"hello", "world"}), "isEmpty", Boolean.FALSE },
+                                        { Arrays.asList(new String[]{}), "isEmpty", Boolean.TRUE },
+                                        { Arrays.asList(new String[]{"hello", "world"}), "iterator.next", "hello" },
+                                        { Arrays.asList(new String[]{"hello", "world"}), "iterator.hasNext", Boolean.TRUE },
+                                        { Arrays.asList(new String[]{"hello", "world"}), "#it = iterator, #it.next, #it.next, #it.hasNext", Boolean.FALSE },
+                                        { Arrays.asList(new String[]{"hello", "world"}), "#it = iterator, #it.next, #it.next", "world" },
+                                        { Arrays.asList(new String[]{"hello", "world"}), "size", new Integer(2) },
+                                        { ROOT, "map[\"test\"]", ROOT },
+                                        { ROOT, "map.size", new Integer(ROOT.getMap().size()) },
+                                        { ROOT, "map.keys", ROOT.getMap().keySet() },
+                                        { ROOT, "map.values", ROOT.getMap().values() },
+                                        { ROOT, "map.keys.size", new Integer(ROOT.getMap().keySet().size()) },
+                                        { ROOT, "map[\"size\"]", ROOT.getMap().get("size") },
+                                        { ROOT, "map.isEmpty", ROOT.getMap().isEmpty() ? Boolean.TRUE : Boolean.FALSE },
+                                        { ROOT, "map[\"isEmpty\"]", null },
+                                    };
+
+	/*===================================================================
+		Public static methods
+	  ===================================================================*/
+    public static TestSuite suite()
+    {
+        TestSuite       result = new TestSuite();
+
+        for (int i = 0; i < TESTS.length; i++) {
+            if (TESTS[i].length == 3) {
+                result.addTest(new CollectionDirectPropertyTest((String)TESTS[i][1], TESTS[i][0], (String)TESTS[i][1], TESTS[i][2]));
+            } else {
+                if (TESTS[i].length == 4) {
+                    result.addTest(new CollectionDirectPropertyTest((String)TESTS[i][1], TESTS[i][0], (String)TESTS[i][1], TESTS[i][2], TESTS[i][3]));
+                } else {
+                    if (TESTS[i].length == 5) {
+                        result.addTest(new CollectionDirectPropertyTest((String)TESTS[i][1], TESTS[i][0], (String)TESTS[i][1], TESTS[i][2], TESTS[i][3], TESTS[i][4]));
+                    } else {
+                        throw new RuntimeException("don't understand TEST format");
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+	/*===================================================================
+		Constructors
+	  ===================================================================*/
+	public CollectionDirectPropertyTest()
+	{
+	    super();
+	}
+
+	public CollectionDirectPropertyTest(String name)
+	{
+	    super(name);
+	}
+
+    public CollectionDirectPropertyTest(String name, Object root, String expressionString, Object expectedResult, Object setValue, Object expectedAfterSetResult)
+    {
+        super(name, root, expressionString, expectedResult, setValue, expectedAfterSetResult);
+    }
+
+    public CollectionDirectPropertyTest(String name, Object root, String expressionString, Object expectedResult, Object setValue)
+    {
+        super(name, root, expressionString, expectedResult, setValue);
+    }
+
+    public CollectionDirectPropertyTest(String name, Object root, String expressionString, Object expectedResult)
+    {
+        super(name, root, expressionString, expectedResult);
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ConstantTest.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ConstantTest.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ConstantTest.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ConstantTest.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,108 @@
+//--------------------------------------------------------------------------
+//  Copyright (c) 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.*;
+import junit.framework.TestSuite;
+import org.apache.ibatis.ognl.ExpressionSyntaxException;
+
+public class ConstantTest extends OgnlTestCase
+{
+    private static Object[][]       TESTS = {
+                                        { "12345", new Integer(12345) },
+                                        { "0x100", new Integer(256) },
+                                        { "0xfE", new Integer(254) },
+                                        { "01000", new Integer(512) },
+                                        { "1234L", new Long(1234) },
+                                        { "12.34", new Double(12.34) },
+                                        { ".1234", new Double(.12340000000000) },
+                                        { "12.34f", new Float(12.34f) },
+                                        { "12.", new Double(12) },
+                                        { "12e+1d", new Double(120) },
+                                        { "'x'", new Character('x') },
+                                        { "'\\n'", new Character('\n') },
+                                        { "'\\u048c'", new Character('\u048c') },
+                                        { "'\\47'", new Character('\47') },
+                                        { "'\\367'", new Character('\367') },
+                                        { "'\\367", ExpressionSyntaxException.class },
+                                        { "'\\x'", ExpressionSyntaxException.class },
+                                        { "\"hello world\"", "hello world" },
+                                        { "\"\\u00a0\\u0068ell\\'o\\\\\\n\\r\\f\\t\\b\\\"\\167orld\\\"\"", "\u00a0hell'o\\\n\r\f\t\b\"world\"" },
+                                        { "\"hello world", ExpressionSyntaxException.class },
+                                        { "\"hello\\x world\"", ExpressionSyntaxException.class },
+                                        { "null", null },
+                                        { "true", Boolean.TRUE },
+                                        { "false", Boolean.FALSE },
+                                        { "{ false, true, null, 0, 1. }", Arrays.asList(new Object[] { Boolean.FALSE, Boolean.TRUE, null, new Integer(0), new Double(1) } ) },
+                                        { "'HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"'", "HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"" },
+                                    };
+
+	/*===================================================================
+		Public static methods
+	  ===================================================================*/
+    public static TestSuite suite()
+    {
+        TestSuite       result = new TestSuite();
+
+        for (int i = 0; i < TESTS.length; i++) {
+            result.addTest(new ConstantTest((String)TESTS[i][0] + " (" + TESTS[i][1] + ")", null, (String)TESTS[i][0], TESTS[i][1]));
+        }
+        return result;
+    }
+
+	/*===================================================================
+		Constructors
+	  ===================================================================*/
+	public ConstantTest()
+	{
+	    super();
+	}
+
+	public ConstantTest(String name)
+	{
+	    super(name);
+	}
+
+    public ConstantTest(String name, Object root, String expressionString, Object expectedResult, Object setValue, Object expectedAfterSetResult)
+    {
+        super(name, root, expressionString, expectedResult, setValue, expectedAfterSetResult);
+    }
+
+    public ConstantTest(String name, Object root, String expressionString, Object expectedResult, Object setValue)
+    {
+        super(name, root, expressionString, expectedResult, setValue);
+    }
+
+    public ConstantTest(String name, Object root, String expressionString, Object expectedResult)
+    {
+        super(name, root, expressionString, expectedResult);
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ConstantTreeTest.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ConstantTreeTest.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ConstantTreeTest.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ConstantTreeTest.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,104 @@
+//--------------------------------------------------------------------------
+//  Copyright (c) 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 junit.framework.TestSuite;
+import org.apache.ibatis.ognl.Ognl;
+import org.apache.ibatis.ognl.OgnlException;
+
+public class ConstantTreeTest extends OgnlTestCase
+{
+    public static int               nonFinalStaticVariable = 15;
+
+    private static Object[][]       TESTS = {
+                                        { "true", Boolean.TRUE },
+                                        { "55", Boolean.TRUE },
+                                        { "@java.awt.Color@black", Boolean.TRUE },
+                                        { "@org.apache.ibatis.ognl.ConstantTreeTest@nonFinalStaticVariable", Boolean.FALSE },
+                                        { "@org.apache.ibatis.ognl.ConstantTreeTest@nonFinalStaticVariable + 10", Boolean.FALSE },
+                                        { "55 + 24 + @java.awt.Event@ALT_MASK", Boolean.TRUE },
+                                        { "name", Boolean.FALSE },
+                                        { "name[i]", Boolean.FALSE },
+                                        { "name[i].property", Boolean.FALSE },
+                                        { "name.{? foo }", Boolean.FALSE },
+                                        { "name.{ foo }", Boolean.FALSE },
+                                        { "name.{ 25 }", Boolean.FALSE }
+                                    };
+
+	/*===================================================================
+		Public static methods
+	  ===================================================================*/
+    public static TestSuite suite()
+    {
+        TestSuite       result = new TestSuite();
+
+        for (int i = 0; i < TESTS.length; i++) {
+            result.addTest(new ConstantTreeTest((String)TESTS[i][0] + " (" + TESTS[i][1] + ")", null, (String)TESTS[i][0], TESTS[i][1]));
+        }
+        return result;
+    }
+
+	/*===================================================================
+		Overridden methods
+	  ===================================================================*/
+    protected void runTest() throws OgnlException
+    {
+        assertTrue(Ognl.isConstant(getExpression(), context) == ((Boolean)getExpectedResult()).booleanValue());
+    }
+
+	/*===================================================================
+		Constructors
+	  ===================================================================*/
+	public ConstantTreeTest()
+	{
+	    super();
+	}
+
+	public ConstantTreeTest(String name)
+	{
+	    super(name);
+	}
+
+    public ConstantTreeTest(String name, Object root, String expressionString, Object expectedResult, Object setValue, Object expectedAfterSetResult)
+    {
+        super(name, root, expressionString, expectedResult, setValue, expectedAfterSetResult);
+    }
+
+    public ConstantTreeTest(String name, Object root, String expressionString, Object expectedResult, Object setValue)
+    {
+        super(name, root, expressionString, expectedResult, setValue);
+    }
+
+    public ConstantTreeTest(String name, Object root, String expressionString, Object expectedResult)
+    {
+        super(name, root, expressionString, expectedResult);
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ContextVariableTest.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ContextVariableTest.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ContextVariableTest.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/ContextVariableTest.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,87 @@
+//--------------------------------------------------------------------------
+//  Copyright (c) 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 junit.framework.TestSuite;
+import org.apache.ibatis.ognl.objects.Simple;
+
+public class ContextVariableTest extends OgnlTestCase
+{
+    private static Object           ROOT = new Simple();
+    private static Object[][]       TESTS = {
+                                          // Naming and referring to names
+                                        { "#root", ROOT }, // Special root reference
+                                        { "#this", ROOT }, // Special this reference
+                                        { "#f=5, #s=6, #f + #s", new Integer(11) },
+                                        { "#six=(#five=5, 6), #five + #six", new Integer(11) }, // Dynamic scoping
+                                    };
+
+	/*===================================================================
+		Public static methods
+	  ===================================================================*/
+    public static TestSuite suite()
+    {
+        TestSuite       result = new TestSuite();
+
+        for (int i = 0; i < TESTS.length; i++) {
+            result.addTest(new ContextVariableTest((String)TESTS[i][0] + " (" + TESTS[i][1] + ")", ROOT, (String)TESTS[i][0], TESTS[i][1]));
+        }
+        return result;
+    }
+
+	/*===================================================================
+		Constructors
+	  ===================================================================*/
+	public ContextVariableTest()
+	{
+	    super();
+	}
+
+	public ContextVariableTest(String name)
+	{
+	    super(name);
+	}
+
+    public ContextVariableTest(String name, Object root, String expressionString, Object expectedResult, Object setValue, Object expectedAfterSetResult)
+    {
+        super(name, root, expressionString, expectedResult, setValue, expectedAfterSetResult);
+    }
+
+    public ContextVariableTest(String name, Object root, String expressionString, Object expectedResult, Object setValue)
+    {
+        super(name, root, expressionString, expectedResult, setValue);
+    }
+
+    public ContextVariableTest(String name, Object root, String expressionString, Object expectedResult)
+    {
+        super(name, root, expressionString, expectedResult);
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/CorrectedObjectNullHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/CorrectedObjectNullHandler.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/CorrectedObjectNullHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/CorrectedObjectNullHandler.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,69 @@
+//--------------------------------------------------------------------------
+//	Copyright (c) 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.Map;
+import org.apache.ibatis.ognl.NullHandler;
+
+public class CorrectedObjectNullHandler extends Object implements NullHandler
+{
+    private String          defaultValue;
+
+    /*===================================================================
+        Constructors
+      ===================================================================*/
+    public CorrectedObjectNullHandler(String defaultValue)
+    {
+        super();
+        this.defaultValue = defaultValue;
+    }
+
+    /*===================================================================
+        TypeConverter interface (overridden)
+      ===================================================================*/
+    public Object nullMethodResult(Map context, Object target, String methodName, Object[] args)
+    {
+        if (methodName.equals("getStringValue")) {
+            return defaultValue;
+        }
+        return null;
+    }
+
+    public Object nullPropertyValue(Map context, Object target, Object property)
+    {
+        Object      result = null;
+
+        if (property.equals("stringValue")) {
+            return defaultValue;
+        }
+        return null;
+    }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/IndexAccessTest.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/IndexAccessTest.java?rev=684410&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/IndexAccessTest.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/ognl/IndexAccessTest.java Sat Aug  9 23:00:18 2008
@@ -0,0 +1,87 @@
+//--------------------------------------------------------------------------
+//  Copyright (c) 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 junit.framework.TestSuite;
+import org.apache.ibatis.ognl.MethodFailedException;
+import org.apache.ibatis.ognl.objects.Root;
+
+public class IndexAccessTest extends OgnlTestCase
+{
+    private static Root             ROOT = new Root();
+
+    private static Object[][]       TESTS = {
+                                          // indexed access of with navigation chain (should start back at root)
+                                        { ROOT, "list[index]", ROOT.getList().get(ROOT.getIndex()) },
+                                        { ROOT, "list[size() - 1]", MethodFailedException.class },
+                                    };
+
+	/*===================================================================
+		Public static methods
+	  ===================================================================*/
+    public static TestSuite suite()
+    {
+        TestSuite       result = new TestSuite();
+
+        for (int i = 0; i < TESTS.length; i++) {
+            result.addTest(new IndexAccessTest((String)TESTS[i][1], TESTS[i][0], (String)TESTS[i][1], TESTS[i][2]));
+        }
+        return result;
+    }
+
+	/*===================================================================
+		Constructors
+	  ===================================================================*/
+	public IndexAccessTest()
+	{
+	    super();
+	}
+
+	public IndexAccessTest(String name)
+	{
+	    super(name);
+	}
+
+    public IndexAccessTest(String name, Object root, String expressionString, Object expectedResult, Object setValue, Object expectedAfterSetResult)
+    {
+        super(name, root, expressionString, expectedResult, setValue, expectedAfterSetResult);
+    }
+
+    public IndexAccessTest(String name, Object root, String expressionString, Object expectedResult, Object setValue)
+    {
+        super(name, root, expressionString, expectedResult, setValue);
+    }
+
+    public IndexAccessTest(String name, Object root, String expressionString, Object expectedResult)
+    {
+        super(name, root, expressionString, expectedResult);
+    }
+}