Package ognl.enhance

Class ExpressionCompiler

  • All Implemented Interfaces:
    OgnlExpressionCompiler

    public class ExpressionCompiler
    extends java.lang.Object
    implements OgnlExpressionCompiler
    Responsible for managing/providing functionality related to compiling generated java source expressions via bytecode enhancements for a given ognl expression.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      protected int _classCounter  
      protected java.util.Map _loaders
      ClassLoader instances.
      protected javassist.ClassPool _pool
      Javassist class definition poool.
      static java.lang.String PRE_CAST
      Key used to store any java source string casting statements in the OgnlContext during class compilation.
    • Constructor Summary

      Constructors 
      Constructor Description
      ExpressionCompiler()
      Default constructor, does nothing.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      static void addCastString​(OgnlContext context, java.lang.String cast)
      Used by castExpression(ognl.OgnlContext, ognl.Node, String) to store the cast java source string in to the current OgnlContext.
      java.lang.String castExpression​(OgnlContext context, Node expression, java.lang.String body)
      Used primarily by AST types like ASTChain where foo.bar.id type references may need to be cast multiple times in order to properly resolve the members in a compiled statement.
      void compileExpression​(OgnlContext context, Node expression, java.lang.Object root)
      The core method executed to compile a specific expression.
      boolean containsMethod​(java.lang.reflect.Method m, java.lang.Class clazz)
      Helper utility method used by compiler to help resolve class->method mappings during method calls to OgnlExpressionCompiler.getSuperOrInterfaceClass(java.lang.reflect.Method, Class).
      java.lang.String createLocalReference​(OgnlContext context, java.lang.String expression, java.lang.Class type)
      Method is used for expressions where multiple inner parameter method calls in generated java source strings cause javassit failures.
      protected java.lang.String generateGetter​(OgnlContext context, javassist.CtClass newClass, javassist.CtClass objClass, javassist.ClassPool pool, javassist.CtMethod valueGetter, Node expression, java.lang.Object root)  
      protected java.lang.String generateOgnlGetter​(javassist.CtClass clazz, javassist.CtMethod valueGetter, javassist.CtField node)
      Fail safe getter creation when normal compilation fails.
      protected java.lang.String generateOgnlSetter​(javassist.CtClass clazz, javassist.CtMethod valueSetter, javassist.CtField node)
      Fail safe setter creation when normal compilation fails.
      protected java.lang.String generateSetter​(OgnlContext context, javassist.CtClass newClass, javassist.CtClass objClass, javassist.ClassPool pool, javassist.CtMethod valueSetter, Node expression, java.lang.Object root)  
      static java.lang.String getCastString​(java.lang.Class type)
      Returns the appropriate casting expression (minus parens) for the specified class type.
      protected EnhancedClassLoader getClassLoader​(OgnlContext context)
      Creates a ClassLoader instance compatible with the javassist classloader and normal OGNL class resolving semantics.
      java.lang.String getClassName​(java.lang.Class clazz)
      Gets a javassist safe class string for the given class instance.
      protected javassist.ClassPool getClassPool​(OgnlContext context, EnhancedClassLoader loader)
      Gets either a new or existing ClassPool for use in compiling javassist classes.
      protected javassist.CtClass getCtClass​(java.lang.Class searchClass)
      Loads a new class definition via javassist for the specified class.
      java.lang.Class getInterfaceClass​(java.lang.Class clazz)
      Used in places where the preferred OgnlExpressionCompiler.getSuperOrInterfaceClass(java.lang.reflect.Method, Class) isn't possible because the method isn't known for a class.
      static java.lang.String getRootExpression​(Node expression, java.lang.Object root, OgnlContext context)
      Convenience method called by many different property/method resolving AST types to get a root expression resolving string for the given node.
      java.lang.Class getRootExpressionClass​(Node rootNode, OgnlContext context)
      For a given root object type returns the base class type to be used in root referenced expressions.
      java.lang.Class getSuperOrInterfaceClass​(java.lang.reflect.Method m, java.lang.Class clazz)
      For the given Method and class finds the highest level interface class this combination can be cast to.
      static boolean shouldCast​(Node expression)
      Used by getRootExpression(ognl.Node, Object, ognl.OgnlContext) to determine if the expression needs to be cast at all.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • PRE_CAST

        public static final java.lang.String PRE_CAST
        Key used to store any java source string casting statements in the OgnlContext during class compilation.
        See Also:
        Constant Field Values
      • _loaders

        protected java.util.Map _loaders
        ClassLoader instances.
      • _pool

        protected javassist.ClassPool _pool
        Javassist class definition poool.
      • _classCounter

        protected int _classCounter
    • Constructor Detail

      • ExpressionCompiler

        public ExpressionCompiler()
        Default constructor, does nothing.
    • Method Detail

      • addCastString

        public static void addCastString​(OgnlContext context,
                                         java.lang.String cast)
        Used by castExpression(ognl.OgnlContext, ognl.Node, String) to store the cast java source string in to the current OgnlContext. This will either add to the existing string present if it already exists or create a new instance and store it using the static key of PRE_CAST.
        Parameters:
        context - The current execution context.
        cast - The java source string to store in to the context.
      • getCastString

        public static java.lang.String getCastString​(java.lang.Class type)
        Returns the appropriate casting expression (minus parens) for the specified class type.

        For instance, if given an Integer object the string "java.lang.Integer" would be returned. For an array of primitive ints "int[]" and so on..

        Parameters:
        type - The class to cast a string expression for.
        Returns:
        The converted raw string version of the class name.
      • getRootExpression

        public static java.lang.String getRootExpression​(Node expression,
                                                         java.lang.Object root,
                                                         OgnlContext context)
        Convenience method called by many different property/method resolving AST types to get a root expression resolving string for the given node. The callers are mostly ignorant and rely on this method to properly determine if the expression should be cast at all and take the appropriate actions if it should.
        Parameters:
        expression - The node to check and generate a root expression to if necessary.
        root - The root object for this execution.
        context - The current execution context.
        Returns:
        Either an empty string or a root path java source string compatible with javassist compilations from the root object up to the specified Node.
      • shouldCast

        public static boolean shouldCast​(Node expression)
        Used by getRootExpression(ognl.Node, Object, ognl.OgnlContext) to determine if the expression needs to be cast at all.
        Parameters:
        expression - The node to check against.
        Returns:
        Yes if the node type should be cast - false otherwise.
      • castExpression

        public java.lang.String castExpression​(OgnlContext context,
                                               Node expression,
                                               java.lang.String body)
        Description copied from interface: OgnlExpressionCompiler
        Used primarily by AST types like ASTChain where foo.bar.id type references may need to be cast multiple times in order to properly resolve the members in a compiled statement.

        This method should be using the various OgnlContext.getCurrentType() / OgnlContext.getCurrentAccessor() methods to inspect the type stack and properly cast to the right classes - but only when necessary.

        Specified by:
        castExpression in interface OgnlExpressionCompiler
        Parameters:
        context - The current execution context.
        expression - The node being checked for casting.
        body - The java source string generated by the given node.
        Returns:
        The body string parameter plus any additional casting syntax needed to make the expression resolvable.
      • getClassName

        public java.lang.String getClassName​(java.lang.Class clazz)
        Description copied from interface: OgnlExpressionCompiler
        Gets a javassist safe class string for the given class instance. This is especially useful for handling array vs. normal class casting strings.
        Specified by:
        getClassName in interface OgnlExpressionCompiler
        Parameters:
        clazz - The class to get a string equivalent javassist compatible string reference for.
        Returns:
        The string equivalent of the class.
      • getSuperOrInterfaceClass

        public java.lang.Class getSuperOrInterfaceClass​(java.lang.reflect.Method m,
                                                        java.lang.Class clazz)
        Description copied from interface: OgnlExpressionCompiler
        For the given Method and class finds the highest level interface class this combination can be cast to.
        Specified by:
        getSuperOrInterfaceClass in interface OgnlExpressionCompiler
        Parameters:
        m - The method the class must implement.
        clazz - The current class being worked with.
        Returns:
        The highest level interface / class that the referenced Method is declared in.
      • containsMethod

        public boolean containsMethod​(java.lang.reflect.Method m,
                                      java.lang.Class clazz)
        Helper utility method used by compiler to help resolve class->method mappings during method calls to OgnlExpressionCompiler.getSuperOrInterfaceClass(java.lang.reflect.Method, Class).
        Parameters:
        m - The method to check for existance of.
        clazz - The class to check for the existance of a matching method definition to the method passed in.
        Returns:
        True if the class contains the specified method, false otherwise.
      • getInterfaceClass

        public java.lang.Class getInterfaceClass​(java.lang.Class clazz)
        Description copied from interface: OgnlExpressionCompiler
        Used in places where the preferred OgnlExpressionCompiler.getSuperOrInterfaceClass(java.lang.reflect.Method, Class) isn't possible because the method isn't known for a class. Attempts to upcast the given class to the next available non-private accessible class so that compiled expressions can reference the interface class of an instance so as not to be compiled in to overly specific statements.
        Specified by:
        getInterfaceClass in interface OgnlExpressionCompiler
        Parameters:
        clazz - The class to attempt to find a compatible interface for.
        Returns:
        The same class if no higher level interface could be matched against or the interface equivalent class.
      • getRootExpressionClass

        public java.lang.Class getRootExpressionClass​(Node rootNode,
                                                      OgnlContext context)
        Description copied from interface: OgnlExpressionCompiler
        For a given root object type returns the base class type to be used in root referenced expressions. This helps in some instances where the root objects themselves are compiled javassist instances that need more generic class equivalents to cast to.
        Specified by:
        getRootExpressionClass in interface OgnlExpressionCompiler
        Parameters:
        rootNode - The root expression node.
        context - The current execution context.
        Returns:
        The root expression class type to cast to for this node.
      • compileExpression

        public void compileExpression​(OgnlContext context,
                                      Node expression,
                                      java.lang.Object root)
                               throws java.lang.Exception
        Description copied from interface: OgnlExpressionCompiler
        The core method executed to compile a specific expression. It is expected that this expression always return a Node with a non null Node.getAccessor() instance - unless an exception is thrown by the method or the statement wasn't compilable in this instance because of missing/null objects in the expression. These instances may in some cases continue to call this compilation method until the expression is resolvable.
        Specified by:
        compileExpression in interface OgnlExpressionCompiler
        Parameters:
        context - The context of execution.
        expression - The pre-parsed root expression node to compile.
        root - The root object for the expression - may be null in many instances so some implementations may exit
        Throws:
        java.lang.Exception - If an error occurs compiling the expression and no strategy has been implemented to handle incremental expression compilation for incomplete expression members.
      • generateGetter

        protected java.lang.String generateGetter​(OgnlContext context,
                                                  javassist.CtClass newClass,
                                                  javassist.CtClass objClass,
                                                  javassist.ClassPool pool,
                                                  javassist.CtMethod valueGetter,
                                                  Node expression,
                                                  java.lang.Object root)
                                           throws java.lang.Exception
        Throws:
        java.lang.Exception
      • createLocalReference

        public java.lang.String createLocalReference​(OgnlContext context,
                                                     java.lang.String expression,
                                                     java.lang.Class type)
        Description copied from interface: OgnlExpressionCompiler
        Method is used for expressions where multiple inner parameter method calls in generated java source strings cause javassit failures. It is hacky and cumbersome to have to generate expressions this way but it's the only current known way to make javassist happy.

        Takes an expression block generated by a node and creates a new method on the base object being compiled so that sufficiently complicated sub expression blocks can be broken out in to distinct methods to be referenced by the core accessor / setter methods in the base compiled root object.

        Specified by:
        createLocalReference in interface OgnlExpressionCompiler
        Parameters:
        context - The current execution context.
        expression - The java source expression to dump in to a seperate method reference.
        type - The return type that should be specified for the new method.
        Returns:
        The method name that will be used to reference the sub expression in place of the actual sub expression itself.
      • generateSetter

        protected java.lang.String generateSetter​(OgnlContext context,
                                                  javassist.CtClass newClass,
                                                  javassist.CtClass objClass,
                                                  javassist.ClassPool pool,
                                                  javassist.CtMethod valueSetter,
                                                  Node expression,
                                                  java.lang.Object root)
                                           throws java.lang.Exception
        Throws:
        java.lang.Exception
      • generateOgnlGetter

        protected java.lang.String generateOgnlGetter​(javassist.CtClass clazz,
                                                      javassist.CtMethod valueGetter,
                                                      javassist.CtField node)
                                               throws java.lang.Exception
        Fail safe getter creation when normal compilation fails.
        Parameters:
        clazz - The javassist class the new method should be attached to.
        valueGetter - The method definition the generated code will be contained within.
        node - The root expression node.
        Returns:
        The generated source string for this method, the method will still be added via the javassist API either way so this is really a convenience for exception reporting / debugging.
        Throws:
        java.lang.Exception - If a javassist error occurs.
      • generateOgnlSetter

        protected java.lang.String generateOgnlSetter​(javassist.CtClass clazz,
                                                      javassist.CtMethod valueSetter,
                                                      javassist.CtField node)
                                               throws java.lang.Exception
        Fail safe setter creation when normal compilation fails.
        Parameters:
        clazz - The javassist class the new method should be attached to.
        valueSetter - The method definition the generated code will be contained within.
        node - The root expression node.
        Returns:
        The generated source string for this method, the method will still be added via the javassist API either way so this is really a convenience for exception reporting / debugging.
        Throws:
        java.lang.Exception - If a javassist error occurs.
      • getClassLoader

        protected EnhancedClassLoader getClassLoader​(OgnlContext context)
        Creates a ClassLoader instance compatible with the javassist classloader and normal OGNL class resolving semantics.
        Parameters:
        context - The current execution context.
        Returns:
        The created ClassLoader instance.
      • getCtClass

        protected javassist.CtClass getCtClass​(java.lang.Class searchClass)
                                        throws javassist.NotFoundException
        Loads a new class definition via javassist for the specified class.
        Parameters:
        searchClass - The class to load.
        Returns:
        The javassist class equivalent.
        Throws:
        javassist.NotFoundException - When the class definition can't be found.
      • getClassPool

        protected javassist.ClassPool getClassPool​(OgnlContext context,
                                                   EnhancedClassLoader loader)
        Gets either a new or existing ClassPool for use in compiling javassist classes. A new class path object is inserted in to the returned ClassPool using the passed in loader instance if a new pool needs to be created.
        Parameters:
        context - The current execution context.
        loader - The ClassLoader instance to use - as returned by getClassLoader(ognl.OgnlContext).
        Returns:
        The existing or new ClassPool instance.