Class TransformContext


  • public class TransformContext
    extends java.lang.Object
    Class used to localise the context information employed when creating a rule from a rule script and using it to transform a method
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      private class  TransformContext.TransformFailure
      private exception class used to throw our way out of the ASM adapter code back into the transform method at the top level.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      Rule createRule​(java.lang.String triggerMethodName, java.lang.String triggerMethodDescriptor)
      called by a check adapter to create a rule specific to a given trigger method.
      void fail​(java.lang.String failMessage, java.lang.String triggerMethodName, java.lang.String triggerMethodDescriptor)
      called by a check or trigger adapter to fail a transform because of a type issue.
      java.lang.String findLeastCommonSuper​(java.lang.String t1, java.lang.String t2)  
      private java.lang.String getKeyTriggerMethodDescriptor​(java.lang.String key)
      return the trigger method descriptor used to construct the supplied rule key
      private java.lang.String getKeyTriggerMethodName​(java.lang.String key)
      return the trigger method name used to construct the supplied rule key
      private org.objectweb.asm.ClassWriter getNonLoadingClassWriter​(int flags)
      get a class writer which will not attempt to load classes.
      private java.lang.String getRuleKey​(java.lang.String triggerMethodName, java.lang.String triggerMethodDescriptor)
      return a unique string key identifying a specific rule compiled against some class and method/signature in the context of a specific class loader
      java.lang.String getTriggerClassName()  
      boolean injectIntoMethod​(java.lang.String name, java.lang.String desc)  
      private java.util.LinkedList<java.lang.String> listInterfaces​(ClassChecker checker)  
      private java.util.LinkedList<java.lang.String> listSupers​(ClassChecker checker)  
      Rule lookupRule​(java.lang.String triggerMethodName, java.lang.String triggerMethodDescriptor)
      called by a trigger adapter to find a rule specific to a given trigger method, expects to find a rule created by the corresponding check adapter.
      boolean matchTargetMethod​(int access, java.lang.String name, java.lang.String desc)  
      private java.lang.String mungeMethodSpecReturnType​(java.lang.String targetMethodSpec)
      detect a method specification which includes a return type preceding the method name and transform it so that the return type is at the end.
      private boolean notifyRules()
      this gets called when a transform attempt completes without any exceptions.
      void parseRule()  
      private void purgeRules()
      this gets called when a transform attempt fails.
      void recordFailedTransform​(java.lang.Throwable th)  
      byte[] transform​(byte[] targetClassBytes)  
      void warn​(java.lang.String triggerMethodName, java.lang.String triggerMethodDescriptor, java.lang.String warningMessage)
      called by a check adapter to warn that a transform was not possible for a potential match target.
      • Methods inherited from class java.lang.Object

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

      • JAVA_METHOD_SPEC_PATTERN

        private static final java.lang.String JAVA_METHOD_SPEC_PATTERN
        pattern used to identify target method specs which include a return type preceding the method name and parameter type list. note that we can only handle a return type in cases where the parameter type list is also specified.
        See Also:
        Constant Field Values
      • triggerClassName

        private java.lang.String triggerClassName
      • targetMethodName

        private java.lang.String targetMethodName
      • targetDescriptor

        private java.lang.String targetDescriptor
      • loader

        private java.lang.ClassLoader loader
      • failed

        private boolean failed
      • ruleMap

        private java.util.HashMap<java.lang.String,​Rule> ruleMap
        a hashmap indexing Rule instances using key classname.methodnameandsig@loaderhashcode. rules are added to this map when they are created and removed when the transform is recorded as having succeeded or failed. a method check adapter will create a rule when it begins a method scan and a method trigger adpater will look it up in order to reuse it
      • firstRule

        private Rule firstRule
    • Method Detail

      • transform

        public byte[] transform​(byte[] targetClassBytes)
      • parseRule

        public void parseRule()
                       throws java.lang.Exception
        Throws:
        java.lang.Exception
      • lookupRule

        public Rule lookupRule​(java.lang.String triggerMethodName,
                               java.lang.String triggerMethodDescriptor)
        called by a trigger adapter to find a rule specific to a given trigger method, expects to find a rule created by the corresponding check adapter. if no rule is found then injection must be bypassed for this method
        Parameters:
        triggerMethodName - the name of a candidate method for injection
        triggerMethodDescriptor - the descriptor of a candidate method for injection
        Returns:
        the rule if it exists or NULL if not
      • createRule

        public Rule createRule​(java.lang.String triggerMethodName,
                               java.lang.String triggerMethodDescriptor)
        called by a check adapter to create a rule specific to a given trigger method. the first such call reuses the rule created by the intiial parse. subsequent calls create a new rule.
        Parameters:
        triggerMethodName - the name of a candidate method for injection
        triggerMethodDescriptor - the descriptor of a candidate method for injection
        Returns:
        the new rule
      • warn

        public void warn​(java.lang.String triggerMethodName,
                         java.lang.String triggerMethodDescriptor,
                         java.lang.String warningMessage)
        called by a check adapter to warn that a transform was not possible for a potential match target. this inhibits injection into the method being warned about allowing other injection operations to continue.
        Parameters:
        triggerMethodName - the name of a candidate method for injection
        triggerMethodDescriptor - the descriptor of a candidate method for injection
        warningMessage - details of the warning
      • fail

        public void fail​(java.lang.String failMessage,
                         java.lang.String triggerMethodName,
                         java.lang.String triggerMethodDescriptor)
        called by a check or trigger adapter to fail a transform because of a type issue. this aborts all injection into the current class not just injection into the current method.
        Parameters:
        failMessage - details of the failure
        triggerMethodName - the name of a candidate method for injection
        triggerMethodDescriptor - the descriptor of a candidate method for injection
      • recordFailedTransform

        public void recordFailedTransform​(java.lang.Throwable th)
      • matchTargetMethod

        public boolean matchTargetMethod​(int access,
                                         java.lang.String name,
                                         java.lang.String desc)
      • injectIntoMethod

        public boolean injectIntoMethod​(java.lang.String name,
                                        java.lang.String desc)
      • getTriggerClassName

        public java.lang.String getTriggerClassName()
      • notifyRules

        private boolean notifyRules()
        this gets called when a transform attempt completes without any exceptions. if there are rules left in the rule map then they will belong successful injections.
      • purgeRules

        private void purgeRules()
        this gets called when a transform attempt fails. if there are rules left in the rule map then they will belong either to earlier successful injections or to the failed transform. in any case they need to be purged.
      • getRuleKey

        private java.lang.String getRuleKey​(java.lang.String triggerMethodName,
                                            java.lang.String triggerMethodDescriptor)
        return a unique string key identifying a specific rule compiled against some class and method/signature in the context of a specific class loader
        Returns:
        a unique string key
      • getKeyTriggerMethodName

        private java.lang.String getKeyTriggerMethodName​(java.lang.String key)
        return the trigger method name used to construct the supplied rule key
        Parameters:
        key -
        Returns:
        the trigger method name
      • getKeyTriggerMethodDescriptor

        private java.lang.String getKeyTriggerMethodDescriptor​(java.lang.String key)
        return the trigger method descriptor used to construct the supplied rule key
        Parameters:
        key -
        Returns:
        the trigger method descriptor
      • mungeMethodSpecReturnType

        private java.lang.String mungeMethodSpecReturnType​(java.lang.String targetMethodSpec)
        detect a method specification which includes a return type preceding the method name and transform it so that the return type is at the end.
        Parameters:
        targetMethodSpec -
        Returns:
        the method spec in the desired format
      • getNonLoadingClassWriter

        private org.objectweb.asm.ClassWriter getNonLoadingClassWriter​(int flags)
        get a class writer which will not attempt to load classes. The default classwriter tries this when a reference type local var frame slot aligns with a slot of reference type in a successor block's frame. This is merely so it can optimize a slot out of the frame change set in the special case where f1[slot].type < f2[slot].type or vice versa by using the least common supereclass. We have to use the Transformer to reuse existing loaded classes and, where a class has not been loaded, to attempt to load the bytecode as a resource and identify supers via the bytecode.
        Parameters:
        flags -
        Returns:
        a non-loading class writer
      • findLeastCommonSuper

        public java.lang.String findLeastCommonSuper​(java.lang.String t1,
                                                     java.lang.String t2)
      • listInterfaces

        private java.util.LinkedList<java.lang.String> listInterfaces​(ClassChecker checker)
      • listSupers

        private java.util.LinkedList<java.lang.String> listSupers​(ClassChecker checker)