Class ClassEnhancerImpl

  • All Implemented Interfaces:
    ClassEnhancer

    public class ClassEnhancerImpl
    extends Object
    implements ClassEnhancer
    Class enhancer using ASM (see http://asm.objectweb.org but included in DataNucleus core repackaged). ASM operates using a SAXParser-like "visitor-pattern". We utilise this as follows :-
    • enhance : start with a ClassReader for the class to be enhanced, and create a EnhancerClassAdapter (attached to a ClassWriter) that will perform the modifications, and use that as a visitor for the reader so that the reader sends its events to the adapter. Within the EnhancerClassAdapter we also make use of a EnhancerMethodAdapter to update individual methods
    • check : take a ClassReader, and create a EnhancerClassChecker that performs the checks. We then set the checker as a visitor for the reader so that the reader sends its events to the checker.
    • Field Detail

      • clr

        protected final ClassLoaderResolver clr
        Class Loader Resolver to use for any loading issues.
      • metaDataMgr

        protected final MetaDataManager metaDataMgr
        MetaData Manager to use.
      • cmd

        protected final ClassMetaData cmd
        MetaData for the class being enhanced.
      • className

        public final String className
        Class name of the class being enhanced
      • update

        protected boolean update
        Flag specifying if the class needs updating.
      • fieldsToAdd

        protected List<ClassField> fieldsToAdd
        List of fields to be added to the class.
      • methodsToAdd

        protected List<ClassMethod> methodsToAdd
        List of methods to be added to the class.
      • initialised

        protected boolean initialised
        Flag for whether we are initialised.
      • inputResourceName

        protected String inputResourceName
        Resource name of the input class (only when the class exists in a class file).
      • inputBytes

        protected byte[] inputBytes
        Bytes of the input class (only when enhancing generated classes with no class file).
      • cls

        protected final Class cls
        Class that is being enhanced.
      • classBytes

        protected byte[] classBytes
        Bytes of the class (after enhancing).
      • pkClassBytes

        protected byte[] pkClassBytes
        Bytes for any auto-generated PK class (if generated during enhancement).
      • asmClassName

        protected String asmClassName
        ASM Class name for this class (replace . with /).
      • classDescriptor

        protected String classDescriptor
        Class descriptor for this class.
    • Constructor Detail

      • ClassEnhancerImpl

        public ClassEnhancerImpl​(ClassMetaData cmd,
                                 ClassLoaderResolver clr,
                                 MetaDataManager mmgr,
                                 EnhancementNamer namer)
        Constructor for an enhancer for the class. The class is assumed to be in the CLASSPATH.
        Parameters:
        cmd - MetaData for the class to be enhanced
        clr - ClassLoader resolver
        mmgr - MetaData manager
        namer - The namer
      • ClassEnhancerImpl

        public ClassEnhancerImpl​(ClassMetaData cmd,
                                 ClassLoaderResolver clr,
                                 MetaDataManager mmgr,
                                 EnhancementNamer namer,
                                 byte[] classBytes)
        Constructor for an enhancer to enhance a class defined by the provided bytes.
        Parameters:
        cmd - MetaData for the class to be enhanced
        clr - ClassLoader resolver
        mmgr - MetaData manager
        namer - The namer
        classBytes - Bytes of the class to enhance
    • Method Detail

      • initialise

        protected void initialise()
        Initialisation of the information for enhancing this class.
      • getClassName

        public String getClassName()
        Description copied from interface: ClassEnhancer
        Accessor for the name of the class being enhanced.
        Specified by:
        getClassName in interface ClassEnhancer
        Returns:
        Class name
      • requiresDetachable

        protected boolean requiresDetachable()
        Convenience method for whether this class needs to implement Detachable
        Returns:
        Whether we need to implement the Detachable interface
      • isPersistable

        public boolean isPersistable​(String className)
        Check if the class is Persistable or is going to be enhanced based on the metadata
        Specified by:
        isPersistable in interface ClassEnhancer
        Parameters:
        className - the class name
        Returns:
        true if Persistable
      • setOptions

        public void setOptions​(Collection<String> options)
        Description copied from interface: ClassEnhancer
        Method to set the options controlling the enhancement.
        Specified by:
        setOptions in interface ClassEnhancer
        Parameters:
        options - The options
      • hasOption

        public boolean hasOption​(String name)
        Description copied from interface: ClassEnhancer
        Accessor for whether a particular option is enabled.
        Specified by:
        hasOption in interface ClassEnhancer
        Parameters:
        name - Name of the option
        Returns:
        Whether it has this option
      • save

        public void save​(String directoryName)
                  throws IOException
        Method to save the class definition bytecode into a class file. If directoryName is specified it will be written to $directoryName/className.class else will overwrite the existing class.
        Specified by:
        save in interface ClassEnhancer
        Parameters:
        directoryName - Name of a directory (or null to overwrite the class)
        Throws:
        IOException - If an I/O error occurs in the write.
      • getClassNameForFileName

        public static String getClassNameForFileName​(String filename)
        Convenience accessor for the class name that is stored in a particular class.
        Parameters:
        filename - Name of the file
        Returns:
        The class name
      • getClassBeingEnhanced

        public Class getClassBeingEnhanced()
        Accessor for the class being enhanced.
        Specified by:
        getClassBeingEnhanced in interface ClassEnhancer
        Returns:
        Class being enhanced
      • getClassDescriptor

        public String getClassDescriptor()
        Accessor for the class descriptor for the class being enhanced
        Specified by:
        getClassDescriptor in interface ClassEnhancer
        Returns:
        class descriptor
      • initialiseMethodsList

        protected void initialiseMethodsList()
        Method to initialise the list of methods to add.
      • initialiseFieldsList

        protected void initialiseFieldsList()
        Method to initialise the list of fields to add.
      • enhance

        public boolean enhance()
        Method to enhance a classes definition.
        Specified by:
        enhance in interface ClassEnhancer
        Returns:
        Whether it was enhanced with no errors
      • getClassBytes

        public byte[] getClassBytes()
        Accessor for the class bytes. Only has relevance to be called after enhance().
        Specified by:
        getClassBytes in interface ClassEnhancer
        Returns:
        The class bytes
      • getPrimaryKeyClassBytes

        public byte[] getPrimaryKeyClassBytes()
        Accessor for the primary-key class bytes (if generating a PK). Only has relevance to be called after enhance().
        Specified by:
        getPrimaryKeyClassBytes in interface ClassEnhancer
        Returns:
        The primary-key class bytes
      • validate

        public boolean validate()
        Description copied from interface: ClassEnhancer
        Validate whether the class is enhanced.
        Specified by:
        validate in interface ClassEnhancer
        Returns:
        Return true if already enhanced class.
      • checkClassIsEnhanced

        protected boolean checkClassIsEnhanced​(boolean logErrors)
        Convenience method to return if a class is enhanced.
        Parameters:
        logErrors - Whether to log any errors (missing methods etc) as errors (otherwise info/debug)
        Returns:
        Whether the class is enhanced