Class ClassEnhancerImpl

java.lang.Object
org.datanucleus.enhancer.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 Details

    • 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.
    • options

      protected Collection<String> options
      Options for enhancement.
    • 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.
    • namer

      protected EnhancementNamer namer
  • Constructor Details

    • 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 Details

    • 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
    • getMethodsList

      public List<ClassMethod> getMethodsList()
      Accessor for the methods required.
      Specified by:
      getMethodsList in interface ClassEnhancer
      Returns:
      List of methods required for enhancement
    • getFieldsList

      public List<ClassField> getFieldsList()
      Accessor for the fields required.
      Specified by:
      getFieldsList in interface ClassEnhancer
      Returns:
      List of fields required for enhancement
    • getClassLoaderResolver

      public ClassLoaderResolver getClassLoaderResolver()
      Accessor for the ClassLoaderResolver
      Specified by:
      getClassLoaderResolver in interface ClassEnhancer
      Returns:
      ClassLoader resolver
    • getMetaDataManager

      public MetaDataManager getMetaDataManager()
      Description copied from interface: ClassEnhancer
      Accessor for the MetaData manager in use.
      Specified by:
      getMetaDataManager in interface ClassEnhancer
      Returns:
      MetaData manager
    • getClassMetaData

      public ClassMetaData getClassMetaData()
      Description copied from interface: ClassEnhancer
      Accessor for the ClassMetaData for the class.
      Specified by:
      getClassMetaData in interface ClassEnhancer
      Returns:
      MetaData for the class
    • 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.
    • setNamer

      public void setNamer(EnhancementNamer namer)
      Specified by:
      setNamer in interface ClassEnhancer
    • 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
    • getASMClassName

      public String getASMClassName()
      Accessor for the ASM class name
      Specified by:
      getASMClassName in interface ClassEnhancer
      Returns:
      ASM class name
    • 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
    • getNamer

      public EnhancementNamer getNamer()
      Specified by:
      getNamer in interface ClassEnhancer