Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/SimpleNode.java URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/SimpleNode.java?rev=684410&view=auto ============================================================================== --- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/SimpleNode.java (added) +++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/SimpleNode.java Sat Aug 9 23:00:18 2008 @@ -0,0 +1,325 @@ +//-------------------------------------------------------------------------- +// 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.*; + +/** + * @author Luke Blanshard ([EMAIL PROTECTED]) + * @author Drew Davidson ([EMAIL PROTECTED]) + */ +public abstract class SimpleNode implements Node, Serializable +{ + protected Node parent; + protected Node[] children; + protected int id; + protected OgnlParser parser; + + private boolean constantValueCalculated; + private boolean hasConstantValue; + private Object constantValue; + + public SimpleNode(int i) { + id = i; + } + + public SimpleNode(OgnlParser p, int i) { + this(i); + parser = p; + } + + public void jjtOpen() { + } + + public void jjtClose() { + } + + public void jjtSetParent(Node n) { parent = n; } + public Node jjtGetParent() { return parent; } + + public void jjtAddChild(Node n, int i) { + if (children == null) { + children = new Node[i + 1]; + } else if (i >= children.length) { + Node c[] = new Node[i + 1]; + System.arraycopy(children, 0, c, 0, children.length); + children = c; + } + children[i] = n; + } + + public Node jjtGetChild(int i) { + return children[i]; + } + + public int jjtGetNumChildren() { + return (children == null) ? 0 : children.length; + } + + /* You can override these two methods in subclasses of SimpleNode to + customize the way the node appears when the tree is dumped. If + your output uses more than one line you should override + toString(String), otherwise overriding toString() is probably all + you need to do. */ + + public String toString() { return OgnlParserTreeConstants.jjtNodeName[id]; } + +// OGNL additions + + public String toString(String prefix) { return prefix + OgnlParserTreeConstants.jjtNodeName[id] + " " + toString(); } + + /* Override this method if you want to customize how the node dumps + out its children. */ + + public void dump(PrintWriter writer, String prefix) { + writer.println(toString(prefix)); + if (children != null) { + for (int i = 0; i < children.length; ++i) { + SimpleNode n = (SimpleNode)children[i]; + if (n != null) { + n.dump(writer, prefix + " "); + } + } + } + } + + public int getIndexInParent() + { + int result = -1; + + if (parent != null) { + int icount = parent.jjtGetNumChildren(); + + for (int i = 0; i < icount; i++) { + if (parent.jjtGetChild(i) == this) { + result = i; + break; + } + } + } + return result; + } + + public Node getNextSibling() + { + Node result = null; + int i = getIndexInParent(); + + if (i >= 0) { + int icount = parent.jjtGetNumChildren(); + + if (i < icount) { + result = parent.jjtGetChild(i + 1); + } + } + return result; + } + + private static String getDepthString(int depth) + { + StringBuffer result = new StringBuffer(""); + + while (depth > 0) { + depth--; + result.append(" "); + } + return new String(result); + } + + protected Object evaluateGetValueBody( OgnlContext context, Object source ) throws OgnlException + { + Object result; + + context.setCurrentObject(source); + context.setCurrentNode(this); + if (!constantValueCalculated) { + constantValueCalculated = true; + hasConstantValue = isConstant(context); + if (hasConstantValue) { + constantValue = getValueBody(context, source); + } + } + return hasConstantValue ? constantValue : getValueBody(context, source); + } + + protected void evaluateSetValueBody( OgnlContext context, Object target, Object value ) throws OgnlException + { + context.setCurrentObject(target); + context.setCurrentNode(this); + setValueBody(context, target, value); + } + + public final Object getValue( OgnlContext context, Object source ) throws OgnlException + { + if (context.getTraceEvaluations()) { + EvaluationPool pool = OgnlRuntime.getEvaluationPool(); + Object result = null; + Throwable evalException = null; + Evaluation evaluation = pool.create(this, source); + + context.pushEvaluation(evaluation); + try { + result = evaluateGetValueBody(context, source); + } catch (OgnlException ex) { + evalException = ex; + throw ex; + } catch (RuntimeException ex) { + evalException = ex; + throw ex; + } finally { + Evaluation eval = context.popEvaluation(); + + eval.setResult(result); + if (evalException != null) { + eval.setException(evalException); + } + if ((evalException == null) && (context.getRootEvaluation() == null) && !context.getKeepLastEvaluation()) { + pool.recycleAll(eval); + } + } + return result; + } else { + return evaluateGetValueBody(context, source); + } + } + + /** Subclasses implement this method to do the actual work of extracting the + appropriate value from the source object. */ + protected abstract Object getValueBody( OgnlContext context, Object source ) throws OgnlException; + + public final void setValue( OgnlContext context, Object target, Object value ) throws OgnlException + { + if (context.getTraceEvaluations()) { + EvaluationPool pool = OgnlRuntime.getEvaluationPool(); + Throwable evalException = null; + Evaluation evaluation = pool.create(this, target, true); + + context.pushEvaluation(evaluation); + try { + evaluateSetValueBody(context, target, value); + } catch (OgnlException ex) { + evalException = ex; + ex.setEvaluation(evaluation); + throw ex; + } catch (RuntimeException ex) { + evalException = ex; + throw ex; + } finally { + Evaluation eval = context.popEvaluation(); + + if (evalException != null) { + eval.setException(evalException); + } + if ((evalException == null) && (context.getRootEvaluation() == null) && !context.getKeepLastEvaluation()) { + pool.recycleAll(eval); + } + } + } else { + evaluateSetValueBody(context, target, value); + } + } + + /** Subclasses implement this method to do the actual work of setting the + appropriate value in the target object. The default implementation + throws an <code>InappropriateExpressionException</code>, meaning that it + cannot be a set expression. + */ + protected void setValueBody( OgnlContext context, Object target, Object value ) throws OgnlException + { + throw new InappropriateExpressionException( this ); + } + + /** + Returns true iff this node is constant without respect to the children. + */ + public boolean isNodeConstant( OgnlContext context ) throws OgnlException + { + return false; + } + + public boolean isConstant( OgnlContext context ) throws OgnlException + { + return isNodeConstant(context); + } + + public boolean isNodeSimpleProperty( OgnlContext context ) throws OgnlException + { + return false; + } + + public boolean isSimpleProperty( OgnlContext context ) throws OgnlException + { + return isNodeSimpleProperty(context); + } + + public boolean isSimpleNavigationChain( OgnlContext context ) throws OgnlException + { + return isSimpleProperty(context); + } + + /** This method may be called from subclasses' jjtClose methods. It flattens the + tree under this node by eliminating any children that are of the same class as + this node and copying their children to this node. */ + protected void flattenTree() + { + boolean shouldFlatten = false; + int newSize = 0; + + for ( int i=0; i < children.length; ++i ) + if ( children[i].getClass() == getClass() ) { + shouldFlatten = true; + newSize += children[i].jjtGetNumChildren(); + } + else + ++newSize; + + if ( shouldFlatten ) + { + Node[] newChildren = new Node[newSize]; + int j = 0; + + for ( int i=0; i < children.length; ++i ) { + Node c = children[i]; + if ( c.getClass() == getClass() ) { + for ( int k=0; k < c.jjtGetNumChildren(); ++k ) + newChildren[j++] = c.jjtGetChild(k); + } + else + newChildren[j++] = c; + } + + if ( j != newSize ) + throw new Error( "Assertion error: " + j + " != " + newSize ); + + this.children = newChildren; + } + } +}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/Token.java URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/Token.java?rev=684410&view=auto ============================================================================== --- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/Token.java (added) +++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/Token.java Sat Aug 9 23:00:18 2008 @@ -0,0 +1,81 @@ +/* Generated By:JavaCC: Do not edit this line. Token.java Version 3.0 */ +package org.apache.ibatis.ognl; + +/** + * Describes the input token stream. + */ + +public class Token { + + /** + * An integer that describes the kind of this token. This numbering + * system is determined by JavaCCParser, and a table of these numbers is + * stored in the file ...Constants.java. + */ + public int kind; + + /** + * beginLine and beginColumn describe the position of the first character + * of this token; endLine and endColumn describe the position of the + * last character of this token. + */ + public int beginLine, beginColumn, endLine, endColumn; + + /** + * The string image of the token. + */ + public String image; + + /** + * A reference to the next regular (non-special) token from the input + * stream. If this is the last token from the input stream, or if the + * token manager has not read tokens beyond this one, this field is + * set to null. This is true only if this token is also a regular + * token. Otherwise, see below for a description of the contents of + * this field. + */ + public Token next; + + /** + * This field is used to access special tokens that occur prior to this + * token, but after the immediately preceding regular (non-special) token. + * If there are no such special tokens, this field is set to null. + * When there are more than one such special token, this field refers + * to the last of these special tokens, which in turn refers to the next + * previous special token through its specialToken field, and so on + * until the first special token (whose specialToken field is null). + * The next fields of special tokens refer to other special tokens that + * immediately follow it (without an intervening regular token). If there + * is no such token, this field is null. + */ + public Token specialToken; + + /** + * Returns the image. + */ + public String toString() + { + return image; + } + + /** + * Returns a new Token object, by default. However, if you want, you + * can create and return subclass objects based on the value of ofKind. + * Simply add the cases to the switch for all those special cases. + * For example, if you have a subclass of Token called IDToken that + * you want to create if ofKind is ID, simlpy add something like : + * + * case MyParserConstants.ID : return new IDToken(); + * + * to the following switch statement. Then you can cast matchedToken + * variable to the appropriate type and use it in your lexical actions. + */ + public static final Token newToken(int ofKind) + { + switch(ofKind) + { + default : return new Token(); + } + } + +} Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/TokenMgrError.java URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/TokenMgrError.java?rev=684410&view=auto ============================================================================== --- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/TokenMgrError.java (added) +++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/TokenMgrError.java Sat Aug 9 23:00:18 2008 @@ -0,0 +1,133 @@ +/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 3.0 */ +package org.apache.ibatis.ognl; + +public class TokenMgrError extends Error +{ + /* + * Ordinals for various reasons why an Error of this type can be thrown. + */ + + /** + * Lexical error occured. + */ + static final int LEXICAL_ERROR = 0; + + /** + * An attempt wass made to create a second instance of a static token manager. + */ + static final int STATIC_LEXER_ERROR = 1; + + /** + * Tried to change to an invalid lexical state. + */ + static final int INVALID_LEXICAL_STATE = 2; + + /** + * Detected (and bailed out of) an infinite loop in the token manager. + */ + static final int LOOP_DETECTED = 3; + + /** + * Indicates the reason why the exception is thrown. It will have + * one of the above 4 values. + */ + int errorCode; + + /** + * Replaces unprintable characters by their espaced (or unicode escaped) + * equivalents in the given string + */ + protected static final String addEscapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case 0 : + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); + } + + /** + * Returns a detailed message for the Error when it is thrown by the + * token manager to indicate a lexical error. + * Parameters : + * EOFSeen : indicates if EOF caused the lexicl error + * curLexState : lexical state in which this error occured + * errorLine : line number when the error occured + * errorColumn : column number when the error occured + * errorAfter : prefix that was seen before this error occured + * curchar : the offending character + * Note: You can customize the lexical error message by modifying this method. + */ + protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) { + return("Lexical error at line " + + errorLine + ", column " + + errorColumn + ". Encountered: " + + (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") + + "after : \"" + addEscapes(errorAfter) + "\""); + } + + /** + * You can also modify the body of this method to customize your error messages. + * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not + * of end-users concern, so you can return something like : + * + * "Internal Error : Please file a bug report .... " + * + * from this method for such cases in the release version of your parser. + */ + public String getMessage() { + return super.getMessage(); + } + + /* + * Constructors of various flavors follow. + */ + + public TokenMgrError() { + } + + public TokenMgrError(String message, int reason) { + super(message); + errorCode = reason; + } + + public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) { + this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason); + } +} Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/TypeConverter.java URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/TypeConverter.java?rev=684410&view=auto ============================================================================== --- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/TypeConverter.java (added) +++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/TypeConverter.java Sat Aug 9 23:00:18 2008 @@ -0,0 +1,58 @@ +//-------------------------------------------------------------------------- +// 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.lang.reflect.Member; +import java.util.Map; + +/** + * Interface for accessing the type conversion facilities within a context. + * @author Luke Blanshard ([EMAIL PROTECTED]) + * @author Drew Davidson ([EMAIL PROTECTED]) + */ +public interface TypeConverter +{ + /** + * Converts the given value to a given type. The OGNL context, target, member and + * name of property being set are given. This method should be able to handle + * conversion in general without any context, target, member or property name specified. + * @param context OGNL context under which the conversion is being done + * @param target target object in which the property is being set + * @param member member (Constructor, Method or Field) being set + * @param propertyName property name being set + * @param value value to be converted + * @param toType type to which value is converted + * @return Converted value of type toType or TypeConverter.NoConversionPossible to indicate that the + conversion was not possible. + */ + public Object convertValue(Map context, Object target, Member member, String propertyName, Object value, Class toType); +} +
