Package org.datanucleus.enhancer
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.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
ClassEnhancerImpl.MyClassVisitor
Convenience class to look up the class name for a file.
-
Field Summary
Fields Modifier and Type Field Description protected String
asmClassName
ASM Class name for this class (replace .protected byte[]
classBytes
Bytes of the class (after enhancing).protected String
classDescriptor
Class descriptor for this class.String
className
Class name of the class being enhancedprotected ClassLoaderResolver
clr
Class Loader Resolver to use for any loading issues.protected Class
cls
Class that is being enhanced.protected ClassMetaData
cmd
MetaData for the class being enhanced.protected List<ClassField>
fieldsToAdd
List of fields to be added to the class.protected boolean
initialised
Flag for whether we are initialised.protected byte[]
inputBytes
Bytes of the input class (only when enhancing generated classes with no class file).protected String
inputResourceName
Resource name of the input class (only when the class exists in a class file).protected MetaDataManager
metaDataMgr
MetaData Manager to use.protected List<ClassMethod>
methodsToAdd
List of methods to be added to the class.protected EnhancementNamer
namer
protected Collection<String>
options
Options for enhancement.protected byte[]
pkClassBytes
Bytes for any auto-generated PK class (if generated during enhancement).protected boolean
update
Flag specifying if the class needs updating.-
Fields inherited from interface org.datanucleus.enhancer.ClassEnhancer
ASM_API_VERSION, OPTION_GENERATE_DEFAULT_CONSTRUCTOR, OPTION_GENERATE_DETACH_LISTENER, OPTION_GENERATE_PK
-
-
Constructor Summary
Constructors Constructor Description ClassEnhancerImpl(ClassMetaData cmd, ClassLoaderResolver clr, MetaDataManager mmgr, EnhancementNamer namer)
Constructor for an enhancer for the class.ClassEnhancerImpl(ClassMetaData cmd, ClassLoaderResolver clr, MetaDataManager mmgr, EnhancementNamer namer, byte[] classBytes)
Constructor for an enhancer to enhance a class defined by the provided bytes.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description protected boolean
checkClassIsEnhanced(boolean logErrors)
Convenience method to return if a class is enhanced.boolean
enhance()
Method to enhance a classes definition.String
getASMClassName()
Accessor for the ASM class nameClass
getClassBeingEnhanced()
Accessor for the class being enhanced.byte[]
getClassBytes()
Accessor for the class bytes.String
getClassDescriptor()
Accessor for the class descriptor for the class being enhancedClassLoaderResolver
getClassLoaderResolver()
Accessor for the ClassLoaderResolverClassMetaData
getClassMetaData()
Accessor for the ClassMetaData for the class.String
getClassName()
Accessor for the name of the class being enhanced.static String
getClassNameForFileName(String filename)
Convenience accessor for the class name that is stored in a particular class.List<ClassField>
getFieldsList()
Accessor for the fields required.MetaDataManager
getMetaDataManager()
Accessor for the MetaData manager in use.List<ClassMethod>
getMethodsList()
Accessor for the methods required.EnhancementNamer
getNamer()
byte[]
getPrimaryKeyClassBytes()
Accessor for the primary-key class bytes (if generating a PK).boolean
hasOption(String name)
Accessor for whether a particular option is enabled.protected void
initialise()
Initialisation of the information for enhancing this class.protected void
initialiseFieldsList()
Method to initialise the list of fields to add.protected void
initialiseMethodsList()
Method to initialise the list of methods to add.boolean
isPersistable(String className)
Check if the class is Persistable or is going to be enhanced based on the metadataprotected boolean
requiresDetachable()
Convenience method for whether this class needs to implement Detachablevoid
save(String directoryName)
Method to save the class definition bytecode into a class file.void
setNamer(EnhancementNamer namer)
void
setOptions(Collection<String> options)
Method to set the options controlling the enhancement.boolean
validate()
Validate whether the class is enhanced.
-
-
-
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.
-
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 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 enhancedclr
- ClassLoader resolvermmgr
- MetaData managernamer
- 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 enhancedclr
- ClassLoader resolvermmgr
- MetaData managernamer
- The namerclassBytes
- 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 interfaceClassEnhancer
- Returns:
- Class name
-
getMethodsList
public List<ClassMethod> getMethodsList()
Accessor for the methods required.- Specified by:
getMethodsList
in interfaceClassEnhancer
- Returns:
- List of methods required for enhancement
-
getFieldsList
public List<ClassField> getFieldsList()
Accessor for the fields required.- Specified by:
getFieldsList
in interfaceClassEnhancer
- Returns:
- List of fields required for enhancement
-
getClassLoaderResolver
public ClassLoaderResolver getClassLoaderResolver()
Accessor for the ClassLoaderResolver- Specified by:
getClassLoaderResolver
in interfaceClassEnhancer
- Returns:
- ClassLoader resolver
-
getMetaDataManager
public MetaDataManager getMetaDataManager()
Description copied from interface:ClassEnhancer
Accessor for the MetaData manager in use.- Specified by:
getMetaDataManager
in interfaceClassEnhancer
- Returns:
- MetaData manager
-
getClassMetaData
public ClassMetaData getClassMetaData()
Description copied from interface:ClassEnhancer
Accessor for the ClassMetaData for the class.- Specified by:
getClassMetaData
in interfaceClassEnhancer
- 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 interfaceClassEnhancer
- 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 interfaceClassEnhancer
- 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 interfaceClassEnhancer
- 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 interfaceClassEnhancer
- 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 interfaceClassEnhancer
-
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 interfaceClassEnhancer
- Returns:
- Class being enhanced
-
getASMClassName
public String getASMClassName()
Accessor for the ASM class name- Specified by:
getASMClassName
in interfaceClassEnhancer
- Returns:
- ASM class name
-
getClassDescriptor
public String getClassDescriptor()
Accessor for the class descriptor for the class being enhanced- Specified by:
getClassDescriptor
in interfaceClassEnhancer
- 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 interfaceClassEnhancer
- 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 interfaceClassEnhancer
- 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 interfaceClassEnhancer
- 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 interfaceClassEnhancer
- 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 interfaceClassEnhancer
-
-