From 6e8117c62750561be2949ffa8030a04e0f4783da Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 12 Dec 2012 12:38:34 +0100 Subject: [PATCH] Polishing along with backports to 3.1.4 --- .../support/ReflectivePropertyAccessor.java | 163 +++++++++--------- .../init/ResourceDatabasePopulator.java | 10 +- 2 files changed, 91 insertions(+), 82 deletions(-) diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java index 031a716a990..81f60416b0c 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java @@ -36,8 +36,9 @@ import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; /** - * Simple PropertyAccessor that uses reflection to access properties for reading and writing. A property can be accessed - * if it is accessible as a field on the object or through a getter (if being read) or a setter (if being written). + * Simple PropertyAccessor that uses reflection to access properties for reading and writing. + * A property can be accessed if it is accessible as a field on the object or through a + * getter (if being read) or a setter (if being written). * * @author Andy Clement * @author Juergen Hoeller @@ -45,11 +46,11 @@ import org.springframework.util.StringUtils; */ public class ReflectivePropertyAccessor implements PropertyAccessor { - protected final Map readerCache = new ConcurrentHashMap(); + private final Map readerCache = new ConcurrentHashMap(); - protected final Map writerCache = new ConcurrentHashMap(); + private final Map writerCache = new ConcurrentHashMap(); - protected final Map typeDescriptorCache = new ConcurrentHashMap(); + private final Map typeDescriptorCache = new ConcurrentHashMap(); /** @@ -365,52 +366,6 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { return null; } - /** - * Captures the member (method/field) to call reflectively to access a property value and the type descriptor for the - * value returned by the reflective call. - */ - private static class InvokerPair { - - final Member member; - - final TypeDescriptor typeDescriptor; - - public InvokerPair(Member member, TypeDescriptor typeDescriptor) { - this.member = member; - this.typeDescriptor = typeDescriptor; - } - - } - - private static class CacheKey { - - private final Class clazz; - - private final String name; - - public CacheKey(Class clazz, String name) { - this.clazz = clazz; - this.name = name; - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - if (!(other instanceof CacheKey)) { - return false; - } - CacheKey otherKey = (CacheKey) other; - return (this.clazz.equals(otherKey.clazz) && this.name.equals(otherKey.name)); - } - - @Override - public int hashCode() { - return this.clazz.hashCode() * 29 + this.name.hashCode(); - } - } - /** * Attempt to create an optimized property accessor tailored for a property of a particular name on * a particular class. The general ReflectivePropertyAccessor will always work but is not optimal @@ -463,29 +418,82 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { return this; } + /** - * An optimized form of a PropertyAccessor that will use reflection but only knows how to access a particular property - * on a particular class. This is unlike the general ReflectivePropertyResolver which manages a cache of methods/fields that - * may be invoked to access different properties on different classes. This optimal accessor exists because looking up - * the appropriate reflective object by class/name on each read is not cheap. + * Captures the member (method/field) to call reflectively to access a property value + * and the type descriptor for the value returned by the reflective call. */ - static class OptimalPropertyAccessor implements PropertyAccessor { + private static class InvokerPair { + + final Member member; + + final TypeDescriptor typeDescriptor; + + public InvokerPair(Member member, TypeDescriptor typeDescriptor) { + this.member = member; + this.typeDescriptor = typeDescriptor; + } + } + + + private static class CacheKey { + + private final Class clazz; + + private final String name; + + public CacheKey(Class clazz, String name) { + this.clazz = clazz; + this.name = name; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof CacheKey)) { + return false; + } + CacheKey otherKey = (CacheKey) other; + return (this.clazz.equals(otherKey.clazz) && this.name.equals(otherKey.name)); + } + + @Override + public int hashCode() { + return this.clazz.hashCode() * 29 + this.name.hashCode(); + } + } + + + /** + * An optimized form of a PropertyAccessor that will use reflection but only knows + * how to access a particular property on a particular class. This is unlike the + * general ReflectivePropertyResolver which manages a cache of methods/fields that + * may be invoked to access different properties on different classes. This optimal + * accessor exists because looking up the appropriate reflective object by class/name + * on each read is not cheap. + */ + private static class OptimalPropertyAccessor implements PropertyAccessor { + private final Member member; + private final TypeDescriptor typeDescriptor; + private final boolean needsToBeMadeAccessible; OptimalPropertyAccessor(InvokerPair target) { this.member = target.member; this.typeDescriptor = target.typeDescriptor; if (this.member instanceof Field) { - Field field = (Field)member; - needsToBeMadeAccessible = (!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) - && !field.isAccessible(); + Field field = (Field) this.member; + this.needsToBeMadeAccessible = (!Modifier.isPublic(field.getModifiers()) || + !Modifier.isPublic(field.getDeclaringClass().getModifiers())) && !field.isAccessible(); } else { - Method method = (Method)member; - needsToBeMadeAccessible = ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) - && !method.isAccessible()); + Method method = (Method) this.member; + this.needsToBeMadeAccessible = ((!Modifier.isPublic(method.getModifiers()) || + !Modifier.isPublic(method.getDeclaringClass().getModifiers())) && !method.isAccessible()); } } @@ -501,8 +509,8 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { if (type.isArray()) { return false; } - if (member instanceof Method) { - Method method = (Method)member; + if (this.member instanceof Method) { + Method method = (Method) this.member; String getterName = "get" + StringUtils.capitalize(name); if (getterName.equals(method.getName())) { return true; @@ -511,31 +519,31 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { return getterName.equals(method.getName()); } else { - Field field = (Field)member; + Field field = (Field) this.member; return field.getName().equals(name); } } public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException { - if (member instanceof Method) { + if (this.member instanceof Method) { try { - if (needsToBeMadeAccessible) { - ReflectionUtils.makeAccessible((Method) member); + if (this.needsToBeMadeAccessible) { + ReflectionUtils.makeAccessible((Method) this.member); } - Object value = ((Method) member).invoke(target); - return new TypedValue(value, typeDescriptor.narrow(value)); + Object value = ((Method) this.member).invoke(target); + return new TypedValue(value, this.typeDescriptor.narrow(value)); } catch (Exception ex) { throw new AccessException("Unable to access property '" + name + "' through getter", ex); } } - if (member instanceof Field) { + if (this.member instanceof Field) { try { - if (needsToBeMadeAccessible) { - ReflectionUtils.makeAccessible((Field)member); + if (this.needsToBeMadeAccessible) { + ReflectionUtils.makeAccessible((Field) this.member); } - Object value = ((Field)member).get(target); - return new TypedValue(value, typeDescriptor.narrow(value)); + Object value = ((Field) this.member).get(target); + return new TypedValue(value, this.typeDescriptor.narrow(value)); } catch (Exception ex) { throw new AccessException("Unable to access field: " + name, ex); @@ -544,12 +552,11 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { throw new AccessException("Neither getter nor field found for property '" + name + "'"); } - public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException { + public boolean canWrite(EvaluationContext context, Object target, String name) { throw new UnsupportedOperationException("Should not be called on an OptimalPropertyAccessor"); } - public void write(EvaluationContext context, Object target, String name, Object newValue) - throws AccessException { + public void write(EvaluationContext context, Object target, String name, Object newValue) { throw new UnsupportedOperationException("Should not be called on an OptimalPropertyAccessor"); } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java index 5c8bf6d9bb3..e2f6eafe368 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java @@ -55,6 +55,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator { private static final Log logger = LogFactory.getLog(ResourceDatabasePopulator.class); + private List scripts = new ArrayList(); private String sqlScriptEncoding; @@ -127,6 +128,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator { this.ignoreFailedDrops = ignoreFailedDrops; } + public void populate(Connection connection) throws SQLException { for (Resource script : this.scripts) { executeSqlScript(connection, applyEncodingIfNecessary(script), this.continueOnError, this.ignoreFailedDrops); @@ -191,8 +193,8 @@ public class ResourceDatabasePopulator implements DatabasePopulator { boolean dropStatement = StringUtils.startsWithIgnoreCase(statement.trim(), "drop"); if (continueOnError || (dropStatement && ignoreFailedDrops)) { if (logger.isDebugEnabled()) { - logger.debug("Failed to execute SQL script statement at line " + lineNumber - + " of resource " + resource + ": " + statement, ex); + logger.debug("Failed to execute SQL script statement at line " + lineNumber + + " of resource " + resource + ": " + statement, ex); } } else { @@ -227,8 +229,8 @@ public class ResourceDatabasePopulator implements DatabasePopulator { String currentStatement = lnr.readLine(); StringBuilder scriptBuilder = new StringBuilder(); while (currentStatement != null) { - if (StringUtils.hasText(currentStatement) - && (this.commentPrefix != null && !currentStatement.startsWith(this.commentPrefix))) { + if (StringUtils.hasText(currentStatement) && + (this.commentPrefix != null && !currentStatement.startsWith(this.commentPrefix))) { if (scriptBuilder.length() > 0) { scriptBuilder.append('\n'); }