This is an automated email from the ASF dual-hosted git repository. ddekany pushed a commit to branch 2.3-gae in repository https://gitbox.apache.org/repos/asf/freemarker.git
commit 950351ab0feea92d7d06d0a9c2f15a3b4aa3f3c6 Author: ddekany <[email protected]> AuthorDate: Mon Dec 16 12:19:59 2019 +0100 Some cleanup in ClassIntrospector and BeansWrapper code --- src/main/java/freemarker/ext/beans/BeanModel.java | 2 +- .../java/freemarker/ext/beans/BeansModelCache.java | 6 ++-- .../java/freemarker/ext/beans/BeansWrapper.java | 6 ++-- .../freemarker/ext/beans/ClassIntrospector.java | 33 ++++++++-------------- .../ext/beans/ClassIntrospectorBuilder.java | 19 +++++++------ 5 files changed, 30 insertions(+), 36 deletions(-) diff --git a/src/main/java/freemarker/ext/beans/BeanModel.java b/src/main/java/freemarker/ext/beans/BeanModel.java index 1f885fa..6c68016 100644 --- a/src/main/java/freemarker/ext/beans/BeanModel.java +++ b/src/main/java/freemarker/ext/beans/BeanModel.java @@ -116,7 +116,7 @@ implements TemplateHashModelEx, AdapterTemplateModel, WrapperTemplateModel, Temp * matching the key name. If a method or property is found, it's wrapped * into {@link freemarker.template.TemplateMethodModelEx} (for a method or * indexed property), or evaluated on-the-fly and the return value wrapped - * into appropriate model (for a non-indexed property) Models for various + * into appropriate model (for a non-indexed property). Models for various * properties and methods are cached on a per-class basis, so the costly * introspection is performed only once per property or method of a class. * (Side-note: this also implies that any class whose method has been called diff --git a/src/main/java/freemarker/ext/beans/BeansModelCache.java b/src/main/java/freemarker/ext/beans/BeansModelCache.java index 7cf18e9..8d6cae5 100644 --- a/src/main/java/freemarker/ext/beans/BeansModelCache.java +++ b/src/main/java/freemarker/ext/beans/BeansModelCache.java @@ -30,8 +30,8 @@ import freemarker.ext.util.ModelFactory; import freemarker.template.TemplateModel; public class BeansModelCache extends ModelCache { - private final Map classToFactory = new ConcurrentHashMap(); - private final Set mappedClassNames = new HashSet(); + private final Map<Class<?>, ModelFactory> classToFactory = new ConcurrentHashMap<Class<?>, ModelFactory>(); + private final Set<String> mappedClassNames = new HashSet<String>(); private final BeansWrapper wrapper; @@ -49,7 +49,7 @@ public class BeansModelCache extends ModelCache { protected TemplateModel create(Object object) { Class clazz = object.getClass(); - ModelFactory factory = (ModelFactory) classToFactory.get(clazz); + ModelFactory factory = classToFactory.get(clazz); if (factory == null) { // Synchronized so that we won't unnecessarily create the same factory for multiple times in parallel. diff --git a/src/main/java/freemarker/ext/beans/BeansWrapper.java b/src/main/java/freemarker/ext/beans/BeansWrapper.java index 586ee12..953c2f4 100644 --- a/src/main/java/freemarker/ext/beans/BeansWrapper.java +++ b/src/main/java/freemarker/ext/beans/BeansWrapper.java @@ -351,7 +351,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable { // synchronize on, even during the classIntrospector is being replaced. sharedIntrospectionLock = new Object(); classIntrospector = new ClassIntrospector( - _BeansAPI.getClassIntrospectorBuilder(bwConf), sharedIntrospectionLock); + _BeansAPI.getClassIntrospectorBuilder(bwConf), sharedIntrospectionLock, false, false); } else { // As this is a read-only BeansWrapper, the classIntrospector is never replaced, and since it's shared by // other BeansWrapper instances, we use the lock belonging to the shared ClassIntrospector. @@ -682,7 +682,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable { * @since 2.3.21 */ public boolean isClassIntrospectionCacheRestricted() { - return classIntrospector.getHasSharedInstanceRestrictons(); + return classIntrospector.getHasSharedInstanceRestrictions(); } /** @@ -692,7 +692,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable { private void replaceClassIntrospector(ClassIntrospectorBuilder builder) { checkModifiable(); - final ClassIntrospector newCI = new ClassIntrospector(builder, sharedIntrospectionLock); + final ClassIntrospector newCI = new ClassIntrospector(builder, sharedIntrospectionLock, false, false); final ClassIntrospector oldCI; // In principle this need not be synchronized, but as apps might publish the configuration improperly, or diff --git a/src/main/java/freemarker/ext/beans/ClassIntrospector.java b/src/main/java/freemarker/ext/beans/ClassIntrospector.java index a31d430..c48a91b 100644 --- a/src/main/java/freemarker/ext/beans/ClassIntrospector.java +++ b/src/main/java/freemarker/ext/beans/ClassIntrospector.java @@ -143,8 +143,8 @@ class ClassIntrospector { final boolean treatDefaultMethodsAsBeanMembers; final boolean bugfixed; - /** See {@link #getHasSharedInstanceRestrictons()} */ - final private boolean hasSharedInstanceRestrictons; + /** See {@link #getHasSharedInstanceRestrictions()} */ + final private boolean hasSharedInstanceRestrictions; /** See {@link #isShared()} */ final private boolean shared; @@ -168,22 +168,12 @@ class ClassIntrospector { // Instantiation: /** - * Creates a new instance, that is hence surely not shared (singleton) instance. - * - * @param pa - * Stores what the values of the JavaBean properties of the returned instance will be. Not {@code null}. - */ - ClassIntrospector(ClassIntrospectorBuilder pa, Object sharedLock) { - this(pa, sharedLock, false, false); - } - - /** - * @param hasSharedInstanceRestrictons + * @param hasSharedInstanceRestrictions * {@code true} exactly if we are creating a new instance with {@link ClassIntrospectorBuilder}. Then * it's {@code true} even if it won't put the instance into the cache. */ ClassIntrospector(ClassIntrospectorBuilder builder, Object sharedLock, - boolean hasSharedInstanceRestrictons, boolean shared) { + boolean hasSharedInstanceRestrictions, boolean shared) { NullArgumentException.check("sharedLock", sharedLock); this.exposureLevel = builder.getExposureLevel(); @@ -195,7 +185,7 @@ class ClassIntrospector { this.sharedLock = sharedLock; - this.hasSharedInstanceRestrictons = hasSharedInstanceRestrictons; + this.hasSharedInstanceRestrictions = hasSharedInstanceRestrictions; this.shared = shared; if (CLASS_CHANGE_NOTIFIER != null) { @@ -204,8 +194,9 @@ class ClassIntrospector { } /** - * Returns a {@link ClassIntrospectorBuilder}-s that could be used to create an identical {@link #ClassIntrospector} - * . The returned {@link ClassIntrospectorBuilder} can be modified without interfering with anything. + * Returns a {@link ClassIntrospectorBuilder} that could be used to create an identical + * {@link #ClassIntrospector}. The returned {@link ClassIntrospectorBuilder} can be modified without interfering + * with anything. */ ClassIntrospectorBuilder createBuilder() { return new ClassIntrospectorBuilder(this); @@ -865,7 +856,7 @@ class ClassIntrospector { * @since 2.3.20 */ void clearCache() { - if (getHasSharedInstanceRestrictons()) { + if (getHasSharedInstanceRestrictions()) { throw new IllegalStateException( "It's not allowed to clear the whole cache in a read-only " + this.getClass().getName() + "instance. Use removeFromClassIntrospectionCache(String prefix) instead."); @@ -1061,14 +1052,14 @@ class ClassIntrospector { * Returns {@code true} if this instance was created with {@link ClassIntrospectorBuilder}, even if it wasn't * actually put into the cache (as we reserve the right to do so in later versions). */ - boolean getHasSharedInstanceRestrictons() { - return hasSharedInstanceRestrictons; + boolean getHasSharedInstanceRestrictions() { + return hasSharedInstanceRestrictions; } /** * Tells if this instance is (potentially) shared among {@link BeansWrapper} instances. * - * @see #getHasSharedInstanceRestrictons() + * @see #getHasSharedInstanceRestrictions() */ boolean isShared() { return shared; diff --git a/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java b/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java index 25688e5..1b54958 100644 --- a/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java +++ b/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java @@ -33,8 +33,10 @@ final class ClassIntrospectorBuilder implements Cloneable { private final boolean bugfixed; - private static final Map/*<PropertyAssignments, Reference<ClassIntrospector>>*/ INSTANCE_CACHE = new HashMap(); - private static final ReferenceQueue INSTANCE_CACHE_REF_QUEUE = new ReferenceQueue(); + private static final Map<ClassIntrospectorBuilder, Reference<ClassIntrospector>> INSTANCE_CACHE + = new HashMap<ClassIntrospectorBuilder, Reference<ClassIntrospector>>(); + private static final ReferenceQueue<ClassIntrospector> INSTANCE_CACHE_REF_QUEUE + = new ReferenceQueue<ClassIntrospector>(); // Properties and their *defaults*: private int exposureLevel = BeansWrapper.EXPOSE_SAFE; @@ -152,10 +154,11 @@ final class ClassIntrospectorBuilder implements Cloneable { } private static void removeClearedReferencesFromInstanceCache() { - Reference clearedRef; + Reference<? extends ClassIntrospector> clearedRef; while ((clearedRef = INSTANCE_CACHE_REF_QUEUE.poll()) != null) { synchronized (INSTANCE_CACHE) { - findClearedRef: for (Iterator it = INSTANCE_CACHE.values().iterator(); it.hasNext(); ) { + findClearedRef: for (Iterator<Reference<ClassIntrospector>> it = INSTANCE_CACHE.values().iterator(); + it.hasNext(); ) { if (it.next() == clearedRef) { it.remove(); break findClearedRef; @@ -173,7 +176,7 @@ final class ClassIntrospectorBuilder implements Cloneable { } /** For unit testing only */ - static Map getInstanceCache() { + static Map<ClassIntrospectorBuilder, Reference<ClassIntrospector>> getInstanceCache() { return INSTANCE_CACHE; } @@ -187,12 +190,12 @@ final class ClassIntrospectorBuilder implements Cloneable { // Instance can be cached. ClassIntrospector instance; synchronized (INSTANCE_CACHE) { - Reference instanceRef = (Reference) INSTANCE_CACHE.get(this); - instance = instanceRef != null ? (ClassIntrospector) instanceRef.get() : null; + Reference<ClassIntrospector> instanceRef = INSTANCE_CACHE.get(this); + instance = instanceRef != null ? instanceRef.get() : null; if (instance == null) { ClassIntrospectorBuilder thisClone = (ClassIntrospectorBuilder) clone(); // prevent any aliasing issues instance = new ClassIntrospector(thisClone, new Object(), true, true); - INSTANCE_CACHE.put(thisClone, new WeakReference(instance, INSTANCE_CACHE_REF_QUEUE)); + INSTANCE_CACHE.put(thisClone, new WeakReference<ClassIntrospector>(instance, INSTANCE_CACHE_REF_QUEUE)); } }
