Some cleanup in ClassIntrospector and BeansWrapper code
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 @@
* 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.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 @@
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 @@
// 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 @@
* @since 2.3.21
*/
public boolean isClassIntrospectionCacheRestricted() {
- return classIntrospector.getHasSharedInstanceRestrictons();
+ return classIntrospector.getHasSharedInstanceRestrictions();
}
/**
@@ -692,7 +692,7 @@
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 @@
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 @@
// 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 @@
this.sharedLock = sharedLock;
- this.hasSharedInstanceRestrictons = hasSharedInstanceRestrictons;
+ this.hasSharedInstanceRestrictions = hasSharedInstanceRestrictions;
this.shared = shared;
if (CLASS_CHANGE_NOTIFIER != null) {
@@ -204,8 +194,9 @@
}
/**
- * 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 @@
* @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 @@
* 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 @@
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 @@
}
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 @@
}
/** For unit testing only */
- static Map getInstanceCache() {
+ static Map<ClassIntrospectorBuilder, Reference<ClassIntrospector>> getInstanceCache() {
return INSTANCE_CACHE;
}
@@ -187,12 +190,12 @@
// 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));
}
}