From 6a388b754c2d17b690bf6095fe425c2202dbcc3f Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Fri, 19 Apr 2013 14:35:22 -0500 Subject: [PATCH] HHH-8159 - Apply fixups indicated by analysis tools --- build.gradle | 16 +- .../java/org/hibernate/AssertionFailure.java | 23 +- .../org/hibernate/ConnectionReleaseMode.java | 2 +- .../src/main/java/org/hibernate/Criteria.java | 6 +- .../java/org/hibernate/HibernateError.java | 21 +- .../hibernate/InvalidMappingException.java | 6 +- .../src/main/java/org/hibernate/LockMode.java | 6 +- .../java/org/hibernate/MappingException.java | 4 +- .../hibernate/MappingNotFoundException.java | 16 +- .../hibernate/ObjectNotFoundException.java | 2 +- .../hibernate/PropertyAccessException.java | 16 +- .../hibernate/PropertyNotFoundException.java | 2 +- .../org/hibernate/PropertyValueException.java | 4 +- .../java/org/hibernate/QueryException.java | 8 +- .../org/hibernate/QueryTimeoutException.java | 3 +- .../java/org/hibernate/SessionFactory.java | 16 +- .../hibernate/StaleObjectStateException.java | 2 +- .../org/hibernate/StaleStateException.java | 2 +- .../org/hibernate/TransactionException.java | 4 +- .../hibernate/TransientObjectException.java | 2 +- .../TransientPropertyValueException.java | 2 +- .../UnresolvableObjectException.java | 5 +- .../internal/AbstractEntityInsertAction.java | 12 +- .../internal/BulkOperationCleanupAction.java | 16 +- .../action/internal/CollectionAction.java | 19 +- .../internal/CollectionRecreateAction.java | 29 +- .../internal/CollectionRemoveAction.java | 30 +- .../internal/CollectionUpdateAction.java | 49 +- .../internal/DelayedPostInsertIdentifier.java | 22 +- .../action/internal/EntityAction.java | 14 +- .../action/internal/EntityDeleteAction.java | 46 +- .../internal/EntityIdentityInsertAction.java | 52 +- .../EntityIncrementVersionProcess.java | 13 +- .../action/internal/EntityInsertAction.java | 50 +- .../action/internal/EntityUpdateAction.java | 73 +- .../internal/EntityVerifyVersionProcess.java | 14 +- .../UnresolvedEntityInsertActions.java | 56 +- .../action/internal/package-info.java | 4 + .../org/hibernate/annotations/QueryHints.java | 20 +- .../BootstrapServiceRegistryBuilder.java | 6 +- .../internal/ClassLoaderServiceImpl.java | 64 +- .../classloading/internal/package-info.java | 4 + .../BootstrapServiceRegistryImpl.java | 37 +- .../internal/StandardServiceRegistryImpl.java | 13 +- .../boot/registry/internal/package-info.java | 4 + .../selector/internal/package-info.java | 4 + .../internal/JavassistInstrumenter.java | 12 +- .../buildtime/internal/package-info.java | 4 + .../buildtime/spi/AbstractInstrumenter.java | 223 ++--- .../buildtime/spi/BasicClassFilter.java | 12 +- .../bytecode/buildtime/spi/ClassFilter.java | 2 +- .../buildtime/spi/ExecutionException.java | 16 + .../bytecode/buildtime/spi/Instrumenter.java | 6 +- .../bytecode/buildtime/spi/Logger.java | 25 + .../bytecode/buildtime/spi/package-info.java | 6 + .../enhance/EnhancementException.java | 16 +- .../bytecode/enhance/package-info.java | 4 + .../enhance/spi/EnhancementContext.java | 38 +- .../bytecode/enhance/spi/Enhancer.java | 147 ++- .../enhance/spi/EnhancerConstants.java | 133 +++ .../bytecode/enhance/spi/package-info.java | 4 + .../internal/FieldInterceptionHelper.java | 60 +- .../javassist/FieldInterceptorImpl.java | 38 +- .../internal/javassist/JavassistHelper.java | 31 +- .../internal/javassist/package-info.java | 4 + .../internal/package-info.java | 4 + .../spi/AbstractFieldInterceptor.java | 43 +- .../spi/LazyPropertyInitializer.java | 6 +- .../instrumentation/spi/package-info.java | 6 + .../javassist/AccessOptimizerAdapter.java | 40 +- .../internal/javassist/BulkAccessor.java | 59 +- .../javassist/BulkAccessorException.java | 115 +-- .../javassist/BulkAccessorFactory.java | 208 ++-- .../javassist/BytecodeProviderImpl.java | 55 +- .../internal/javassist/FastClass.java | 153 ++- .../internal/javassist/FieldFilter.java | 29 +- .../internal/javassist/FieldHandler.java | 170 +++- .../internal/javassist/FieldTransformer.java | 891 ++++++++++-------- .../InstantiationOptimizerAdapter.java | 11 +- .../javassist/JavassistClassTransformer.java | 48 +- .../javassist/ProxyFactoryFactoryImpl.java | 36 +- .../javassist/ReflectionOptimizerImpl.java | 11 +- .../javassist/TransformingClassLoader.java | 51 +- .../internal/javassist/package-info.java | 4 + .../spi/AbstractClassTransformerImpl.java | 13 +- .../bytecode/spi/BasicProxyFactory.java | 4 +- .../bytecode/spi/ByteCodeHelper.java | 29 +- .../bytecode/spi/ClassTransformer.java | 35 +- .../spi/EntityInstrumentationMetadata.java | 26 +- .../bytecode/spi/InstrumentedClassLoader.java | 22 +- .../spi/NotInstrumentedException.java | 12 +- .../bytecode/spi/ReflectionOptimizer.java | 32 +- .../hibernate/bytecode/spi/package-info.java | 4 + .../org/hibernate/cache/CacheException.java | 37 +- ...oCacheRegionFactoryAvailableException.java | 25 +- .../org/hibernate/cache/RegionFactory.java | 2 + .../org/hibernate/cache/spi/CacheKey.java | 10 +- .../org/hibernate/cache/spi/FilterKey.java | 46 +- .../cache/spi/NaturalIdCacheKey.java | 62 +- .../org/hibernate/cache/spi/QueryCache.java | 42 +- .../cache/spi/QueryCacheFactory.java | 17 +- .../org/hibernate/cache/spi/QueryKey.java | 14 +- .../java/org/hibernate/cache/spi/Region.java | 15 +- .../hibernate/cache/spi/RegionFactory.java | 2 +- .../cache/spi/TransactionalDataRegion.java | 6 + .../cache/spi/UpdateTimestampsCache.java | 82 +- .../cache/spi/access/AccessType.java | 31 + .../spi/access/RegionAccessStrategy.java | 2 + .../access/UnknownAccessTypeException.java | 9 + .../hibernate/cache/spi/entry/CacheEntry.java | 33 +- .../cache/spi/entry/CacheEntryStructure.java | 20 +- .../cache/spi/entry/CollectionCacheEntry.java | 51 +- .../spi/entry/ReferenceCacheEntryImpl.java | 25 +- .../spi/entry/StandardCacheEntryImpl.java | 128 ++- .../cache/spi/entry/StructuredCacheEntry.java | 36 +- .../entry/StructuredCollectionCacheEntry.java | 16 +- .../spi/entry/StructuredMapCacheEntry.java | 30 +- .../spi/entry/UnstructuredCacheEntry.java | 11 +- .../hibernate/cfg/AbstractPropertyHolder.java | 25 +- .../java/org/hibernate/cfg/AccessType.java | 31 +- .../hibernate/internal/util/StringHelper.java | 8 +- .../AbstractCollectionPersister.java | 8 +- .../bytecode/enhancement/EnhancerTest.java | 21 +- .../test/legacy/CustomPersister.java | 2 +- shared/config/checkstyle/checkstyle.xml | 172 +++- shared/config/checkstyle/public_checks.xml | 145 --- shared/config/checkstyle/todo-checks.xml | 15 + 127 files changed, 3128 insertions(+), 1768 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/action/internal/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/boot/registry/internal/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/internal/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/bytecode/enhance/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/EnhancerConstants.java create mode 100644 hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/javassist/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/spi/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/bytecode/spi/package-info.java delete mode 100644 shared/config/checkstyle/public_checks.xml create mode 100644 shared/config/checkstyle/todo-checks.xml diff --git a/build.gradle b/build.gradle index 635607a90a..dcedcdd7db 100644 --- a/build.gradle +++ b/build.gradle @@ -315,8 +315,14 @@ subprojects { subProject -> task checkstylePublicSources(type: Checkstyle) { checkstyleClasspath = checkstyleMain.checkstyleClasspath classpath = checkstyleMain.classpath - configFile = rootProject.file( 'shared/config/checkstyle/public_checks.xml' ) + configFile = rootProject.file( 'shared/config/checkstyle/checkstyle.xml' ) source subProject.sourceSets.main.originalJavaSrcDirs + // exclude generated sources + exclude '**/generated-src/**' + // because cfg package is a mess mainly from annotation stuff + exclude '**/org/hibernate/cfg/**' + exclude '**/org/hibernate/cfg/*' + // because this should only report on api/spi exclude '**/internal/**' exclude '**/internal/*' ignoreFailures = false @@ -331,13 +337,21 @@ subprojects { subProject -> // Report configs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ checkstyle { + sourceSets = [ subProject.sourceSets.main ] configFile = rootProject.file( 'shared/config/checkstyle/checkstyle.xml' ) showViolations = false ignoreFailures = true } + // exclude generated sources + checkstyleMain.exclude '**/generated-src/**' + // because cfg package is a mess mainly from annotation stuff + checkstyleMain.exclude '**/org/hibernate/cfg/**' + checkstyleMain.exclude '**/org/hibernate/cfg/*' + findbugs { ignoreFailures = true } + buildDashboard.dependsOn check // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/hibernate-core/src/main/java/org/hibernate/AssertionFailure.java b/hibernate-core/src/main/java/org/hibernate/AssertionFailure.java index cc36bccf64..880ba44a9a 100644 --- a/hibernate-core/src/main/java/org/hibernate/AssertionFailure.java +++ b/hibernate-core/src/main/java/org/hibernate/AssertionFailure.java @@ -33,19 +33,22 @@ import org.hibernate.internal.CoreMessageLogger; * @author Gavin King */ public class AssertionFailure extends RuntimeException { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, AssertionFailure.class.getName()); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + AssertionFailure.class.getName() + ); /** * Creates an instance of AssertionFailure using the given message. * * @param message The message explaining the reason for the exception */ - public AssertionFailure(String message) { - super( message ); - LOG.failed( this ); - } + public AssertionFailure(String message) { + super( message ); + LOG.failed( this ); + } /** * Creates an instance of AssertionFailure using the given message and underlying cause. @@ -53,8 +56,8 @@ public class AssertionFailure extends RuntimeException { * @param message The message explaining the reason for the exception * @param cause The underlying cause. */ - public AssertionFailure(String message, Throwable cause) { - super( message, cause ); - LOG.failed( cause ); - } + public AssertionFailure(String message, Throwable cause) { + super( message, cause ); + LOG.failed( cause ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/ConnectionReleaseMode.java b/hibernate-core/src/main/java/org/hibernate/ConnectionReleaseMode.java index 700e0b1bd5..25309ca10e 100644 --- a/hibernate-core/src/main/java/org/hibernate/ConnectionReleaseMode.java +++ b/hibernate-core/src/main/java/org/hibernate/ConnectionReleaseMode.java @@ -60,7 +60,7 @@ public enum ConnectionReleaseMode{ * * @return The matched enum value. */ - public static ConnectionReleaseMode parse(final String name){ + public static ConnectionReleaseMode parse(final String name) { return ConnectionReleaseMode.valueOf( name.toUpperCase() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/Criteria.java b/hibernate-core/src/main/java/org/hibernate/Criteria.java index 17152825dc..84b0beb000 100644 --- a/hibernate-core/src/main/java/org/hibernate/Criteria.java +++ b/hibernate-core/src/main/java/org/hibernate/Criteria.java @@ -119,7 +119,7 @@ public interface Criteria extends CriteriaSpecification { * @return this (for method chaining) */ public Criteria add(Criterion criterion); - + /** * Add an {@link Order ordering} to the result set. * @@ -393,7 +393,7 @@ public interface Criteria extends CriteriaSpecification { * @return this (for method chaining) */ public Criteria setMaxResults(int maxResults); - + /** * Set the first result to be retrieved. * @@ -531,7 +531,7 @@ public interface Criteria extends CriteriaSpecification { * exeucting the SQL or processing the SQL results. */ public List list() throws HibernateException; - + /** * Get the results as an instance of {@link ScrollableResults}. * diff --git a/hibernate-core/src/main/java/org/hibernate/HibernateError.java b/hibernate-core/src/main/java/org/hibernate/HibernateError.java index 4376031c02..26b76b73b7 100644 --- a/hibernate-core/src/main/java/org/hibernate/HibernateError.java +++ b/hibernate-core/src/main/java/org/hibernate/HibernateError.java @@ -28,16 +28,23 @@ package org.hibernate; * * @author Steve Ebersole */ -public abstract class HibernateError extends HibernateException { +public class HibernateError extends HibernateException { + /** + * Constructs HibernateError with the condition message. + * + * @param message Message explaining the exception/error condition + */ public HibernateError(String message) { super( message ); } - public HibernateError(Throwable root) { - super( root ); - } - - public HibernateError(String message, Throwable root) { - super( message, root ); + /** + * Constructs HibernateError with the condition message and cause. + * + * @param message Message explaining the exception/error condition + * @param cause The underlying cause. + */ + public HibernateError(String message, Throwable cause) { + super( message, cause ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/InvalidMappingException.java b/hibernate-core/src/main/java/org/hibernate/InvalidMappingException.java index 474f295882..6a486a4050 100644 --- a/hibernate-core/src/main/java/org/hibernate/InvalidMappingException.java +++ b/hibernate-core/src/main/java/org/hibernate/InvalidMappingException.java @@ -61,7 +61,7 @@ public class InvalidMappingException extends MappingException { * @param path The path (type specific) of the invalid mapping document */ public InvalidMappingException(String customMessage, String type, String path) { - super(customMessage); + super( customMessage ); this.type=type; this.path=path; } @@ -104,7 +104,7 @@ public class InvalidMappingException extends MappingException { * @param path The path (type specific) of the invalid mapping document */ public InvalidMappingException(String type, String path) { - this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path); + this( "Could not parse mapping document from " + type + (path==null?"":" " + path), type, path ); } /** @@ -115,7 +115,7 @@ public class InvalidMappingException extends MappingException { * @param cause The underlying cause */ public InvalidMappingException(String type, String path, Throwable cause) { - this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path, cause); + this( "Could not parse mapping document from " + type + (path==null?"":" " + path), type, path, cause ); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/LockMode.java b/hibernate-core/src/main/java/org/hibernate/LockMode.java index cde6b6bdf0..01a569e257 100644 --- a/hibernate-core/src/main/java/org/hibernate/LockMode.java +++ b/hibernate-core/src/main/java/org/hibernate/LockMode.java @@ -57,7 +57,7 @@ public enum LockMode { * * @deprecated instead use PESSIMISTIC_WRITE */ - @Deprecated + @Deprecated UPGRADE( 10 ), /** * Attempt to obtain an upgrade lock, using an Oracle-style @@ -89,7 +89,7 @@ public enum LockMode { * * @deprecated instead use PESSIMISTIC_FORCE_INCREMENT */ - @Deprecated + @Deprecated FORCE( 15 ), /** @@ -151,6 +151,4 @@ public enum LockMode { public boolean lessThan(LockMode mode) { return level < mode.level; } - - } diff --git a/hibernate-core/src/main/java/org/hibernate/MappingException.java b/hibernate-core/src/main/java/org/hibernate/MappingException.java index 31d6aec618..6e62096188 100644 --- a/hibernate-core/src/main/java/org/hibernate/MappingException.java +++ b/hibernate-core/src/main/java/org/hibernate/MappingException.java @@ -46,7 +46,7 @@ public class MappingException extends HibernateException { * @param cause The underlying cause */ public MappingException(Throwable cause) { - super(cause); + super( cause ); } /** @@ -55,7 +55,7 @@ public class MappingException extends HibernateException { * @param message A message explaining the exception condition */ public MappingException(String message) { - super(message); + super( message ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/MappingNotFoundException.java b/hibernate-core/src/main/java/org/hibernate/MappingNotFoundException.java index 73680e32eb..5be7da0087 100644 --- a/hibernate-core/src/main/java/org/hibernate/MappingNotFoundException.java +++ b/hibernate-core/src/main/java/org/hibernate/MappingNotFoundException.java @@ -41,9 +41,9 @@ public class MappingNotFoundException extends MappingException { * @param cause The underlying cause */ public MappingNotFoundException(String customMessage, String type, String path, Throwable cause) { - super(customMessage, cause); - this.type=type; - this.path=path; + super( customMessage, cause ); + this.type = type; + this.path = path; } /** @@ -54,9 +54,9 @@ public class MappingNotFoundException extends MappingException { * @param path The path (type specific) of the mapping that could not be found */ public MappingNotFoundException(String customMessage, String type, String path) { - super(customMessage); - this.type=type; - this.path=path; + super( customMessage ); + this.type = type; + this.path = path; } /** @@ -66,7 +66,7 @@ public class MappingNotFoundException extends MappingException { * @param path The path (type specific) of the mapping that could not be found */ public MappingNotFoundException(String type, String path) { - this(type + ": " + path + " not found", type, path); + this( type + ": " + path + " not found", type, path ); } /** @@ -77,7 +77,7 @@ public class MappingNotFoundException extends MappingException { * @param cause The underlying cause */ public MappingNotFoundException(String type, String path, Throwable cause) { - this(type + ": " + path + " not found", type, path, cause); + this( type + ": " + path + " not found", type, path, cause ); } public String getType() { diff --git a/hibernate-core/src/main/java/org/hibernate/ObjectNotFoundException.java b/hibernate-core/src/main/java/org/hibernate/ObjectNotFoundException.java index a69dd6e551..08eb066282 100644 --- a/hibernate-core/src/main/java/org/hibernate/ObjectNotFoundException.java +++ b/hibernate-core/src/main/java/org/hibernate/ObjectNotFoundException.java @@ -46,6 +46,6 @@ public class ObjectNotFoundException extends UnresolvableObjectException { * @param entityName The name of the entity */ public ObjectNotFoundException(Serializable identifier, String entityName) { - super(identifier, entityName); + super( identifier, entityName ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/PropertyAccessException.java b/hibernate-core/src/main/java/org/hibernate/PropertyAccessException.java index 2c0620e7a9..95d31f5145 100644 --- a/hibernate-core/src/main/java/org/hibernate/PropertyAccessException.java +++ b/hibernate-core/src/main/java/org/hibernate/PropertyAccessException.java @@ -57,7 +57,7 @@ public class PropertyAccessException extends HibernateException { boolean wasSetter, Class persistentClass, String propertyName) { - super(message, cause); + super( message, cause ); this.persistentClass = persistentClass; this.wasSetter = wasSetter; this.propertyName = propertyName; @@ -72,15 +72,9 @@ public class PropertyAccessException extends HibernateException { } @Override - public String getMessage() { - return super.getMessage() + - ( wasSetter ? " setter of " : " getter of ") + - StringHelper.qualify( persistentClass.getName(), propertyName ); + public String getMessage() { + return super.getMessage() + + ( wasSetter ? " setter of " : " getter of " ) + + StringHelper.qualify( persistentClass.getName(), propertyName ); } } - - - - - - diff --git a/hibernate-core/src/main/java/org/hibernate/PropertyNotFoundException.java b/hibernate-core/src/main/java/org/hibernate/PropertyNotFoundException.java index b2498525fa..deaae34ada 100644 --- a/hibernate-core/src/main/java/org/hibernate/PropertyNotFoundException.java +++ b/hibernate-core/src/main/java/org/hibernate/PropertyNotFoundException.java @@ -36,6 +36,6 @@ public class PropertyNotFoundException extends MappingException { * @param message A message explaining the exception condition */ public PropertyNotFoundException(String message) { - super(message); + super( message ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/PropertyValueException.java b/hibernate-core/src/main/java/org/hibernate/PropertyValueException.java index 9634fd5c0c..052cc52617 100644 --- a/hibernate-core/src/main/java/org/hibernate/PropertyValueException.java +++ b/hibernate-core/src/main/java/org/hibernate/PropertyValueException.java @@ -46,7 +46,7 @@ public class PropertyValueException extends HibernateException { * @param propertyName The name of the property being accessed. */ public PropertyValueException(String message, String entityName, String propertyName) { - super(message); + super( message ); this.entityName = entityName; this.propertyName = propertyName; } @@ -60,7 +60,7 @@ public class PropertyValueException extends HibernateException { } @Override - public String getMessage() { + public String getMessage() { return super.getMessage() + " : " + StringHelper.qualify( entityName, propertyName ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/QueryException.java b/hibernate-core/src/main/java/org/hibernate/QueryException.java index fd20591a22..6a0a27d752 100644 --- a/hibernate-core/src/main/java/org/hibernate/QueryException.java +++ b/hibernate-core/src/main/java/org/hibernate/QueryException.java @@ -39,7 +39,7 @@ public class QueryException extends HibernateException { * @param message A message explaining the exception condition */ public QueryException(String message) { - super(message); + super( message ); } /** @@ -49,7 +49,7 @@ public class QueryException extends HibernateException { * @param cause The underlying cause */ public QueryException(String message, Throwable cause) { - super(message, cause); + super( message, cause ); } /** @@ -59,7 +59,7 @@ public class QueryException extends HibernateException { * @param queryString The query being evaluated when the exception occurred */ public QueryException(String message, String queryString) { - super(message); + super( message ); this.queryString = queryString; } @@ -69,7 +69,7 @@ public class QueryException extends HibernateException { * @param cause The underlying cause */ public QueryException(Exception cause) { - super(cause); + super( cause ); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/QueryTimeoutException.java b/hibernate-core/src/main/java/org/hibernate/QueryTimeoutException.java index 666833fbb3..b29cce8337 100644 --- a/hibernate-core/src/main/java/org/hibernate/QueryTimeoutException.java +++ b/hibernate-core/src/main/java/org/hibernate/QueryTimeoutException.java @@ -39,7 +39,6 @@ public class QueryTimeoutException extends JDBCException { * @param sql The sql being executed when the exception occurred. */ public QueryTimeoutException(String message, SQLException sqlException, String sql) { - super(message, sqlException, sql); + super( message, sqlException, sql ); } - } diff --git a/hibernate-core/src/main/java/org/hibernate/SessionFactory.java b/hibernate-core/src/main/java/org/hibernate/SessionFactory.java index d363fdf099..91eb409f96 100644 --- a/hibernate-core/src/main/java/org/hibernate/SessionFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/SessionFactory.java @@ -253,7 +253,7 @@ public interface SessionFactory extends Referenceable, Serializable { * @deprecated Use {@link Cache#evictEntityRegion(Class)} accessed through * {@link #getCache()} instead. */ - @Deprecated + @Deprecated public void evict(Class persistentClass) throws HibernateException; /** @@ -271,7 +271,7 @@ public interface SessionFactory extends Referenceable, Serializable { * @deprecated Use {@link Cache#containsEntity(Class, Serializable)} accessed through * {@link #getCache()} instead. */ - @Deprecated + @Deprecated public void evict(Class persistentClass, Serializable id) throws HibernateException; /** @@ -288,7 +288,7 @@ public interface SessionFactory extends Referenceable, Serializable { * @deprecated Use {@link Cache#evictEntityRegion(String)} accessed through * {@link #getCache()} instead. */ - @Deprecated + @Deprecated public void evictEntity(String entityName) throws HibernateException; /** @@ -306,7 +306,7 @@ public interface SessionFactory extends Referenceable, Serializable { * @deprecated Use {@link Cache#evictEntity(String,Serializable)} accessed through * {@link #getCache()} instead. */ - @Deprecated + @Deprecated public void evictEntity(String entityName, Serializable id) throws HibernateException; /** @@ -323,7 +323,7 @@ public interface SessionFactory extends Referenceable, Serializable { * @deprecated Use {@link Cache#evictCollectionRegion(String)} accessed through * {@link #getCache()} instead. */ - @Deprecated + @Deprecated public void evictCollection(String roleName) throws HibernateException; /** @@ -341,7 +341,7 @@ public interface SessionFactory extends Referenceable, Serializable { * @deprecated Use {@link Cache#evictCollection(String,Serializable)} accessed through * {@link #getCache()} instead. */ - @Deprecated + @Deprecated public void evictCollection(String roleName, Serializable id) throws HibernateException; /** @@ -355,7 +355,7 @@ public interface SessionFactory extends Referenceable, Serializable { * @deprecated Use {@link Cache#evictQueryRegion(String)} accessed through * {@link #getCache()} instead. */ - @Deprecated + @Deprecated public void evictQueries(String cacheRegion) throws HibernateException; /** @@ -367,7 +367,7 @@ public interface SessionFactory extends Referenceable, Serializable { * @deprecated Use {@link Cache#evictQueryRegions} accessed through * {@link #getCache()} instead. */ - @Deprecated + @Deprecated public void evictQueries() throws HibernateException; /** diff --git a/hibernate-core/src/main/java/org/hibernate/StaleObjectStateException.java b/hibernate-core/src/main/java/org/hibernate/StaleObjectStateException.java index e10ccd6cb2..19cc4964fb 100644 --- a/hibernate-core/src/main/java/org/hibernate/StaleObjectStateException.java +++ b/hibernate-core/src/main/java/org/hibernate/StaleObjectStateException.java @@ -44,7 +44,7 @@ public class StaleObjectStateException extends StaleStateException { * @param identifier The identifier of the entity */ public StaleObjectStateException(String entityName, Serializable identifier) { - super("Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)"); + super( "Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)" ); this.entityName = entityName; this.identifier = identifier; } diff --git a/hibernate-core/src/main/java/org/hibernate/StaleStateException.java b/hibernate-core/src/main/java/org/hibernate/StaleStateException.java index f7ace1a9f0..909d0e7b30 100755 --- a/hibernate-core/src/main/java/org/hibernate/StaleStateException.java +++ b/hibernate-core/src/main/java/org/hibernate/StaleStateException.java @@ -40,6 +40,6 @@ public class StaleStateException extends HibernateException { * @param message The message explaining the exception condition */ public StaleStateException(String message) { - super(message); + super( message ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/TransactionException.java b/hibernate-core/src/main/java/org/hibernate/TransactionException.java index 61a2bb11e5..cdaea0f7e8 100644 --- a/hibernate-core/src/main/java/org/hibernate/TransactionException.java +++ b/hibernate-core/src/main/java/org/hibernate/TransactionException.java @@ -37,7 +37,7 @@ public class TransactionException extends HibernateException { * @param cause The underlying cause */ public TransactionException(String message, Throwable cause) { - super(message,cause); + super( message, cause ); } /** @@ -46,7 +46,7 @@ public class TransactionException extends HibernateException { * @param message The message explaining the exception condition */ public TransactionException(String message) { - super(message); + super( message ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/TransientObjectException.java b/hibernate-core/src/main/java/org/hibernate/TransientObjectException.java index f51070a552..d110c88aba 100644 --- a/hibernate-core/src/main/java/org/hibernate/TransientObjectException.java +++ b/hibernate-core/src/main/java/org/hibernate/TransientObjectException.java @@ -35,7 +35,7 @@ public class TransientObjectException extends HibernateException { * @param message The message explaining the exception condition */ public TransientObjectException(String message) { - super(message); + super( message ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/TransientPropertyValueException.java b/hibernate-core/src/main/java/org/hibernate/TransientPropertyValueException.java index eec3347269..079fb9f1c2 100644 --- a/hibernate-core/src/main/java/org/hibernate/TransientPropertyValueException.java +++ b/hibernate-core/src/main/java/org/hibernate/TransientPropertyValueException.java @@ -50,7 +50,7 @@ public class TransientPropertyValueException extends TransientObjectException { String transientEntityName, String propertyOwnerEntityName, String propertyName) { - super(message); + super( message ); this.transientEntityName = transientEntityName; this.propertyOwnerEntityName = propertyOwnerEntityName; this.propertyName = propertyName; diff --git a/hibernate-core/src/main/java/org/hibernate/UnresolvableObjectException.java b/hibernate-core/src/main/java/org/hibernate/UnresolvableObjectException.java index 1d19e27b5a..73a9237dc6 100644 --- a/hibernate-core/src/main/java/org/hibernate/UnresolvableObjectException.java +++ b/hibernate-core/src/main/java/org/hibernate/UnresolvableObjectException.java @@ -48,7 +48,7 @@ public class UnresolvableObjectException extends HibernateException { } protected UnresolvableObjectException(String message, Serializable identifier, String clazz) { - super(message); + super( message ); this.identifier = identifier; this.entityName = clazz; } @@ -79,8 +79,7 @@ public class UnresolvableObjectException extends HibernateException { @Override public String getMessage() { - return super.getMessage() + ": " + - MessageHelper.infoString(entityName, identifier); + return super.getMessage() + ": " + MessageHelper.infoString( entityName, identifier ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/AbstractEntityInsertAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/AbstractEntityInsertAction.java index 612ffd55ed..3f411d4396 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/AbstractEntityInsertAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/AbstractEntityInsertAction.java @@ -72,7 +72,7 @@ public abstract class AbstractEntityInsertAction extends EntityAction { this.isExecuted = false; this.areTransientReferencesNullified = false; - if (id != null) { + if ( id != null ) { handleNaturalIdPreSaveNotifications(); } } @@ -139,7 +139,7 @@ public abstract class AbstractEntityInsertAction extends EntityAction { */ public final void makeEntityManaged() { nullifyTransientReferencesIfNotAlready(); - Object version = Versioning.getVersion( getState(), getPersister() ); + final Object version = Versioning.getVersion( getState(), getPersister() ); getSession().getPersistenceContext().addEntity( getInstance(), ( getPersister().isMutable() ? Status.MANAGED : Status.READ_ONLY ), @@ -168,12 +168,12 @@ public abstract class AbstractEntityInsertAction extends EntityAction { protected abstract EntityKey getEntityKey(); @Override - public void afterDeserialize(SessionImplementor session) { + public void afterDeserialize(SessionImplementor session) { super.afterDeserialize( session ); // IMPL NOTE: non-flushed changes code calls this method with session == null... // guard against NullPointerException if ( session != null ) { - EntityEntry entityEntry = session.getPersistenceContext().getEntry( getInstance() ); + final EntityEntry entityEntry = session.getPersistenceContext().getEntry( getInstance() ); this.state = entityEntry.getLoadedState(); } } @@ -194,9 +194,11 @@ public abstract class AbstractEntityInsertAction extends EntityAction { /** * Handle sending notifications needed for natural-id after saving + * + * @param generatedId The generated entity identifier */ public void handleNaturalIdPostSaveNotifications(Serializable generatedId) { - if (isEarlyInsert()) { + if ( isEarlyInsert() ) { // with early insert, we still need to add a local (transactional) natural id cross-reference getSession().getPersistenceContext().getNaturalIdHelper().manageLocalNaturalIdCrossReference( getPersister(), diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/BulkOperationCleanupAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/BulkOperationCleanupAction.java index f8917f4653..7423691c76 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/BulkOperationCleanupAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/BulkOperationCleanupAction.java @@ -73,8 +73,8 @@ public class BulkOperationCleanupAction implements Executable, Serializable { * @param affectedQueryables The affected entity persisters. */ public BulkOperationCleanupAction(SessionImplementor session, Queryable... affectedQueryables) { - SessionFactoryImplementor factory = session.getFactory(); - LinkedHashSet spacesList = new LinkedHashSet(); + final SessionFactoryImplementor factory = session.getFactory(); + final LinkedHashSet spacesList = new LinkedHashSet(); for ( Queryable persister : affectedQueryables ) { spacesList.addAll( Arrays.asList( (String[]) persister.getQuerySpaces() ) ); @@ -85,10 +85,10 @@ public class BulkOperationCleanupAction implements Executable, Serializable { naturalIdCleanups.add( new NaturalIdCleanup( persister.getNaturalIdCacheAccessStrategy() ) ); } - Set roles = factory.getCollectionRolesByEntityParticipant( persister.getEntityName() ); + final Set roles = factory.getCollectionRolesByEntityParticipant( persister.getEntityName() ); if ( roles != null ) { for ( String role : roles ) { - CollectionPersister collectionPersister = factory.getCollectionPersister( role ); + final CollectionPersister collectionPersister = factory.getCollectionPersister( role ); if ( collectionPersister.hasCache() ) { collectionCleanups.add( new CollectionCleanup( collectionPersister.getCacheAccessStrategy() ) ); } @@ -113,10 +113,10 @@ public class BulkOperationCleanupAction implements Executable, Serializable { */ @SuppressWarnings({ "unchecked" }) public BulkOperationCleanupAction(SessionImplementor session, Set tableSpaces) { - LinkedHashSet spacesList = new LinkedHashSet(); + final LinkedHashSet spacesList = new LinkedHashSet(); spacesList.addAll( tableSpaces ); - SessionFactoryImplementor factory = session.getFactory(); + final SessionFactoryImplementor factory = session.getFactory(); for ( String entityName : factory.getAllClassMetadata().keySet() ) { final EntityPersister persister = factory.getEntityPersister( entityName ); final String[] entitySpaces = (String[]) persister.getQuerySpaces(); @@ -130,10 +130,10 @@ public class BulkOperationCleanupAction implements Executable, Serializable { naturalIdCleanups.add( new NaturalIdCleanup( persister.getNaturalIdCacheAccessStrategy() ) ); } - Set roles = session.getFactory().getCollectionRolesByEntityParticipant( persister.getEntityName() ); + final Set roles = session.getFactory().getCollectionRolesByEntityParticipant( persister.getEntityName() ); if ( roles != null ) { for ( String role : roles ) { - CollectionPersister collectionPersister = factory.getCollectionPersister( role ); + final CollectionPersister collectionPersister = factory.getCollectionPersister( role ); if ( collectionPersister.hasCache() ) { collectionCleanups.add( new CollectionCleanup( collectionPersister.getCacheAccessStrategy() ) diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionAction.java index 55884de903..dc36d245c4 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionAction.java @@ -54,8 +54,8 @@ public abstract class CollectionAction implements Executable, Serializable, Comp private final Serializable key; private final String collectionRole; - public CollectionAction( - final CollectionPersister persister, + protected CollectionAction( + final CollectionPersister persister, final PersistentCollection collection, final Serializable key, final SessionImplementor session) { @@ -144,7 +144,7 @@ public abstract class CollectionAction implements Executable, Serializable, Comp protected final void evict() throws CacheException { if ( persister.hasCache() ) { - CacheKey ck = session.generateCacheKey( + final CacheKey ck = session.generateCacheKey( key, persister.getKeyType(), persister.getRole() @@ -155,22 +155,21 @@ public abstract class CollectionAction implements Executable, Serializable, Comp @Override public String toString() { - return StringHelper.unqualify( getClass().getName() ) + - MessageHelper.infoString( collectionRole, key ); + return StringHelper.unqualify( getClass().getName() ) + MessageHelper.infoString( collectionRole, key ); } @Override public int compareTo(Object other) { - CollectionAction action = ( CollectionAction ) other; - //sort first by role name - int roleComparison = collectionRole.compareTo( action.collectionRole ); + final CollectionAction action = (CollectionAction) other; + + // sort first by role name + final int roleComparison = collectionRole.compareTo( action.collectionRole ); if ( roleComparison != 0 ) { return roleComparison; } else { //then by fk - return persister.getKeyType() - .compare( key, action.key ); + return persister.getKeyType().compare( key, action.key ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionRecreateAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionRecreateAction.java index ea7767fd4b..5d6e64707f 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionRecreateAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionRecreateAction.java @@ -26,7 +26,6 @@ package org.hibernate.action.internal; import java.io.Serializable; import org.hibernate.HibernateException; -import org.hibernate.cache.CacheException; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.event.service.spi.EventListenerGroup; @@ -37,13 +36,24 @@ import org.hibernate.event.spi.PreCollectionRecreateEvent; import org.hibernate.event.spi.PreCollectionRecreateEventListener; import org.hibernate.persister.collection.CollectionPersister; +/** + * The action for recreating a collection + */ public final class CollectionRecreateAction extends CollectionAction { + /** + * Constructs a CollectionRecreateAction + * + * @param collection The collection being recreated + * @param persister The collection persister + * @param id The collection key + * @param session The session + */ public CollectionRecreateAction( final PersistentCollection collection, final CollectionPersister persister, final Serializable id, - final SessionImplementor session) throws CacheException { + final SessionImplementor session) { super( persister, collection, id, session ); } @@ -54,25 +64,18 @@ public final class CollectionRecreateAction extends CollectionAction { final PersistentCollection collection = getCollection(); preRecreate(); - getPersister().recreate( collection, getKey(), getSession() ); - - getSession().getPersistenceContext() - .getCollectionEntry(collection) - .afterAction(collection); - + getSession().getPersistenceContext().getCollectionEntry( collection ).afterAction( collection ); evict(); - postRecreate(); if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) { - getSession().getFactory().getStatisticsImplementor() - .recreateCollection( getPersister().getRole() ); + getSession().getFactory().getStatisticsImplementor().recreateCollection( getPersister().getRole() ); } } private void preRecreate() { - EventListenerGroup listenerGroup = listenerGroup( EventType.PRE_COLLECTION_RECREATE ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.PRE_COLLECTION_RECREATE ); if ( listenerGroup.isEmpty() ) { return; } @@ -83,7 +86,7 @@ public final class CollectionRecreateAction extends CollectionAction { } private void postRecreate() { - EventListenerGroup listenerGroup = listenerGroup( EventType.POST_COLLECTION_RECREATE ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.POST_COLLECTION_RECREATE ); if ( listenerGroup.isEmpty() ) { return; } diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionRemoveAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionRemoveAction.java index e341e18474..f77b55eec0 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionRemoveAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionRemoveAction.java @@ -37,11 +37,13 @@ import org.hibernate.event.spi.PreCollectionRemoveEvent; import org.hibernate.event.spi.PreCollectionRemoveEventListener; import org.hibernate.persister.collection.CollectionPersister; +/** + * The action for removing a collection + */ public final class CollectionRemoveAction extends CollectionAction { - - private boolean emptySnapshot; private final Object affectedOwner; - + private boolean emptySnapshot; + /** * Removes a persistent collection from its loaded owner. * @@ -62,7 +64,7 @@ public final class CollectionRemoveAction extends CollectionAction { final boolean emptySnapshot, final SessionImplementor session) { super( persister, collection, id, session ); - if (collection == null) { + if ( collection == null ) { throw new AssertionFailure("collection == null"); } this.emptySnapshot = emptySnapshot; @@ -92,7 +94,7 @@ public final class CollectionRemoveAction extends CollectionAction { final boolean emptySnapshot, final SessionImplementor session) { super( persister, null, id, session ); - if (affectedOwner == null) { + if ( affectedOwner == null ) { throw new AssertionFailure("affectedOwner == null"); } this.emptySnapshot = emptySnapshot; @@ -112,24 +114,20 @@ public final class CollectionRemoveAction extends CollectionAction { } final PersistentCollection collection = getCollection(); - if (collection!=null) { - getSession().getPersistenceContext() - .getCollectionEntry(collection) - .afterAction(collection); + if ( collection != null ) { + getSession().getPersistenceContext().getCollectionEntry( collection ).afterAction( collection ); } - - evict(); - postRemove(); + evict(); + postRemove(); if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) { - getSession().getFactory().getStatisticsImplementor() - .removeCollection( getPersister().getRole() ); + getSession().getFactory().getStatisticsImplementor().removeCollection( getPersister().getRole() ); } } private void preRemove() { - EventListenerGroup listenerGroup = listenerGroup( EventType.PRE_COLLECTION_REMOVE ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.PRE_COLLECTION_REMOVE ); if ( listenerGroup.isEmpty() ) { return; } @@ -145,7 +143,7 @@ public final class CollectionRemoveAction extends CollectionAction { } private void postRemove() { - EventListenerGroup listenerGroup = listenerGroup( EventType.POST_COLLECTION_REMOVE ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.POST_COLLECTION_REMOVE ); if ( listenerGroup.isEmpty() ) { return; } diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionUpdateAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionUpdateAction.java index 31c565ce15..655bed0eff 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionUpdateAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionUpdateAction.java @@ -38,10 +38,21 @@ import org.hibernate.event.spi.PreCollectionUpdateEventListener; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.pretty.MessageHelper; +/** + * The action for updating a collection + */ public final class CollectionUpdateAction extends CollectionAction { - private final boolean emptySnapshot; + /** + * Constructs a CollectionUpdateAction + * + * @param collection The collection to update + * @param persister The collection persister + * @param id The collection key + * @param emptySnapshot Indicates if the snapshot is empty + * @param session The session + */ public CollectionUpdateAction( final PersistentCollection collection, final CollectionPersister persister, @@ -58,26 +69,31 @@ public final class CollectionUpdateAction extends CollectionAction { final SessionImplementor session = getSession(); final CollectionPersister persister = getPersister(); final PersistentCollection collection = getCollection(); - boolean affectedByFilters = persister.isAffectedByEnabledFilters(session); + final boolean affectedByFilters = persister.isAffectedByEnabledFilters( session ); preUpdate(); if ( !collection.wasInitialized() ) { - if ( !collection.hasQueuedOperations() ) throw new AssertionFailure( "no queued adds" ); + if ( !collection.hasQueuedOperations() ) { + throw new AssertionFailure( "no queued adds" ); + } //do nothing - we only need to notify the cache... } else if ( !affectedByFilters && collection.empty() ) { - if ( !emptySnapshot ) persister.remove( id, session ); + if ( !emptySnapshot ) { + persister.remove( id, session ); + } } - else if ( collection.needsRecreate(persister) ) { - if (affectedByFilters) { + else if ( collection.needsRecreate( persister ) ) { + if ( affectedByFilters ) { throw new HibernateException( - "cannot recreate collection while filter is enabled: " + - MessageHelper.collectionInfoString(persister, collection, - id, session ) + "cannot recreate collection while filter is enabled: " + + MessageHelper.collectionInfoString( persister, collection, id, session ) ); } - if ( !emptySnapshot ) persister.remove( id, session ); + if ( !emptySnapshot ) { + persister.remove( id, session ); + } persister.recreate( collection, id, session ); } else { @@ -86,22 +102,17 @@ public final class CollectionUpdateAction extends CollectionAction { persister.insertRows( collection, id, session ); } - getSession().getPersistenceContext() - .getCollectionEntry(collection) - .afterAction(collection); - + getSession().getPersistenceContext().getCollectionEntry( collection ).afterAction( collection ); evict(); - postUpdate(); if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) { - getSession().getFactory().getStatisticsImplementor(). - updateCollection( getPersister().getRole() ); + getSession().getFactory().getStatisticsImplementor().updateCollection( getPersister().getRole() ); } } private void preUpdate() { - EventListenerGroup listenerGroup = listenerGroup( EventType.PRE_COLLECTION_UPDATE ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.PRE_COLLECTION_UPDATE ); if ( listenerGroup.isEmpty() ) { return; } @@ -116,7 +127,7 @@ public final class CollectionUpdateAction extends CollectionAction { } private void postUpdate() { - EventListenerGroup listenerGroup = listenerGroup( EventType.POST_COLLECTION_UPDATE ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.POST_COLLECTION_UPDATE ); if ( listenerGroup.isEmpty() ) { return; } diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/DelayedPostInsertIdentifier.java b/hibernate-core/src/main/java/org/hibernate/action/internal/DelayedPostInsertIdentifier.java index 37a29f374c..785e38f25c 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/DelayedPostInsertIdentifier.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/DelayedPostInsertIdentifier.java @@ -38,15 +38,19 @@ import java.io.Serializable; * @author Steve Ebersole */ public class DelayedPostInsertIdentifier implements Serializable { - private static long SEQUENCE = 0; - private final long sequence; + private static long sequence; + private final long identifier; + + /** + * Constructs a DelayedPostInsertIdentifier + */ public DelayedPostInsertIdentifier() { synchronized( DelayedPostInsertIdentifier.class ) { - if ( SEQUENCE == Long.MAX_VALUE ) { - SEQUENCE = 0; + if ( sequence == Long.MAX_VALUE ) { + sequence = 0; } - this.sequence = SEQUENCE++; + this.identifier = sequence++; } } @@ -58,18 +62,18 @@ public class DelayedPostInsertIdentifier implements Serializable { if ( o == null || getClass() != o.getClass() ) { return false; } - final DelayedPostInsertIdentifier that = ( DelayedPostInsertIdentifier ) o; - return sequence == that.sequence; + final DelayedPostInsertIdentifier that = (DelayedPostInsertIdentifier) o; + return identifier == that.identifier; } @Override public int hashCode() { - return ( int ) ( sequence ^ ( sequence >>> 32 ) ); + return (int) ( identifier ^ ( identifier >>> 32 ) ); } @Override public String toString() { - return ""; + return ""; } } diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityAction.java index ddaa7f44d4..5b29ddd326 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityAction.java @@ -84,7 +84,7 @@ public abstract class EntityAction protected abstract boolean hasPostCommitEventListeners(); - public boolean needsAfterTransactionCompletion() { + protected boolean needsAfterTransactionCompletion() { return persister.hasCache() || hasPostCommitEventListeners(); } @@ -104,16 +104,16 @@ public abstract class EntityAction */ public final Serializable getId() { if ( id instanceof DelayedPostInsertIdentifier ) { - Serializable eeId = session.getPersistenceContext().getEntry( instance ).getId(); + final Serializable eeId = session.getPersistenceContext().getEntry( instance ).getId(); return eeId instanceof DelayedPostInsertIdentifier ? null : eeId; } return id; } public final DelayedPostInsertIdentifier getDelayedId() { - return DelayedPostInsertIdentifier.class.isInstance( id ) ? - DelayedPostInsertIdentifier.class.cast( id ) : - null; + return DelayedPostInsertIdentifier.class.isInstance( id ) + ? DelayedPostInsertIdentifier.class.cast( id ) + : null; } /** @@ -160,9 +160,9 @@ public abstract class EntityAction @Override public int compareTo(Object other) { - EntityAction action = ( EntityAction ) other; + final EntityAction action = (EntityAction) other; //sort first by entity name - int roleComparison = entityName.compareTo( action.entityName ); + final int roleComparison = entityName.compareTo( action.entityName ); if ( roleComparison != 0 ) { return roleComparison; } diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java index ed1ae724f8..9cd13d1524 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java @@ -29,7 +29,6 @@ import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.access.SoftLock; -import org.hibernate.engine.spi.CachedNaturalIdValueSource; import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.SessionImplementor; @@ -37,11 +36,13 @@ import org.hibernate.event.service.spi.EventListenerGroup; import org.hibernate.event.spi.EventType; import org.hibernate.event.spi.PostDeleteEvent; import org.hibernate.event.spi.PostDeleteEventListener; -import org.hibernate.event.spi.PostInsertEventListener; import org.hibernate.event.spi.PreDeleteEvent; import org.hibernate.event.spi.PreDeleteEventListener; import org.hibernate.persister.entity.EntityPersister; +/** + * The action for performing an entity deletion. + */ public final class EntityDeleteAction extends EntityAction { private final Object version; private final boolean isCascadeDeleteEnabled; @@ -50,14 +51,25 @@ public final class EntityDeleteAction extends EntityAction { private SoftLock lock; private Object[] naturalIdValues; + /** + * Constructs an EntityDeleteAction. + * + * @param id The entity identifier + * @param state The current (extracted) entity state + * @param version The current entity version + * @param instance The entity instance + * @param persister The entity persister + * @param isCascadeDeleteEnabled Whether cascade delete is enabled + * @param session The session + */ public EntityDeleteAction( final Serializable id, - final Object[] state, - final Object version, - final Object instance, - final EntityPersister persister, - final boolean isCascadeDeleteEnabled, - final SessionImplementor session) { + final Object[] state, + final Object version, + final Object instance, + final EntityPersister persister, + final boolean isCascadeDeleteEnabled, + final SessionImplementor session) { super( session, id, instance, persister ); this.version = version; this.isCascadeDeleteEnabled = isCascadeDeleteEnabled; @@ -73,12 +85,12 @@ public final class EntityDeleteAction extends EntityAction { @Override public void execute() throws HibernateException { - Serializable id = getId(); - EntityPersister persister = getPersister(); - SessionImplementor session = getSession(); - Object instance = getInstance(); + final Serializable id = getId(); + final EntityPersister persister = getPersister(); + final SessionImplementor session = getSession(); + final Object instance = getInstance(); - boolean veto = preDelete(); + final boolean veto = preDelete(); Object version = this.version; if ( persister.isVersionPropertyGenerated() ) { @@ -106,7 +118,7 @@ public final class EntityDeleteAction extends EntityAction { // exists on the database (needed for identity-column key generation), and // remove it from the session cache final PersistenceContext persistenceContext = session.getPersistenceContext(); - EntityEntry entry = persistenceContext.removeEntry( instance ); + final EntityEntry entry = persistenceContext.removeEntry( instance ); if ( entry == null ) { throw new AssertionFailure( "possible nonthreadsafe access to session" ); } @@ -130,7 +142,7 @@ public final class EntityDeleteAction extends EntityAction { private boolean preDelete() { boolean veto = false; - EventListenerGroup listenerGroup = listenerGroup( EventType.PRE_DELETE ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.PRE_DELETE ); if ( listenerGroup.isEmpty() ) { return veto; } @@ -142,7 +154,7 @@ public final class EntityDeleteAction extends EntityAction { } private void postDelete() { - EventListenerGroup listenerGroup = listenerGroup( EventType.POST_DELETE ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.POST_DELETE ); if ( listenerGroup.isEmpty() ) { return; } @@ -159,7 +171,7 @@ public final class EntityDeleteAction extends EntityAction { } private void postCommitDelete() { - EventListenerGroup listenerGroup = listenerGroup( EventType.POST_COMMIT_DELETE ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.POST_COMMIT_DELETE ); if ( listenerGroup.isEmpty() ) { return; } diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityIdentityInsertAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityIdentityInsertAction.java index 54b325782f..2edcd836a2 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityIdentityInsertAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityIdentityInsertAction.java @@ -37,21 +37,37 @@ import org.hibernate.event.spi.PreInsertEvent; import org.hibernate.event.spi.PreInsertEventListener; import org.hibernate.persister.entity.EntityPersister; +/** + * The action for performing entity insertions when entity is using IDENTITY column identifier generation + * + * @see EntityInsertAction + */ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction { private final boolean isDelayed; private final EntityKey delayedEntityKey; private EntityKey entityKey; - //private CacheEntry cacheEntry; private Serializable generatedId; + /** + * Constructs an EntityIdentityInsertAction + * + * @param state The current (extracted) entity state + * @param instance The entity instance + * @param persister The entity persister + * @param isVersionIncrementDisabled Whether version incrementing is disabled + * @param session The session + * @param isDelayed Are we in a situation which allows the insertion to be delayed? + * + * @throws HibernateException Indicates an illegal state + */ public EntityIdentityInsertAction( Object[] state, Object instance, EntityPersister persister, boolean isVersionIncrementDisabled, SessionImplementor session, - boolean isDelayed) throws HibernateException { + boolean isDelayed) { super( ( isDelayed ? generateDelayedPostInsertIdentifier() : null ), state, @@ -72,7 +88,7 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction final SessionImplementor session = getSession(); final Object instance = getInstance(); - boolean veto = preInsert(); + final boolean veto = preInsert(); // Don't need to lock the cache here, since if someone // else inserted the same pk first, the insert would fail @@ -109,13 +125,13 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction } @Override - public boolean needsAfterTransactionCompletion() { + public boolean needsAfterTransactionCompletion() { //TODO: simply remove this override if we fix the above todos return hasPostCommitEventListeners(); } @Override - protected boolean hasPostCommitEventListeners() { + protected boolean hasPostCommitEventListeners() { final EventListenerGroup group = listenerGroup( EventType.POST_COMMIT_INSERT ); for ( PostInsertEventListener listener : group.listeners() ) { if ( listener.requiresPostCommitHanding( getPersister() ) ) { @@ -141,7 +157,7 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction getSession().getPersistenceContext().replaceDelayedEntityIdentityInsertKeys( delayedEntityKey, generatedId ); } - EventListenerGroup listenerGroup = listenerGroup( EventType.POST_INSERT ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.POST_INSERT ); if ( listenerGroup.isEmpty() ) { return; } @@ -158,7 +174,7 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction } private void postCommitInsert() { - EventListenerGroup listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT ); if ( listenerGroup.isEmpty() ) { return; } @@ -175,9 +191,10 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction } private boolean preInsert() { - EventListenerGroup listenerGroup = listenerGroup( EventType.PRE_INSERT ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.PRE_INSERT ); if ( listenerGroup.isEmpty() ) { - return false; // NO_VETO + // NO_VETO + return false; } boolean veto = false; final PreInsertEvent event = new PreInsertEvent( getInstance(), null, getState(), getPersister(), eventSource() ); @@ -187,11 +204,24 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction return veto; } + /** + * Access to the generated identifier + * + * @return The generated identifier + */ public final Serializable getGeneratedId() { return generatedId; } - // TODO: nothing seems to use this method; can it be renmoved? + /** + * Access to the delayed entity key + * + * @return The delayed entity key + * + * @deprecated No Hibernate code currently uses this method + */ + @Deprecated + @SuppressWarnings("UnusedDeclaration") public EntityKey getDelayedEntityKey() { return delayedEntityKey; } @@ -206,7 +236,7 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction return entityKey != null ? entityKey : delayedEntityKey; } - private synchronized static DelayedPostInsertIdentifier generateDelayedPostInsertIdentifier() { + private static synchronized DelayedPostInsertIdentifier generateDelayedPostInsertIdentifier() { return new DelayedPostInsertIdentifier(); } diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityIncrementVersionProcess.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityIncrementVersionProcess.java index d50532c801..ca06a02de8 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityIncrementVersionProcess.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityIncrementVersionProcess.java @@ -29,7 +29,8 @@ import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.entity.EntityPersister; /** - * Verify/Increment the entity version + * A BeforeTransactionCompletionProcess impl to verify and increment an entity version as party + * of before-transaction-completion processing * * @author Scott Marlow */ @@ -37,6 +38,12 @@ public class EntityIncrementVersionProcess implements BeforeTransactionCompletio private final Object object; private final EntityEntry entry; + /** + * Constructs an EntityIncrementVersionProcess for the given entity. + * + * @param object The entity instance + * @param entry The entity's EntityEntry reference + */ public EntityIncrementVersionProcess(Object object, EntityEntry entry) { this.object = object; this.entry = entry; @@ -50,9 +57,7 @@ public class EntityIncrementVersionProcess implements BeforeTransactionCompletio @Override public void doBeforeTransactionCompletion(SessionImplementor session) { final EntityPersister persister = entry.getPersister(); - Object nextVersion = persister.forceVersionIncrement( - entry.getId(), entry.getVersion(), session - ); + final Object nextVersion = persister.forceVersionIncrement( entry.getId(), entry.getVersion(), session ); entry.forceLocked( object, nextVersion ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityInsertAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityInsertAction.java index ea645fcdc8..fba5c3e6ef 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityInsertAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityInsertAction.java @@ -42,11 +42,27 @@ import org.hibernate.event.spi.PreInsertEvent; import org.hibernate.event.spi.PreInsertEventListener; import org.hibernate.persister.entity.EntityPersister; +/** + * The action for performing an entity insertion, for entities not defined to use IDENTITY generation. + * + * @see EntityIdentityInsertAction + */ public final class EntityInsertAction extends AbstractEntityInsertAction { private Object version; private Object cacheEntry; + /** + * Constructs an EntityInsertAction. + * + * @param id The entity identifier + * @param state The current (extracted) entity state + * @param instance The entity instance + * @param version The current entity version value + * @param persister The entity's persister + * @param isVersionIncrementDisabled Whether version incrementing is disabled. + * @param session The session + */ public EntityInsertAction( Serializable id, Object[] state, @@ -54,7 +70,7 @@ public final class EntityInsertAction extends AbstractEntityInsertAction { Object version, EntityPersister persister, boolean isVersionIncrementDisabled, - SessionImplementor session) throws HibernateException { + SessionImplementor session) { super( id, state, instance, isVersionIncrementDisabled, persister, session ); this.version = version; } @@ -73,12 +89,12 @@ public final class EntityInsertAction extends AbstractEntityInsertAction { public void execute() throws HibernateException { nullifyTransientReferencesIfNotAlready(); - EntityPersister persister = getPersister(); - SessionImplementor session = getSession(); - Object instance = getInstance(); - Serializable id = getId(); + final EntityPersister persister = getPersister(); + final SessionImplementor session = getSession(); + final Object instance = getInstance(); + final Serializable id = getId(); - boolean veto = preInsert(); + final boolean veto = preInsert(); // Don't need to lock the cache here, since if someone // else inserted the same pk first, the insert would fail @@ -86,8 +102,8 @@ public final class EntityInsertAction extends AbstractEntityInsertAction { if ( !veto ) { persister.insert( id, getState(), instance, session ); - - EntityEntry entry = session.getPersistenceContext().getEntry( instance ); + + final EntityEntry entry = session.getPersistenceContext().getEntry( instance ); if ( entry == null ) { throw new AssertionFailure( "possible non-threadsafe access to session" ); } @@ -99,7 +115,7 @@ public final class EntityInsertAction extends AbstractEntityInsertAction { if ( persister.isVersionPropertyGenerated() ) { version = Versioning.getVersion( getState(), persister ); } - entry.postUpdate(instance, getState(), version); + entry.postUpdate( instance, getState(), version ); } getSession().getPersistenceContext().registerInsertedKey( getPersister(), getId() ); @@ -108,7 +124,7 @@ public final class EntityInsertAction extends AbstractEntityInsertAction { final SessionFactoryImplementor factory = getSession().getFactory(); if ( isCachePutEnabled( persister, session ) ) { - CacheEntry ce = persister.buildCacheEntry( + final CacheEntry ce = persister.buildCacheEntry( instance, getState(), version, @@ -116,14 +132,14 @@ public final class EntityInsertAction extends AbstractEntityInsertAction { ); cacheEntry = persister.getCacheEntryStructure().structure(ce); final CacheKey ck = session.generateCacheKey( id, persister.getIdentifierType(), persister.getRootEntityName() ); - boolean put = persister.getCacheAccessStrategy().insert( ck, cacheEntry, version ); + final boolean put = persister.getCacheAccessStrategy().insert( ck, cacheEntry, version ); if ( put && factory.getStatistics().isStatisticsEnabled() ) { factory.getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() ); } } - handleNaturalIdPostSaveNotifications(id); + handleNaturalIdPostSaveNotifications( id ); postInsert(); @@ -136,7 +152,7 @@ public final class EntityInsertAction extends AbstractEntityInsertAction { } private void postInsert() { - EventListenerGroup listenerGroup = listenerGroup( EventType.POST_INSERT ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.POST_INSERT ); if ( listenerGroup.isEmpty() ) { return; } @@ -153,7 +169,7 @@ public final class EntityInsertAction extends AbstractEntityInsertAction { } private void postCommitInsert() { - EventListenerGroup listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT ); if ( listenerGroup.isEmpty() ) { return; } @@ -172,7 +188,7 @@ public final class EntityInsertAction extends AbstractEntityInsertAction { private boolean preInsert() { boolean veto = false; - EventListenerGroup listenerGroup = listenerGroup( EventType.PRE_INSERT ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.PRE_INSERT ); if ( listenerGroup.isEmpty() ) { return veto; } @@ -185,10 +201,10 @@ public final class EntityInsertAction extends AbstractEntityInsertAction { @Override public void doAfterTransactionCompletion(boolean success, SessionImplementor session) throws HibernateException { - EntityPersister persister = getPersister(); + final EntityPersister persister = getPersister(); if ( success && isCachePutEnabled( persister, getSession() ) ) { final CacheKey ck = getSession().generateCacheKey( getId(), persister.getIdentifierType(), persister.getRootEntityName() ); - boolean put = persister.getCacheAccessStrategy().afterInsert( ck, cacheEntry, version ); + final boolean put = persister.getCacheAccessStrategy().afterInsert( ck, cacheEntry, version ); if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) { getSession().getFactory().getStatisticsImplementor() diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java index fd875fbb27..9b1c763693 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java @@ -46,6 +46,9 @@ import org.hibernate.event.spi.PreUpdateEventListener; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.type.TypeHelper; +/** + * The action for performing entity updates. + */ public final class EntityUpdateAction extends EntityAction { private final Object[] state; private final Object[] previousState; @@ -58,18 +61,33 @@ public final class EntityUpdateAction extends EntityAction { private Object cacheEntry; private SoftLock lock; + /** + * Constructs an EntityUpdateAction + * + * @param id The entity identifier + * @param state The current (extracted) entity state + * @param dirtyProperties The indexes (in reference to state) properties with dirty state + * @param hasDirtyCollection Were any collections dirty? + * @param previousState The previous (stored) state + * @param previousVersion The previous (stored) version + * @param nextVersion The incremented version + * @param instance The entity instance + * @param rowId The entity's rowid + * @param persister The entity's persister + * @param session The session + */ public EntityUpdateAction( - final Serializable id, - final Object[] state, - final int[] dirtyProperties, - final boolean hasDirtyCollection, - final Object[] previousState, - final Object previousVersion, - final Object nextVersion, - final Object instance, - final Object rowId, - final EntityPersister persister, - final SessionImplementor session) throws HibernateException { + final Serializable id, + final Object[] state, + final int[] dirtyProperties, + final boolean hasDirtyCollection, + final Object[] previousState, + final Object previousVersion, + final Object nextVersion, + final Object instance, + final Object rowId, + final EntityPersister persister, + final SessionImplementor session) { super( session, id, instance, persister ); this.state = state; this.previousState = previousState; @@ -107,12 +125,12 @@ public final class EntityUpdateAction extends EntityAction { @Override public void execute() throws HibernateException { - Serializable id = getId(); - EntityPersister persister = getPersister(); - SessionImplementor session = getSession(); - Object instance = getInstance(); + final Serializable id = getId(); + final EntityPersister persister = getPersister(); + final SessionImplementor session = getSession(); + final Object instance = getInstance(); - boolean veto = preUpdate(); + final boolean veto = preUpdate(); final SessionFactoryImplementor factory = getSession().getFactory(); Object previousVersion = this.previousVersion; @@ -150,7 +168,7 @@ public final class EntityUpdateAction extends EntityAction { ); } - EntityEntry entry = getSession().getPersistenceContext().getEntry( instance ); + final EntityEntry entry = getSession().getPersistenceContext().getEntry( instance ); if ( entry == null ) { throw new AssertionFailure( "possible nonthreadsafe access to session" ); } @@ -185,9 +203,9 @@ public final class EntityUpdateAction extends EntityAction { } else { //TODO: inefficient if that cache is just going to ignore the updated state! - CacheEntry ce = persister.buildCacheEntry( instance,state, nextVersion, getSession() ); + final CacheEntry ce = persister.buildCacheEntry( instance,state, nextVersion, getSession() ); cacheEntry = persister.getCacheEntryStructure().structure( ce ); - boolean put = persister.getCacheAccessStrategy().update( ck, cacheEntry, nextVersion, previousVersion ); + final boolean put = persister.getCacheAccessStrategy().update( ck, cacheEntry, nextVersion, previousVersion ); if ( put && factory.getStatistics().isStatisticsEnabled() ) { factory.getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() ); } @@ -205,14 +223,13 @@ public final class EntityUpdateAction extends EntityAction { postUpdate(); if ( factory.getStatistics().isStatisticsEnabled() && !veto ) { - factory.getStatisticsImplementor() - .updateEntity( getPersister().getEntityName() ); + factory.getStatisticsImplementor().updateEntity( getPersister().getEntityName() ); } } private boolean preUpdate() { boolean veto = false; - EventListenerGroup listenerGroup = listenerGroup( EventType.PRE_UPDATE ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.PRE_UPDATE ); if ( listenerGroup.isEmpty() ) { return veto; } @@ -231,7 +248,7 @@ public final class EntityUpdateAction extends EntityAction { } private void postUpdate() { - EventListenerGroup listenerGroup = listenerGroup( EventType.POST_UPDATE ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.POST_UPDATE ); if ( listenerGroup.isEmpty() ) { return; } @@ -250,7 +267,7 @@ public final class EntityUpdateAction extends EntityAction { } private void postCommitUpdate() { - EventListenerGroup listenerGroup = listenerGroup( EventType.POST_COMMIT_UPDATE ); + final EventListenerGroup listenerGroup = listenerGroup( EventType.POST_COMMIT_UPDATE ); if ( listenerGroup.isEmpty() ) { return; } @@ -282,17 +299,17 @@ public final class EntityUpdateAction extends EntityAction { @Override public void doAfterTransactionCompletion(boolean success, SessionImplementor session) throws CacheException { - EntityPersister persister = getPersister(); + final EntityPersister persister = getPersister(); if ( persister.hasCache() ) { final CacheKey ck = getSession().generateCacheKey( - getId(), + getId(), persister.getIdentifierType(), persister.getRootEntityName() - ); + ); if ( success && cacheEntry!=null /*!persister.isCacheInvalidationRequired()*/ ) { - boolean put = persister.getCacheAccessStrategy().afterUpdate( ck, cacheEntry, nextVersion, previousVersion, lock ); + final boolean put = persister.getCacheAccessStrategy().afterUpdate( ck, cacheEntry, nextVersion, previousVersion, lock ); if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) { getSession().getFactory().getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() ); diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityVerifyVersionProcess.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityVerifyVersionProcess.java index 85b99a30da..6c1d694195 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityVerifyVersionProcess.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityVerifyVersionProcess.java @@ -31,15 +31,21 @@ import org.hibernate.persister.entity.EntityPersister; import org.hibernate.pretty.MessageHelper; /** - * Verify/Increment the entity version + * A BeforeTransactionCompletionProcess impl to verify an entity version as part of + * before-transaction-completion processing * * @author Scott Marlow */ public class EntityVerifyVersionProcess implements BeforeTransactionCompletionProcess { - @SuppressWarnings( {"FieldCanBeLocal", "UnusedDeclaration"}) private final Object object; private final EntityEntry entry; + /** + * Constructs an EntityVerifyVersionProcess + * + * @param object The entity instance + * @param entry The entity's referenced EntityEntry + */ public EntityVerifyVersionProcess(Object object, EntityEntry entry) { this.object = object; this.entry = entry; @@ -49,7 +55,7 @@ public class EntityVerifyVersionProcess implements BeforeTransactionCompletionPr public void doBeforeTransactionCompletion(SessionImplementor session) { final EntityPersister persister = entry.getPersister(); - Object latestVersion = persister.getCurrentVersion( entry.getId(), session ); + final Object latestVersion = persister.getCurrentVersion( entry.getId(), session ); if ( !entry.getVersion().equals( latestVersion ) ) { throw new OptimisticLockException( object, @@ -59,4 +65,4 @@ public class EntityVerifyVersionProcess implements BeforeTransactionCompletionPr ); } } -} \ No newline at end of file +} diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/UnresolvedEntityInsertActions.java b/hibernate-core/src/main/java/org/hibernate/action/internal/UnresolvedEntityInsertActions.java index e6e18e9acf..99fbaae36f 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/UnresolvedEntityInsertActions.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/UnresolvedEntityInsertActions.java @@ -62,7 +62,8 @@ public class UnresolvedEntityInsertActions { private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, UnresolvedEntityInsertActions.class.getName() - ); + ); + private static final int INIT_SIZE = 5; private final Map dependenciesByAction = @@ -121,17 +122,18 @@ public class UnresolvedEntityInsertActions { LOG.trace( "No entity insert actions have non-nullable, transient entity dependencies." ); } else { - AbstractEntityInsertAction firstDependentAction = + final AbstractEntityInsertAction firstDependentAction = dependenciesByAction.keySet().iterator().next(); logCannotResolveNonNullableTransientDependencies( firstDependentAction.getSession() ); - NonNullableTransientDependencies nonNullableTransientDependencies = + final NonNullableTransientDependencies nonNullableTransientDependencies = dependenciesByAction.get( firstDependentAction ); - Object firstTransientDependency = + final Object firstTransientDependency = nonNullableTransientDependencies.getNonNullableTransientEntities().iterator().next(); - String firstPropertyPath = + final String firstPropertyPath = nonNullableTransientDependencies.getNonNullableTransientPropertyPaths( firstTransientDependency ).iterator().next(); + throw new TransientPropertyValueException( "Not-null property references a transient value - transient instance must be saved before current operation", firstDependentAction.getSession().guessEntityName( firstTransientDependency ), @@ -143,23 +145,20 @@ public class UnresolvedEntityInsertActions { private void logCannotResolveNonNullableTransientDependencies(SessionImplementor session) { for ( Map.Entry> entry : dependentActionsByTransientEntity.entrySet() ) { - Object transientEntity = entry.getKey(); - String transientEntityName = session.guessEntityName( transientEntity ); - Serializable transientEntityId = session.getFactory().getEntityPersister( transientEntityName ).getIdentifier( transientEntity, session ); - String transientEntityString = MessageHelper.infoString( transientEntityName, transientEntityId ); - Set dependentEntityStrings = new TreeSet(); - Set nonNullableTransientPropertyPaths = new TreeSet(); + final Object transientEntity = entry.getKey(); + final String transientEntityName = session.guessEntityName( transientEntity ); + final Serializable transientEntityId = session.getFactory().getEntityPersister( transientEntityName ).getIdentifier( transientEntity, session ); + final String transientEntityString = MessageHelper.infoString( transientEntityName, transientEntityId ); + final Set dependentEntityStrings = new TreeSet(); + final Set nonNullableTransientPropertyPaths = new TreeSet(); for ( AbstractEntityInsertAction dependentAction : entry.getValue() ) { dependentEntityStrings.add( MessageHelper.infoString( dependentAction.getEntityName(), dependentAction.getId() ) ); for ( String path : dependenciesByAction.get( dependentAction ).getNonNullableTransientPropertyPaths( transientEntity ) ) { - String fullPath = new StringBuilder( dependentAction.getEntityName().length() + path.length() + 1 ) - .append( dependentAction.getEntityName() ) - .append( '.' ) - .append( path ) - .toString(); + final String fullPath = dependentAction.getEntityName() + '.' + path; nonNullableTransientPropertyPaths.add( fullPath ); } } + LOG.cannotResolveNonNullableTransientDependencies( transientEntityString, dependentEntityStrings, @@ -200,7 +199,7 @@ public class UnresolvedEntityInsertActions { */ @SuppressWarnings({ "unchecked" }) public Set resolveDependentActions(Object managedEntity, SessionImplementor session) { - EntityEntry entityEntry = session.getPersistenceContext().getEntry( managedEntity ); + final EntityEntry entityEntry = session.getPersistenceContext().getEntry( managedEntity ); if ( entityEntry.getStatus() != Status.MANAGED && entityEntry.getStatus() != Status.READ_ONLY ) { throw new IllegalArgumentException( "EntityEntry did not have status MANAGED or READ_ONLY: " + entityEntry ); } @@ -208,7 +207,7 @@ public class UnresolvedEntityInsertActions { final boolean traceEnabled = LOG.isTraceEnabled(); // Find out if there are any unresolved insertions that are waiting for the // specified entity to be resolved. - Set dependentActions = dependentActionsByTransientEntity.remove( managedEntity ); + final Set dependentActions = dependentActionsByTransientEntity.remove( managedEntity ); if ( dependentActions == null ) { if ( traceEnabled ) { LOG.tracev( @@ -216,9 +215,10 @@ public class UnresolvedEntityInsertActions { MessageHelper.infoString( entityEntry.getEntityName(), entityEntry.getId() ) ); } - return Collections.emptySet(); //NOTE EARLY EXIT! + // NOTE EARLY EXIT! + return Collections.emptySet(); } - Set resolvedActions = new IdentitySet( ); + final Set resolvedActions = new IdentitySet( ); if ( traceEnabled ) { LOG.tracev( "Unresolved inserts before resolving [{0}]: [{1}]", @@ -234,7 +234,7 @@ public class UnresolvedEntityInsertActions { MessageHelper.infoString( entityEntry.getEntityName(), entityEntry.getId() ) ); } - NonNullableTransientDependencies dependencies = dependenciesByAction.get( dependentAction ); + final NonNullableTransientDependencies dependencies = dependenciesByAction.get( dependentAction ); dependencies.resolveNonNullableTransientEntity( managedEntity ); if ( dependencies.isEmpty() ) { if ( traceEnabled ) { @@ -269,11 +269,11 @@ public class UnresolvedEntityInsertActions { @Override public String toString() { - StringBuilder sb = new StringBuilder( getClass().getSimpleName() ) + final StringBuilder sb = new StringBuilder( getClass().getSimpleName() ) .append( '[' ); for ( Map.Entry entry : dependenciesByAction.entrySet() ) { - AbstractEntityInsertAction insert = entry.getKey(); - NonNullableTransientDependencies dependencies = entry.getValue(); + final AbstractEntityInsertAction insert = entry.getKey(); + final NonNullableTransientDependencies dependencies = entry.getValue(); sb.append( "[insert=" ) .append( insert ) .append( " dependencies=[" ) @@ -290,7 +290,7 @@ public class UnresolvedEntityInsertActions { * @throws IOException if there is an error writing this object to the output stream. */ public void serialize(ObjectOutputStream oos) throws IOException { - int queueSize = dependenciesByAction.size(); + final int queueSize = dependenciesByAction.size(); LOG.tracev( "Starting serialization of [{0}] unresolved insert entries", queueSize ); oos.writeInt( queueSize ); for ( AbstractEntityInsertAction unresolvedAction : dependenciesByAction.keySet() ) { @@ -312,12 +312,12 @@ public class UnresolvedEntityInsertActions { ObjectInputStream ois, SessionImplementor session) throws IOException, ClassNotFoundException { - UnresolvedEntityInsertActions rtn = new UnresolvedEntityInsertActions(); + final UnresolvedEntityInsertActions rtn = new UnresolvedEntityInsertActions(); - int queueSize = ois.readInt(); + final int queueSize = ois.readInt(); LOG.tracev( "Starting deserialization of [{0}] unresolved insert entries", queueSize ); for ( int i = 0; i < queueSize; i++ ) { - AbstractEntityInsertAction unresolvedAction = ( AbstractEntityInsertAction ) ois.readObject(); + final AbstractEntityInsertAction unresolvedAction = (AbstractEntityInsertAction) ois.readObject(); unresolvedAction.afterDeserialize( session ); rtn.addUnresolvedEntityInsertAction( unresolvedAction, diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/package-info.java b/hibernate-core/src/main/java/org/hibernate/action/internal/package-info.java new file mode 100644 index 0000000000..7d1d434ea9 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/package-info.java @@ -0,0 +1,4 @@ +/** + * Internals for action processing. + */ +package org.hibernate.action.internal; diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/QueryHints.java b/hibernate-core/src/main/java/org/hibernate/annotations/QueryHints.java index d16e8015a5..15bd9a1ac8 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/QueryHints.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/QueryHints.java @@ -40,7 +40,7 @@ public class QueryHints { * @see org.hibernate.Query#setCacheMode * @see org.hibernate.SQLQuery#setCacheMode */ - public static final String CACHE_MODE = "org.hibernate.cacheMode"; + public static final String CACHE_MODE = "org.hibernate.cacheMode"; /** * The cache region to use. @@ -48,7 +48,7 @@ public class QueryHints { * @see org.hibernate.Query#setCacheRegion * @see org.hibernate.SQLQuery#setCacheRegion */ - public static final String CACHE_REGION = "org.hibernate.cacheRegion"; + public static final String CACHE_REGION = "org.hibernate.cacheRegion"; /** * Are the query results cacheable? @@ -56,12 +56,12 @@ public class QueryHints { * @see org.hibernate.Query#setCacheable * @see org.hibernate.SQLQuery#setCacheable */ - public static final String CACHEABLE = "org.hibernate.cacheable"; + public static final String CACHEABLE = "org.hibernate.cacheable"; /** * Is the query callable? Note: only valid for named native sql queries. */ - public static final String CALLABLE = "org.hibernate.callable"; + public static final String CALLABLE = "org.hibernate.callable"; /** * Defines a comment to be applied to the SQL sent to the database. @@ -69,7 +69,7 @@ public class QueryHints { * @see org.hibernate.Query#setComment * @see org.hibernate.SQLQuery#setComment */ - public static final String COMMENT = "org.hibernate.comment"; + public static final String COMMENT = "org.hibernate.comment"; /** * Defines the JDBC fetch size to use. @@ -77,7 +77,7 @@ public class QueryHints { * @see org.hibernate.Query#setFetchSize * @see org.hibernate.SQLQuery#setFetchSize */ - public static final String FETCH_SIZE = "org.hibernate.fetchSize"; + public static final String FETCH_SIZE = "org.hibernate.fetchSize"; /** * The flush mode to associate with the execution of the query. @@ -86,7 +86,7 @@ public class QueryHints { * @see org.hibernate.SQLQuery#setFlushMode * @see org.hibernate.Session#setFlushMode */ - public static final String FLUSH_MODE = "org.hibernate.flushMode"; + public static final String FLUSH_MODE = "org.hibernate.flushMode"; /** * Should entities returned from the query be set in read only mode? @@ -95,7 +95,7 @@ public class QueryHints { * @see org.hibernate.SQLQuery#setReadOnly * @see org.hibernate.Session#setReadOnly */ - public static final String READ_ONLY = "org.hibernate.readOnly"; + public static final String READ_ONLY = "org.hibernate.readOnly"; /** * Apply a Hibernate query timeout, which is defined in seconds. @@ -103,11 +103,11 @@ public class QueryHints { * @see org.hibernate.Query#setTimeout * @see org.hibernate.SQLQuery#setTimeout */ - public static final String TIMEOUT_HIBERNATE = "org.hibernate.timeout"; + public static final String TIMEOUT_HIBERNATE = "org.hibernate.timeout"; /** * Apply a JPA query timeout, which is defined in milliseconds. */ - public static final String TIMEOUT_JPA = "javax.persistence.query.timeout"; + public static final String TIMEOUT_JPA = "javax.persistence.query.timeout"; } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/BootstrapServiceRegistryBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/BootstrapServiceRegistryBuilder.java index ec3da4699c..775ea0f4cf 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/BootstrapServiceRegistryBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/BootstrapServiceRegistryBuilder.java @@ -202,9 +202,9 @@ public class BootstrapServiceRegistryBuilder { // the providedClassLoaders and the overridenClassLoader. final Set classLoaders = new HashSet(); - if ( providedClassLoaders != null ) { - classLoaders.addAll( providedClassLoaders ); - } + if ( providedClassLoaders != null ) { + classLoaders.addAll( providedClassLoaders ); + } classLoaderService = new ClassLoaderServiceImpl( classLoaders ); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/ClassLoaderServiceImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/ClassLoaderServiceImpl.java index 5c51256e1f..7e7c4ada58 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/ClassLoaderServiceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/ClassLoaderServiceImpl.java @@ -53,14 +53,27 @@ public class ClassLoaderServiceImpl implements ClassLoaderService { private final ClassLoader aggregatedClassLoader; + /** + * Constructs a ClassLoaderServiceImpl with standard set-up + */ public ClassLoaderServiceImpl() { this( ClassLoaderServiceImpl.class.getClassLoader() ); } + /** + * Constructs a ClassLoaderServiceImpl with the given ClassLoader + * + * @param classLoader The ClassLoader to use + */ public ClassLoaderServiceImpl(ClassLoader classLoader) { this( Collections.singletonList( classLoader ) ); } + /** + * Constructs a ClassLoaderServiceImpl with the given ClassLoader instances + * + * @param providedClassLoaders The ClassLoader instances to use + */ public ClassLoaderServiceImpl(Collection providedClassLoaders) { final LinkedHashSet orderedClassLoaderSet = new LinkedHashSet(); @@ -91,22 +104,31 @@ public class ClassLoaderServiceImpl implements ClassLoaderService { this.aggregatedClassLoader = new AggregatedClassLoader( orderedClassLoaderSet ); } - @SuppressWarnings({"UnusedDeclaration", "unchecked", "deprecation"}) + /** + * No longer used/supported! + * + * @param configValues The config values + * + * @return The built service + * + * @deprecated No longer used/supported! + */ @Deprecated - public static ClassLoaderServiceImpl fromConfigSettings(Map configVales) { + @SuppressWarnings({"UnusedDeclaration", "unchecked", "deprecation"}) + public static ClassLoaderServiceImpl fromConfigSettings(Map configValues) { final List providedClassLoaders = new ArrayList(); - final Collection classLoaders = (Collection) configVales.get( AvailableSettings.CLASSLOADERS ); + final Collection classLoaders = (Collection) configValues.get( AvailableSettings.CLASSLOADERS ); if ( classLoaders != null ) { for ( ClassLoader classLoader : classLoaders ) { providedClassLoaders.add( classLoader ); } } - addIfSet( providedClassLoaders, AvailableSettings.APP_CLASSLOADER, configVales ); - addIfSet( providedClassLoaders, AvailableSettings.RESOURCES_CLASSLOADER, configVales ); - addIfSet( providedClassLoaders, AvailableSettings.HIBERNATE_CLASSLOADER, configVales ); - addIfSet( providedClassLoaders, AvailableSettings.ENVIRONMENT_CLASSLOADER, configVales ); + addIfSet( providedClassLoaders, AvailableSettings.APP_CLASSLOADER, configValues ); + addIfSet( providedClassLoaders, AvailableSettings.RESOURCES_CLASSLOADER, configValues ); + addIfSet( providedClassLoaders, AvailableSettings.HIBERNATE_CLASSLOADER, configValues ); + addIfSet( providedClassLoaders, AvailableSettings.ENVIRONMENT_CLASSLOADER, configValues ); if ( providedClassLoaders.isEmpty() ) { log.debugf( "Incoming config yielded no classloaders; adding standard SE ones" ); @@ -244,7 +266,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService { try { log.tracef( "trying via [ClassLoader.getResourceAsStream(\"%s\")]", name ); - InputStream stream = aggregatedClassLoader.getResourceAsStream( name ); + final InputStream stream = aggregatedClassLoader.getResourceAsStream( name ); if ( stream != null ) { return stream; } @@ -252,7 +274,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService { catch ( Exception ignore ) { } - final String stripped = name.startsWith( "/" ) ? name.substring(1) : null; + final String stripped = name.startsWith( "/" ) ? name.substring( 1 ) : null; if ( stripped != null ) { try { @@ -264,7 +286,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService { try { log.tracef( "trying via [ClassLoader.getResourceAsStream(\"%s\")]", stripped ); - InputStream stream = aggregatedClassLoader.getResourceAsStream( stripped ); + final InputStream stream = aggregatedClassLoader.getResourceAsStream( stripped ); if ( stream != null ) { return stream; } @@ -278,9 +300,9 @@ public class ClassLoaderServiceImpl implements ClassLoaderService { @Override public List locateResources(String name) { - ArrayList urls = new ArrayList(); + final ArrayList urls = new ArrayList(); try { - Enumeration urlEnumeration = aggregatedClassLoader.getResources( name ); + final Enumeration urlEnumeration = aggregatedClassLoader.getResources( name ); if ( urlEnumeration != null && urlEnumeration.hasMoreElements() ) { while ( urlEnumeration.hasMoreElements() ) { urls.add( urlEnumeration.nextElement() ); @@ -308,10 +330,28 @@ public class ClassLoaderServiceImpl implements ClassLoaderService { // completely temporary !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + /** + * Hack around continued (temporary) need to sometimes set the TCCL for code we call that expects it. + * + * @param The result type + */ public static interface Work { + /** + * The work to be performed with the TCCL set + * + * @return The result of the work + */ public T perform(); } + /** + * Perform some discrete work with with the TCCL set to our aggregated ClassLoader + * + * @param work The discrete work to be done + * @param The type of the work result + * + * @return The work result. + */ public T withTccl(Work work) { final ClassLoader tccl = Thread.currentThread().getContextClassLoader(); diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/package-info.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/package-info.java new file mode 100644 index 0000000000..f08d497ee5 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/package-info.java @@ -0,0 +1,4 @@ +/** + * The class loading service internals. + */ +package org.hibernate.boot.registry.classloading.internal; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/BootstrapServiceRegistryImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/BootstrapServiceRegistryImpl.java index 2780846ea3..048733e3da 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/BootstrapServiceRegistryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/BootstrapServiceRegistryImpl.java @@ -42,8 +42,9 @@ import org.hibernate.service.spi.ServiceRegistryImplementor; /** * {@link ServiceRegistry} implementation containing specialized "bootstrap" services, specifically:
    - *
  • {@link ClassLoaderService}
  • - *
  • {@link IntegratorService}
  • + *
  • {@link ClassLoaderService}
  • + *
  • {@link IntegratorService}
  • + *
  • {@link StrategySelector}
  • *
* * IMPL NOTE : Currently implements the deprecated {@link org.hibernate.service.BootstrapServiceRegistry} contract @@ -61,10 +62,29 @@ public class BootstrapServiceRegistryImpl private final ServiceBinding strategySelectorBinding; private final ServiceBinding integratorServiceBinding; + /** + * Constructs a BootstrapServiceRegistryImpl. + * + * Do not use directly generally speaking. Use {@link org.hibernate.boot.registry.BootstrapServiceRegistryBuilder} + * instead. + * + * @see org.hibernate.boot.registry.BootstrapServiceRegistryBuilder + */ public BootstrapServiceRegistryImpl() { this( new ClassLoaderServiceImpl(), NO_INTEGRATORS ); } + /** + * Constructs a BootstrapServiceRegistryImpl. + * + * Do not use directly generally speaking. Use {@link org.hibernate.boot.registry.BootstrapServiceRegistryBuilder} + * instead. + * + * @param classLoaderService The ClassLoaderService to use + * @param providedIntegrators The group of explicitly provided integrators + * + * @see org.hibernate.boot.registry.BootstrapServiceRegistryBuilder + */ public BootstrapServiceRegistryImpl( ClassLoaderService classLoaderService, LinkedHashSet providedIntegrators) { @@ -88,6 +108,19 @@ public class BootstrapServiceRegistryImpl ); } + + /** + * Constructs a BootstrapServiceRegistryImpl. + * + * Do not use directly generally speaking. Use {@link org.hibernate.boot.registry.BootstrapServiceRegistryBuilder} + * instead. + * + * @param classLoaderService The ClassLoaderService to use + * @param strategySelector The StrategySelector to use + * @param integratorService The IntegratorService to use + * + * @see org.hibernate.boot.registry.BootstrapServiceRegistryBuilder + */ public BootstrapServiceRegistryImpl( ClassLoaderService classLoaderService, StrategySelector strategySelector, diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/StandardServiceRegistryImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/StandardServiceRegistryImpl.java index 966f2bebd9..d1b3790d42 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/StandardServiceRegistryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/StandardServiceRegistryImpl.java @@ -37,13 +37,24 @@ import org.hibernate.service.spi.ServiceBinding; import org.hibernate.service.spi.ServiceInitiator; /** - * Hibernate implementation of the standard service registry. + * Standard Hibernate implementation of the standard service registry. * * @author Steve Ebersole */ public class StandardServiceRegistryImpl extends AbstractServiceRegistryImpl implements StandardServiceRegistry { private final Map configurationValues; + /** + * Constructs a StandardServiceRegistryImpl. Should not be instantiated directly; use + * {@link org.hibernate.boot.registry.StandardServiceRegistryBuilder} instead + * + * @param bootstrapServiceRegistry The bootstrap service registry. + * @param serviceInitiators Any StandardServiceInitiators provided by the user to the builder + * @param providedServices Any standard services provided directly to the builder + * @param configurationValues Configuration values + * + * @see org.hibernate.boot.registry.StandardServiceRegistryBuilder + */ @SuppressWarnings( {"unchecked"}) public StandardServiceRegistryImpl( BootstrapServiceRegistry bootstrapServiceRegistry, diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/package-info.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/package-info.java new file mode 100644 index 0000000000..1f1adfd33e --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/package-info.java @@ -0,0 +1,4 @@ +/** + * The internals for building service registries. + */ +package org.hibernate.boot.registry.internal; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/package-info.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/package-info.java new file mode 100644 index 0000000000..e1eaeb1535 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/package-info.java @@ -0,0 +1,4 @@ +/** + * Internals for building StrategySelector + */ +package org.hibernate.boot.registry.selector.internal; diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/internal/JavassistInstrumenter.java b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/internal/JavassistInstrumenter.java index 1182ed9d18..6cb07124a5 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/internal/JavassistInstrumenter.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/internal/JavassistInstrumenter.java @@ -51,17 +51,23 @@ public class JavassistInstrumenter extends AbstractInstrumenter { private final BytecodeProviderImpl provider = new BytecodeProviderImpl(); + /** + * Constructs the Javassist-based instrumenter. + * + * @param logger Logger to use + * @param options Instrumentation options + */ public JavassistInstrumenter(Logger logger, Options options) { super( logger, options ); } @Override - protected ClassDescriptor getClassDescriptor(byte[] bytecode) throws IOException { + protected ClassDescriptor getClassDescriptor(byte[] bytecode) throws IOException { return new CustomClassDescriptor( bytecode ); } @Override - protected ClassTransformer getClassTransformer(ClassDescriptor descriptor, Set classNames) { + protected ClassTransformer getClassTransformer(ClassDescriptor descriptor, Set classNames) { if ( descriptor.isInstrumented() ) { logger.debug( "class [" + descriptor.getName() + "] already instrumented" ); return null; @@ -85,7 +91,7 @@ public class JavassistInstrumenter extends AbstractInstrumenter { } public boolean isInstrumented() { - String[] interfaceNames = classFile.getInterfaces(); + final String[] interfaceNames = classFile.getInterfaces(); for ( String interfaceName : interfaceNames ) { if ( FieldHandled.class.getName().equals( interfaceName ) ) { return true; diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/internal/package-info.java b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/internal/package-info.java new file mode 100644 index 0000000000..cf297b2957 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/internal/package-info.java @@ -0,0 +1,4 @@ +/** + * Javassist support internals + */ +package org.hibernate.bytecode.buildtime.internal; diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/AbstractInstrumenter.java b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/AbstractInstrumenter.java index 190b592e4c..dbccc69765 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/AbstractInstrumenter.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/AbstractInstrumenter.java @@ -48,7 +48,7 @@ import org.hibernate.bytecode.spi.ClassTransformer; public abstract class AbstractInstrumenter implements Instrumenter { private static final int ZIP_MAGIC = 0x504B0304; private static final int CLASS_MAGIC = 0xCAFEBABE; - + protected final Logger logger; protected final Options options; @@ -92,7 +92,7 @@ public abstract class AbstractInstrumenter implements Instrumenter { * @param files The files. */ public void execute(Set files) { - Set classNames = new HashSet(); + final Set classNames = new HashSet(); if ( options.performExtendedInstrumentation() ) { logger.debug( "collecting class names for extended instrumentation determination" ); @@ -136,26 +136,26 @@ public abstract class AbstractInstrumenter implements Instrumenter { * @throws Exception indicates problems accessing the file or its contents. */ private void collectClassNames(File file, final Set classNames) throws Exception { - if ( isClassFile( file ) ) { - byte[] bytes = ByteCodeHelper.readByteCode( file ); - ClassDescriptor descriptor = getClassDescriptor( bytes ); - classNames.add( descriptor.getName() ); - } - else if ( isJarFile( file ) ) { - ZipEntryHandler collector = new ZipEntryHandler() { - public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception { + if ( isClassFile( file ) ) { + final byte[] bytes = ByteCodeHelper.readByteCode( file ); + final ClassDescriptor descriptor = getClassDescriptor( bytes ); + classNames.add( descriptor.getName() ); + } + else if ( isJarFile( file ) ) { + final ZipEntryHandler collector = new ZipEntryHandler() { + public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception { if ( !entry.isDirectory() ) { // see if the entry represents a class file - DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) ); + final DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) ); if ( din.readInt() == CLASS_MAGIC ) { - classNames.add( getClassDescriptor( byteCode ).getName() ); + classNames.add( getClassDescriptor( byteCode ).getName() ); } } - } - }; - ZipFileProcessor processor = new ZipFileProcessor( collector ); - processor.process( file ); - } + } + }; + final ZipFileProcessor processor = new ZipFileProcessor( collector ); + processor.process( file ); + } } /** @@ -168,8 +168,8 @@ public abstract class AbstractInstrumenter implements Instrumenter { * @throws IOException Indicates problem access the file. */ protected final boolean isClassFile(File file) throws IOException { - return checkMagic( file, CLASS_MAGIC ); - } + return checkMagic( file, CLASS_MAGIC ); + } /** * Does this file represent a zip file of some format? @@ -180,20 +180,20 @@ public abstract class AbstractInstrumenter implements Instrumenter { * * @throws IOException Indicates problem access the file. */ - protected final boolean isJarFile(File file) throws IOException { - return checkMagic(file, ZIP_MAGIC); - } + protected final boolean isJarFile(File file) throws IOException { + return checkMagic( file, ZIP_MAGIC ); + } protected final boolean checkMagic(File file, long magic) throws IOException { - DataInputStream in = new DataInputStream( new FileInputStream( file ) ); - try { - int m = in.readInt(); - return magic == m; - } - finally { - in.close(); - } - } + final DataInputStream in = new DataInputStream( new FileInputStream( file ) ); + try { + final int m = in.readInt(); + return magic == m; + } + finally { + in.close(); + } + } /** * Actually process the file by applying instrumentation transformations to any classes it contains. @@ -207,17 +207,17 @@ public abstract class AbstractInstrumenter implements Instrumenter { * @throws Exception Indicates an issue either access files or applying the transformations. */ protected void processFile(File file, Set classNames) throws Exception { - if ( isClassFile( file ) ) { + if ( isClassFile( file ) ) { logger.debug( "processing class file : " + file.getAbsolutePath() ); - processClassFile( file, classNames ); - } - else if ( isJarFile( file ) ) { + processClassFile( file, classNames ); + } + else if ( isJarFile( file ) ) { logger.debug( "processing jar file : " + file.getAbsolutePath() ); - processJarFile( file, classNames ); - } - else { - logger.debug( "ignoring file : " + file.getAbsolutePath() ); - } + processJarFile( file, classNames ); + } + else { + logger.debug( "ignoring file : " + file.getAbsolutePath() ); + } } /** @@ -230,16 +230,16 @@ public abstract class AbstractInstrumenter implements Instrumenter { * @throws Exception Indicates an issue either access files or applying the transformations. */ protected void processClassFile(File file, Set classNames) throws Exception { - byte[] bytes = ByteCodeHelper.readByteCode( file ); - ClassDescriptor descriptor = getClassDescriptor( bytes ); - ClassTransformer transformer = getClassTransformer( descriptor, classNames ); + final byte[] bytes = ByteCodeHelper.readByteCode( file ); + final ClassDescriptor descriptor = getClassDescriptor( bytes ); + final ClassTransformer transformer = getClassTransformer( descriptor, classNames ); if ( transformer == null ) { logger.debug( "no trasformer for class file : " + file.getAbsolutePath() ); return; } logger.info( "processing class : " + descriptor.getName() + "; file = " + file.getAbsolutePath() ); - byte[] transformedBytes = transformer.transform( + final byte[] transformedBytes = transformer.transform( getClass().getClassLoader(), descriptor.getName(), null, @@ -247,7 +247,7 @@ public abstract class AbstractInstrumenter implements Instrumenter { descriptor.getBytes() ); - OutputStream out = new FileOutputStream( file ); + final OutputStream out = new FileOutputStream( file ); try { out.write( transformedBytes ); out.flush(); @@ -272,61 +272,62 @@ public abstract class AbstractInstrumenter implements Instrumenter { * @throws Exception Indicates an issue either access files or applying the transformations. */ protected void processJarFile(final File file, final Set classNames) throws Exception { - File tempFile = File.createTempFile( - file.getName(), - null, - new File( file.getAbsoluteFile().getParent() ) - ); + final File tempFile = File.createTempFile( + file.getName(), + null, + new File( file.getAbsoluteFile().getParent() ) + ); - try { - FileOutputStream fout = new FileOutputStream( tempFile, false ); + try { + final FileOutputStream fout = new FileOutputStream( tempFile, false ); try { final ZipOutputStream out = new ZipOutputStream( fout ); - ZipEntryHandler transformer = new ZipEntryHandler() { + final ZipEntryHandler transformer = new ZipEntryHandler() { public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception { - logger.debug( "starting zip entry : " + entry.toString() ); - if ( !entry.isDirectory() ) { - // see if the entry represents a class file - DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) ); - if ( din.readInt() == CLASS_MAGIC ) { - ClassDescriptor descriptor = getClassDescriptor( byteCode ); - ClassTransformer transformer = getClassTransformer( descriptor, classNames ); - if ( transformer == null ) { - logger.debug( "no transformer for zip entry : " + entry.toString() ); - } - else { - logger.info( "processing class : " + descriptor.getName() + "; entry = " + file.getAbsolutePath() ); - byteCode = transformer.transform( - getClass().getClassLoader(), - descriptor.getName(), - null, - null, - descriptor.getBytes() - ); - } - } - else { - logger.debug( "ignoring zip entry : " + entry.toString() ); - } + logger.debug( "starting zip entry : " + entry.toString() ); + if ( !entry.isDirectory() ) { + // see if the entry represents a class file + final DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) ); + if ( din.readInt() == CLASS_MAGIC ) { + final ClassDescriptor descriptor = getClassDescriptor( byteCode ); + final ClassTransformer transformer = getClassTransformer( descriptor, classNames ); + if ( transformer == null ) { + logger.debug( "no transformer for zip entry : " + entry.toString() ); } - - ZipEntry outEntry = new ZipEntry( entry.getName() ); - outEntry.setMethod( entry.getMethod() ); - outEntry.setComment( entry.getComment() ); - outEntry.setSize( byteCode.length ); - - if ( outEntry.getMethod() == ZipEntry.STORED ){ - CRC32 crc = new CRC32(); - crc.update( byteCode ); - outEntry.setCrc( crc.getValue() ); - outEntry.setCompressedSize( byteCode.length ); + else { + logger.info( "processing class : " + descriptor.getName() + "; entry = " + file.getAbsolutePath() ); + byteCode = transformer.transform( + getClass().getClassLoader(), + descriptor.getName(), + null, + null, + descriptor.getBytes() + ); } - out.putNextEntry( outEntry ); - out.write( byteCode ); - out.closeEntry(); + } + else { + logger.debug( "ignoring zip entry : " + entry.toString() ); + } + } + + final ZipEntry outEntry = new ZipEntry( entry.getName() ); + outEntry.setMethod( entry.getMethod() ); + outEntry.setComment( entry.getComment() ); + outEntry.setSize( byteCode.length ); + + if ( outEntry.getMethod() == ZipEntry.STORED ){ + final CRC32 crc = new CRC32(); + crc.update( byteCode ); + outEntry.setCrc( crc.getValue() ); + outEntry.setCompressedSize( byteCode.length ); + } + out.putNextEntry( outEntry ); + out.write( byteCode ); + out.closeEntry(); } }; - ZipFileProcessor processor = new ZipFileProcessor( transformer ); + + final ZipFileProcessor processor = new ZipFileProcessor( transformer ); processor.process( file ); out.close(); } @@ -334,21 +335,21 @@ public abstract class AbstractInstrumenter implements Instrumenter { fout.close(); } - if ( file.delete() ) { - File newFile = new File( tempFile.getAbsolutePath() ); - if( !newFile.renameTo( file ) ) { - throw new IOException( "can not rename " + tempFile + " to " + file ); - } - } - else { - throw new IOException( "can not delete " + file ); - } - } - finally { - if ( ! tempFile.delete() ) { + if ( file.delete() ) { + final File newFile = new File( tempFile.getAbsolutePath() ); + if( ! newFile.renameTo( file ) ) { + throw new IOException( "can not rename " + tempFile + " to " + file ); + } + } + else { + throw new IOException( "can not delete " + file ); + } + } + finally { + if ( ! tempFile.delete() ) { logger.info( "Unable to cleanup temporary jar file : " + tempFile.getAbsolutePath() ); } - } + } } /** @@ -419,19 +420,19 @@ public abstract class AbstractInstrumenter implements Instrumenter { } public void process(File file) throws Exception { - ZipInputStream zip = new ZipInputStream( new FileInputStream( file ) ); + final ZipInputStream zip = new ZipInputStream( new FileInputStream( file ) ); try { ZipEntry entry; while ( (entry = zip.getNextEntry()) != null ) { - byte bytes[] = ByteCodeHelper.readByteCode( zip ); + final byte[] bytes = ByteCodeHelper.readByteCode( zip ); entryHandler.handleEntry( entry, bytes ); zip.closeEntry(); } - } - finally { - zip.close(); - } + } + finally { + zip.close(); + } } } } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/BasicClassFilter.java b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/BasicClassFilter.java index 642fb3811f..a62b16eeb2 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/BasicClassFilter.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/BasicClassFilter.java @@ -39,10 +39,19 @@ public class BasicClassFilter implements ClassFilter { private final Set includedClassNames = new HashSet(); private final boolean isAllEmpty; + /** + * Constructs a BasicClassFilter with given configuration. + */ public BasicClassFilter() { this( null, null ); } + /** + * Constructs a BasicClassFilter with standard set of configuration. + * + * @param includedPackages Name of packages whose classes should be accepted. + * @param includedClassNames Name of classes that should be accepted. + */ public BasicClassFilter(String[] includedPackages, String[] includedClassNames) { this.includedPackages = includedPackages; if ( includedClassNames != null ) { @@ -50,9 +59,10 @@ public class BasicClassFilter implements ClassFilter { } isAllEmpty = ( this.includedPackages == null || this.includedPackages.length == 0 ) - && ( this.includedClassNames.isEmpty() ); + && ( this.includedClassNames.isEmpty() ); } + @Override public boolean shouldInstrumentClass(String className) { return isAllEmpty || includedClassNames.contains( className ) || diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/ClassFilter.java b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/ClassFilter.java index 935e4a5912..62f4352264 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/ClassFilter.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/ClassFilter.java @@ -30,7 +30,7 @@ package org.hibernate.bytecode.buildtime.spi; */ public interface ClassFilter { /** - * Should this class be included in instrumentation + * Should this class be included in instrumentation. * * @param className The name of the class to check * diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/ExecutionException.java b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/ExecutionException.java index 0b09fe61e8..b9d61a8c14 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/ExecutionException.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/ExecutionException.java @@ -30,14 +30,30 @@ package org.hibernate.bytecode.buildtime.spi; */ @SuppressWarnings( {"UnusedDeclaration"}) public class ExecutionException extends RuntimeException { + /** + * Constructs an ExecutionException. + * + * @param message The message explaining the exception condition + */ public ExecutionException(String message) { super( message ); } + /** + * Constructs an ExecutionException. + * + * @param cause The underlying cause. + */ public ExecutionException(Throwable cause) { super( cause ); } + /** + * Constructs an ExecutionException. + * + * @param message The message explaining the exception condition + * @param cause The underlying cause. + */ public ExecutionException(String message, Throwable cause) { super( message, cause ); } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/Instrumenter.java b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/Instrumenter.java index 3a281b91f0..a9be338877 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/Instrumenter.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/Instrumenter.java @@ -27,20 +27,20 @@ import java.io.File; import java.util.Set; /** - * Basic contract for performing instrumentation + * Basic contract for performing instrumentation. * * @author Steve Ebersole */ public interface Instrumenter { /** - * Perform the instrumentation + * Perform the instrumentation. * * @param files The file on which to perform instrumentation */ public void execute(Set files); /** - * Instrumentation options + * Instrumentation options. */ public static interface Options { /** diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/Logger.java b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/Logger.java index 7a489687cc..41f8ec1fb0 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/Logger.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/Logger.java @@ -30,13 +30,38 @@ package org.hibernate.bytecode.buildtime.spi; * @author Steve Ebersole */ public interface Logger { + /** + * Log a message with TRACE semantics. + * + * @param message The message to log. + */ public void trace(String message); + /** + * Log a message with DEBUG semantics. + * + * @param message The message to log. + */ public void debug(String message); + /** + * Log a message with INFO semantics. + * + * @param message The message to log. + */ public void info(String message); + /** + * Log a message with WARN semantics. + * + * @param message The message to log. + */ public void warn(String message); + /** + * Log a message with ERROR semantics. + * + * @param message The message to log. + */ public void error(String message); } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/package-info.java b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/package-info.java new file mode 100644 index 0000000000..a37e4dffcf --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/spi/package-info.java @@ -0,0 +1,6 @@ +/** + * Package defining build-time bytecode code enhancement (instrumentation) support. + * + * This package should mostly be considered deprecated in favor of {@link org.hibernate.bytecode.enhance} + */ +package org.hibernate.bytecode.buildtime.spi; diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/EnhancementException.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/EnhancementException.java index 2955cbcec6..129f78cd9c 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/EnhancementException.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/EnhancementException.java @@ -26,14 +26,18 @@ package org.hibernate.bytecode.enhance; import org.hibernate.HibernateException; /** + * An exception indicating some kind of problem performing bytecode enhancement. + * * @author Steve Ebersole */ public class EnhancementException extends HibernateException { - public EnhancementException(String message) { - super( message ); - } - - public EnhancementException(String message, Throwable root) { - super( message, root ); + /** + * Constructs an EnhancementException + * + * @param message Message explaining the exception condition + * @param cause The underlying cause. + */ + public EnhancementException(String message, Throwable cause) { + super( message, cause ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/package-info.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/package-info.java new file mode 100644 index 0000000000..b8e84966d6 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/package-info.java @@ -0,0 +1,4 @@ +/** + * Package defining bytecode code enhancement (instrumentation) support. + */ +package org.hibernate.bytecode.enhance; diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/EnhancementContext.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/EnhancementContext.java index f42c3ae83d..dc9cd7479d 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/EnhancementContext.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/EnhancementContext.java @@ -27,8 +27,18 @@ import javassist.CtClass; import javassist.CtField; /** - * todo : not sure its a great idea to expose Javassist classes this way. - * maybe wrap them in our own contracts? + * The context for performing an enhancement. Enhancement can happen in any number of ways:
    + *
  • Build time, via Ant
  • + *
  • Build time, via Maven
  • + *
  • Build time, via Gradle
  • + *
  • Runtime, via agent
  • + *
  • Runtime, via JPA constructs
  • + *
+ * + * This interface isolates the code that actually does the enhancement from the underlying context in which + * the enhancement is being performed. + * + * @todo Not sure its a great idea to expose Javassist classes this way. maybe wrap them in our own contracts? * * @author Steve Ebersole */ @@ -37,6 +47,8 @@ public interface EnhancementContext { * Obtain access to the ClassLoader that can be used to load Class references. In JPA SPI terms, this * should be a "temporary class loader" as defined by * {@link javax.persistence.spi.PersistenceUnitInfo#getNewTempClassLoader()} + * + * @return The class loader that the enhancer can use. */ public ClassLoader getLoadingClassLoader(); @@ -68,6 +80,13 @@ public interface EnhancementContext { */ public boolean doDirtyCheckingInline(CtClass classDescriptor); + /** + * Does the given class define any lazy loadable attributes? + * + * @param classDescriptor The class to check + * + * @return true/false + */ public boolean hasLazyLoadableAttributes(CtClass classDescriptor); // todo : may be better to invert these 2 such that the context is asked for an ordered list of persistent fields for an entity/composite @@ -75,14 +94,14 @@ public interface EnhancementContext { /** * Does the field represent persistent state? Persistent fields will be "enhanced". *

- // may be better to perform basic checks in the caller (non-static, etc) and call out with just the - // Class name and field name... - + * may be better to perform basic checks in the caller (non-static, etc) and call out with just the + * Class name and field name... + * * @param ctField The field reference. * * @return {@code true} if the field is ; {@code false} otherwise. */ - public boolean isPersistentField(CtField ctField); + public boolean isPersistentField(CtField ctField); /** * For fields which are persistent (according to {@link #isPersistentField}), determine the corresponding ordering @@ -94,5 +113,12 @@ public interface EnhancementContext { */ public CtField[] order(CtField[] persistentFields); + /** + * Determine if a field is lazy loadable. + * + * @param field The field to check + * + * @return {@code true} if the field is lazy loadable; {@code false} otherwise. + */ public boolean isLazyLoadable(CtField field); } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/Enhancer.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/Enhancer.java index 4473739e92..b3455b6734 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/Enhancer.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/Enhancer.java @@ -29,10 +29,8 @@ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; import java.util.IdentityHashMap; import java.util.List; -import java.util.Map; import javassist.CannotCompileException; import javassist.ClassPool; @@ -65,36 +63,16 @@ import org.hibernate.engine.spi.ManagedEntity; import org.hibernate.engine.spi.PersistentAttributeInterceptable; import org.hibernate.engine.spi.PersistentAttributeInterceptor; import org.hibernate.internal.CoreMessageLogger; -import org.hibernate.mapping.PersistentClass; /** + * Class responsible for performing enhancement. + * * @author Steve Ebersole * @author Jason Greene */ public class Enhancer { private static final CoreMessageLogger log = Logger.getMessageLogger( CoreMessageLogger.class, Enhancer.class.getName() ); - public static final String PERSISTENT_FIELD_READER_PREFIX = "$$_hibernate_read_"; - public static final String PERSISTENT_FIELD_WRITER_PREFIX = "$$_hibernate_write_"; - - public static final String ENTITY_INSTANCE_GETTER_NAME = "$$_hibernate_getEntityInstance"; - - public static final String ENTITY_ENTRY_FIELD_NAME = "$$_hibernate_entityEntryHolder"; - public static final String ENTITY_ENTRY_GETTER_NAME = "$$_hibernate_getEntityEntry"; - public static final String ENTITY_ENTRY_SETTER_NAME = "$$_hibernate_setEntityEntry"; - - public static final String PREVIOUS_FIELD_NAME = "$$_hibernate_previousManagedEntity"; - public static final String PREVIOUS_GETTER_NAME = "$$_hibernate_getPreviousManagedEntity"; - public static final String PREVIOUS_SETTER_NAME = "$$_hibernate_setPreviousManagedEntity"; - - public static final String NEXT_FIELD_NAME = "$$_hibernate_nextManagedEntity"; - public static final String NEXT_GETTER_NAME = "$$_hibernate_getNextManagedEntity"; - public static final String NEXT_SETTER_NAME = "$$_hibernate_setNextManagedEntity"; - - public static final String INTERCEPTOR_FIELD_NAME = "$$_hibernate_attributeInterceptor"; - public static final String INTERCEPTOR_GETTER_NAME = "$$_hibernate_getInterceptor"; - public static final String INTERCEPTOR_SETTER_NAME = "$$_hibernate_setInterceptor"; - private final EnhancementContext enhancementContext; private final ClassPool classPool; @@ -105,6 +83,12 @@ public class Enhancer { private final CtClass entityEntryCtClass; private final CtClass objectCtClass; + /** + * Constructs the Enhancer, using the given context. + * + * @param enhancementContext Describes the context in which enhancement will occur so as to give access + * to contextual/environmental information. + */ public Enhancer(EnhancementContext enhancementContext) { this.enhancementContext = enhancementContext; this.classPool = buildClassPool( enhancementContext ); @@ -154,8 +138,8 @@ public class Enhancer { } private ClassPool buildClassPool(EnhancementContext enhancementContext) { - ClassPool classPool = new ClassPool( false ); - ClassLoader loadingClassLoader = enhancementContext.getLoadingClassLoader(); + final ClassPool classPool = new ClassPool( false ); + final ClassLoader loadingClassLoader = enhancementContext.getLoadingClassLoader(); if ( loadingClassLoader != null ) { classPool.appendClassPath( new LoaderClassPath( loadingClassLoader ) ); } @@ -171,7 +155,7 @@ public class Enhancer { * @return The enhanced bytecode. Could be the same as the original bytecode if the original was * already enhanced or we could not enhance it for some reason. * - * @throws EnhancementException + * @throws EnhancementException Indicates a problem performing the enhancement */ public byte[] enhance(String className, byte[] originalBytes) throws EnhancementException { final CtClass managedCtClass; @@ -185,27 +169,27 @@ public class Enhancer { enhance( managedCtClass ); - DataOutputStream out = null; + final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + final DataOutputStream out; try { - ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); out = new DataOutputStream( byteStream ); - managedCtClass.toBytecode( out ); - return byteStream.toByteArray(); + try { + managedCtClass.toBytecode( out ); + return byteStream.toByteArray(); + } + finally { + try { + out.close(); + } + catch (IOException e) { + //swallow + } + } } catch (Exception e) { log.unableToTransformClass( e.getMessage() ); throw new HibernateException( "Unable to transform class: " + e.getMessage() ); } - finally { - try { - if ( out != null ) { - out.close(); - } - } - catch (IOException e) { - //swallow - } - } } private void enhance(CtClass managedCtClass) { @@ -261,7 +245,7 @@ public class Enhancer { managedCtClass.addMethod( CtNewMethod.make( objectCtClass, - ENTITY_INSTANCE_GETTER_NAME, + EnhancerConstants.ENTITY_INSTANCE_GETTER_NAME, new CtClass[0], new CtClass[0], "{ return this; }", @@ -284,9 +268,9 @@ public class Enhancer { addFieldWithGetterAndSetter( managedCtClass, entityEntryCtClass, - ENTITY_ENTRY_FIELD_NAME, - ENTITY_ENTRY_GETTER_NAME, - ENTITY_ENTRY_SETTER_NAME + EnhancerConstants.ENTITY_ENTRY_FIELD_NAME, + EnhancerConstants.ENTITY_ENTRY_GETTER_NAME, + EnhancerConstants.ENTITY_ENTRY_SETTER_NAME ); } @@ -294,9 +278,9 @@ public class Enhancer { addFieldWithGetterAndSetter( managedCtClass, managedEntityCtClass, - PREVIOUS_FIELD_NAME, - PREVIOUS_GETTER_NAME, - PREVIOUS_SETTER_NAME + EnhancerConstants.PREVIOUS_FIELD_NAME, + EnhancerConstants.PREVIOUS_GETTER_NAME, + EnhancerConstants.PREVIOUS_SETTER_NAME ); } @@ -304,9 +288,9 @@ public class Enhancer { addFieldWithGetterAndSetter( managedCtClass, managedEntityCtClass, - NEXT_FIELD_NAME, - NEXT_GETTER_NAME, - NEXT_SETTER_NAME + EnhancerConstants.NEXT_FIELD_NAME, + EnhancerConstants.NEXT_GETTER_NAME, + EnhancerConstants.NEXT_SETTER_NAME ); } @@ -400,9 +384,9 @@ public class Enhancer { addFieldWithGetterAndSetter( managedCtClass, attributeInterceptorCtClass, - INTERCEPTOR_FIELD_NAME, - INTERCEPTOR_GETTER_NAME, - INTERCEPTOR_SETTER_NAME + EnhancerConstants.INTERCEPTOR_FIELD_NAME, + EnhancerConstants.INTERCEPTOR_GETTER_NAME, + EnhancerConstants.INTERCEPTOR_SETTER_NAME ); } @@ -445,7 +429,8 @@ public class Enhancer { theField.setModifiers( theField.getModifiers() | Modifier.TRANSIENT ); } theField.setModifiers( Modifier.setPrivate( theField.getModifiers() ) ); - AnnotationsAttribute annotationsAttribute = getVisibleAnnotations( theField.getFieldInfo() ); + + final AnnotationsAttribute annotationsAttribute = getVisibleAnnotations( theField.getFieldInfo() ); annotationsAttribute.addAnnotation( new Annotation( Transient.class.getName(), constPool ) ); return theField; } @@ -490,7 +475,7 @@ public class Enhancer { final FieldInfo fieldInfo = persistentField.getFieldInfo(); final String fieldName = fieldInfo.getName(); - final String readerName = PERSISTENT_FIELD_READER_PREFIX + fieldName; + final String readerName = EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX + fieldName; // read attempts only have to deal lazy-loading support, not dirty checking; so if the field // is not enabled as lazy-loadable return a plain simple getter as the reader @@ -498,7 +483,7 @@ public class Enhancer { // not lazy-loadable... // EARLY RETURN!!! try { - CtMethod reader = CtNewMethod.getter( readerName, persistentField ); + final CtMethod reader = CtNewMethod.getter( readerName, persistentField ); managedCtClass.addMethod( reader ); return reader; } @@ -515,11 +500,11 @@ public class Enhancer { } // temporary solution... - String methodBody = typeDescriptor.buildReadInterceptionBodyFragment( fieldName ) + final String methodBody = typeDescriptor.buildReadInterceptionBodyFragment( fieldName ) + " return this." + fieldName + ";"; try { - CtMethod reader = CtNewMethod.make( + final CtMethod reader = CtNewMethod.make( Modifier.PRIVATE, persistentField.getType(), readerName, @@ -550,7 +535,7 @@ public class Enhancer { final FieldInfo fieldInfo = persistentField.getFieldInfo(); final String fieldName = fieldInfo.getName(); - final String writerName = PERSISTENT_FIELD_WRITER_PREFIX + fieldName; + final String writerName = EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX + fieldName; final CtMethod writer; @@ -560,7 +545,7 @@ public class Enhancer { writer = CtNewMethod.setter( writerName, persistentField ); } else { - String methodBody = typeDescriptor.buildWriteInterceptionBodyFragment( fieldName ); + final String methodBody = typeDescriptor.buildWriteInterceptionBodyFragment( fieldName ); writer = CtNewMethod.make( Modifier.PRIVATE, CtClass.voidType, @@ -602,15 +587,15 @@ public class Enhancer { final String methodName = methodInfo.getName(); // skip methods added by enhancement - if ( methodName.startsWith( PERSISTENT_FIELD_READER_PREFIX ) - || methodName.startsWith( PERSISTENT_FIELD_WRITER_PREFIX ) - || methodName.equals( ENTITY_INSTANCE_GETTER_NAME ) - || methodName.equals( ENTITY_ENTRY_GETTER_NAME ) - || methodName.equals( ENTITY_ENTRY_SETTER_NAME ) - || methodName.equals( PREVIOUS_GETTER_NAME ) - || methodName.equals( PREVIOUS_SETTER_NAME ) - || methodName.equals( NEXT_GETTER_NAME ) - || methodName.equals( NEXT_SETTER_NAME ) ) { + if ( methodName.startsWith( EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX ) + || methodName.startsWith( EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX ) + || methodName.equals( EnhancerConstants.ENTITY_INSTANCE_GETTER_NAME ) + || methodName.equals( EnhancerConstants.ENTITY_ENTRY_GETTER_NAME ) + || methodName.equals( EnhancerConstants.ENTITY_ENTRY_SETTER_NAME ) + || methodName.equals( EnhancerConstants.PREVIOUS_GETTER_NAME ) + || methodName.equals( EnhancerConstants.PREVIOUS_SETTER_NAME ) + || methodName.equals( EnhancerConstants.NEXT_GETTER_NAME ) + || methodName.equals( EnhancerConstants.NEXT_SETTER_NAME ) ) { continue; } @@ -621,15 +606,15 @@ public class Enhancer { } try { - CodeIterator itr = codeAttr.iterator(); + final CodeIterator itr = codeAttr.iterator(); while ( itr.hasNext() ) { - int index = itr.next(); - int op = itr.byteAt( index ); + final int index = itr.next(); + final int op = itr.byteAt( index ); if ( op != Opcode.PUTFIELD && op != Opcode.GETFIELD ) { continue; } - int constIndex = itr.u16bitAt( index+1 ); + final int constIndex = itr.u16bitAt( index+1 ); final String fieldName = constPool.getFieldrefName( constIndex ); final PersistentAttributeDescriptor attributeDescriptor = attributeDescriptorMap.get( fieldName ); @@ -646,27 +631,27 @@ public class Enhancer { ); if ( op == Opcode.GETFIELD ) { - int read_method_index = constPool.addMethodrefInfo( + final int readMethodIndex = constPool.addMethodrefInfo( constPool.getThisClassInfo(), attributeDescriptor.getReader().getName(), attributeDescriptor.getReader().getSignature() ); itr.writeByte( Opcode.INVOKESPECIAL, index ); - itr.write16bit( read_method_index, index+1 ); + itr.write16bit( readMethodIndex, index+1 ); } else { - int write_method_index = constPool.addMethodrefInfo( + final int writeMethodIndex = constPool.addMethodrefInfo( constPool.getThisClassInfo(), attributeDescriptor.getWriter().getName(), attributeDescriptor.getWriter().getSignature() ); itr.writeByte( Opcode.INVOKESPECIAL, index ); - itr.write16bit( write_method_index, index+1 ); + itr.write16bit( writeMethodIndex, index+1 ); } } - StackMapTable smt = MapMaker.make( classPool, methodInfo ); - methodInfo.getCodeAttribute().setAttribute(smt); + final StackMapTable smt = MapMaker.make( classPool, methodInfo ); + methodInfo.getCodeAttribute().setAttribute( smt ); } catch (BadBytecode e) { throw new EnhancementException( @@ -748,7 +733,7 @@ public class Enhancer { } } - private static abstract class AbstractAttributeTypeDescriptor implements AttributeTypeDescriptor { + private abstract static class AbstractAttributeTypeDescriptor implements AttributeTypeDescriptor { @Override public String buildInLineDirtyCheckingBodyFragment(String fieldName) { // for now... diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/EnhancerConstants.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/EnhancerConstants.java new file mode 100644 index 0000000000..5c80f7a068 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/EnhancerConstants.java @@ -0,0 +1,133 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2013, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.bytecode.enhance.spi; + +/** + * Constants used during enhancement. + * + * @author Steve Ebersole + */ +public class EnhancerConstants { + /** + * Prefix for persistent-field reader methods. + */ + public static final String PERSISTENT_FIELD_READER_PREFIX = "$$_hibernate_read_"; + + /** + * Prefix for persistent-field writer methods. + */ + public static final String PERSISTENT_FIELD_WRITER_PREFIX = "$$_hibernate_write_"; + + /** + * Name of the method used to get reference the the entity instance (this in the case of enhanced classes). + */ + public static final String ENTITY_INSTANCE_GETTER_NAME = "$$_hibernate_getEntityInstance"; + + /** + * Name of the field used to hold the {@link org.hibernate.engine.spi.EntityEntry} + */ + public static final String ENTITY_ENTRY_FIELD_NAME = "$$_hibernate_entityEntryHolder"; + + /** + * Name of the method used to read the {@link org.hibernate.engine.spi.EntityEntry} field. + * + * @see #ENTITY_ENTRY_FIELD_NAME + */ + public static final String ENTITY_ENTRY_GETTER_NAME = "$$_hibernate_getEntityEntry"; + + /** + * Name of the method used to write the {@link org.hibernate.engine.spi.EntityEntry} field. + * + * @see #ENTITY_ENTRY_FIELD_NAME + */ + public static final String ENTITY_ENTRY_SETTER_NAME = "$$_hibernate_setEntityEntry"; + + /** + * Name of the field used to hold the previous {@link org.hibernate.engine.spi.ManagedEntity}. + * + * Together, previous/next are used to define a "linked list" + * + * @see #NEXT_FIELD_NAME + */ + public static final String PREVIOUS_FIELD_NAME = "$$_hibernate_previousManagedEntity"; + + /** + * Name of the method used to read the previous {@link org.hibernate.engine.spi.ManagedEntity} field + * + * @see #PREVIOUS_FIELD_NAME + */ + public static final String PREVIOUS_GETTER_NAME = "$$_hibernate_getPreviousManagedEntity"; + + /** + * Name of the method used to write the previous {@link org.hibernate.engine.spi.ManagedEntity} field + * + * @see #PREVIOUS_FIELD_NAME + */ + public static final String PREVIOUS_SETTER_NAME = "$$_hibernate_setPreviousManagedEntity"; + + /** + * Name of the field used to hold the previous {@link org.hibernate.engine.spi.ManagedEntity}. + * + * Together, previous/next are used to define a "linked list" + * + * @see #PREVIOUS_FIELD_NAME + */ + public static final String NEXT_FIELD_NAME = "$$_hibernate_nextManagedEntity"; + + /** + * Name of the method used to read the next {@link org.hibernate.engine.spi.ManagedEntity} field + * + * @see #NEXT_FIELD_NAME + */ + public static final String NEXT_GETTER_NAME = "$$_hibernate_getNextManagedEntity"; + + /** + * Name of the method used to write the next {@link org.hibernate.engine.spi.ManagedEntity} field + * + * @see #NEXT_FIELD_NAME + */ + public static final String NEXT_SETTER_NAME = "$$_hibernate_setNextManagedEntity"; + + /** + * Name of the field used to store the {@link org.hibernate.engine.spi.PersistentAttributeInterceptable}. + */ + public static final String INTERCEPTOR_FIELD_NAME = "$$_hibernate_attributeInterceptor"; + + /** + * Name of the method used to read the interceptor + * + * @see #INTERCEPTOR_FIELD_NAME + */ + public static final String INTERCEPTOR_GETTER_NAME = "$$_hibernate_getInterceptor"; + + /** + * Name of the method used to write the interceptor + * + * @see #INTERCEPTOR_FIELD_NAME + */ + public static final String INTERCEPTOR_SETTER_NAME = "$$_hibernate_setInterceptor"; + + private EnhancerConstants() { + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/package-info.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/package-info.java new file mode 100644 index 0000000000..ab08393eee --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/package-info.java @@ -0,0 +1,4 @@ +/** + * Package defining bytecode code enhancement (instrumentation) support. + */ +package org.hibernate.bytecode.enhance.spi; diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/FieldInterceptionHelper.java b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/FieldInterceptionHelper.java index 8d87441a24..49a9c47465 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/FieldInterceptionHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/FieldInterceptionHelper.java @@ -46,14 +46,18 @@ public class FieldInterceptionHelper { private static final Set INSTRUMENTATION_DELEGATES = buildInstrumentationDelegates(); private static Set buildInstrumentationDelegates() { - HashSet delegates = new HashSet(); + final HashSet delegates = new HashSet(); delegates.add( JavassistDelegate.INSTANCE ); return delegates; } - private FieldInterceptionHelper() { - } - + /** + * Utility to check to see if a given entity class is instrumented. + * + * @param entityClass The entity class to check + * + * @return {@code true} if it has been instrumented; {@code false} otherwise + */ public static boolean isInstrumented(Class entityClass) { for ( Delegate delegate : INSTRUMENTATION_DELEGATES ) { if ( delegate.isInstrumented( entityClass ) ) { @@ -63,17 +67,34 @@ public class FieldInterceptionHelper { return false; } - public static boolean isInstrumented(Object entity) { - return entity != null && isInstrumented( entity.getClass() ); + /** + * Utility to check to see if a given object is an instance of an instrumented class. If the instance + * is {@code null}, the check returns {@code false} + * + * @param object The object to check + * + * @return {@code true} if it has been instrumented; {@code false} otherwise + */ + public static boolean isInstrumented(Object object) { + return object != null && isInstrumented( object.getClass() ); } - public static FieldInterceptor extractFieldInterceptor(Object entity) { - if ( entity == null ) { + /** + * Assuming the given object is an enhanced entity, extract and return its interceptor. Will + * return {@code null} if object is {@code null}, or if the object was deemed to not be + * instrumented + * + * @param object The object from which to extract the interceptor + * + * @return The extracted interceptor, or {@code null} + */ + public static FieldInterceptor extractFieldInterceptor(Object object) { + if ( object == null ) { return null; } FieldInterceptor interceptor = null; for ( Delegate delegate : INSTRUMENTATION_DELEGATES ) { - interceptor = delegate.extractInterceptor( entity ); + interceptor = delegate.extractInterceptor( object ); if ( interceptor != null ) { break; } @@ -81,12 +102,21 @@ public class FieldInterceptionHelper { return interceptor; } - + /** + * Assuming the given object is an enhanced entity, inject a field interceptor. + * + * @param entity The entity instance + * @param entityName The entity name + * @param uninitializedFieldNames The names of any uninitialized fields + * @param session The session + * + * @return The injected interceptor + */ public static FieldInterceptor injectFieldInterceptor( Object entity, - String entityName, - Set uninitializedFieldNames, - SessionImplementor session) { + String entityName, + Set uninitializedFieldNames, + SessionImplementor session) { if ( entity == null ) { return null; } @@ -144,4 +174,8 @@ public class FieldInterceptionHelper { return null; } } + + private FieldInterceptionHelper() { + } + } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/javassist/FieldInterceptorImpl.java b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/javassist/FieldInterceptorImpl.java index 4e245b5fdc..1d37ebd961 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/javassist/FieldInterceptorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/javassist/FieldInterceptorImpl.java @@ -47,7 +47,7 @@ import org.hibernate.proxy.LazyInitializer; * @author Steve Ebersole */ @SuppressWarnings( {"UnnecessaryUnboxing", "UnnecessaryBoxing"}) -public final class FieldInterceptorImpl extends AbstractFieldInterceptor implements FieldHandler, Serializable { +final class FieldInterceptorImpl extends AbstractFieldInterceptor implements FieldHandler, Serializable { FieldInterceptorImpl(SessionImplementor session, Set uninitializedFields, String entityName) { super( session, uninitializedFields, entityName ); @@ -57,46 +57,41 @@ public final class FieldInterceptorImpl extends AbstractFieldInterceptor impleme // FieldHandler impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public boolean readBoolean(Object target, String name, boolean oldValue) { - return ( ( Boolean ) intercept( target, name, oldValue ) ) - .booleanValue(); + return ( (Boolean) intercept( target, name, oldValue ) ).booleanValue(); } public byte readByte(Object target, String name, byte oldValue) { - return ( ( Byte ) intercept( target, name, Byte.valueOf( oldValue ) ) ).byteValue(); + return ( (Byte) intercept( target, name, Byte.valueOf( oldValue ) ) ).byteValue(); } public char readChar(Object target, String name, char oldValue) { - return ( ( Character ) intercept( target, name, Character.valueOf( oldValue ) ) ) - .charValue(); + return ( (Character) intercept( target, name, Character.valueOf( oldValue ) ) ).charValue(); } public double readDouble(Object target, String name, double oldValue) { - return ( ( Double ) intercept( target, name, Double.valueOf( oldValue ) ) ) - .doubleValue(); + return ( (Double) intercept( target, name, Double.valueOf( oldValue ) ) ).doubleValue(); } public float readFloat(Object target, String name, float oldValue) { - return ( ( Float ) intercept( target, name, Float.valueOf( oldValue ) ) ) - .floatValue(); + return ( (Float) intercept( target, name, Float.valueOf( oldValue ) ) ).floatValue(); } public int readInt(Object target, String name, int oldValue) { - return ( ( Integer ) intercept( target, name, Integer.valueOf( oldValue ) ) ); + return ( (Integer) intercept( target, name, Integer.valueOf( oldValue ) ) ); } public long readLong(Object target, String name, long oldValue) { - return ( ( Long ) intercept( target, name, Long.valueOf( oldValue ) ) ).longValue(); + return ( (Long) intercept( target, name, Long.valueOf( oldValue ) ) ).longValue(); } public short readShort(Object target, String name, short oldValue) { - return ( ( Short ) intercept( target, name, Short.valueOf( oldValue ) ) ) - .shortValue(); + return ( (Short) intercept( target, name, Short.valueOf( oldValue ) ) ).shortValue(); } public Object readObject(Object target, String name, Object oldValue) { Object value = intercept( target, name, oldValue ); - if (value instanceof HibernateProxy) { - LazyInitializer li = ( (HibernateProxy) value ).getHibernateLazyInitializer(); + if ( value instanceof HibernateProxy ) { + final LazyInitializer li = ( (HibernateProxy) value ).getHibernateLazyInitializer(); if ( li.isUnwrap() ) { value = li.getImplementation(); } @@ -159,11 +154,10 @@ public final class FieldInterceptorImpl extends AbstractFieldInterceptor impleme } public String toString() { - return "FieldInterceptorImpl(" + - "entityName=" + getEntityName() + - ",dirty=" + isDirty() + - ",uninitializedFields=" + getUninitializedFields() + - ')'; + return "FieldInterceptorImpl(entityName=" + getEntityName() + + ",dirty=" + isDirty() + + ",uninitializedFields=" + getUninitializedFields() + + ')'; } -} \ No newline at end of file +} diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/javassist/JavassistHelper.java b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/javassist/JavassistHelper.java index acd49547c0..07cb95e35d 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/javassist/JavassistHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/javassist/JavassistHelper.java @@ -30,23 +30,42 @@ import org.hibernate.bytecode.internal.javassist.FieldHandled; import org.hibernate.engine.spi.SessionImplementor; /** + * Javassist specific helper + * * @author Steve Ebersole */ public class JavassistHelper { private JavassistHelper() { } + /** + * Perform the Javassist-specific field interceptor extraction + * + * @param entity The entity from which to extract the interceptor + * + * @return The extracted interceptor + */ public static FieldInterceptor extractFieldInterceptor(Object entity) { - return ( FieldInterceptor ) ( ( FieldHandled ) entity ).getFieldHandler(); + return (FieldInterceptor) ( (FieldHandled) entity ).getFieldHandler(); } + /** + * Perform the Javassist-specific field interceptor injection + * + * @param entity The entity instance + * @param entityName The entity name + * @param uninitializedFieldNames The names of any uninitialized fields + * @param session The session + * + * @return The generated and injected interceptor + */ public static FieldInterceptor injectFieldInterceptor( Object entity, - String entityName, - Set uninitializedFieldNames, - SessionImplementor session) { - FieldInterceptorImpl fieldInterceptor = new FieldInterceptorImpl( session, uninitializedFieldNames, entityName ); - ( ( FieldHandled ) entity ).setFieldHandler( fieldInterceptor ); + String entityName, + Set uninitializedFieldNames, + SessionImplementor session) { + final FieldInterceptorImpl fieldInterceptor = new FieldInterceptorImpl( session, uninitializedFieldNames, entityName ); + ( (FieldHandled) entity ).setFieldHandler( fieldInterceptor ); return fieldInterceptor; } } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/javassist/package-info.java b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/javassist/package-info.java new file mode 100644 index 0000000000..ff7d51f4c7 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/javassist/package-info.java @@ -0,0 +1,4 @@ +/** + * Javassist support internals + */ +package org.hibernate.bytecode.instrumentation.internal.javassist; diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/package-info.java b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/package-info.java new file mode 100644 index 0000000000..601ddd6b55 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/internal/package-info.java @@ -0,0 +1,4 @@ +/** + * Bytecode instrumentation internals + */ +package org.hibernate.bytecode.instrumentation.internal; diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/spi/AbstractFieldInterceptor.java b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/spi/AbstractFieldInterceptor.java index 5aaaa8b687..0cd75cebe4 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/spi/AbstractFieldInterceptor.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/spi/AbstractFieldInterceptor.java @@ -29,6 +29,8 @@ import org.hibernate.LazyInitializationException; import org.hibernate.engine.spi.SessionImplementor; /** + * Base support for FieldInterceptor implementations. + * * @author Steve Ebersole */ public abstract class AbstractFieldInterceptor implements FieldInterceptor, Serializable { @@ -49,26 +51,32 @@ public abstract class AbstractFieldInterceptor implements FieldInterceptor, Seri // FieldInterceptor impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public final void setSession(SessionImplementor session) { this.session = session; } + @Override public final boolean isInitialized() { return uninitializedFields == null || uninitializedFields.size() == 0; } + @Override public final boolean isInitialized(String field) { return uninitializedFields == null || !uninitializedFields.contains( field ); } + @Override public final void dirty() { dirty = true; } + @Override public final boolean isDirty() { return dirty; } + @Override public final void clearDirty() { dirty = false; } @@ -76,6 +84,15 @@ public abstract class AbstractFieldInterceptor implements FieldInterceptor, Seri // subclass accesses ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + /** + * Interception of access to the named field + * + * @param target The call target + * @param fieldName The name of the field. + * @param value The value. + * + * @return ? + */ protected final Object intercept(Object target, String fieldName, Object value) { if ( initializing ) { return value; @@ -92,14 +109,14 @@ public abstract class AbstractFieldInterceptor implements FieldInterceptor, Seri final Object result; initializing = true; try { - result = ( ( LazyPropertyInitializer ) session.getFactory() - .getEntityPersister( entityName ) ) + result = ( (LazyPropertyInitializer) session.getFactory().getEntityPersister( entityName ) ) .initializeLazyProperty( fieldName, target, session ); } finally { initializing = false; } - uninitializedFields = null; //let's assume that there is only one lazy fetch group, for now! + // let's assume that there is only one lazy fetch group, for now! + uninitializedFields = null; return result; } else { @@ -107,18 +124,38 @@ public abstract class AbstractFieldInterceptor implements FieldInterceptor, Seri } } + /** + * Access to the session + * + * @return The associated session + */ public final SessionImplementor getSession() { return session; } + /** + * Access to all currently uninitialized fields + * + * @return The name of all currently uninitialized fields + */ public final Set getUninitializedFields() { return uninitializedFields; } + /** + * Access to the intercepted entity name + * + * @return The entity name + */ public final String getEntityName() { return entityName; } + /** + * Is the instance currently initializing? + * + * @return true/false. + */ public final boolean isInitializing() { return initializing; } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/spi/LazyPropertyInitializer.java b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/spi/LazyPropertyInitializer.java index c637672004..4dbc2b01cb 100755 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/spi/LazyPropertyInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/spi/LazyPropertyInitializer.java @@ -35,19 +35,21 @@ import org.hibernate.engine.spi.SessionImplementor; public interface LazyPropertyInitializer { /** - * Marker value for uninitialized properties + * Marker value for uninitialized properties. */ public static final Serializable UNFETCHED_PROPERTY = new Serializable() { + @Override public String toString() { return ""; } + public Object readResolve() { return UNFETCHED_PROPERTY; } }; /** - * Initialize the property, and return its new value + * Initialize the property, and return its new value. * * @param fieldName The name of the field being initialized * @param entity The entity on which the initialization is occurring diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/spi/package-info.java b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/spi/package-info.java new file mode 100644 index 0000000000..3b0e974256 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/instrumentation/spi/package-info.java @@ -0,0 +1,6 @@ +/** + * Package defining bytecode code enhancement (instrumentation) support. + * + * This package should mostly be considered deprecated in favor of {@link org.hibernate.bytecode.enhance} + */ +package org.hibernate.bytecode.instrumentation.spi; diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/AccessOptimizerAdapter.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/AccessOptimizerAdapter.java index 5ffd661467..9cba73ae3d 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/AccessOptimizerAdapter.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/AccessOptimizerAdapter.java @@ -27,6 +27,7 @@ import java.io.Serializable; import org.hibernate.PropertyAccessException; import org.hibernate.bytecode.spi.ReflectionOptimizer; +import org.hibernate.cfg.AvailableSettings; /** * The {@link org.hibernate.bytecode.spi.ReflectionOptimizer.AccessOptimizer} implementation for Javassist @@ -36,24 +37,36 @@ import org.hibernate.bytecode.spi.ReflectionOptimizer; */ public class AccessOptimizerAdapter implements ReflectionOptimizer.AccessOptimizer, Serializable { - public static final String PROPERTY_GET_EXCEPTION = - "exception getting property value with Javassist (set hibernate.bytecode.use_reflection_optimizer=false for more info)"; + private static final String PROPERTY_GET_EXCEPTION = String.format( + "exception getting property value with Javassist (set %s to false for more info)", + AvailableSettings.USE_REFLECTION_OPTIMIZER + ); - public static final String PROPERTY_SET_EXCEPTION = - "exception setting property value with Javassist (set hibernate.bytecode.use_reflection_optimizer=false for more info)"; + private static final String PROPERTY_SET_EXCEPTION = String.format( + "exception setting property value with Javassist (set %s to false for more info)", + AvailableSettings.USE_REFLECTION_OPTIMIZER + ); private final BulkAccessor bulkAccessor; private final Class mappedClass; + /** + * Constructs an AccessOptimizerAdapter + * + * @param bulkAccessor The bulk accessor to use + * @param mappedClass The mapped class + */ public AccessOptimizerAdapter(BulkAccessor bulkAccessor, Class mappedClass) { this.bulkAccessor = bulkAccessor; this.mappedClass = mappedClass; } + @Override public String[] getPropertyNames() { return bulkAccessor.getGetters(); } + @Override public Object[] getPropertyValues(Object object) { try { return bulkAccessor.getPropertyValues( object ); @@ -61,14 +74,15 @@ public class AccessOptimizerAdapter implements ReflectionOptimizer.AccessOptimiz catch ( Throwable t ) { throw new PropertyAccessException( t, - PROPERTY_GET_EXCEPTION, - false, - mappedClass, - getterName( t, bulkAccessor ) - ); + PROPERTY_GET_EXCEPTION, + false, + mappedClass, + getterName( t, bulkAccessor ) + ); } } + @Override public void setPropertyValues(Object object, Object[] values) { try { bulkAccessor.setPropertyValues( object, values ); @@ -76,10 +90,10 @@ public class AccessOptimizerAdapter implements ReflectionOptimizer.AccessOptimiz catch ( Throwable t ) { throw new PropertyAccessException( t, - PROPERTY_SET_EXCEPTION, - true, - mappedClass, - setterName( t, bulkAccessor ) + PROPERTY_SET_EXCEPTION, + true, + mappedClass, + setterName( t, bulkAccessor ) ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BulkAccessor.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BulkAccessor.java index 940c1a64dc..47fcdcb97c 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BulkAccessor.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BulkAccessor.java @@ -26,22 +26,36 @@ package org.hibernate.bytecode.internal.javassist; import java.io.Serializable; /** - * A JavaBean accessor. - *

- *

This object provides methods that set/get multiple properties - * of a JavaBean at once. This class and its support classes have been - * developed for the comaptibility with cglib - * (http://cglib.sourceforge.net/). + * A JavaBean bulk accessor, which provides methods capable of getting/setting multiple properties + * of a JavaBean at once. * * @author Muga Nishizawa - * @author modified by Shigeru Chiba + * @author Shigeru Chiba */ public abstract class BulkAccessor implements Serializable { protected Class target; protected String[] getters, setters; protected Class[] types; - protected BulkAccessor() { + /** + * Creates a new instance of BulkAccessor. The created instance provides methods for setting/getting + * specified properties at once. + * + * @param beanClass the class of the JavaBeans accessed + * through the created object. + * @param getters the names of setter methods for specified properties. + * @param setters the names of getter methods for specified properties. + * @param types the types of specified properties. + * + * @return The created bulk accessor + */ + public static BulkAccessor create( + Class beanClass, + String[] getters, + String[] setters, + Class[] types) { + final BulkAccessorFactory factory = new BulkAccessorFactory( beanClass, getters, setters, types ); + return factory.create(); } /** @@ -64,15 +78,19 @@ public abstract class BulkAccessor implements Serializable { * Returns the values of properties of a given bean. * * @param bean JavaBean. + * + * @return The property values */ public Object[] getPropertyValues(Object bean) { - Object[] values = new Object[getters.length]; + final Object[] values = new Object[getters.length]; getPropertyValues( bean, values ); return values; } /** * Returns the types of properties. + * + * @return The property types */ public Class[] getPropertyTypes() { return types.clone(); @@ -80,6 +98,8 @@ public abstract class BulkAccessor implements Serializable { /** * Returns the setter names of properties. + * + * @return The getter names */ public String[] getGetters() { return getters.clone(); @@ -87,28 +107,13 @@ public abstract class BulkAccessor implements Serializable { /** * Returns the getter names of the properties. + * + * @return The setter names */ public String[] getSetters() { return setters.clone(); } - /** - * Creates a new instance of BulkAccessor. - * The created instance provides methods for setting/getting - * specified properties at once. - * - * @param beanClass the class of the JavaBeans accessed - * through the created object. - * @param getters the names of setter methods for specified properties. - * @param setters the names of getter methods for specified properties. - * @param types the types of specified properties. - */ - public static BulkAccessor create( - Class beanClass, - String[] getters, - String[] setters, - Class[] types) { - BulkAccessorFactory factory = new BulkAccessorFactory( beanClass, getters, setters, types ); - return factory.create(); + private BulkAccessor() { } } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BulkAccessorException.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BulkAccessorException.java index 0b2a23f29e..2ec4559a98 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BulkAccessorException.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BulkAccessorException.java @@ -23,79 +23,64 @@ */ package org.hibernate.bytecode.internal.javassist; +import org.hibernate.HibernateException; + /** * An exception thrown while generating a bulk accessor. - * + * * @author Muga Nishizawa * @author modified by Shigeru Chiba */ -public class BulkAccessorException extends RuntimeException { - private Throwable myCause; +public class BulkAccessorException extends HibernateException { + private final int index; - /** - * Gets the cause of this throwable. - * It is for JDK 1.3 compatibility. - */ - public Throwable getCause() { - return (myCause == this ? null : myCause); - } + /** + * Constructs an exception. + * + * @param message Message explaining the exception condition + */ + public BulkAccessorException(String message) { + this( message, -1 ); + } - /** - * Initializes the cause of this throwable. - * It is for JDK 1.3 compatibility. - */ - public synchronized Throwable initCause(Throwable cause) { - myCause = cause; - return this; - } + /** + * Constructs an exception. + * + * @param message Message explaining the exception condition + * @param index The index of the property that causes an exception. + */ + public BulkAccessorException(String message, int index) { + this( message, index, null ); + } - private int index; + /** + * Constructs an exception. + * + * @param message Message explaining the exception condition + * @param cause The underlying cause + */ + public BulkAccessorException(String message, Exception cause) { + this( message, -1, cause ); + } - /** - * Constructs an exception. - */ - public BulkAccessorException(String message) { - super(message); - index = -1; - initCause(null); - } + /** + * Constructs an exception. + * + * @param message Message explaining the exception condition + * @param index The index of the property that causes an exception. + * @param cause The underlying cause + */ + public BulkAccessorException(String message, int index, Exception cause) { + super( message + " : @" + index, cause ); + this.index = index; + } - /** - * Constructs an exception. - * - * @param index the index of the property that causes an exception. - */ - public BulkAccessorException(String message, int index) { - this(message + ": " + index); - this.index = index; - } - - /** - * Constructs an exception. - */ - public BulkAccessorException(String message, Throwable cause) { - super(message); - index = -1; - initCause(cause); - } - - /** - * Constructs an exception. - * - * @param index the index of the property that causes an exception. - */ - public BulkAccessorException(Throwable cause, int index) { - this("Property " + index); - this.index = index; - initCause(cause); - } - - /** - * Returns the index of the property that causes this exception. - * - * @return -1 if the index is not specified. - */ - public int getIndex() { - return this.index; - } + /** + * Returns the index of the property that causes this exception. + * + * @return -1 if the index is not specified. + */ + public int getIndex() { + return this.index; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BulkAccessorFactory.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BulkAccessorFactory.java index 40be75c89a..b8e2d5b4ef 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BulkAccessorFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BulkAccessorFactory.java @@ -54,7 +54,8 @@ class BulkAccessorFactory { private static final String GET_SETTER_DESC = "(Ljava/lang/Object;[Ljava/lang/Object;)V"; private static final String THROWABLE_CLASS_NAME = Throwable.class.getName(); private static final String BULKEXCEPTION_CLASS_NAME = BulkAccessorException.class.getName(); - private static int counter = 0; + + private static int counter; private Class targetBean; private String[] getterNames; @@ -64,9 +65,9 @@ class BulkAccessorFactory { BulkAccessorFactory( Class target, - String[] getterNames, - String[] setterNames, - Class[] types) { + String[] getterNames, + String[] setterNames, + Class[] types) { this.targetBean = target; this.getterNames = getterNames; this.setterNames = setterNames; @@ -75,20 +76,20 @@ class BulkAccessorFactory { } BulkAccessor create() { - Method[] getters = new Method[getterNames.length]; - Method[] setters = new Method[setterNames.length]; + final Method[] getters = new Method[getterNames.length]; + final Method[] setters = new Method[setterNames.length]; findAccessors( targetBean, getterNames, setterNames, types, getters, setters ); - Class beanClass; + final Class beanClass; try { - ClassFile classfile = make( getters, setters ); - ClassLoader loader = this.getClassLoader(); + final ClassFile classfile = make( getters, setters ); + final ClassLoader loader = this.getClassLoader(); if ( writeDirectory != null ) { FactoryHelper.writeFile( classfile, writeDirectory ); } beanClass = FactoryHelper.toClass( classfile, loader, getDomain() ); - return ( BulkAccessor ) this.newInstance( beanClass ); + return (BulkAccessor) this.newInstance( beanClass ); } catch ( Exception e ) { throw new BulkAccessorException( e.getMessage(), e ); @@ -96,7 +97,7 @@ class BulkAccessorFactory { } private ProtectionDomain getDomain() { - Class cl; + final Class cl; if ( this.targetBean != null ) { cl = this.targetBean; } @@ -111,10 +112,10 @@ class BulkAccessorFactory { // set the name of bulk accessor. className = className + "_$$_bulkaccess_" + counter++; if ( className.startsWith( "java." ) ) { - className = "org.javassist.tmp." + className; + className = PACKAGE_NAME_PREFIX + className; } - ClassFile classfile = new ClassFile( false, className, BULKACESSOR_CLASS_NAME ); + final ClassFile classfile = new ClassFile( false, className, BULKACESSOR_CLASS_NAME ); classfile.setAccessFlags( AccessFlag.PUBLIC ); addDefaultConstructor( classfile ); addGetter( classfile, getters ); @@ -132,9 +133,9 @@ class BulkAccessorFactory { } private Object newInstance(Class type) throws Exception { - BulkAccessor instance = ( BulkAccessor ) type.newInstance(); + final BulkAccessor instance = (BulkAccessor) type.newInstance(); instance.target = targetBean; - int len = getterNames.length; + final int len = getterNames.length; instance.getters = new String[len]; instance.setters = new String[len]; instance.types = new Class[len]; @@ -150,34 +151,35 @@ class BulkAccessorFactory { /** * Declares a constructor that takes no parameter. * - * @param classfile - * @throws CannotCompileException + * @param classfile The class descriptor + * + * @throws CannotCompileException Indicates trouble with the underlying Javassist calls */ private void addDefaultConstructor(ClassFile classfile) throws CannotCompileException { - ConstPool cp = classfile.getConstPool(); - String cons_desc = "()V"; - MethodInfo mi = new MethodInfo( cp, MethodInfo.nameInit, cons_desc ); + final ConstPool constPool = classfile.getConstPool(); + final String constructorSignature = "()V"; + final MethodInfo constructorMethodInfo = new MethodInfo( constPool, MethodInfo.nameInit, constructorSignature ); - Bytecode code = new Bytecode( cp, 0, 1 ); + final Bytecode code = new Bytecode( constPool, 0, 1 ); // aload_0 code.addAload( 0 ); // invokespecial - code.addInvokespecial( BulkAccessor.class.getName(), MethodInfo.nameInit, cons_desc ); + code.addInvokespecial( BulkAccessor.class.getName(), MethodInfo.nameInit, constructorSignature ); // return code.addOpcode( Opcode.RETURN ); - mi.setCodeAttribute( code.toCodeAttribute() ); - mi.setAccessFlags( AccessFlag.PUBLIC ); - classfile.addMethod( mi ); + constructorMethodInfo.setCodeAttribute( code.toCodeAttribute() ); + constructorMethodInfo.setAccessFlags( AccessFlag.PUBLIC ); + classfile.addMethod( constructorMethodInfo ); } private void addGetter(ClassFile classfile, final Method[] getters) throws CannotCompileException { - ConstPool cp = classfile.getConstPool(); - int target_type_index = cp.addClassInfo( this.targetBean.getName() ); - String desc = GET_SETTER_DESC; - MethodInfo mi = new MethodInfo( cp, GENERATED_GETTER_NAME, desc ); + final ConstPool constPool = classfile.getConstPool(); + final int targetBeanConstPoolIndex = constPool.addClassInfo( this.targetBean.getName() ); + final String desc = GET_SETTER_DESC; + final MethodInfo getterMethodInfo = new MethodInfo( constPool, GENERATED_GETTER_NAME, desc ); - Bytecode code = new Bytecode( cp, 6, 4 ); + final Bytecode code = new Bytecode( constPool, 6, 4 ); /* | this | bean | args | raw bean | */ if ( getters.length >= 0 ) { // aload_1 // load bean @@ -188,12 +190,13 @@ class BulkAccessorFactory { code.addAstore( 3 ); for ( int i = 0; i < getters.length; ++i ) { if ( getters[i] != null ) { - Method getter = getters[i]; + final Method getter = getters[i]; // aload_2 // args code.addAload( 2 ); // iconst_i // continue to aastore - code.addIconst( i ); // growing stack is 1 - Class returnType = getter.getReturnType(); + // growing stack is 1 + code.addIconst( i ); + final Class returnType = getter.getReturnType(); int typeIndex = -1; if ( returnType.isPrimitive() ) { typeIndex = FactoryHelper.typeIndex( returnType ); @@ -205,23 +208,24 @@ class BulkAccessorFactory { // aload_3 // load the raw bean code.addAload( 3 ); - String getter_desc = RuntimeSupport.makeDescriptor( getter ); - String getterName = getter.getName(); + final String getterSignature = RuntimeSupport.makeDescriptor( getter ); + final String getterName = getter.getName(); if ( this.targetBean.isInterface() ) { // invokeinterface - code.addInvokeinterface( target_type_index, getterName, getter_desc, 1 ); + code.addInvokeinterface( targetBeanConstPoolIndex, getterName, getterSignature, 1 ); } else { // invokevirtual - code.addInvokevirtual( target_type_index, getterName, getter_desc ); + code.addInvokevirtual( targetBeanConstPoolIndex, getterName, getterSignature ); } - if ( typeIndex >= 0 ) { // is a primitive type + if ( typeIndex >= 0 ) { + // is a primitive type // invokespecial code.addInvokespecial( FactoryHelper.wrapperTypes[typeIndex], - MethodInfo.nameInit, - FactoryHelper.wrapperDesc[typeIndex] + MethodInfo.nameInit, + FactoryHelper.wrapperDesc[typeIndex] ); } @@ -234,22 +238,24 @@ class BulkAccessorFactory { // return code.addOpcode( Opcode.RETURN ); - mi.setCodeAttribute( code.toCodeAttribute() ); - mi.setAccessFlags( AccessFlag.PUBLIC ); - classfile.addMethod( mi ); + getterMethodInfo.setCodeAttribute( code.toCodeAttribute() ); + getterMethodInfo.setAccessFlags( AccessFlag.PUBLIC ); + classfile.addMethod( getterMethodInfo ); } private void addSetter(ClassFile classfile, final Method[] setters) throws CannotCompileException { - ConstPool cp = classfile.getConstPool(); - int target_type_index = cp.addClassInfo( this.targetBean.getName() ); - String desc = GET_SETTER_DESC; - MethodInfo mi = new MethodInfo( cp, GENERATED_SETTER_NAME, desc ); + final ConstPool constPool = classfile.getConstPool(); + final int targetTypeConstPoolIndex = constPool.addClassInfo( this.targetBean.getName() ); + final String desc = GET_SETTER_DESC; + final MethodInfo setterMethodInfo = new MethodInfo( constPool, GENERATED_SETTER_NAME, desc ); - Bytecode code = new Bytecode( cp, 4, 6 ); + final Bytecode code = new Bytecode( constPool, 4, 6 ); StackMapTable stackmap = null; /* | this | bean | args | i | raw bean | exception | */ if ( setters.length > 0 ) { - int start, end; // required to exception table + // required to exception table + int start; + int end; // iconst_0 // i code.addIconst( 0 ); // istore_3 // store i @@ -266,7 +272,7 @@ class BulkAccessorFactory { int lastIndex = 0; for ( int i = 0; i < setters.length; ++i ) { if ( setters[i] != null ) { - int diff = i - lastIndex; + final int diff = i - lastIndex; if ( diff > 0 ) { // iinc 3, 1 code.addOpcode( Opcode.IINC ); @@ -285,26 +291,26 @@ class BulkAccessorFactory { // aaload code.addOpcode( Opcode.AALOAD ); // checkcast - Class[] setterParamTypes = setters[i].getParameterTypes(); - Class setterParamType = setterParamTypes[0]; + final Class[] setterParamTypes = setters[i].getParameterTypes(); + final Class setterParamType = setterParamTypes[0]; if ( setterParamType.isPrimitive() ) { // checkcast (case of primitive type) // invokevirtual (case of primitive type) - this.addUnwrapper( classfile, code, setterParamType ); + this.addUnwrapper( code, setterParamType ); } else { // checkcast (case of reference type) code.addCheckcast( setterParamType.getName() ); } /* current stack len = 2 */ - String rawSetterMethod_desc = RuntimeSupport.makeDescriptor( setters[i] ); + final String rawSetterMethodDesc = RuntimeSupport.makeDescriptor( setters[i] ); if ( !this.targetBean.isInterface() ) { // invokevirtual - code.addInvokevirtual( target_type_index, setters[i].getName(), rawSetterMethod_desc ); + code.addInvokevirtual( targetTypeConstPoolIndex, setters[i].getName(), rawSetterMethodDesc ); } else { // invokeinterface - Class[] params = setters[i].getParameterTypes(); + final Class[] params = setters[i].getParameterTypes(); int size; if ( params[0].equals( Double.TYPE ) || params[0].equals( Long.TYPE ) ) { size = 3; @@ -313,7 +319,7 @@ class BulkAccessorFactory { size = 2; } - code.addInvokeinterface( target_type_index, setters[i].getName(), rawSetterMethod_desc, size ); + code.addInvokeinterface( targetTypeConstPoolIndex, setters[i].getName(), rawSetterMethodDesc, size ); } } @@ -323,9 +329,9 @@ class BulkAccessorFactory { code.addOpcode( Opcode.RETURN ); /* current stack len = 0 */ // register in exception table - int throwableType_index = cp.addClassInfo( THROWABLE_CLASS_NAME ); - int handler_pc = code.currentPc(); - code.addExceptionHandler( start, end, handler_pc, throwableType_index ); + final int throwableTypeIndex = constPool.addClassInfo( THROWABLE_CLASS_NAME ); + final int handlerPc = code.currentPc(); + code.addExceptionHandler( start, end, handlerPc, throwableTypeIndex ); // astore 5 // store exception code.addAstore( 5 ); // new // BulkAccessorException @@ -337,38 +343,48 @@ class BulkAccessorFactory { // iload_3 // i code.addIload( 3 ); // invokespecial // BulkAccessorException. - String cons_desc = "(Ljava/lang/Throwable;I)V"; - code.addInvokespecial( BULKEXCEPTION_CLASS_NAME, MethodInfo.nameInit, cons_desc ); + final String consDesc = "(Ljava/lang/Throwable;I)V"; + code.addInvokespecial( BULKEXCEPTION_CLASS_NAME, MethodInfo.nameInit, consDesc ); // athrow code.addOpcode( Opcode.ATHROW ); - StackMapTable.Writer writer = new StackMapTable.Writer(32); - int[] localTags = { StackMapTable.OBJECT, StackMapTable.OBJECT, StackMapTable.OBJECT, StackMapTable.INTEGER }; - int[] localData = { cp.getThisClassInfo(), cp.addClassInfo("java/lang/Object"), - cp.addClassInfo("[Ljava/lang/Object;"), 0}; - int[] stackTags = { StackMapTable.OBJECT }; - int[] stackData = { throwableType_index }; - writer.fullFrame(handler_pc, localTags, localData, stackTags, stackData); - stackmap = writer.toStackMapTable(cp); + final StackMapTable.Writer writer = new StackMapTable.Writer(32); + final int[] localTags = { + StackMapTable.OBJECT, + StackMapTable.OBJECT, + StackMapTable.OBJECT, + StackMapTable.INTEGER + }; + final int[] localData = { + constPool.getThisClassInfo(), + constPool.addClassInfo( "java/lang/Object" ), + constPool.addClassInfo( "[Ljava/lang/Object;" ), + 0 + }; + final int[] stackTags = { + StackMapTable.OBJECT + }; + final int[] stackData = { + throwableTypeIndex + }; + writer.fullFrame( handlerPc, localTags, localData, stackTags, stackData ); + stackmap = writer.toStackMapTable( constPool ); } else { // return code.addOpcode( Opcode.RETURN ); } - CodeAttribute ca = code.toCodeAttribute(); - if (stackmap != null) { - ca.setAttribute(stackmap); + final CodeAttribute ca = code.toCodeAttribute(); + if ( stackmap != null ) { + ca.setAttribute( stackmap ); } - mi.setCodeAttribute( ca ); - mi.setAccessFlags( AccessFlag.PUBLIC ); - classfile.addMethod( mi ); + setterMethodInfo.setCodeAttribute( ca ); + setterMethodInfo.setAccessFlags( AccessFlag.PUBLIC ); + classfile.addMethod( setterMethodInfo ); } - private void addUnwrapper( - ClassFile classfile, - Bytecode code, - Class type) { - int index = FactoryHelper.typeIndex( type ); - String wrapperType = FactoryHelper.wrapperTypes[index]; + private void addUnwrapper(Bytecode code, Class type) { + final int index = FactoryHelper.typeIndex( type ); + final String wrapperType = FactoryHelper.wrapperTypes[index]; // checkcast code.addCheckcast( wrapperType ); // invokevirtual @@ -377,21 +393,21 @@ class BulkAccessorFactory { private static void findAccessors( Class clazz, - String[] getterNames, - String[] setterNames, - Class[] types, - Method[] getters, - Method[] setters) { - int length = types.length; + String[] getterNames, + String[] setterNames, + Class[] types, + Method[] getters, + Method[] setters) { + final int length = types.length; if ( setterNames.length != length || getterNames.length != length ) { throw new BulkAccessorException( "bad number of accessors" ); } - Class[] getParam = new Class[0]; - Class[] setParam = new Class[1]; + final Class[] getParam = new Class[0]; + final Class[] setParam = new Class[1]; for ( int i = 0; i < length; i++ ) { if ( getterNames[i] != null ) { - Method getter = findAccessor( clazz, getterNames[i], getParam, i ); + final Method getter = findAccessor( clazz, getterNames[i], getParam, i ); if ( getter.getReturnType() != types[i] ) { throw new BulkAccessorException( "wrong return type: " + getterNames[i], i ); } @@ -406,13 +422,11 @@ class BulkAccessorFactory { } } - private static Method findAccessor( - Class clazz, - String name, - Class[] params, - int index) throws BulkAccessorException { + @SuppressWarnings("unchecked") + private static Method findAccessor(Class clazz, String name, Class[] params, int index) + throws BulkAccessorException { try { - Method method = clazz.getDeclaredMethod( name, params ); + final Method method = clazz.getDeclaredMethod( name, params ); if ( Modifier.isPrivate( method.getModifiers() ) ) { throw new BulkAccessorException( "private property", index ); } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BytecodeProviderImpl.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BytecodeProviderImpl.java index 4fac7c1677..a529a5ef7a 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BytecodeProviderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/BytecodeProviderImpl.java @@ -48,8 +48,10 @@ import org.hibernate.internal.util.StringHelper; * @author Steve Ebersole */ public class BytecodeProviderImpl implements BytecodeProvider { - - private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, BytecodeProviderImpl.class.getName()); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + BytecodeProviderImpl.class.getName() + ); @Override public ProxyFactoryFactory getProxyFactoryFactory() { @@ -59,9 +61,9 @@ public class BytecodeProviderImpl implements BytecodeProvider { @Override public ReflectionOptimizer getReflectionOptimizer( Class clazz, - String[] getterNames, - String[] setterNames, - Class[] types) { + String[] getterNames, + String[] setterNames, + Class[] types) { FastClass fastClass; BulkAccessor bulkAccessor; try { @@ -73,7 +75,7 @@ public class BytecodeProviderImpl implements BytecodeProvider { } else { //test out the optimizer: - Object instance = fastClass.newInstance(); + final Object instance = fastClass.newInstance(); bulkAccessor.setPropertyValues( instance, bulkAccessor.getPropertyValues( instance ) ); } } @@ -81,28 +83,39 @@ public class BytecodeProviderImpl implements BytecodeProvider { catch ( Throwable t ) { fastClass = null; bulkAccessor = null; - if (LOG.isDebugEnabled()) { - int index = 0; - if (t instanceof BulkAccessorException) index = ((BulkAccessorException)t).getIndex(); - if (index >= 0) LOG.debugf("Reflection optimizer disabled for: %s [%s: %s (property %s)", - clazz.getName(), - StringHelper.unqualify(t.getClass().getName()), - t.getMessage(), - setterNames[index]); - else LOG.debugf("Reflection optimizer disabled for: %s [%s: %s", - clazz.getName(), - StringHelper.unqualify(t.getClass().getName()), - t.getMessage()); - } + if ( LOG.isDebugEnabled() ) { + int index = 0; + if (t instanceof BulkAccessorException) { + index = ( (BulkAccessorException) t ).getIndex(); + } + if ( index >= 0 ) { + LOG.debugf( + "Reflection optimizer disabled for %s [%s: %s (property %s)]", + clazz.getName(), + StringHelper.unqualify( t.getClass().getName() ), + t.getMessage(), + setterNames[index] + ); + } + else { + LOG.debugf( + "Reflection optimizer disabled for %s [%s: %s]", + clazz.getName(), + StringHelper.unqualify( t.getClass().getName() ), + t.getMessage() + ); + } + } } if ( fastClass != null && bulkAccessor != null ) { return new ReflectionOptimizerImpl( new InstantiationOptimizerAdapter( fastClass ), - new AccessOptimizerAdapter( bulkAccessor, clazz ) + new AccessOptimizerAdapter( bulkAccessor, clazz ) ); } - return null; + + return null; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FastClass.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FastClass.java index 82069f103a..e629dfeec3 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FastClass.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FastClass.java @@ -30,34 +30,66 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; /** + * Fast access to class information + * * @author Muga Nishizawa */ public class FastClass implements Serializable { - private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; - private Class type; + private final Class type; - private FastClass() { + /** + * Constructs a FastClass + * + * @param type The class to optimize + * + * @return The fast class access to the given class + */ + public static FastClass create(Class type) { + return new FastClass( type ); } private FastClass(Class type) { this.type = type; } + /** + * Access to invoke a method on the class that this fast class handles + * + * @param name The name of the method to invoke, + * @param parameterTypes The method parameter types + * @param obj The instance on which to invoke the method + * @param args The parameter arguments + * + * @return The method result + * + * @throws InvocationTargetException Indicates a problem performing invocation + */ public Object invoke( String name, - Class[] parameterTypes, - Object obj, - Object[] args) throws InvocationTargetException { + Class[] parameterTypes, + Object obj, + Object[] args) throws InvocationTargetException { return this.invoke( this.getIndex( name, parameterTypes ), obj, args ); } + /** + * Access to invoke a method on the class that this fast class handles by its index + * + * @param index The method index + * @param obj The instance on which to invoke the method + * @param args The parameter arguments + * + * @return The method result + * + * @throws InvocationTargetException Indicates a problem performing invocation + */ public Object invoke( int index, - Object obj, - Object[] args) throws InvocationTargetException { - Method[] methods = this.type.getMethods(); + Object obj, + Object[] args) throws InvocationTargetException { + final Method[] methods = this.type.getMethods(); try { return methods[index].invoke( obj, args ); } @@ -71,22 +103,49 @@ public class FastClass implements Serializable { } } + /** + * Invoke the default constructor + * + * @return The constructed instance + * + * @throws InvocationTargetException Indicates a problem performing invocation + */ public Object newInstance() throws InvocationTargetException { return this.newInstance( this.getIndex( EMPTY_CLASS_ARRAY ), null ); } + /** + * Invoke a parameterized constructor + * + * @param parameterTypes The parameter types + * @param args The parameter arguments to pass along + * + * @return The constructed instance + * + * @throws InvocationTargetException Indicates a problem performing invocation + */ public Object newInstance( Class[] parameterTypes, - Object[] args) throws InvocationTargetException { + Object[] args) throws InvocationTargetException { return this.newInstance( this.getIndex( parameterTypes ), args ); } + /** + * Invoke a constructor by its index + * + * @param index The constructor index + * @param args The parameter arguments to pass along + * + * @return The constructed instance + * + * @throws InvocationTargetException Indicates a problem performing invocation + */ public Object newInstance( int index, - Object[] args) throws InvocationTargetException { - Constructor[] conss = this.type.getConstructors(); + Object[] args) throws InvocationTargetException { + final Constructor[] constructors = this.type.getConstructors(); try { - return conss[index].newInstance( args ); + return constructors[index].newInstance( args ); } catch ( ArrayIndexOutOfBoundsException e ) { throw new IllegalArgumentException( "Cannot find matching method/constructor" ); @@ -99,9 +158,18 @@ public class FastClass implements Serializable { } } + /** + * Locate the index of a method + * + * @param name The method name + * @param parameterTypes The method parameter types + * + * @return The index + */ public int getIndex(String name, Class[] parameterTypes) { - Method[] methods = this.type.getMethods(); - boolean eq = true; + final Method[] methods = this.type.getMethods(); + boolean eq; + for ( int i = 0; i < methods.length; ++i ) { if ( !Modifier.isPublic( methods[i].getModifiers() ) ) { continue; @@ -109,7 +177,7 @@ public class FastClass implements Serializable { if ( !methods[i].getName().equals( name ) ) { continue; } - Class[] params = methods[i].getParameterTypes(); + final Class[] params = methods[i].getParameterTypes(); if ( params.length != parameterTypes.length ) { continue; } @@ -127,14 +195,22 @@ public class FastClass implements Serializable { return -1; } + /** + * Locate the index of a constructor + * + * @param parameterTypes The constructor parameter types + * + * @return The index + */ public int getIndex(Class[] parameterTypes) { - Constructor[] conss = this.type.getConstructors(); - boolean eq = true; - for ( int i = 0; i < conss.length; ++i ) { - if ( !Modifier.isPublic( conss[i].getModifiers() ) ) { + final Constructor[] constructors = this.type.getConstructors(); + boolean eq; + + for ( int i = 0; i < constructors.length; ++i ) { + if ( !Modifier.isPublic( constructors[i].getModifiers() ) ) { continue; } - Class[] params = conss[i].getParameterTypes(); + final Class[] params = constructors[i].getParameterTypes(); if ( params.length != parameterTypes.length ) { continue; } @@ -152,42 +228,37 @@ public class FastClass implements Serializable { return -1; } - public int getMaxIndex() { - Method[] methods = this.type.getMethods(); - int count = 0; - for ( int i = 0; i < methods.length; ++i ) { - if ( Modifier.isPublic( methods[i].getModifiers() ) ) { - count++; - } - } - return count; - } - + /** + * Get the wrapped class name + * + * @return The class name + */ public String getName() { return this.type.getName(); } + /** + * Get the wrapped java class reference + * + * @return The class reference + */ public Class getJavaClass() { return this.type; } + @Override public String toString() { return this.type.toString(); } + @Override public int hashCode() { return this.type.hashCode(); } + @Override public boolean equals(Object o) { - if (! ( o instanceof FastClass ) ) { - return false; - } - return this.type.equals( ( ( FastClass ) o ).type ); - } - - public static FastClass create(Class type) { - FastClass fc = new FastClass( type ); - return fc; + return o instanceof FastClass + && this.type.equals( ((FastClass) o).type ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldFilter.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldFilter.java index 6d7d975f8a..c1241c4e85 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldFilter.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldFilter.java @@ -23,7 +23,6 @@ */ package org.hibernate.bytecode.internal.javassist; - /** * Contract for deciding whether fields should be read and/or write intercepted. * @@ -34,8 +33,9 @@ public interface FieldFilter { /** * Should the given field be read intercepted? * - * @param desc - * @param name + * @param desc The field descriptor + * @param name The field name + * * @return true if the given field should be read intercepted; otherwise * false. */ @@ -44,14 +44,33 @@ public interface FieldFilter { /** * Should the given field be write intercepted? * - * @param desc - * @param name + * @param desc The field descriptor + * @param name The field name + * * @return true if the given field should be write intercepted; otherwise * false. */ boolean handleWrite(String desc, String name); + /** + * Should read access to the given field be intercepted? + * + * @param fieldOwnerClassName The class where the field being accessed is defined + * @param fieldName The name of the field being accessed + * + * @return true if the given field read access should be write intercepted; otherwise + * false. + */ boolean handleReadAccess(String fieldOwnerClassName, String fieldName); + /** + * Should write access to the given field be intercepted? + * + * @param fieldOwnerClassName The class where the field being accessed is defined + * @param fieldName The name of the field being accessed + * + * @return true if the given field write access should be write intercepted; otherwise + * false. + */ boolean handleWriteAccess(String fieldOwnerClassName, String fieldName); } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldHandler.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldHandler.java index 135f6433ec..98225bd1a0 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldHandler.java @@ -28,52 +28,214 @@ package org.hibernate.bytecode.internal.javassist; * * @author Muga Nishizawa */ +@SuppressWarnings("UnusedDeclaration") public interface FieldHandler { /** * Called to handle writing an int value to a given field. * - * @param obj ? + * @param obj The object instance on which the write was invoked * @param name The name of the field being written * @param oldValue The old field value * @param newValue The new field value. - * @return ? + * + * @return The new value, typically the same as the newValue argument */ int writeInt(Object obj, String name, int oldValue, int newValue); + /** + * Called to handle writing a char value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * @param newValue The new field value. + * + * @return The new value, typically the same as the newValue argument + */ char writeChar(Object obj, String name, char oldValue, char newValue); + /** + * Called to handle writing a byte value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * @param newValue The new field value. + * + * @return The new value, typically the same as the newValue argument + */ byte writeByte(Object obj, String name, byte oldValue, byte newValue); - boolean writeBoolean(Object obj, String name, boolean oldValue, - boolean newValue); + /** + * Called to handle writing a boolean value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * @param newValue The new field value. + * + * @return The new value, typically the same as the newValue argument + */ + boolean writeBoolean(Object obj, String name, boolean oldValue, boolean newValue); + /** + * Called to handle writing a short value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * @param newValue The new field value. + * + * @return The new value, typically the same as the newValue argument + */ short writeShort(Object obj, String name, short oldValue, short newValue); + /** + * Called to handle writing a float value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * @param newValue The new field value. + * + * @return The new value, typically the same as the newValue argument + */ float writeFloat(Object obj, String name, float oldValue, float newValue); + /** + * Called to handle writing a double value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * @param newValue The new field value. + * + * @return The new value, typically the same as the newValue argument + */ double writeDouble(Object obj, String name, double oldValue, double newValue); + /** + * Called to handle writing a long value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * @param newValue The new field value. + * + * @return The new value, typically the same as the newValue argument + */ long writeLong(Object obj, String name, long oldValue, long newValue); + /** + * Called to handle writing an Object value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * @param newValue The new field value. + * + * @return The new value, typically the same as the newValue argument; may be different for entity references + */ Object writeObject(Object obj, String name, Object oldValue, Object newValue); + /** + * Called to handle reading an int value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * + * @return The field value + */ int readInt(Object obj, String name, int oldValue); + /** + * Called to handle reading a char value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * + * @return The field value + */ char readChar(Object obj, String name, char oldValue); + /** + * Called to handle reading a byte value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * + * @return The field value + */ byte readByte(Object obj, String name, byte oldValue); + /** + * Called to handle reading a boolean value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * + * @return The field value + */ boolean readBoolean(Object obj, String name, boolean oldValue); + /** + * Called to handle reading a short value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * + * @return The field value + */ short readShort(Object obj, String name, short oldValue); + /** + * Called to handle reading a float value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * + * @return The field value + */ float readFloat(Object obj, String name, float oldValue); + /** + * Called to handle reading a double value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * + * @return The field value + */ double readDouble(Object obj, String name, double oldValue); + /** + * Called to handle reading a long value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * + * @return The field value + */ long readLong(Object obj, String name, long oldValue); + /** + * Called to handle reading an Object value to a given field. + * + * @param obj The object instance on which the write was invoked + * @param name The name of the field being written + * @param oldValue The old field value + * + * @return The field value + */ Object readObject(Object obj, String name, Object oldValue); } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldTransformer.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldTransformer.java index eb586fde0c..6e3b43b6e5 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldTransformer.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldTransformer.java @@ -28,7 +28,6 @@ import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.util.Iterator; import java.util.List; import javassist.CannotCompileException; @@ -61,571 +60,691 @@ public class FieldTransformer { private static final String EACH_WRITE_METHOD_PREFIX = "$javassist_write_"; - private static final String FIELD_HANDLED_TYPE_NAME = FieldHandled.class - .getName(); + private static final String FIELD_HANDLED_TYPE_NAME = FieldHandled.class.getName(); private static final String HANDLER_FIELD_NAME = "$JAVASSIST_READ_WRITE_HANDLER"; - private static final String FIELD_HANDLER_TYPE_NAME = FieldHandler.class - .getName(); + private static final String FIELD_HANDLER_TYPE_NAME = FieldHandler.class.getName(); - private static final String HANDLER_FIELD_DESCRIPTOR = 'L' + FIELD_HANDLER_TYPE_NAME - .replace('.', '/') + ';'; + private static final String HANDLER_FIELD_DESCRIPTOR = 'L' + FIELD_HANDLER_TYPE_NAME.replace( '.', '/' ) + ';'; private static final String GETFIELDHANDLER_METHOD_NAME = "getFieldHandler"; private static final String SETFIELDHANDLER_METHOD_NAME = "setFieldHandler"; - private static final String GETFIELDHANDLER_METHOD_DESCRIPTOR = "()" - + HANDLER_FIELD_DESCRIPTOR; + private static final String GETFIELDHANDLER_METHOD_DESCRIPTOR = "()" + HANDLER_FIELD_DESCRIPTOR; - private static final String SETFIELDHANDLER_METHOD_DESCRIPTOR = "(" - + HANDLER_FIELD_DESCRIPTOR + ")V"; + private static final String SETFIELDHANDLER_METHOD_DESCRIPTOR = "(" + HANDLER_FIELD_DESCRIPTOR + ")V"; - private FieldFilter filter; - - private ClassPool classPool; + private final FieldFilter filter; + private final ClassPool classPool; - public FieldTransformer() { - this(null, null); - } - - public FieldTransformer(FieldFilter f, ClassPool c) { + FieldTransformer(FieldFilter f, ClassPool c) { filter = f; classPool = c; } - - public void setClassPool(ClassPool c) { - classPool = c; - } - - public void setFieldFilter(FieldFilter f) { - filter = f; - } + /** + * Transform the class contained in the given file, writing the result back to the same file. + * + * @param file The file containing the class to be transformed + * + * @throws Exception Indicates a problem performing the transformation + */ public void transform(File file) throws Exception { - DataInputStream in = new DataInputStream(new FileInputStream(file)); - ClassFile classfile = new ClassFile(in); - transform(classfile); - DataOutputStream out = new DataOutputStream(new FileOutputStream(file)); + final DataInputStream in = new DataInputStream( new FileInputStream( file ) ); + final ClassFile classfile = new ClassFile( in ); + transform( classfile ); + + final DataOutputStream out = new DataOutputStream( new FileOutputStream( file ) ); try { - classfile.write(out); - } finally { + classfile.write( out ); + } + finally { out.close(); } } - public void transform(ClassFile classfile) throws Exception { - if (classfile.isInterface()) { + /** + * Transform the class defined by the given ClassFile descriptor. The ClassFile descriptor itself is mutated + * + * @param classFile The class file descriptor + * + * @throws Exception Indicates a problem performing the transformation + */ + public void transform(ClassFile classFile) throws Exception { + if ( classFile.isInterface() ) { return; } try { - addFieldHandlerField(classfile); - addGetFieldHandlerMethod(classfile); - addSetFieldHandlerMethod(classfile); - addFieldHandledInterface(classfile); - addReadWriteMethods(classfile); - transformInvokevirtualsIntoPutAndGetfields(classfile); - } catch (CannotCompileException e) { - throw new RuntimeException(e.getMessage(), e); + addFieldHandlerField( classFile ); + addGetFieldHandlerMethod( classFile ); + addSetFieldHandlerMethod( classFile ); + addFieldHandledInterface( classFile ); + addReadWriteMethods( classFile ); + transformInvokevirtualsIntoPutAndGetfields( classFile ); + } + catch (CannotCompileException e) { + throw new RuntimeException( e.getMessage(), e ); } } - private void addFieldHandlerField(ClassFile classfile) - throws CannotCompileException { - ConstPool cp = classfile.getConstPool(); - FieldInfo finfo = new FieldInfo(cp, HANDLER_FIELD_NAME, - HANDLER_FIELD_DESCRIPTOR); - finfo.setAccessFlags(AccessFlag.PRIVATE | AccessFlag.TRANSIENT); - classfile.addField(finfo); + private void addFieldHandlerField(ClassFile classfile) throws CannotCompileException { + final ConstPool constPool = classfile.getConstPool(); + final FieldInfo fieldInfo = new FieldInfo( constPool, HANDLER_FIELD_NAME, HANDLER_FIELD_DESCRIPTOR ); + fieldInfo.setAccessFlags( AccessFlag.PRIVATE | AccessFlag.TRANSIENT ); + classfile.addField( fieldInfo ); } - private void addGetFieldHandlerMethod(ClassFile classfile) - throws CannotCompileException, BadBytecode { - ConstPool cp = classfile.getConstPool(); - int this_class_index = cp.getThisClassInfo(); - MethodInfo minfo = new MethodInfo(cp, GETFIELDHANDLER_METHOD_NAME, - GETFIELDHANDLER_METHOD_DESCRIPTOR); + private void addGetFieldHandlerMethod(ClassFile classfile) throws CannotCompileException, BadBytecode { + final ConstPool constPool = classfile.getConstPool(); + final int thisClassInfo = constPool.getThisClassInfo(); + final MethodInfo getterMethodInfo = new MethodInfo( + constPool, + GETFIELDHANDLER_METHOD_NAME, + GETFIELDHANDLER_METHOD_DESCRIPTOR + ); + /* local variable | this | */ - Bytecode code = new Bytecode(cp, 2, 1); + final Bytecode code = new Bytecode( constPool, 2, 1 ); // aload_0 // load this - code.addAload(0); + code.addAload( 0 ); // getfield // get field "$JAVASSIST_CALLBACK" defined already - code.addOpcode(Opcode.GETFIELD); - int field_index = cp.addFieldrefInfo(this_class_index, - HANDLER_FIELD_NAME, HANDLER_FIELD_DESCRIPTOR); - code.addIndex(field_index); + code.addOpcode( Opcode.GETFIELD ); + final int fieldIndex = constPool.addFieldrefInfo( thisClassInfo, HANDLER_FIELD_NAME, HANDLER_FIELD_DESCRIPTOR ); + code.addIndex( fieldIndex ); // areturn // return the value of the field - code.addOpcode(Opcode.ARETURN); - minfo.setCodeAttribute(code.toCodeAttribute()); - minfo.setAccessFlags(AccessFlag.PUBLIC); - CodeAttribute codeAttribute = minfo.getCodeAttribute(); - if (codeAttribute != null) { - StackMapTable smt = MapMaker.make(classPool, minfo); - codeAttribute.setAttribute(smt); + code.addOpcode( Opcode.ARETURN ); + getterMethodInfo.setCodeAttribute( code.toCodeAttribute() ); + getterMethodInfo.setAccessFlags( AccessFlag.PUBLIC ); + final CodeAttribute codeAttribute = getterMethodInfo.getCodeAttribute(); + if ( codeAttribute != null ) { + final StackMapTable smt = MapMaker.make( classPool, getterMethodInfo ); + codeAttribute.setAttribute( smt ); } - classfile.addMethod(minfo); + classfile.addMethod( getterMethodInfo ); } - private void addSetFieldHandlerMethod(ClassFile classfile) - throws CannotCompileException, BadBytecode { - ConstPool cp = classfile.getConstPool(); - int this_class_index = cp.getThisClassInfo(); - MethodInfo minfo = new MethodInfo(cp, SETFIELDHANDLER_METHOD_NAME, - SETFIELDHANDLER_METHOD_DESCRIPTOR); + private void addSetFieldHandlerMethod(ClassFile classfile) throws CannotCompileException, BadBytecode { + final ConstPool constPool = classfile.getConstPool(); + final int thisClassInfo = constPool.getThisClassInfo(); + final MethodInfo methodInfo = new MethodInfo( + constPool, + SETFIELDHANDLER_METHOD_NAME, + SETFIELDHANDLER_METHOD_DESCRIPTOR + ); + /* local variables | this | callback | */ - Bytecode code = new Bytecode(cp, 3, 3); - // aload_0 // load this - code.addAload(0); - // aload_1 // load callback - code.addAload(1); + final Bytecode code = new Bytecode(constPool, 3, 3); + // aload_0 : load this + code.addAload( 0 ); + // aload_1 : load callback + code.addAload( 1 ); // putfield // put field "$JAVASSIST_CALLBACK" defined already - code.addOpcode(Opcode.PUTFIELD); - int field_index = cp.addFieldrefInfo(this_class_index, - HANDLER_FIELD_NAME, HANDLER_FIELD_DESCRIPTOR); - code.addIndex(field_index); + code.addOpcode( Opcode.PUTFIELD ); + final int fieldIndex = constPool.addFieldrefInfo( thisClassInfo, HANDLER_FIELD_NAME, HANDLER_FIELD_DESCRIPTOR ); + code.addIndex( fieldIndex ); // return - code.addOpcode(Opcode.RETURN); - minfo.setCodeAttribute(code.toCodeAttribute()); - minfo.setAccessFlags(AccessFlag.PUBLIC); - CodeAttribute codeAttribute = minfo.getCodeAttribute(); - if (codeAttribute != null) { - StackMapTable smt = MapMaker.make(classPool, minfo); - codeAttribute.setAttribute(smt); + code.addOpcode( Opcode.RETURN ); + methodInfo.setCodeAttribute( code.toCodeAttribute() ); + methodInfo.setAccessFlags( AccessFlag.PUBLIC ); + final CodeAttribute codeAttribute = methodInfo.getCodeAttribute(); + if ( codeAttribute != null ) { + final StackMapTable smt = MapMaker.make( classPool, methodInfo ); + codeAttribute.setAttribute( smt ); } - classfile.addMethod(minfo); + classfile.addMethod( methodInfo ); } private void addFieldHandledInterface(ClassFile classfile) { - String[] interfaceNames = classfile.getInterfaces(); - String[] newInterfaceNames = new String[interfaceNames.length + 1]; - System.arraycopy(interfaceNames, 0, newInterfaceNames, 0, - interfaceNames.length); + final String[] interfaceNames = classfile.getInterfaces(); + final String[] newInterfaceNames = new String[interfaceNames.length + 1]; + System.arraycopy( interfaceNames, 0, newInterfaceNames, 0, interfaceNames.length ); newInterfaceNames[newInterfaceNames.length - 1] = FIELD_HANDLED_TYPE_NAME; - classfile.setInterfaces(newInterfaceNames); + classfile.setInterfaces( newInterfaceNames ); } - private void addReadWriteMethods(ClassFile classfile) - throws CannotCompileException, BadBytecode { - List fields = classfile.getFields(); - for (Iterator field_iter = fields.iterator(); field_iter.hasNext();) { - FieldInfo finfo = (FieldInfo) field_iter.next(); - if ((finfo.getAccessFlags() & AccessFlag.STATIC) == 0 - && (!finfo.getName().equals(HANDLER_FIELD_NAME))) { + private void addReadWriteMethods(ClassFile classfile) throws CannotCompileException, BadBytecode { + final List fields = classfile.getFields(); + for ( Object field : fields ) { + final FieldInfo finfo = (FieldInfo) field; + if ( (finfo.getAccessFlags() & AccessFlag.STATIC) == 0 && (!finfo.getName().equals( HANDLER_FIELD_NAME )) ) { // case of non-static field - if (filter.handleRead(finfo.getDescriptor(), finfo - .getName())) { - addReadMethod(classfile, finfo); + if ( filter.handleRead( finfo.getDescriptor(), finfo.getName() ) ) { + addReadMethod( classfile, finfo ); } - if (filter.handleWrite(finfo.getDescriptor(), finfo - .getName())) { - addWriteMethod(classfile, finfo); + if ( filter.handleWrite( finfo.getDescriptor(), finfo.getName() ) ) { + addWriteMethod( classfile, finfo ); } } } } - private void addReadMethod(ClassFile classfile, FieldInfo finfo) - throws CannotCompileException, BadBytecode { - ConstPool cp = classfile.getConstPool(); - int this_class_index = cp.getThisClassInfo(); - String desc = "()" + finfo.getDescriptor(); - MethodInfo minfo = new MethodInfo(cp, EACH_READ_METHOD_PREFIX - + finfo.getName(), desc); + private void addReadMethod(ClassFile classfile, FieldInfo finfo) throws CannotCompileException, BadBytecode { + final ConstPool constPool = classfile.getConstPool(); + final int thisClassInfo = constPool.getThisClassInfo(); + final String readMethodDescriptor = "()" + finfo.getDescriptor(); + final MethodInfo readMethodInfo = new MethodInfo( + constPool, + EACH_READ_METHOD_PREFIX + finfo.getName(), + readMethodDescriptor + ); + /* local variables | target obj | each oldvalue | */ - Bytecode code = new Bytecode(cp, 5, 3); + final Bytecode code = new Bytecode(constPool, 5, 3); // aload_0 - code.addAload(0); + code.addAload( 0 ); // getfield // get each field - code.addOpcode(Opcode.GETFIELD); - int base_field_index = cp.addFieldrefInfo(this_class_index, finfo - .getName(), finfo.getDescriptor()); - code.addIndex(base_field_index); + code.addOpcode( Opcode.GETFIELD ); + final int baseFieldIndex = constPool.addFieldrefInfo( thisClassInfo, finfo.getName(), finfo.getDescriptor() ); + code.addIndex( baseFieldIndex ); // aload_0 - code.addAload(0); - // invokeinterface // invoke Enabled.getInterceptFieldCallback() - int enabled_class_index = cp.addClassInfo(FIELD_HANDLED_TYPE_NAME); - code.addInvokeinterface(enabled_class_index, - GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR, - 1); + code.addAload( 0 ); + // invokeinterface : invoke Enabled.getInterceptFieldCallback() + final int enabledClassIndex = constPool.addClassInfo( FIELD_HANDLED_TYPE_NAME ); + code.addInvokeinterface( + enabledClassIndex, + GETFIELDHANDLER_METHOD_NAME, + GETFIELDHANDLER_METHOD_DESCRIPTOR, + 1 + ); // ifnonnull - code.addOpcode(Opcode.IFNONNULL); - code.addIndex(4); + code.addOpcode( Opcode.IFNONNULL ); + code.addIndex( 4 ); // *return // each type - addTypeDependDataReturn(code, finfo.getDescriptor()); + addTypeDependDataReturn( code, finfo.getDescriptor() ); // *store_1 // each type - addTypeDependDataStore(code, finfo.getDescriptor(), 1); + addTypeDependDataStore( code, finfo.getDescriptor(), 1 ); // aload_0 - code.addAload(0); + code.addAload( 0 ); // invokeinterface // invoke Enabled.getInterceptFieldCallback() - code.addInvokeinterface(enabled_class_index, - GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR, - 1); + code.addInvokeinterface( + enabledClassIndex, + GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR, + 1 + ); // aload_0 - code.addAload(0); + code.addAload( 0 ); // ldc // name of the field - code.addLdc(finfo.getName()); + code.addLdc( finfo.getName() ); // *load_1 // each type - addTypeDependDataLoad(code, finfo.getDescriptor(), 1); + addTypeDependDataLoad( code, finfo.getDescriptor(), 1 ); // invokeinterface // invoke Callback.read*() // each type - addInvokeFieldHandlerMethod(classfile, code, finfo.getDescriptor(), - true); + addInvokeFieldHandlerMethod( + classfile, code, finfo.getDescriptor(), + true + ); // *return // each type - addTypeDependDataReturn(code, finfo.getDescriptor()); + addTypeDependDataReturn( code, finfo.getDescriptor() ); - minfo.setCodeAttribute(code.toCodeAttribute()); - minfo.setAccessFlags(AccessFlag.PUBLIC); - CodeAttribute codeAttribute = minfo.getCodeAttribute(); - if (codeAttribute != null) { - StackMapTable smt = MapMaker.make(classPool, minfo); - codeAttribute.setAttribute(smt); + readMethodInfo.setCodeAttribute( code.toCodeAttribute() ); + readMethodInfo.setAccessFlags( AccessFlag.PUBLIC ); + final CodeAttribute codeAttribute = readMethodInfo.getCodeAttribute(); + if ( codeAttribute != null ) { + final StackMapTable smt = MapMaker.make( classPool, readMethodInfo ); + codeAttribute.setAttribute( smt ); } - classfile.addMethod(minfo); + classfile.addMethod( readMethodInfo ); } - private void addWriteMethod(ClassFile classfile, FieldInfo finfo) - throws CannotCompileException, BadBytecode { - ConstPool cp = classfile.getConstPool(); - int this_class_index = cp.getThisClassInfo(); - String desc = "(" + finfo.getDescriptor() + ")V"; - MethodInfo minfo = new MethodInfo(cp, EACH_WRITE_METHOD_PREFIX - + finfo.getName(), desc); + private void addWriteMethod(ClassFile classfile, FieldInfo finfo) throws CannotCompileException, BadBytecode { + final ConstPool constPool = classfile.getConstPool(); + final int thisClassInfo = constPool.getThisClassInfo(); + final String writeMethodDescriptor = "(" + finfo.getDescriptor() + ")V"; + final MethodInfo writeMethodInfo = new MethodInfo( + constPool, + EACH_WRITE_METHOD_PREFIX+ finfo.getName(), + writeMethodDescriptor + ); + /* local variables | target obj | each oldvalue | */ - Bytecode code = new Bytecode(cp, 6, 3); + final Bytecode code = new Bytecode(constPool, 6, 3); // aload_0 - code.addAload(0); - // invokeinterface // enabled.getInterceptFieldCallback() - int enabled_class_index = cp.addClassInfo(FIELD_HANDLED_TYPE_NAME); - code.addInvokeinterface(enabled_class_index, - GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR, - 1); + code.addAload( 0 ); + // invokeinterface : enabled.getInterceptFieldCallback() + final int enabledClassIndex = constPool.addClassInfo( FIELD_HANDLED_TYPE_NAME ); + code.addInvokeinterface( + enabledClassIndex, + GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR, + 1 + ); // ifnonnull (label1) - code.addOpcode(Opcode.IFNONNULL); - code.addIndex(9); + code.addOpcode( Opcode.IFNONNULL ); + code.addIndex( 9 ); // aload_0 - code.addAload(0); + code.addAload( 0 ); // *load_1 - addTypeDependDataLoad(code, finfo.getDescriptor(), 1); + addTypeDependDataLoad( code, finfo.getDescriptor(), 1 ); // putfield - code.addOpcode(Opcode.PUTFIELD); - int base_field_index = cp.addFieldrefInfo(this_class_index, finfo - .getName(), finfo.getDescriptor()); - code.addIndex(base_field_index); - code.growStack(-Descriptor.dataSize(finfo.getDescriptor())); + code.addOpcode( Opcode.PUTFIELD ); + final int baseFieldIndex = constPool.addFieldrefInfo( thisClassInfo, finfo.getName(), finfo.getDescriptor() ); + code.addIndex( baseFieldIndex ); + code.growStack( -Descriptor.dataSize( finfo.getDescriptor() ) ); // return ; - code.addOpcode(Opcode.RETURN); + code.addOpcode( Opcode.RETURN ); // aload_0 - code.addAload(0); + code.addAload( 0 ); // dup - code.addOpcode(Opcode.DUP); + code.addOpcode( Opcode.DUP ); // invokeinterface // enabled.getInterceptFieldCallback() - code.addInvokeinterface(enabled_class_index, - GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR, - 1); + code.addInvokeinterface( + enabledClassIndex, + GETFIELDHANDLER_METHOD_NAME, + GETFIELDHANDLER_METHOD_DESCRIPTOR, + 1 + ); // aload_0 - code.addAload(0); + code.addAload( 0 ); // ldc // field name - code.addLdc(finfo.getName()); + code.addLdc( finfo.getName() ); // aload_0 - code.addAload(0); + code.addAload( 0 ); // getfield // old value of the field - code.addOpcode(Opcode.GETFIELD); - code.addIndex(base_field_index); - code.growStack(Descriptor.dataSize(finfo.getDescriptor()) - 1); + code.addOpcode( Opcode.GETFIELD ); + code.addIndex( baseFieldIndex ); + code.growStack( Descriptor.dataSize( finfo.getDescriptor() ) - 1 ); // *load_1 - addTypeDependDataLoad(code, finfo.getDescriptor(), 1); + addTypeDependDataLoad( code, finfo.getDescriptor(), 1 ); // invokeinterface // callback.write*(..) - addInvokeFieldHandlerMethod(classfile, code, finfo.getDescriptor(), - false); + addInvokeFieldHandlerMethod( classfile, code, finfo.getDescriptor(), false ); // putfield // new value of the field - code.addOpcode(Opcode.PUTFIELD); - code.addIndex(base_field_index); - code.growStack(-Descriptor.dataSize(finfo.getDescriptor())); + code.addOpcode( Opcode.PUTFIELD ); + code.addIndex( baseFieldIndex ); + code.growStack( -Descriptor.dataSize( finfo.getDescriptor() ) ); // return - code.addOpcode(Opcode.RETURN); + code.addOpcode( Opcode.RETURN ); - minfo.setCodeAttribute(code.toCodeAttribute()); - minfo.setAccessFlags(AccessFlag.PUBLIC); - CodeAttribute codeAttribute = minfo.getCodeAttribute(); - if (codeAttribute != null) { - StackMapTable smt = MapMaker.make(classPool, minfo); - codeAttribute.setAttribute(smt); + writeMethodInfo.setCodeAttribute( code.toCodeAttribute() ); + writeMethodInfo.setAccessFlags( AccessFlag.PUBLIC ); + final CodeAttribute codeAttribute = writeMethodInfo.getCodeAttribute(); + if ( codeAttribute != null ) { + final StackMapTable smt = MapMaker.make( classPool, writeMethodInfo ); + codeAttribute.setAttribute( smt ); } - classfile.addMethod(minfo); + classfile.addMethod( writeMethodInfo ); } - private void transformInvokevirtualsIntoPutAndGetfields(ClassFile classfile) - throws CannotCompileException, BadBytecode { - List methods = classfile.getMethods(); - for (Iterator method_iter = methods.iterator(); method_iter.hasNext();) { - MethodInfo minfo = (MethodInfo) method_iter.next(); - String methodName = minfo.getName(); - if (methodName.startsWith(EACH_READ_METHOD_PREFIX) - || methodName.startsWith(EACH_WRITE_METHOD_PREFIX) - || methodName.equals(GETFIELDHANDLER_METHOD_NAME) - || methodName.equals(SETFIELDHANDLER_METHOD_NAME)) { + private void transformInvokevirtualsIntoPutAndGetfields(ClassFile classfile) throws CannotCompileException, BadBytecode { + for ( Object o : classfile.getMethods() ) { + final MethodInfo methodInfo = (MethodInfo) o; + final String methodName = methodInfo.getName(); + if ( methodName.startsWith( EACH_READ_METHOD_PREFIX ) + || methodName.startsWith( EACH_WRITE_METHOD_PREFIX ) + || methodName.equals( GETFIELDHANDLER_METHOD_NAME ) + || methodName.equals( SETFIELDHANDLER_METHOD_NAME ) ) { continue; } - CodeAttribute codeAttr = minfo.getCodeAttribute(); - if (codeAttr == null) { + + final CodeAttribute codeAttr = methodInfo.getCodeAttribute(); + if ( codeAttr == null ) { continue; } - CodeIterator iter = codeAttr.iterator(); - while (iter.hasNext()) { + + final CodeIterator iter = codeAttr.iterator(); + while ( iter.hasNext() ) { int pos = iter.next(); - pos = transformInvokevirtualsIntoGetfields(classfile, iter, pos); - pos = transformInvokevirtualsIntoPutfields(classfile, iter, pos); + pos = transformInvokevirtualsIntoGetfields( classfile, iter, pos ); + transformInvokevirtualsIntoPutfields( classfile, iter, pos ); } - StackMapTable smt = MapMaker.make(classPool, minfo); - codeAttr.setAttribute(smt); + final StackMapTable smt = MapMaker.make( classPool, methodInfo ); + codeAttr.setAttribute( smt ); } } private int transformInvokevirtualsIntoGetfields(ClassFile classfile, CodeIterator iter, int pos) { - ConstPool cp = classfile.getConstPool(); - int c = iter.byteAt(pos); - if (c != Opcode.GETFIELD) { + final ConstPool constPool = classfile.getConstPool(); + final int c = iter.byteAt( pos ); + if ( c != Opcode.GETFIELD ) { return pos; } - int index = iter.u16bitAt(pos + 1); - String fieldName = cp.getFieldrefName(index); - String className = cp.getFieldrefClassName(index); + + final int index = iter.u16bitAt( pos + 1 ); + final String fieldName = constPool.getFieldrefName( index ); + final String className = constPool.getFieldrefClassName( index ); if ( !filter.handleReadAccess( className, fieldName ) ) { return pos; } - String desc = "()" + cp.getFieldrefType( index ); - int read_method_index = cp.addMethodrefInfo( - cp.getThisClassInfo(), + + final String fieldReaderMethodDescriptor = "()" + constPool.getFieldrefType( index ); + final int fieldReaderMethodIndex = constPool.addMethodrefInfo( + constPool.getThisClassInfo(), EACH_READ_METHOD_PREFIX + fieldName, - desc + fieldReaderMethodDescriptor ); - iter.writeByte(Opcode.INVOKEVIRTUAL, pos); - iter.write16bit(read_method_index, pos + 1); + iter.writeByte( Opcode.INVOKEVIRTUAL, pos ); + iter.write16bit( fieldReaderMethodIndex, pos + 1 ); return pos; } - private int transformInvokevirtualsIntoPutfields( - ClassFile classfile, - CodeIterator iter, int pos) { - ConstPool cp = classfile.getConstPool(); - int c = iter.byteAt(pos); - if (c != Opcode.PUTFIELD) { + private int transformInvokevirtualsIntoPutfields(ClassFile classfile, CodeIterator iter, int pos) { + final ConstPool constPool = classfile.getConstPool(); + final int c = iter.byteAt( pos ); + if ( c != Opcode.PUTFIELD ) { return pos; } - int index = iter.u16bitAt(pos + 1); - String fieldName = cp.getFieldrefName(index); - String className = cp.getFieldrefClassName(index); + + final int index = iter.u16bitAt( pos + 1 ); + final String fieldName = constPool.getFieldrefName( index ); + final String className = constPool.getFieldrefClassName( index ); if ( !filter.handleWriteAccess( className, fieldName ) ) { return pos; } - String desc = "(" + cp.getFieldrefType( index ) + ")V"; - int write_method_index = cp.addMethodrefInfo( - cp.getThisClassInfo(), + + final String fieldWriterMethodDescriptor = "(" + constPool.getFieldrefType( index ) + ")V"; + final int fieldWriterMethodIndex = constPool.addMethodrefInfo( + constPool.getThisClassInfo(), EACH_WRITE_METHOD_PREFIX + fieldName, - desc + fieldWriterMethodDescriptor ); - iter.writeByte(Opcode.INVOKEVIRTUAL, pos); - iter.write16bit(write_method_index, pos + 1); + iter.writeByte( Opcode.INVOKEVIRTUAL, pos ); + iter.write16bit( fieldWriterMethodIndex, pos + 1 ); return pos; } - private static void addInvokeFieldHandlerMethod(ClassFile classfile, - Bytecode code, String typeName, boolean isReadMethod) { - ConstPool cp = classfile.getConstPool(); + private static void addInvokeFieldHandlerMethod( + ClassFile classfile, + Bytecode code, + String typeName, + boolean isReadMethod) { + final ConstPool constPool = classfile.getConstPool(); // invokeinterface - int callback_type_index = cp.addClassInfo(FIELD_HANDLER_TYPE_NAME); - if ((typeName.charAt(0) == 'L') - && (typeName.charAt(typeName.length() - 1) == ';') - || (typeName.charAt(0) == '[')) { + final int callbackTypeIndex = constPool.addClassInfo( FIELD_HANDLER_TYPE_NAME ); + if ( ( typeName.charAt( 0 ) == 'L' ) + && ( typeName.charAt( typeName.length() - 1 ) == ';' ) + || ( typeName.charAt( 0 ) == '[' ) ) { // reference type - int indexOfL = typeName.indexOf('L'); + final int indexOfL = typeName.indexOf( 'L' ); String type; - if (indexOfL == 0) { + if ( indexOfL == 0 ) { // not array - type = typeName.substring(1, typeName.length() - 1); - type = type.replace('/', '.'); - } else if (indexOfL == -1) { + type = typeName.substring( 1, typeName.length() - 1 ); + type = type.replace( '/', '.' ); + } + else if ( indexOfL == -1 ) { // array of primitive type // do nothing type = typeName; - } else { + } + else { // array of reference type - type = typeName.replace('/', '.'); + type = typeName.replace( '/', '.' ); } - if (isReadMethod) { - code - .addInvokeinterface( - callback_type_index, - "readObject", - "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;", - 4); + + if ( isReadMethod ) { + code.addInvokeinterface( + callbackTypeIndex, + "readObject", + "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;", + 4 + ); // checkcast - code.addCheckcast(type); - } else { - code - .addInvokeinterface( - callback_type_index, - "writeObject", - "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - 5); - // checkcast - code.addCheckcast(type); + code.addCheckcast( type ); } - } else if (typeName.equals("Z")) { + else { + code.addInvokeinterface( + callbackTypeIndex, + "writeObject", + "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + 5 + ); + // checkcast + code.addCheckcast( type ); + } + } + else if ( typeName.equals( "Z" ) ) { // boolean - if (isReadMethod) { - code.addInvokeinterface(callback_type_index, "readBoolean", - "(Ljava/lang/Object;Ljava/lang/String;Z)Z", 4); - } else { - code.addInvokeinterface(callback_type_index, "writeBoolean", - "(Ljava/lang/Object;Ljava/lang/String;ZZ)Z", 5); + if ( isReadMethod ) { + code.addInvokeinterface( + callbackTypeIndex, + "readBoolean", + "(Ljava/lang/Object;Ljava/lang/String;Z)Z", + 4 + ); } - } else if (typeName.equals("B")) { + else { + code.addInvokeinterface( + callbackTypeIndex, + "writeBoolean", + "(Ljava/lang/Object;Ljava/lang/String;ZZ)Z", + 5 + ); + } + } + else if ( typeName.equals( "B" ) ) { // byte - if (isReadMethod) { - code.addInvokeinterface(callback_type_index, "readByte", - "(Ljava/lang/Object;Ljava/lang/String;B)B", 4); - } else { - code.addInvokeinterface(callback_type_index, "writeByte", - "(Ljava/lang/Object;Ljava/lang/String;BB)B", 5); + if ( isReadMethod ) { + code.addInvokeinterface( + callbackTypeIndex, + "readByte", + "(Ljava/lang/Object;Ljava/lang/String;B)B", + 4 + ); } - } else if (typeName.equals("C")) { + else { + code.addInvokeinterface( + callbackTypeIndex, + "writeByte", + "(Ljava/lang/Object;Ljava/lang/String;BB)B", + 5 + ); + } + } + else if ( typeName.equals( "C" ) ) { // char - if (isReadMethod) { - code.addInvokeinterface(callback_type_index, "readChar", - "(Ljava/lang/Object;Ljava/lang/String;C)C", 4); - } else { - code.addInvokeinterface(callback_type_index, "writeChar", - "(Ljava/lang/Object;Ljava/lang/String;CC)C", 5); + if ( isReadMethod ) { + code.addInvokeinterface( + callbackTypeIndex, + "readChar", + "(Ljava/lang/Object;Ljava/lang/String;C)C", + 4 + ); } - } else if (typeName.equals("I")) { + else { + code.addInvokeinterface( + callbackTypeIndex, + "writeChar", + "(Ljava/lang/Object;Ljava/lang/String;CC)C", + 5 + ); + } + } + else if ( typeName.equals( "I" ) ) { // int - if (isReadMethod) { - code.addInvokeinterface(callback_type_index, "readInt", - "(Ljava/lang/Object;Ljava/lang/String;I)I", 4); - } else { - code.addInvokeinterface(callback_type_index, "writeInt", - "(Ljava/lang/Object;Ljava/lang/String;II)I", 5); + if ( isReadMethod ) { + code.addInvokeinterface( + callbackTypeIndex, + "readInt", + "(Ljava/lang/Object;Ljava/lang/String;I)I", + 4 + ); } - } else if (typeName.equals("S")) { + else { + code.addInvokeinterface( + callbackTypeIndex, + "writeInt", + "(Ljava/lang/Object;Ljava/lang/String;II)I", + 5 + ); + } + } + else if ( typeName.equals( "S" ) ) { // short - if (isReadMethod) { - code.addInvokeinterface(callback_type_index, "readShort", - "(Ljava/lang/Object;Ljava/lang/String;S)S", 4); - } else { - code.addInvokeinterface(callback_type_index, "writeShort", - "(Ljava/lang/Object;Ljava/lang/String;SS)S", 5); + if ( isReadMethod ) { + code.addInvokeinterface( + callbackTypeIndex, + "readShort", + "(Ljava/lang/Object;Ljava/lang/String;S)S", + 4 + ); } - } else if (typeName.equals("D")) { + else { + code.addInvokeinterface( + callbackTypeIndex, + "writeShort", + "(Ljava/lang/Object;Ljava/lang/String;SS)S", + 5 + ); + } + } + else if ( typeName.equals( "D" ) ) { // double - if (isReadMethod) { - code.addInvokeinterface(callback_type_index, "readDouble", - "(Ljava/lang/Object;Ljava/lang/String;D)D", 5); - } else { - code.addInvokeinterface(callback_type_index, "writeDouble", - "(Ljava/lang/Object;Ljava/lang/String;DD)D", 7); + if ( isReadMethod ) { + code.addInvokeinterface( + callbackTypeIndex, + "readDouble", + "(Ljava/lang/Object;Ljava/lang/String;D)D", + 5 + ); } - } else if (typeName.equals("F")) { + else { + code.addInvokeinterface( + callbackTypeIndex, + "writeDouble", + "(Ljava/lang/Object;Ljava/lang/String;DD)D", + 7 + ); + } + } + else if ( typeName.equals( "F" ) ) { // float - if (isReadMethod) { - code.addInvokeinterface(callback_type_index, "readFloat", - "(Ljava/lang/Object;Ljava/lang/String;F)F", 4); - } else { - code.addInvokeinterface(callback_type_index, "writeFloat", - "(Ljava/lang/Object;Ljava/lang/String;FF)F", 5); + if ( isReadMethod ) { + code.addInvokeinterface( + callbackTypeIndex, + "readFloat", + "(Ljava/lang/Object;Ljava/lang/String;F)F", + 4 + ); } - } else if (typeName.equals("J")) { + else { + code.addInvokeinterface( + callbackTypeIndex, + "writeFloat", + "(Ljava/lang/Object;Ljava/lang/String;FF)F", + 5 + ); + } + } + else if ( typeName.equals( "J" ) ) { // long - if (isReadMethod) { - code.addInvokeinterface(callback_type_index, "readLong", - "(Ljava/lang/Object;Ljava/lang/String;J)J", 5); - } else { - code.addInvokeinterface(callback_type_index, "writeLong", - "(Ljava/lang/Object;Ljava/lang/String;JJ)J", 7); + if ( isReadMethod ) { + code.addInvokeinterface( + callbackTypeIndex, + "readLong", + "(Ljava/lang/Object;Ljava/lang/String;J)J", + 5 + ); } - } else { + else { + code.addInvokeinterface( + callbackTypeIndex, + "writeLong", + "(Ljava/lang/Object;Ljava/lang/String;JJ)J", + 7 + ); + } + } + else { // bad type - throw new RuntimeException("bad type: " + typeName); + throw new RuntimeException( "bad type: " + typeName ); } } - private static void addTypeDependDataLoad(Bytecode code, String typeName, - int i) { - if ((typeName.charAt(0) == 'L') - && (typeName.charAt(typeName.length() - 1) == ';') - || (typeName.charAt(0) == '[')) { + private static void addTypeDependDataLoad(Bytecode code, String typeName, int i) { + if ( typeName.charAt( 0 ) == 'L' + && typeName.charAt( typeName.length() - 1 ) == ';' + || typeName.charAt( 0 ) == '[' ) { // reference type - code.addAload(i); - } else if (typeName.equals("Z") || typeName.equals("B") - || typeName.equals("C") || typeName.equals("I") - || typeName.equals("S")) { + code.addAload( i ); + } + else if ( typeName.equals( "Z" ) + || typeName.equals( "B" ) + || typeName.equals( "C" ) + || typeName.equals( "I" ) + || typeName.equals( "S" ) ) { // boolean, byte, char, int, short - code.addIload(i); - } else if (typeName.equals("D")) { + code.addIload( i ); + } + else if ( typeName.equals( "D" ) ) { // double - code.addDload(i); - } else if (typeName.equals("F")) { + code.addDload( i ); + } + else if ( typeName.equals( "F" ) ) { // float - code.addFload(i); - } else if (typeName.equals("J")) { + code.addFload( i ); + } + else if ( typeName.equals( "J" ) ) { // long - code.addLload(i); - } else { + code.addLload( i ); + } + else { // bad type - throw new RuntimeException("bad type: " + typeName); + throw new RuntimeException( "bad type: " + typeName ); } } - private static void addTypeDependDataStore(Bytecode code, String typeName, - int i) { - if ((typeName.charAt(0) == 'L') - && (typeName.charAt(typeName.length() - 1) == ';') - || (typeName.charAt(0) == '[')) { + private static void addTypeDependDataStore(Bytecode code, String typeName, int i) { + if ( typeName.charAt( 0 ) == 'L' + && typeName.charAt( typeName.length() - 1 ) == ';' + || typeName.charAt( 0 ) == '[' ) { // reference type - code.addAstore(i); - } else if (typeName.equals("Z") || typeName.equals("B") - || typeName.equals("C") || typeName.equals("I") - || typeName.equals("S")) { + code.addAstore( i ); + } + else if ( typeName.equals( "Z" ) + || typeName.equals( "B" ) + || typeName.equals( "C" ) + || typeName.equals( "I" ) + || typeName.equals( "S" ) ) { // boolean, byte, char, int, short - code.addIstore(i); - } else if (typeName.equals("D")) { + code.addIstore( i ); + } + else if ( typeName.equals( "D" ) ) { // double - code.addDstore(i); - } else if (typeName.equals("F")) { + code.addDstore( i ); + } + else if ( typeName.equals( "F" ) ) { // float - code.addFstore(i); - } else if (typeName.equals("J")) { + code.addFstore( i ); + } + else if ( typeName.equals( "J" ) ) { // long - code.addLstore(i); - } else { + code.addLstore( i ); + } + else { // bad type - throw new RuntimeException("bad type: " + typeName); + throw new RuntimeException( "bad type: " + typeName ); } } private static void addTypeDependDataReturn(Bytecode code, String typeName) { - if ((typeName.charAt(0) == 'L') - && (typeName.charAt(typeName.length() - 1) == ';') - || (typeName.charAt(0) == '[')) { + if ( typeName.charAt( 0 ) == 'L' + && typeName.charAt( typeName.length() - 1 ) == ';' + || typeName.charAt( 0 ) == '[') { // reference type - code.addOpcode(Opcode.ARETURN); - } else if (typeName.equals("Z") || typeName.equals("B") - || typeName.equals("C") || typeName.equals("I") - || typeName.equals("S")) { + code.addOpcode( Opcode.ARETURN ); + } + else if ( typeName.equals( "Z" ) + || typeName.equals( "B" ) + || typeName.equals( "C" ) + || typeName.equals( "I" ) + || typeName.equals( "S" ) ) { // boolean, byte, char, int, short - code.addOpcode(Opcode.IRETURN); - } else if (typeName.equals("D")) { + code.addOpcode( Opcode.IRETURN ); + } + else if ( typeName.equals( "D" ) ) { // double - code.addOpcode(Opcode.DRETURN); - } else if (typeName.equals("F")) { + code.addOpcode( Opcode.DRETURN ); + } + else if ( typeName.equals( "F" ) ) { // float - code.addOpcode(Opcode.FRETURN); - } else if (typeName.equals("J")) { + code.addOpcode( Opcode.FRETURN ); + } + else if ( typeName.equals( "J" ) ) { // long - code.addOpcode(Opcode.LRETURN); - } else { + code.addOpcode( Opcode.LRETURN ); + } + else { // bad type - throw new RuntimeException("bad type: " + typeName); + throw new RuntimeException( "bad type: " + typeName ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/InstantiationOptimizerAdapter.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/InstantiationOptimizerAdapter.java index a66000b0af..c064b82e66 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/InstantiationOptimizerAdapter.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/InstantiationOptimizerAdapter.java @@ -37,18 +37,25 @@ import org.hibernate.bytecode.spi.ReflectionOptimizer; public class InstantiationOptimizerAdapter implements ReflectionOptimizer.InstantiationOptimizer, Serializable { private final FastClass fastClass; + /** + * Constructs the InstantiationOptimizerAdapter + * + * @param fastClass The fast class for the class to be instantiated here. + */ public InstantiationOptimizerAdapter(FastClass fastClass) { this.fastClass = fastClass; } + @Override public Object newInstance() { try { return fastClass.newInstance(); } - catch ( Throwable t ) { + catch ( Exception e ) { throw new InstantiationException( "Could not instantiate entity with Javassist optimizer: ", - fastClass.getJavaClass(), t + fastClass.getJavaClass(), + e ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/JavassistClassTransformer.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/JavassistClassTransformer.java index d8f440117e..d8d725b678 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/JavassistClassTransformer.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/JavassistClassTransformer.java @@ -49,10 +49,17 @@ import org.hibernate.internal.CoreMessageLogger; * @author Dustin Schultz */ public class JavassistClassTransformer extends AbstractClassTransformerImpl { + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + JavassistClassTransformer.class.getName() + ); - private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, - JavassistClassTransformer.class.getName()); - + /** + * Constructs the JavassistClassTransformer + * + * @param classFilter The filter used to determine which classes to transform + * @param fieldFilter The filter used to determine which fields to transform + */ public JavassistClassTransformer(ClassFilter classFilter, org.hibernate.bytecode.buildtime.spi.FieldFilter fieldFilter) { super( classFilter, fieldFilter ); } @@ -73,23 +80,27 @@ public class JavassistClassTransformer extends AbstractClassTransformerImpl { LOG.unableToBuildEnhancementMetamodel( className ); return classfileBuffer; } - // This is the same as ClassPool.getDefault() but ensures a new ClassPool per - ClassPool cp = new ClassPool(); + + final ClassPool cp = new ClassPool(); cp.appendSystemPath(); - cp.appendClassPath(new ClassClassPath(this.getClass())); - cp.appendClassPath(new ClassClassPath(classfile.getClass())); + cp.appendClassPath( new ClassClassPath( this.getClass() ) ); + cp.appendClassPath( new ClassClassPath( classfile.getClass() ) ); + try { - cp.makeClassIfNew(new ByteArrayInputStream(classfileBuffer)); - } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); + cp.makeClassIfNew( new ByteArrayInputStream( classfileBuffer ) ); } - FieldTransformer transformer = getFieldTransformer( classfile, cp ); + catch (IOException e) { + throw new RuntimeException( e.getMessage(), e ); + } + + final FieldTransformer transformer = getFieldTransformer( classfile, cp ); if ( transformer != null ) { LOG.debugf( "Enhancing %s", className ); + DataOutputStream out = null; try { transformer.transform( classfile ); - ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); out = new DataOutputStream( byteStream ); classfile.write( out ); return byteStream.toByteArray(); @@ -100,7 +111,9 @@ public class JavassistClassTransformer extends AbstractClassTransformerImpl { } finally { try { - if ( out != null ) out.close(); + if ( out != null ) { + out.close(); + } } catch (IOException e) { //swallow @@ -131,14 +144,15 @@ public class JavassistClassTransformer extends AbstractClassTransformerImpl { public boolean handleWriteAccess(String fieldOwnerClassName, String fieldName) { return fieldFilter.shouldTransformFieldAccess( classfile.getName(), fieldOwnerClassName, fieldName ); } - }, classPool + }, + classPool ); } private boolean alreadyInstrumented(ClassFile classfile) { - String[] intfs = classfile.getInterfaces(); - for ( int i = 0; i < intfs.length; i++ ) { - if ( FieldHandled.class.getName().equals( intfs[i] ) ) { + final String[] interfaces = classfile.getInterfaces(); + for ( String anInterface : interfaces ) { + if ( FieldHandled.class.getName().equals( anInterface ) ) { return true; } } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/ProxyFactoryFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/ProxyFactoryFactoryImpl.java index 73db828ef9..abb5cbb04d 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/ProxyFactoryFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/ProxyFactoryFactoryImpl.java @@ -53,6 +53,14 @@ public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory { return new JavassistProxyFactory(); } + /** + * Constructs a BasicProxyFactoryImpl + * + * @param superClass The abstract super class (or null if none). + * @param interfaces Interfaces to be proxied (or null if none). + * + * @return The constructed BasicProxyFactoryImpl + */ public BasicProxyFactory buildBasicProxyFactory(Class superClass, Class[] interfaces) { return new BasicProxyFactoryImpl( superClass, interfaces ); } @@ -64,7 +72,8 @@ public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory { if ( superClass == null && ( interfaces == null || interfaces.length < 1 ) ) { throw new AssertionFailure( "attempting to build proxy without any superclass or interfaces" ); } - javassist.util.proxy.ProxyFactory factory = new javassist.util.proxy.ProxyFactory(); + + final javassist.util.proxy.ProxyFactory factory = new javassist.util.proxy.ProxyFactory(); factory.setFilter( FINALIZE_FILTER ); if ( superClass != null ) { factory.setSuperclass( superClass ); @@ -77,7 +86,7 @@ public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory { public Object getProxy() { try { - ProxyObject proxy = ( ProxyObject ) proxyClass.newInstance(); + final ProxyObject proxy = (ProxyObject) proxyClass.newInstance(); proxy.setHandler( new PassThroughHandler( proxy, proxyClass.getName() ) ); return proxy; } @@ -108,12 +117,13 @@ public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory { this.proxiedClassName = proxiedClassName; } + @SuppressWarnings("unchecked") public Object invoke( Object object, - Method method, - Method method1, - Object[] args) throws Exception { - String name = method.getName(); + Method method, + Method method1, + Object[] args) throws Exception { + final String name = method.getName(); if ( "toString".equals( name ) ) { return proxiedClassName + "@" + System.identityHashCode( object ); } @@ -123,18 +133,22 @@ public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory { else if ( "hashCode".equals( name ) ) { return System.identityHashCode( object ); } - boolean hasGetterSignature = method.getParameterTypes().length == 0 && method.getReturnType() != null; - boolean hasSetterSignature = method.getParameterTypes().length == 1 && ( method.getReturnType() == null || method.getReturnType() == void.class ); + + final boolean hasGetterSignature = method.getParameterTypes().length == 0 + && method.getReturnType() != null; + final boolean hasSetterSignature = method.getParameterTypes().length == 1 + && ( method.getReturnType() == null || method.getReturnType() == void.class ); + if ( name.startsWith( "get" ) && hasGetterSignature ) { - String propName = name.substring( 3 ); + final String propName = name.substring( 3 ); return data.get( propName ); } else if ( name.startsWith( "is" ) && hasGetterSignature ) { - String propName = name.substring( 2 ); + final String propName = name.substring( 2 ); return data.get( propName ); } else if ( name.startsWith( "set" ) && hasSetterSignature) { - String propName = name.substring( 3 ); + final String propName = name.substring( 3 ); data.put( propName, args[0] ); return null; } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/ReflectionOptimizerImpl.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/ReflectionOptimizerImpl.java index e95bc67254..ce754dc798 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/ReflectionOptimizerImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/ReflectionOptimizerImpl.java @@ -33,21 +33,28 @@ import org.hibernate.bytecode.spi.ReflectionOptimizer; * @author Steve Ebersole */ public class ReflectionOptimizerImpl implements ReflectionOptimizer, Serializable { - private final InstantiationOptimizer instantiationOptimizer; private final AccessOptimizer accessOptimizer; + /** + * Constructs a ReflectionOptimizerImpl + * + * @param instantiationOptimizer The instantiation optimizer to use + * @param accessOptimizer The property access optimizer to use. + */ public ReflectionOptimizerImpl( InstantiationOptimizer instantiationOptimizer, - AccessOptimizer accessOptimizer) { + AccessOptimizer accessOptimizer) { this.instantiationOptimizer = instantiationOptimizer; this.accessOptimizer = accessOptimizer; } + @Override public InstantiationOptimizer getInstantiationOptimizer() { return instantiationOptimizer; } + @Override public AccessOptimizer getAccessOptimizer() { return accessOptimizer; } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/TransformingClassLoader.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/TransformingClassLoader.java index 0c03fa93be..0e96020a59 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/TransformingClassLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/TransformingClassLoader.java @@ -33,46 +33,53 @@ import javassist.NotFoundException; import org.hibernate.HibernateException; /** + * A ClassLoader implementation applying Class transformations as they are being loaded. + * * @author Steve Ebersole */ +@SuppressWarnings("UnusedDeclaration") public class TransformingClassLoader extends ClassLoader { private ClassLoader parent; private ClassPool classPool; - /*package*/ TransformingClassLoader(ClassLoader parent, String[] classpath) { + TransformingClassLoader(ClassLoader parent, String[] classpaths) { this.parent = parent; - classPool = new ClassPool( true ); - for ( int i = 0; i < classpath.length; i++ ) { + this.classPool = new ClassPool( true ); + for ( String classpath : classpaths ) { try { - classPool.appendClassPath( classpath[i] ); + classPool.appendClassPath( classpath ); } - catch ( NotFoundException e ) { + catch (NotFoundException e) { throw new HibernateException( "Unable to resolve requested classpath for transformation [" + - classpath[i] + "] : " + e.getMessage() + classpath + "] : " + e.getMessage() ); } } } + @Override protected Class findClass(String name) throws ClassNotFoundException { - try { - CtClass cc = classPool.get( name ); - // todo : modify the class definition if not already transformed... - byte[] b = cc.toBytecode(); - return defineClass( name, b, 0, b.length ); - } - catch ( NotFoundException e ) { - throw new ClassNotFoundException(); - } - catch ( IOException e ) { - throw new ClassNotFoundException(); - } - catch ( CannotCompileException e ) { - throw new ClassNotFoundException(); - } - } + try { + final CtClass cc = classPool.get( name ); + // todo : modify the class definition if not already transformed... + byte[] b = cc.toBytecode(); + return defineClass( name, b, 0, b.length ); + } + catch (NotFoundException e) { + throw new ClassNotFoundException(); + } + catch (IOException e) { + throw new ClassNotFoundException(); + } + catch (CannotCompileException e) { + throw new ClassNotFoundException(); + } + } + /** + * Used to release resources. Call when done with the ClassLoader + */ public void release() { classPool = null; parent = null; diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/package-info.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/package-info.java new file mode 100644 index 0000000000..7cddc225e3 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/package-info.java @@ -0,0 +1,4 @@ +/** + * Javassist support internals + */ +package org.hibernate.bytecode.internal.javassist; diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/AbstractClassTransformerImpl.java b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/AbstractClassTransformerImpl.java index b310ac2207..a1d98cbffb 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/AbstractClassTransformerImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/AbstractClassTransformerImpl.java @@ -35,7 +35,6 @@ import org.hibernate.bytecode.buildtime.spi.FieldFilter; * @author Steve Ebersole */ public abstract class AbstractClassTransformerImpl implements ClassTransformer { - protected final ClassFilter classFilter; protected final FieldFilter fieldFilter; @@ -44,6 +43,7 @@ public abstract class AbstractClassTransformerImpl implements ClassTransformer { this.fieldFilter = fieldFilter; } + @Override public byte[] transform( ClassLoader loader, String className, @@ -60,6 +60,17 @@ public abstract class AbstractClassTransformerImpl implements ClassTransformer { } } + /** + * Delegate the transformation call from {@link #transform} + * + * @param loader The class loader to use + * @param className The name of the class to transform + * @param classBeingRedefined If an already loaded class is being redefined, then pass this as a parameter + * @param protectionDomain The protection domain of the class being (re)defined + * @param classfileBuffer The bytes of the class file. + * + * @return The transformed (enhanced/instrumented) bytes. + */ protected abstract byte[] doTransform( ClassLoader loader, String className, diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/BasicProxyFactory.java b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/BasicProxyFactory.java index 41c6d136ab..c8447b7b30 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/BasicProxyFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/BasicProxyFactory.java @@ -24,13 +24,13 @@ package org.hibernate.bytecode.spi; /** - * A proxy factory for "basic proxy" generation + * A proxy factory for "basic proxy" generation. * * @author Steve Ebersole */ public interface BasicProxyFactory { /** - * Get a proxy reference. + * Get a proxy reference.. * * @return A proxy reference. */ diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/ByteCodeHelper.java b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/ByteCodeHelper.java index 623f1079fd..92784286a0 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/ByteCodeHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/ByteCodeHelper.java @@ -37,12 +37,15 @@ import java.util.zip.ZipInputStream; * @author Steve Ebersole */ public class ByteCodeHelper { + /** + * Disallow instantiation (its a helper) + */ private ByteCodeHelper() { } /** * Reads class byte array info from the given input stream. - *

+ * * The stream is closed within this method! * * @param inputStream The stream containing the class binary; null will lead to an {@link IOException} @@ -56,13 +59,13 @@ public class ByteCodeHelper { throw new IOException( "null input stream" ); } - byte[] buffer = new byte[409600]; + final byte[] buffer = new byte[409600]; byte[] classBytes = new byte[0]; try { int r = inputStream.read( buffer ); while ( r >= buffer.length ) { - byte[] temp = new byte[ classBytes.length + buffer.length ]; + final byte[] temp = new byte[ classBytes.length + buffer.length ]; // copy any previously read bytes into the temp array System.arraycopy( classBytes, 0, temp, 0, classBytes.length ); // copy the just read bytes into the temp array (after the previously read) @@ -72,7 +75,7 @@ public class ByteCodeHelper { r = inputStream.read( buffer ); } if ( r != -1 ) { - byte[] temp = new byte[ classBytes.length + r ]; + final byte[] temp = new byte[ classBytes.length + r ]; // copy any previously read bytes into the temp array System.arraycopy( classBytes, 0, temp, 0, classBytes.length ); // copy the just read bytes into the temp array (after the previously read) @@ -109,18 +112,18 @@ public class ByteCodeHelper { * Read class definition a zip (jar) file entry. * * @param zip The zip entry stream. - * + * * @return The class bytes * * @throws IOException Indicates a problem accessing the given stream. */ public static byte[] readByteCode(ZipInputStream zip) throws IOException { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - InputStream in = new BufferedInputStream( zip ); - int b; - while ( ( b = in.read() ) != -1 ) { - bout.write( b ); - } - return bout.toByteArray(); - } + final ByteArrayOutputStream bout = new ByteArrayOutputStream(); + final InputStream in = new BufferedInputStream( zip ); + int b; + while ( ( b = in.read() ) != -1 ) { + bout.write( b ); + } + return bout.toByteArray(); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/ClassTransformer.java b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/ClassTransformer.java index 0480c9b8f8..4fc0a56b38 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/ClassTransformer.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/ClassTransformer.java @@ -32,25 +32,24 @@ import java.security.ProtectionDomain; * entity class files when they are loaded and redefined. The transformation * occurs before the class is defined by the JVM * - * * @author Bill Burke * @author Emmanuel Bernard */ -public interface ClassTransformer -{ - /** - * Invoked when a class is being loaded or redefined to add hooks for persistence bytecode manipulation - * - * @param loader the defining class loaderof the class being transformed. It may be null if using bootstrap loader - * @param classname The name of the class being transformed - * @param classBeingRedefined If an already loaded class is being redefined, then pass this as a parameter - * @param protectionDomain ProtectionDomain of the class being (re)-defined - * @param classfileBuffer The input byte buffer in class file format - * @return A well-formed class file that can be loaded - */ - public byte[] transform(ClassLoader loader, - String classname, - Class classBeingRedefined, - ProtectionDomain protectionDomain, - byte[] classfileBuffer); +public interface ClassTransformer { + /** + * Invoked when a class is being loaded or redefined to add hooks for persistence bytecode manipulation. + * + * @param loader the defining class loaderof the class being transformed. It may be null if using bootstrap loader + * @param classname The name of the class being transformed + * @param classBeingRedefined If an already loaded class is being redefined, then pass this as a parameter + * @param protectionDomain ProtectionDomain of the class being (re)-defined + * @param classfileBuffer The input byte buffer in class file format + * @return A well-formed class file that can be loaded + */ + public byte[] transform( + ClassLoader loader, + String classname, + Class classBeingRedefined, + ProtectionDomain protectionDomain, + byte[] classfileBuffer); } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/EntityInstrumentationMetadata.java b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/EntityInstrumentationMetadata.java index 3c9ceb7611..005d4026e5 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/EntityInstrumentationMetadata.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/EntityInstrumentationMetadata.java @@ -42,15 +42,15 @@ public interface EntityInstrumentationMetadata { public String getEntityName(); /** - * Has the entity class been bytecode instrumented? + * Has the entity class been bytecode instrumented? * * @return {@code true} indicates the entity class is instrumented for Hibernate use; {@code false} * indicates it is not */ - public boolean isInstrumented(); + public boolean isInstrumented(); - /** - * Build and inject a field interceptor instance into the instrumented entity. + /** + * Build and inject a field interceptor instance into the instrumented entity. * * @param entity The entity into which built interceptor should be injected * @param entityName The name of the entity @@ -60,15 +60,15 @@ public interface EntityInstrumentationMetadata { * @return The built and injected interceptor * * @throws NotInstrumentedException Thrown if {@link #isInstrumented()} returns {@code false} - */ - public FieldInterceptor injectInterceptor( - Object entity, - String entityName, - Set uninitializedFieldNames, - SessionImplementor session) throws NotInstrumentedException; + */ + public FieldInterceptor injectInterceptor( + Object entity, + String entityName, + Set uninitializedFieldNames, + SessionImplementor session) throws NotInstrumentedException; - /** - * Extract the field interceptor instance from the instrumented entity. + /** + * Extract the field interceptor instance from the instrumented entity. * * @param entity The entity from which to extract the interceptor * @@ -76,5 +76,5 @@ public interface EntityInstrumentationMetadata { * * @throws NotInstrumentedException Thrown if {@link #isInstrumented()} returns {@code false} */ - public FieldInterceptor extractInterceptor(Object entity) throws NotInstrumentedException; + public FieldInterceptor extractInterceptor(Object entity) throws NotInstrumentedException; } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/InstrumentedClassLoader.java b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/InstrumentedClassLoader.java index 033530527b..a293ec9c91 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/InstrumentedClassLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/InstrumentedClassLoader.java @@ -26,39 +26,45 @@ package org.hibernate.bytecode.spi; import java.io.InputStream; /** - * A specialized classloader which performs bytecode enhancement on class - * definitions as they are loaded into the classloader scope. + * A specialized ClassLoader which performs bytecode enhancement on class definitions as they are loaded + * into the ClassLoader scope. * * @author Emmanuel Bernard * @author Steve Ebersole */ public class InstrumentedClassLoader extends ClassLoader { + private final ClassTransformer classTransformer; - private ClassTransformer classTransformer; - + /** + * Constructs an InstrumentedClassLoader. + * + * @param parent The parent ClassLoader + * @param classTransformer The transformer to use for applying enhancement + */ public InstrumentedClassLoader(ClassLoader parent, ClassTransformer classTransformer) { super( parent ); this.classTransformer = classTransformer; } + @Override public Class loadClass(String name) throws ClassNotFoundException { if ( name.startsWith( "java." ) || classTransformer == null ) { return getParent().loadClass( name ); } - Class c = findLoadedClass( name ); + final Class c = findLoadedClass( name ); if ( c != null ) { return c; } - InputStream is = this.getResourceAsStream( name.replace( '.', '/' ) + ".class" ); + final InputStream is = this.getResourceAsStream( name.replace( '.', '/' ) + ".class" ); if ( is == null ) { throw new ClassNotFoundException( name + " not found" ); } try { - byte[] originalBytecode = ByteCodeHelper.readByteCode( is ); - byte[] transformedBytecode = classTransformer.transform( getParent(), name, null, null, originalBytecode ); + final byte[] originalBytecode = ByteCodeHelper.readByteCode( is ); + final byte[] transformedBytecode = classTransformer.transform( getParent(), name, null, null, originalBytecode ); if ( originalBytecode == transformedBytecode ) { // no transformations took place, so handle it as we would a // non-instrumented class diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/NotInstrumentedException.java b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/NotInstrumentedException.java index 19e7eb08ce..8bb788b2cd 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/NotInstrumentedException.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/NotInstrumentedException.java @@ -26,14 +26,18 @@ package org.hibernate.bytecode.spi; import org.hibernate.HibernateException; /** + * Indicates a condition where an instrumented/enhanced class was expected, but the class was not + * instrumented/enhanced. + * * @author Steve Ebersole */ public class NotInstrumentedException extends HibernateException { + /** + * Constructs a NotInstrumentedException + * + * @param message Message explaining the exception condition + */ public NotInstrumentedException(String message) { super( message ); } - - public NotInstrumentedException(String message, Throwable root) { - super( message, root ); - } } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/ReflectionOptimizer.java b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/ReflectionOptimizer.java index 8205ede743..53361b28c0 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/ReflectionOptimizer.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/ReflectionOptimizer.java @@ -29,8 +29,18 @@ package org.hibernate.bytecode.spi; * @author Steve Ebersole */ public interface ReflectionOptimizer { - + /** + * Retrieve the optimizer for calling an entity's constructor via reflection. + * + * @return The optimizer for instantiation + */ public InstantiationOptimizer getInstantiationOptimizer(); + + /** + * Retrieve the optimizer for accessing the entity's persistent state. + * + * @return The optimizer for persistent state access + */ public AccessOptimizer getAccessOptimizer(); /** @@ -51,8 +61,28 @@ public interface ReflectionOptimizer { * @author Steve Ebersole */ public interface AccessOptimizer { + /** + * Get the name of all properties. + * + * @return The name of all properties. + */ public String[] getPropertyNames(); + + /** + * Get the value of all properties from the given entity + * + * @param object The entity from which to extract values. + * + * @return The values. + */ public Object[] getPropertyValues(Object object); + + /** + * Set all property values into an entity instance. + * + * @param object The entity instance + * @param values The values to inject + */ public void setPropertyValues(Object object, Object[] values); } } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/spi/package-info.java b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/package-info.java new file mode 100644 index 0000000000..7c085649b2 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/spi/package-info.java @@ -0,0 +1,4 @@ +/** + * Package defining bytecode code enhancement (instrumentation) support. + */ +package org.hibernate.bytecode.spi; diff --git a/hibernate-core/src/main/java/org/hibernate/cache/CacheException.java b/hibernate-core/src/main/java/org/hibernate/cache/CacheException.java index 3505e41ec8..83c66cbe09 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/CacheException.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/CacheException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,26 +20,41 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.cache; + import org.hibernate.HibernateException; /** * Something went wrong in the cache */ public class CacheException extends HibernateException { - - public CacheException(String s) { - super(s); + /** + * Constructs a CacheException. + * + * @param message Message explaining the exception condition + */ + public CacheException(String message) { + super( message ); } - public CacheException(String s, Throwable e) { - super(s, e); + /** + * Constructs a CacheException. + * + * @param message Message explaining the exception condition + * @param cause The underlying cause + */ + public CacheException(String message, Throwable cause) { + super( message, cause ); } - - public CacheException(Throwable e) { - super(e); + + /** + * Constructs a CacheException. + * + * @param cause The underlying cause + */ + public CacheException(Throwable cause) { + super( cause ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/NoCacheRegionFactoryAvailableException.java b/hibernate-core/src/main/java/org/hibernate/cache/NoCacheRegionFactoryAvailableException.java index a59e7f5956..66492c8d22 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/NoCacheRegionFactoryAvailableException.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/NoCacheRegionFactoryAvailableException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,21 +20,30 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.cache; + import org.hibernate.cfg.Environment; /** - * Implementation of NoCacheRegionFactoryAvailableException. + * Indicates a condition where a second-level cache implementation was expected to be to available, but + * none was found on the classpath. * * @author Steve Ebersole */ public class NoCacheRegionFactoryAvailableException extends CacheException { - private static final String MSG = "Second-level cache is used in the application, but property " - + Environment.CACHE_REGION_FACTORY + " is not given, please either disable second level cache" + - " or set correct region factory class name to property "+Environment.CACHE_REGION_FACTORY+ - " (and make sure the second level cache provider, hibernate-infinispan, for example, is available in the classpath)."; + private static final String MSG = String.format( + "Second-level cache is used in the application, but property %s is not given; " + + "please either disable second level cache or set correct region factory using the %s setting " + + "and make sure the second level cache provider (hibernate-infinispan, e.g.) is available on the " + + "classpath.", + Environment.CACHE_REGION_FACTORY, + Environment.CACHE_REGION_FACTORY + ); + + /** + * Constructs a NoCacheRegionFactoryAvailableException with a standard message. + */ public NoCacheRegionFactoryAvailableException() { super( MSG ); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/RegionFactory.java b/hibernate-core/src/main/java/org/hibernate/cache/RegionFactory.java index 8934f2d6f0..e0d3b07130 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/RegionFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/RegionFactory.java @@ -24,6 +24,8 @@ package org.hibernate.cache; /** + * Legacy (deprecated) namespace for the RegionFactory contract. + * * @author Steve Ebersole * * @deprecated Moved, but still need this definition for ehcache diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java index b12222ed06..f24ab650db 100755 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java @@ -97,10 +97,10 @@ public class CacheKey implements Serializable { //hashCode is part of this check since it is pre-calculated and hash must match for equals to be true return false; } - CacheKey that = (CacheKey) other; - return EqualsHelper.equals( entityOrRoleName, that.entityOrRoleName ) && - type.isEqual( key, that.key ) && - EqualsHelper.equals( tenantId, that.tenantId ); + final CacheKey that = (CacheKey) other; + return EqualsHelper.equals( entityOrRoleName, that.entityOrRoleName ) + && type.isEqual( key, that.key ) + && EqualsHelper.equals( tenantId, that.tenantId ); } @Override @@ -111,6 +111,6 @@ public class CacheKey implements Serializable { @Override public String toString() { // Used to be required for OSCache - return entityOrRoleName + '#' + key.toString();//"CacheKey#" + type.toString(key, sf); + return entityOrRoleName + '#' + key.toString(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/FilterKey.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/FilterKey.java index dd5ecea569..084f8f6de4 100755 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/FilterKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/FilterKey.java @@ -40,43 +40,55 @@ import org.hibernate.type.Type; * @author Gavin King */ public final class FilterKey implements Serializable { - private String filterName; - private Map filterParameters = new HashMap(); - - public FilterKey(String name, Map params, Map types) { + private final String filterName; + private final Map filterParameters = new HashMap(); + + FilterKey(String name, Map params, Map types) { filterName = name; for ( Map.Entry paramEntry : params.entrySet() ) { - Type type = types.get( paramEntry.getKey() ); + final Type type = types.get( paramEntry.getKey() ); filterParameters.put( paramEntry.getKey(), new TypedValue( type, paramEntry.getValue() ) ); } } - + + @Override public int hashCode() { int result = 13; result = 37 * result + filterName.hashCode(); result = 37 * result + filterParameters.hashCode(); return result; } - + + @Override public boolean equals(Object other) { - if ( !(other instanceof FilterKey) ) return false; - FilterKey that = (FilterKey) other; - if ( !that.filterName.equals(filterName) ) return false; - if ( !that.filterParameters.equals(filterParameters) ) return false; - return true; + if ( !(other instanceof FilterKey) ) { + return false; + } + + final FilterKey that = (FilterKey) other; + return that.filterName.equals( filterName ) + && that.filterParameters.equals( filterParameters ); } - + + @Override public String toString() { return "FilterKey[" + filterName + filterParameters + ']'; } - + + /** + * Constructs a number of FilterKey instances, given the currently enabled filters + * + * @param enabledFilters The currently enabled filters + * + * @return The filter keys, one per enabled filter + */ public static Set createFilterKeys(Map enabledFilters) { - if ( enabledFilters.size()==0 ) { + if ( enabledFilters.size() == 0 ) { return null; } - Set result = new HashSet(); + final Set result = new HashSet(); for ( Filter filter : enabledFilters.values() ) { - FilterKey key = new FilterKey( + final FilterKey key = new FilterKey( filter.getName(), ( (FilterImpl) filter ).getParameters(), filter.getFilterDefinition().getParameterTypes() diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java index 61c1ed9a6c..bd0a7624ea 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java @@ -76,38 +76,38 @@ public class NaturalIdCacheKey implements Serializable { result = prime * result + ( ( this.tenantId == null ) ? 0 : this.tenantId.hashCode() ); for ( int i = 0; i < naturalIdValues.length; i++ ) { final int naturalIdPropertyIndex = naturalIdPropertyIndexes[i]; - final Type type = propertyTypes[naturalIdPropertyIndex]; + final Type type = propertyTypes[naturalIdPropertyIndex]; final Object value = naturalIdValues[i]; - + result = prime * result + (value != null ? type.getHashCode( value, factory ) : 0); - + this.naturalIdValues[i] = type.disassemble( value, session, null ); } - + this.hashCode = result; initTransients(); } - - private void initTransients() { - this.toString = new ValueHolder( - new ValueHolder.DeferredInitializer() { - @Override - public String initialize() { - //Complex toString is needed as naturalIds for entities are not simply based on a single value like primary keys - //the only same way to differentiate the keys is to included the disassembled values in the string. - final StringBuilder toStringBuilder = new StringBuilder( entityName ).append( "##NaturalId[" ); - for ( int i = 0; i < naturalIdValues.length; i++ ) { - toStringBuilder.append( naturalIdValues[i] ); - if ( i + 1 < naturalIdValues.length ) { - toStringBuilder.append( ", " ); - } - } - toStringBuilder.append( "]" ); - return toStringBuilder.toString(); - } - } - ); + private void initTransients() { + this.toString = new ValueHolder( + new ValueHolder.DeferredInitializer() { + @Override + public String initialize() { + //Complex toString is needed as naturalIds for entities are not simply based on a single value like primary keys + //the only same way to differentiate the keys is to included the disassembled values in the string. + final StringBuilder toStringBuilder = new StringBuilder( entityName ).append( "##NaturalId[" ); + for ( int i = 0; i < naturalIdValues.length; i++ ) { + toStringBuilder.append( naturalIdValues[i] ); + if ( i + 1 < naturalIdValues.length ) { + toStringBuilder.append( ", " ); + } + } + toStringBuilder.append( "]" ); + + return toStringBuilder.toString(); + } + } + ); } @SuppressWarnings( {"UnusedDeclaration"}) @@ -129,7 +129,7 @@ public class NaturalIdCacheKey implements Serializable { public String toString() { return toString.getValue(); } - + @Override public int hashCode() { return this.hashCode; @@ -154,10 +154,10 @@ public class NaturalIdCacheKey implements Serializable { && EqualsHelper.equals( tenantId, other.tenantId ) && Arrays.deepEquals( this.naturalIdValues, other.naturalIdValues ); } - - private void readObject(ObjectInputStream ois) - throws ClassNotFoundException, IOException { - ois.defaultReadObject(); - initTransients(); - } + + private void readObject(ObjectInputStream ois) + throws ClassNotFoundException, IOException { + ois.defaultReadObject(); + initTransients(); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryCache.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryCache.java index a0d7cfdce7..ebbbc4e719 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryCache.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryCache.java @@ -40,15 +40,53 @@ import org.hibernate.type.Type; * @author Gavin King */ public interface QueryCache { - + /** + * Clear items from the query cache. + * + * @throws CacheException Indicates a problem delegating to the underlying cache. + */ public void clear() throws CacheException; - + + /** + * Put a result into the query cache. + * + * @param key The cache key + * @param returnTypes The result types + * @param result The results to cache + * @param isNaturalKeyLookup Was this a natural id lookup? + * @param session The originating session + * + * @return Whether the put actually happened. + * + * @throws HibernateException Indicates a problem delegating to the underlying cache. + */ public boolean put(QueryKey key, Type[] returnTypes, List result, boolean isNaturalKeyLookup, SessionImplementor session) throws HibernateException; + /** + * Get results from the cache. + * + * @param key The cache key + * @param returnTypes The result types + * @param isNaturalKeyLookup Was this a natural id lookup? + * @param spaces The query spaces (used in invalidation plus validation checks) + * @param session The originating session + * + * @return The cached results; may be null. + * + * @throws HibernateException Indicates a problem delegating to the underlying cache. + */ public List get(QueryKey key, Type[] returnTypes, boolean isNaturalKeyLookup, Set spaces, SessionImplementor session) throws HibernateException; + /** + * Destroy the cache. + */ public void destroy(); + /** + * The underlying cache factory region being used. + * + * @return The cache region. + */ public QueryResultsRegion getRegion(); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryCacheFactory.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryCacheFactory.java index 4e83677995..5b61ee39da 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryCacheFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryCacheFactory.java @@ -25,7 +25,6 @@ package org.hibernate.cache.spi; import java.util.Properties; -import org.hibernate.HibernateException; import org.hibernate.cfg.Settings; /** @@ -35,9 +34,19 @@ import org.hibernate.cfg.Settings; * @author Steve Ebersole */ public interface QueryCacheFactory { + /** + * Builds a named query cache. + * + * @param regionName The cache region name + * @param updateTimestampsCache The cache of timestamp values to use to perform up-to-date checks. + * @param settings The Hibernate SessionFactory settings. + * @param props Any properties. + * + * @return The cache. + */ public QueryCache getQueryCache( - String regionName, - UpdateTimestampsCache updateTimestampsCache, + String regionName, + UpdateTimestampsCache updateTimestampsCache, Settings settings, - Properties props) throws HibernateException; + Properties props); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryKey.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryKey.java index c1fc20395d..b00d885ac2 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryKey.java @@ -72,8 +72,7 @@ public class QueryKey implements Serializable { * @param queryParameters The query parameters * @param filterKeys The keys of any enabled filters. * @param session The current session. - * @param customTransformer The result transformer; should be - * null if data is not transformed before being cached. + * @param customTransformer The result transformer; should be null if data is not transformed before being cached. * * @return The generate query cache key. */ @@ -223,11 +222,12 @@ public class QueryKey implements Serializable { } @Override - public boolean equals(Object other) { + public boolean equals(Object other) { if ( !( other instanceof QueryKey ) ) { return false; } - QueryKey that = ( QueryKey ) other; + + final QueryKey that = (QueryKey) other; if ( !sqlQueryString.equals( that.sqlQueryString ) ) { return false; } @@ -265,13 +265,13 @@ public class QueryKey implements Serializable { } @Override - public int hashCode() { + public int hashCode() { return hashCode; } @Override - public String toString() { - StringBuilder buffer = new StringBuilder( "sql: " ).append( sqlQueryString ); + public String toString() { + final StringBuilder buffer = new StringBuilder( "sql: " ).append( sqlQueryString ); if ( positionalParameterValues != null ) { buffer.append( "; parameters: " ); for ( Object positionalParameterValue : positionalParameterValues ) { diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/Region.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/Region.java index f409f627e7..61ba0743b1 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/Region.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/Region.java @@ -96,8 +96,21 @@ public interface Region { */ public Map toMap(); + /** + * Get the next timestamp according to the underlying cache implementor. + * + * @todo Document the usages of this method so providers know exactly what is expected. + * + * @return The next timestamp + */ public long nextTimestamp(); - //we really should change this return type to `long` instead of `int` + /** + * Get a timeout value. + * + * @todo Again, document the usages of this method so providers know exactly what is expected. + * + * @return The time out value + */ public int getTimeout(); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/RegionFactory.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/RegionFactory.java index 65f0b217c5..9d7d97f06e 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/RegionFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/RegionFactory.java @@ -135,7 +135,7 @@ public interface RegionFactory extends Service { throws CacheException; /** - * Build a cache region specialized for storing query results + * Build a cache region specialized for storing query results. * * @param regionName The name of the region. * @param properties Configuration properties. diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/TransactionalDataRegion.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/TransactionalDataRegion.java index 17380f04b1..da12232caa 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/TransactionalDataRegion.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/TransactionalDataRegion.java @@ -50,5 +50,11 @@ public interface TransactionalDataRegion extends Region { */ public boolean isTransactionAware(); + /** + * Get the description of the type of data to be stored here, which would have been given to the RegionFactory + * when creating this region + * + * @return The data descriptor. + */ public CacheDataDescription getCacheDataDescription(); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/UpdateTimestampsCache.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/UpdateTimestampsCache.java index 6a72c0ac3a..59d7c637cb 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/UpdateTimestampsCache.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/UpdateTimestampsCache.java @@ -46,14 +46,25 @@ import org.hibernate.internal.CoreMessageLogger; * @author Mikheil Kapanadze */ public class UpdateTimestampsCache { - - public static final String REGION_NAME = UpdateTimestampsCache.class.getName(); private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, UpdateTimestampsCache.class.getName() ); + /** + * The region name of the update-timestamps cache. + */ + public static final String REGION_NAME = UpdateTimestampsCache.class.getName(); + + private final SessionFactoryImplementor factory; private final TimestampsRegion region; - public UpdateTimestampsCache(Settings settings, Properties props, final SessionFactoryImplementor factory) throws HibernateException { + /** + * Constructs an UpdateTimestampsCache. + * + * @param settings The SessionFactory settings + * @param props Any properties + * @param factory The SessionFactory + */ + public UpdateTimestampsCache(Settings settings, Properties props, final SessionFactoryImplementor factory) { this.factory = factory; final String prefix = settings.getCacheRegionPrefix(); final String regionName = prefix == null ? REGION_NAME : prefix + '.' + REGION_NAME; @@ -62,11 +73,24 @@ public class UpdateTimestampsCache { this.region = settings.getRegionFactory().buildTimestampsRegion( regionName, props ); } - @SuppressWarnings({"UnusedDeclaration"}) - public UpdateTimestampsCache(Settings settings, Properties props) throws HibernateException { - this( settings, props, null ); - } + /** + * Constructs an UpdateTimestampsCache. + * + * @param settings The SessionFactory settings + * @param props Any properties + */ + @SuppressWarnings({"UnusedDeclaration"}) + public UpdateTimestampsCache(Settings settings, Properties props) { + this( settings, props, null ); + } + /** + * Perform pre-invalidation. + * + * @param spaces The spaces to pre-invalidate + * + * @throws CacheException Indicated problem delegating to underlying region. + */ @SuppressWarnings({"UnnecessaryBoxing"}) public void preinvalidate(Serializable[] spaces) throws CacheException { final boolean debug = LOG.isDebugEnabled(); @@ -87,12 +111,19 @@ public class UpdateTimestampsCache { } } + /** + * Perform invalidation. + * + * @param spaces The spaces to pre-invalidate + * + * @throws CacheException Indicated problem delegating to underlying region. + */ @SuppressWarnings({"UnnecessaryBoxing"}) public void invalidate(Serializable[] spaces) throws CacheException { - final boolean debug = LOG.isDebugEnabled(); - final boolean stats = factory != null && factory.getStatistics().isStatisticsEnabled(); + final boolean debug = LOG.isDebugEnabled(); + final boolean stats = factory != null && factory.getStatistics().isStatisticsEnabled(); - final Long ts = region.nextTimestamp(); + final Long ts = region.nextTimestamp(); for (Serializable space : spaces) { if ( debug ) { @@ -107,13 +138,23 @@ public class UpdateTimestampsCache { } } + /** + * Perform an up-to-date check for the given set of query spaces. + * + * @param spaces The spaces to check + * @param timestamp The timestamp against which to check. + * + * @return Whether all those spaces are up-to-date + * + * @throws CacheException Indicated problem delegating to underlying region. + */ @SuppressWarnings({"unchecked", "UnnecessaryUnboxing"}) - public boolean isUpToDate(Set spaces, Long timestamp) throws HibernateException { + public boolean isUpToDate(Set spaces, Long timestamp) throws CacheException { final boolean debug = LOG.isDebugEnabled(); final boolean stats = factory != null && factory.getStatistics().isStatisticsEnabled(); for ( Serializable space : (Set) spaces ) { - Long lastUpdate = (Long) region.get( space ); + final Long lastUpdate = (Long) region.get( space ); if ( lastUpdate == null ) { if ( stats ) { factory.getStatisticsImplementor().updateTimestampsCacheMiss(); @@ -142,10 +183,20 @@ public class UpdateTimestampsCache { return true; } + /** + * Clear the update-timestamps data. + * + * @throws CacheException Indicates problem delegating call to underlying region. + */ public void clear() throws CacheException { region.evictAll(); } + /** + * Destroys the cache. + * + * @throws CacheException Indicates problem delegating call to underlying region. + */ public void destroy() { try { region.destroy(); @@ -155,12 +206,17 @@ public class UpdateTimestampsCache { } } + /** + * Get the underlying cache region where data is stored.. + * + * @return The underlying region. + */ public TimestampsRegion getRegion() { return region; } @Override - public String toString() { + public String toString() { return "UpdateTimestampsCache"; } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/AccessType.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/AccessType.java index 336a6295f6..ff7aa633a3 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/AccessType.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/AccessType.java @@ -29,9 +29,23 @@ package org.hibernate.cache.spi.access; * @author Steve Ebersole */ public enum AccessType { + /** + * Read-only access. Data may be added and removed, but not mutated. + */ READ_ONLY( "read-only" ), + /** + * Read and write access (strict). Data may be added, removed and mutated. + */ READ_WRITE( "read-write" ), + /** + * Read and write access (non-strict). Data may be added, removed and mutated. The non-strictness comes from + * the fact that locks are not maintained as tightly as in {@link #READ_WRITE}, which leads to better throughput + * but may also lead to inconsistencies. + */ NONSTRICT_READ_WRITE( "nonstrict-read-write" ), + /** + * A read and write strategy where isolation/locking is maintained in conjunction with a JTA transaction. + */ TRANSACTIONAL( "transactional" ); private final String externalName; @@ -40,14 +54,31 @@ public enum AccessType { this.externalName = externalName; } + /** + * Get the corresponding externalized name for this value. + * + * @return The corresponding externalized name. + */ public String getExternalName() { return externalName; } + @Override public String toString() { return "AccessType[" + externalName + "]"; } + /** + * Resolve an AccessType from its external name. + * + * @param externalName The external representation to resolve + * + * @return The access type. + * + * @throws UnknownAccessTypeException If the externalName was not recognized. + * + * @see #getExternalName() + */ public static AccessType fromExternalName(String externalName) { if ( externalName == null ) { return null; diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/RegionAccessStrategy.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/RegionAccessStrategy.java index dee0edcfe5..2f4988b82b 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/RegionAccessStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/RegionAccessStrategy.java @@ -26,6 +26,8 @@ package org.hibernate.cache.spi.access; import org.hibernate.cache.CacheException; /** + * Base access strategy for all regions. + * * @author Gail Badner */ public interface RegionAccessStrategy { diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/UnknownAccessTypeException.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/UnknownAccessTypeException.java index 26753d2d5b..53e05fd5df 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/UnknownAccessTypeException.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/UnknownAccessTypeException.java @@ -26,9 +26,18 @@ package org.hibernate.cache.spi.access; import org.hibernate.HibernateException; /** + * Indicates that an unknown AccessType external name was encountered + * * @author Steve Ebersole + * + * @see AccessType#fromExternalName(String) */ public class UnknownAccessTypeException extends HibernateException { + /** + * Constructs the UnknownAccessTypeException. + * + * @param accessTypeName The external name that could not be resolved. + */ public UnknownAccessTypeException(String accessTypeName) { super( "Unknown access type [" + accessTypeName + "]" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/CacheEntry.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/CacheEntry.java index 63d847563a..d73d3a67f0 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/CacheEntry.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/CacheEntry.java @@ -25,10 +25,6 @@ package org.hibernate.cache.spi.entry; import java.io.Serializable; -import org.hibernate.Interceptor; -import org.hibernate.event.spi.EventSource; -import org.hibernate.persister.entity.EntityPersister; - /** * A cached instance of a persistent class * @@ -36,6 +32,11 @@ import org.hibernate.persister.entity.EntityPersister; * @author Steve Ebersole */ public interface CacheEntry extends Serializable { + /** + * Does this entry represent a direct entity reference (rather than disassembled state)? + * + * @return true/false + */ public boolean isReferenceEntry(); /** @@ -53,18 +54,22 @@ public interface CacheEntry extends Serializable { */ public Object getVersion(); + /** + * Does the represented data contain any un-fetched attribute values? + * + * @return true/false + */ public boolean areLazyPropertiesUnfetched(); - - // todo: this was added to support initializing an entity's EntityEntry snapshot during reattach; - // this should be refactored to instead expose a method to assemble a EntityEntry based on this - // state for return. + /** + * Get the underlying disassembled state + * + * todo : this was added to support initializing an entity's EntityEntry snapshot during reattach; + * this should be refactored to instead expose a method to assemble a EntityEntry based on this + * state for return. + * + * @return The disassembled state + */ public Serializable[] getDisassembledState(); } - - - - - - diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/CacheEntryStructure.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/CacheEntryStructure.java index 5bc5414846..0fac0bb25c 100755 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/CacheEntryStructure.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/CacheEntryStructure.java @@ -26,9 +26,27 @@ package org.hibernate.cache.spi.entry; import org.hibernate.engine.spi.SessionFactoryImplementor; /** + * Strategy for how cache entries are "structured" for storing into the cache. + * * @author Gavin King */ public interface CacheEntryStructure { + /** + * Convert the cache item into its "structured" form. Perfectly valid to return the item as-is. + * + * @param item The item to structure. + * + * @return The structured form. + */ public Object structure(Object item); - public Object destructure(Object map, SessionFactoryImplementor factory); + + /** + * Convert the previous structured form of the item back into its item form. + * + * @param structured The structured form. + * @param factory The session factory. + * + * @return The item + */ + public Object destructure(Object structured, SessionFactoryImplementor factory); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/CollectionCacheEntry.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/CollectionCacheEntry.java index 2b8bb3661c..8ceab7f0b4 100755 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/CollectionCacheEntry.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/CollectionCacheEntry.java @@ -30,34 +30,53 @@ import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.persister.collection.CollectionPersister; /** + * Cacheable representation of persistent collections + * * @author Gavin King */ public class CollectionCacheEntry implements Serializable { - private final Serializable state; - + + /** + * Constructs a CollectionCacheEntry + * + * @param collection The persistent collection instance + * @param persister The collection persister + */ + public CollectionCacheEntry(PersistentCollection collection, CollectionPersister persister) { + this.state = collection.disassemble( persister ); + } + + CollectionCacheEntry(Serializable state) { + this.state = state; + } + + /** + * Retrieve the cached collection state. + * + * @return The cached collection state. + */ public Serializable[] getState() { //TODO: assumes all collections disassemble to an array! return (Serializable[]) state; } - public CollectionCacheEntry(PersistentCollection collection, CollectionPersister persister) { - this.state = collection.disassemble(persister); - } - - CollectionCacheEntry(Serializable state) { - this.state = state; - } - + /** + * Assembles the collection from the cached state. + * + * @param collection The persistent collection instance being assembled + * @param persister The collection persister + * @param owner The collection owner instance + */ public void assemble( - final PersistentCollection collection, - final CollectionPersister persister, - final Object owner - ) { - collection.initializeFromCache(persister, state, owner); + final PersistentCollection collection, + final CollectionPersister persister, + final Object owner) { + collection.initializeFromCache( persister, state, owner ); collection.afterInitialize(); } - + + @Override public String toString() { return "CollectionCacheEntry" + ArrayHelper.toString( getState() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/ReferenceCacheEntryImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/ReferenceCacheEntryImpl.java index 95d00ed8db..6babb78bb8 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/ReferenceCacheEntryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/ReferenceCacheEntryImpl.java @@ -25,22 +25,35 @@ package org.hibernate.cache.spi.entry; import java.io.Serializable; -import org.hibernate.Interceptor; -import org.hibernate.event.spi.EventSource; -import org.hibernate.persister.entity.EntityPersister; - /** + * Specialized CacheEntry for storing direct references to entity instances. + * * @author Steve Ebersole */ public class ReferenceCacheEntryImpl implements CacheEntry { private final Object reference; private final String subclass; + /** + * Constructs a ReferenceCacheEntryImpl + * + * @param reference The reference entity instance + * @param subclass The specific subclass + */ public ReferenceCacheEntryImpl(Object reference, String subclass) { this.reference = reference; this.subclass = subclass; } + /** + * Provides access to the stored reference. + * + * @return The stored reference + */ + public Object getReference() { + return reference; + } + @Override public boolean isReferenceEntry() { return true; @@ -68,8 +81,4 @@ public class ReferenceCacheEntryImpl implements CacheEntry { // reference data is not disassembled into the cache return null; } - - public Object getReference() { - return reference; - } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StandardCacheEntryImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StandardCacheEntryImpl.java index 51f9fceacd..1e3ef07f38 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StandardCacheEntryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StandardCacheEntryImpl.java @@ -40,6 +40,8 @@ import org.hibernate.persister.entity.EntityPersister; import org.hibernate.type.TypeHelper; /** + * Standard representation of entity cached data using the "disassembled state". + * * @author Steve Ebersole */ public class StandardCacheEntryImpl implements CacheEntry { @@ -48,6 +50,48 @@ public class StandardCacheEntryImpl implements CacheEntry { private final boolean lazyPropertiesAreUnfetched; private final Object version; + /** + * Constructs a StandardCacheEntryImpl + * + * @param state The extracted state + * @param persister The entity persister + * @param unfetched Are any values present in state unfetched? + * @param version The current version (if versioned) + * @param session The originating session + * @param owner The owner + * + * @throws HibernateException Generally indicates a problem performing the dis-assembly. + */ + public StandardCacheEntryImpl( + final Object[] state, + final EntityPersister persister, + final boolean unfetched, + final Object version, + final SessionImplementor session, + final Object owner) + throws HibernateException { + // disassembled state gets put in a new array (we write to cache by value!) + this.disassembledState = TypeHelper.disassemble( + state, + persister.getPropertyTypes(), + persister.isLazyPropertiesCacheable() ? null : persister.getPropertyLaziness(), + session, + owner + ); + subclass = persister.getEntityName(); + lazyPropertiesAreUnfetched = unfetched || !persister.isLazyPropertiesCacheable(); + this.version = version; + } + + StandardCacheEntryImpl(Serializable[] state, String subclass, boolean unfetched, Object version) { + this.disassembledState = state; + this.subclass = subclass; + this.lazyPropertiesAreUnfetched = unfetched; + this.version = version; + } + + + @Override public boolean isReferenceEntry() { return false; @@ -76,76 +120,57 @@ public class StandardCacheEntryImpl implements CacheEntry { return version; } - public StandardCacheEntryImpl( - final Object[] state, - final EntityPersister persister, - final boolean unfetched, - final Object version, - final SessionImplementor session, - final Object owner) - throws HibernateException { - //disassembled state gets put in a new array (we write to cache by value!) - this.disassembledState = TypeHelper.disassemble( - state, - persister.getPropertyTypes(), - persister.isLazyPropertiesCacheable() ? - null : persister.getPropertyLaziness(), - session, - owner - ); - subclass = persister.getEntityName(); - lazyPropertiesAreUnfetched = unfetched || !persister.isLazyPropertiesCacheable(); - this.version = version; - } - - StandardCacheEntryImpl(Serializable[] state, String subclass, boolean unfetched, Object version) { - this.disassembledState = state; - this.subclass = subclass; - this.lazyPropertiesAreUnfetched = unfetched; - this.version = version; - } - + /** + * After assembly, is a copy of the array needed? + * + * @return true/false + */ public boolean isDeepCopyNeeded() { // for now always return true. // todo : See discussion on HHH-7872 return true; } + /** + * Assemble the previously disassembled state represented by this entry into the given entity instance. + * + * Additionally manages the PreLoadEvent callbacks. + * + * @param instance The entity instance + * @param id The entity identifier + * @param persister The entity persister + * @param interceptor (currently unused) + * @param session The session + * + * @return The assembled state + * + * @throws HibernateException Indicates a problem performing assembly or calling the PreLoadEventListeners. + * + * @see org.hibernate.type.Type#assemble + * @see org.hibernate.type.Type#disassemble + */ public Object[] assemble( final Object instance, final Serializable id, final EntityPersister persister, final Interceptor interceptor, - final EventSource session) - throws HibernateException { - - if ( !persister.getEntityName().equals(subclass) ) { - throw new AssertionFailure("Tried to assemble a different subclass instance"); + final EventSource session) throws HibernateException { + if ( !persister.getEntityName().equals( subclass ) ) { + throw new AssertionFailure( "Tried to assemble a different subclass instance" ); } - return assemble(disassembledState, instance, id, persister, interceptor, session); - } - - private static Object[] assemble( - final Serializable[] values, - final Object result, - final Serializable id, - final EntityPersister persister, - final Interceptor interceptor, - final EventSource session) throws HibernateException { - //assembled state gets put in a new array (we read from cache by value!) - Object[] assembledProps = TypeHelper.assemble( - values, + final Object[] assembledProps = TypeHelper.assemble( + disassembledState, persister.getPropertyTypes(), - session, result + session, instance ); - //persister.setIdentifier(result, id); //before calling interceptor, for consistency with normal load + //persister.setIdentifier(instance, id); //before calling interceptor, for consistency with normal load //TODO: reuse the PreLoadEvent final PreLoadEvent preLoadEvent = new PreLoadEvent( session ) - .setEntity( result ) + .setEntity( instance ) .setState( assembledProps ) .setId( id ) .setPersister( persister ); @@ -159,11 +184,12 @@ public class StandardCacheEntryImpl implements CacheEntry { listener.onPreLoad( preLoadEvent ); } - persister.setPropertyValues( result, assembledProps ); + persister.setPropertyValues( instance, assembledProps ); return assembledProps; } + @Override public String toString() { return "CacheEntry(" + subclass + ')' + ArrayHelper.toString( disassembledState ); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredCacheEntry.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredCacheEntry.java index 90e1f86952..e9107c4601 100755 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredCacheEntry.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredCacheEntry.java @@ -38,31 +38,39 @@ import org.hibernate.persister.entity.EntityPersister; * @author Steve Ebersole */ public class StructuredCacheEntry implements CacheEntryStructure { - private EntityPersister persister; + /** + * Constructs a StructuredCacheEntry strategy + * + * @param persister The persister whose data needs to be structured. + */ public StructuredCacheEntry(EntityPersister persister) { this.persister = persister; } - - public Object destructure(Object item, SessionFactoryImplementor factory) { - Map map = (Map) item; - boolean lazyPropertiesUnfetched = ( (Boolean) map.get("_lazyPropertiesUnfetched") ).booleanValue(); - String subclass = (String) map.get("_subclass"); - Object version = map.get("_version"); - EntityPersister subclassPersister = factory.getEntityPersister(subclass); - String[] names = subclassPersister.getPropertyNames(); - Serializable[] state = new Serializable[names.length]; - for ( int i=0; i map = (Map) structured; + final Serializable[] state = new Serializable[ map.size()*2 ]; + int i = 0; + for ( Map.Entry me : map.entrySet() ) { state[i++] = (Serializable) me.getKey(); state[i++] = (Serializable) me.getValue(); } return new CollectionCacheEntry(state); } + private StructuredMapCacheEntry() { + } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/UnstructuredCacheEntry.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/UnstructuredCacheEntry.java index b9221e3816..31e7b9f240 100755 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/UnstructuredCacheEntry.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/UnstructuredCacheEntry.java @@ -32,14 +32,21 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; * @author Steve Ebersole */ public class UnstructuredCacheEntry implements CacheEntryStructure { + /** + * Access to the singleton instance. + */ public static final UnstructuredCacheEntry INSTANCE = new UnstructuredCacheEntry(); + @Override public Object structure(Object item) { return item; } - public Object destructure(Object map, SessionFactoryImplementor factory) { - return map; + @Override + public Object destructure(Object structured, SessionFactoryImplementor factory) { + return structured; } + private UnstructuredCacheEntry() { + } } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java b/hibernate-core/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java index 8676f63d12..bccd2d9a36 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java @@ -42,6 +42,8 @@ import org.hibernate.annotations.common.reflection.XProperty; import org.hibernate.internal.util.StringHelper; /** + * No idea. + * * @author Emmanuel Bernard */ public abstract class AbstractPropertyHolder implements PropertyHolder { @@ -57,7 +59,7 @@ public abstract class AbstractPropertyHolder implements PropertyHolder { private Boolean isInIdClass; - public AbstractPropertyHolder( + AbstractPropertyHolder( String path, PropertyHolder parent, XClass clazzToProcess, @@ -68,25 +70,34 @@ public abstract class AbstractPropertyHolder implements PropertyHolder { buildHierarchyColumnOverride( clazzToProcess ); } - + @Override public boolean isInIdClass() { return isInIdClass != null ? isInIdClass : parent != null ? parent.isInIdClass() : false; } + @Override public void setInIdClass(Boolean isInIdClass) { this.isInIdClass = isInIdClass; } + @Override public String getPath() { return path; } + /** + * Get the mappings + * + * @return The mappings + */ protected Mappings getMappings() { return mappings; } /** - * property can be null + * Set the property be processed. property can be null + * + * @param property The property */ protected void setCurrentProperty(XProperty property) { if ( property == null ) { @@ -124,8 +135,8 @@ public abstract class AbstractPropertyHolder implements PropertyHolder { * replace the placeholder 'collection&&element' with nothing * * These rules are here to support both JPA 2 and legacy overriding rules. - * */ + @Override public Column[] getOverriddenColumn(String propertyName) { Column[] result = getExactOverriddenColumn( propertyName ); if (result == null) { @@ -192,8 +203,8 @@ public abstract class AbstractPropertyHolder implements PropertyHolder { * replace the placeholder 'collection&&element' with nothing * * These rules are here to support both JPA 2 and legacy overriding rules. - * */ + @Override public JoinColumn[] getOverriddenJoinColumn(String propertyName) { JoinColumn[] result = getExactOverriddenJoinColumn( propertyName ); if ( result == null && propertyName.contains( ".collection&&element." ) ) { @@ -226,8 +237,8 @@ public abstract class AbstractPropertyHolder implements PropertyHolder { * replace the placeholder 'collection&&element' with nothing * * These rules are here to support both JPA 2 and legacy overriding rules. - * */ + @Override public JoinTable getJoinTable(XProperty property) { final String propertyName = StringHelper.qualify( getPath(), property.getName() ); JoinTable result = getOverriddenJoinTable( propertyName ); @@ -242,7 +253,6 @@ public abstract class AbstractPropertyHolder implements PropertyHolder { * replace the placeholder 'collection&&element' with nothing * * These rules are here to support both JPA 2 and legacy overriding rules. - * */ public JoinTable getOverriddenJoinTable(String propertyName) { JoinTable result = getExactOverriddenJoinTable( propertyName ); @@ -384,6 +394,7 @@ public abstract class AbstractPropertyHolder implements PropertyHolder { return tableOverride; } + @Override public void setParentProperty(String parentProperty) { throw new AssertionFailure( "Setting the parent property to a non component" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AccessType.java b/hibernate-core/src/main/java/org/hibernate/cfg/AccessType.java index 8e9c1d7ea4..da06603d24 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AccessType.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AccessType.java @@ -46,30 +46,49 @@ public enum AccessType { private final String accessType; - AccessType(String type) { + private AccessType(String type) { this.accessType = type; } + /** + * Retrieves the external name for this access type + * + * @return The external name + */ public String getType() { return accessType; } - public static AccessType getAccessStrategy(String type) { - if ( type == null ) { + /** + * Resolve an externalized name to the AccessType enum value it names. + * + * @param externalName The external name + * + * @return The matching AccessType; {@link #DEFAULT} is returned rather than {@code null} + */ + public static AccessType getAccessStrategy(String externalName) { + if ( externalName == null ) { return DEFAULT; } - else if ( FIELD.getType().equals( type ) ) { + else if ( FIELD.getType().equals( externalName ) ) { return FIELD; } - else if ( PROPERTY.getType().equals( type ) ) { + else if ( PROPERTY.getType().equals( externalName ) ) { return PROPERTY; } else { - // TODO historically if the type string could not be matched default access was used. Maybe this should be an exception though!? + // TODO historically if the externalName string could not be matched default access was used. Maybe this should be an exception though!? return DEFAULT; } } + /** + * Convert the JPA access type enum to the corresponding AccessType enum value. + * + * @param type The JPA enum value + * + * @return The Hibernate AccessType + */ public static AccessType getAccessStrategy(javax.persistence.AccessType type) { if ( javax.persistence.AccessType.PROPERTY.equals( type ) ) { return PROPERTY; diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/StringHelper.java b/hibernate-core/src/main/java/org/hibernate/internal/util/StringHelper.java index f68c7457bb..b4c043de2c 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/util/StringHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/util/StringHelper.java @@ -455,13 +455,9 @@ public final class StringHelper { public static String qualify(String prefix, String name) { if ( name == null || prefix == null ) { - throw new NullPointerException(); + throw new NullPointerException( "prefix or name were null attempting to build qualified name" ); } - return new StringBuilder( prefix.length() + name.length() + 1 ) - .append(prefix) - .append('.') - .append(name) - .toString(); + return prefix + '.' + name; } public static String[] qualify(String prefix, String[] names) { diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index 96cf05b129..819ad1b0a4 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -245,12 +245,12 @@ public abstract class AbstractCollectionPersister this.factory = factory; this.cacheAccessStrategy = cacheAccessStrategy; if ( factory.getSettings().isStructuredCacheEntriesEnabled() ) { - cacheEntryStructure = collection.isMap() ? - new StructuredMapCacheEntry() : - new StructuredCollectionCacheEntry(); + cacheEntryStructure = collection.isMap() + ? StructuredMapCacheEntry.INSTANCE + : StructuredCollectionCacheEntry.INSTANCE; } else { - cacheEntryStructure = new UnstructuredCacheEntry(); + cacheEntryStructure = UnstructuredCacheEntry.INSTANCE; } dialect = factory.getDialect(); diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTest.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTest.java index 42d10e1c66..05014bccb0 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTest.java @@ -36,12 +36,11 @@ import org.hibernate.EntityMode; import org.hibernate.LockMode; import org.hibernate.bytecode.enhance.spi.EnhancementContext; import org.hibernate.bytecode.enhance.spi.Enhancer; -import org.hibernate.cfg.Configuration; +import org.hibernate.bytecode.enhance.spi.EnhancerConstants; import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.ManagedEntity; import org.hibernate.engine.spi.PersistentAttributeInterceptor; import org.hibernate.engine.spi.Status; -import org.hibernate.mapping.PersistentClass; import org.junit.Test; @@ -123,30 +122,30 @@ public class EnhancerTest extends BaseUnitTestCase { // call the new methods // - Method setter = entityClass.getMethod( Enhancer.ENTITY_ENTRY_SETTER_NAME, EntityEntry.class ); - Method getter = entityClass.getMethod( Enhancer.ENTITY_ENTRY_GETTER_NAME ); + Method setter = entityClass.getMethod( EnhancerConstants.ENTITY_ENTRY_SETTER_NAME, EntityEntry.class ); + Method getter = entityClass.getMethod( EnhancerConstants.ENTITY_ENTRY_GETTER_NAME ); assertNull( getter.invoke( entityInstance ) ); setter.invoke( entityInstance, makeEntityEntry() ); assertNotNull( getter.invoke( entityInstance ) ); setter.invoke( entityInstance, new Object[] {null} ); assertNull( getter.invoke( entityInstance ) ); - Method entityInstanceGetter = entityClass.getMethod( Enhancer.ENTITY_INSTANCE_GETTER_NAME ); + Method entityInstanceGetter = entityClass.getMethod( EnhancerConstants.ENTITY_INSTANCE_GETTER_NAME ); assertSame( entityInstance, entityInstanceGetter.invoke( entityInstance ) ); - Method previousGetter = entityClass.getMethod( Enhancer.PREVIOUS_GETTER_NAME ); - Method previousSetter = entityClass.getMethod( Enhancer.PREVIOUS_SETTER_NAME, ManagedEntity.class ); + Method previousGetter = entityClass.getMethod( EnhancerConstants.PREVIOUS_GETTER_NAME ); + Method previousSetter = entityClass.getMethod( EnhancerConstants.PREVIOUS_SETTER_NAME, ManagedEntity.class ); previousSetter.invoke( entityInstance, entityInstance ); assertSame( entityInstance, previousGetter.invoke( entityInstance ) ); - Method nextGetter = entityClass.getMethod( Enhancer.PREVIOUS_GETTER_NAME ); - Method nextSetter = entityClass.getMethod( Enhancer.PREVIOUS_SETTER_NAME, ManagedEntity.class ); + Method nextGetter = entityClass.getMethod( EnhancerConstants.PREVIOUS_GETTER_NAME ); + Method nextSetter = entityClass.getMethod( EnhancerConstants.PREVIOUS_SETTER_NAME, ManagedEntity.class ); nextSetter.invoke( entityInstance, entityInstance ); assertSame( entityInstance, nextGetter.invoke( entityInstance ) ); // add an attribute interceptor... - Method interceptorGetter = entityClass.getMethod( Enhancer.INTERCEPTOR_GETTER_NAME ); - Method interceptorSetter = entityClass.getMethod( Enhancer.INTERCEPTOR_SETTER_NAME, PersistentAttributeInterceptor.class ); + Method interceptorGetter = entityClass.getMethod( EnhancerConstants.INTERCEPTOR_GETTER_NAME ); + Method interceptorSetter = entityClass.getMethod( EnhancerConstants.INTERCEPTOR_SETTER_NAME, PersistentAttributeInterceptor.class ); assertNull( interceptorGetter.invoke( entityInstance ) ); entityClass.getMethod( "getId" ).invoke( entityInstance ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java b/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java index ba4ff61bf5..a4b56b0193 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java +++ b/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java @@ -568,7 +568,7 @@ public class CustomPersister implements EntityPersister { @Override public CacheEntryStructure getCacheEntryStructure() { - return new UnstructuredCacheEntry(); + return UnstructuredCacheEntry.INSTANCE; } @Override diff --git a/shared/config/checkstyle/checkstyle.xml b/shared/config/checkstyle/checkstyle.xml index 930d7cbfbd..a595af07b1 100644 --- a/shared/config/checkstyle/checkstyle.xml +++ b/shared/config/checkstyle/checkstyle.xml @@ -25,33 +25,86 @@ - - - + + + + + + + + + + + - + + + + + + + + - + + - + + @@ -67,12 +120,26 @@ - + + - + + @@ -88,33 +155,46 @@ + - - - + - - - + + + - - + + + + + + + @@ -129,19 +209,43 @@ - + + + + + + - + - + + diff --git a/shared/config/checkstyle/public_checks.xml b/shared/config/checkstyle/public_checks.xml deleted file mode 100644 index 8cdad56c57..0000000000 --- a/shared/config/checkstyle/public_checks.xml +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/shared/config/checkstyle/todo-checks.xml b/shared/config/checkstyle/todo-checks.xml new file mode 100644 index 0000000000..9ba45b4189 --- /dev/null +++ b/shared/config/checkstyle/todo-checks.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + \ No newline at end of file