You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2016/12/06 22:30:14 UTC
[19/24] incubator-freemarker git commit: Utilizing Java 5 generics at
some places where it doesn't break backward compatibility. Replaceding
freemarker.ext.util.IdentityHashMap usages with java.util.IdentityHashMap.
Some internal naming cleanup.
Utilizing Java 5 generics at some places where it doesn't break backward compatibility. Replaceding freemarker.ext.util.IdentityHashMap usages with java.util.IdentityHashMap. Some internal naming cleanup.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/277956d9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/277956d9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/277956d9
Branch: refs/heads/2.3
Commit: 277956d94a5e5972f47f24188ea1c48b13d6b70b
Parents: 5be880d
Author: ddekany <dd...@apache.org>
Authored: Sat Dec 3 19:29:35 2016 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sun Dec 4 13:19:27 2016 +0100
----------------------------------------------------------------------
src/main/java/freemarker/core/NewBI.java | 8 +-
.../debug/impl/RmiDebuggedEnvironmentImpl.java | 2 +-
.../freemarker/ext/beans/ArgumentTypes.java | 75 +++++----
.../java/freemarker/ext/beans/BeanModel.java | 6 +-
.../java/freemarker/ext/beans/BeansWrapper.java | 87 ++++++-----
.../ext/beans/BeansWrapperBuilder.java | 17 +-
.../freemarker/ext/beans/ClassIntrospector.java | 156 ++++++++++---------
.../java/freemarker/ext/beans/_BeansAPI.java | 70 +++++----
.../freemarker/ext/util/IdentityHashMap.java | 9 +-
.../java/freemarker/ext/util/ModelCache.java | 19 ++-
.../template/DefaultObjectWrapper.java | 23 +--
.../template/DefaultObjectWrapperBuilder.java | 18 ++-
.../template/ObjectWrapperAndUnwrapper.java | 2 +-
.../java/freemarker/template/_TemplateAPI.java | 2 -
14 files changed, 264 insertions(+), 230 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/277956d9/src/main/java/freemarker/core/NewBI.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/NewBI.java b/src/main/java/freemarker/core/NewBI.java
index c7842de..eddd823 100644
--- a/src/main/java/freemarker/core/NewBI.java
+++ b/src/main/java/freemarker/core/NewBI.java
@@ -21,6 +21,7 @@ package freemarker.core;
import java.util.List;
+import freemarker.ext.beans.BeanModel;
import freemarker.ext.beans.BeansWrapper;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;
@@ -35,8 +36,7 @@ import freemarker.template.TemplateModelException;
*/
class NewBI extends BuiltIn {
- static final Class BEAN_MODEL_CLASS = freemarker.ext.beans.BeanModel.class;
- static Class JYTHON_MODEL_CLASS;
+ static Class<?> JYTHON_MODEL_CLASS;
static {
try {
JYTHON_MODEL_CLASS = Class.forName("freemarker.ext.jython.JythonModel");
@@ -53,7 +53,7 @@ class NewBI extends BuiltIn {
class ConstructorFunction implements TemplateMethodModelEx {
- private final Class cl;
+ private final Class<?> cl;
private final Environment env;
public ConstructorFunction(String classname, Environment env, Template template) throws TemplateException {
@@ -63,7 +63,7 @@ class NewBI extends BuiltIn {
throw new _MiscTemplateException(NewBI.this, env,
"Class ", cl.getName(), " does not implement freemarker.template.TemplateModel");
}
- if (BEAN_MODEL_CLASS.isAssignableFrom(cl)) {
+ if (BeanModel.class.isAssignableFrom(cl)) {
throw new _MiscTemplateException(NewBI.this, env,
"Bean Models cannot be instantiated using the ?", key, " built-in");
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/277956d9/src/main/java/freemarker/debug/impl/RmiDebuggedEnvironmentImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/debug/impl/RmiDebuggedEnvironmentImpl.java b/src/main/java/freemarker/debug/impl/RmiDebuggedEnvironmentImpl.java
index 8bb1b3c..ec6e5a4 100644
--- a/src/main/java/freemarker/debug/impl/RmiDebuggedEnvironmentImpl.java
+++ b/src/main/java/freemarker/debug/impl/RmiDebuggedEnvironmentImpl.java
@@ -27,6 +27,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -38,7 +39,6 @@ import freemarker.core.Configurable;
import freemarker.core.Environment;
import freemarker.debug.DebugModel;
import freemarker.debug.DebuggedEnvironment;
-import freemarker.ext.util.IdentityHashMap;
import freemarker.template.Configuration;
import freemarker.template.SimpleCollection;
import freemarker.template.SimpleScalar;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/277956d9/src/main/java/freemarker/ext/beans/ArgumentTypes.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/ArgumentTypes.java b/src/main/java/freemarker/ext/beans/ArgumentTypes.java
index 11f1b77..e383259 100644
--- a/src/main/java/freemarker/ext/beans/ArgumentTypes.java
+++ b/src/main/java/freemarker/ext/beans/ArgumentTypes.java
@@ -54,7 +54,7 @@ final class ArgumentTypes {
/**
* The types of the arguments; for varags this contains the exploded list (not the array).
*/
- private final Class[] types;
+ private final Class<?>[] types;
private final boolean bugfixed;
@@ -65,7 +65,7 @@ final class ArgumentTypes {
*/
ArgumentTypes(Object[] args, boolean bugfixed) {
int ln = args.length;
- Class[] typesTmp = new Class[ln];
+ Class<?>[] typesTmp = new Class[ln];
for (int i = 0; i < ln; ++i) {
Object arg = args[i];
typesTmp[i] = arg == null
@@ -109,22 +109,21 @@ final class ArgumentTypes {
* {@link EmptyCallableMemberDescriptor#AMBIGUOUS_METHOD}.
*/
MaybeEmptyCallableMemberDescriptor getMostSpecific(
- List/*<ReflectionCallableMemberDescriptor>*/ memberDescs, boolean varArg) {
- LinkedList/*<ReflectionCallableMemberDescriptor>*/ applicables = getApplicables(memberDescs, varArg);
+ List<ReflectionCallableMemberDescriptor> memberDescs, boolean varArg) {
+ LinkedList<CallableMemberDescriptor> applicables = getApplicables(memberDescs, varArg);
if (applicables.isEmpty()) {
return EmptyCallableMemberDescriptor.NO_SUCH_METHOD;
}
if (applicables.size() == 1) {
- return (CallableMemberDescriptor) applicables.getFirst();
+ return applicables.getFirst();
}
- LinkedList/*<CallableMemberDescriptor>*/ maximals = new LinkedList();
- for (Iterator applicablesIter = applicables.iterator(); applicablesIter.hasNext(); ) {
- CallableMemberDescriptor applicable = (CallableMemberDescriptor) applicablesIter.next();
+ LinkedList<CallableMemberDescriptor> maximals = new LinkedList<CallableMemberDescriptor>();
+ for (CallableMemberDescriptor applicable : applicables) {
boolean lessSpecific = false;
- for (Iterator maximalsIter = maximals.iterator();
+ for (Iterator<CallableMemberDescriptor> maximalsIter = maximals.iterator();
maximalsIter.hasNext(); ) {
- CallableMemberDescriptor maximal = (CallableMemberDescriptor) maximalsIter.next();
+ CallableMemberDescriptor maximal = maximalsIter.next();
final int cmpRes = compareParameterListPreferability(
applicable.getParamTypes(), maximal.getParamTypes(), varArg);
if (cmpRes > 0) {
@@ -140,7 +139,7 @@ final class ArgumentTypes {
if (maximals.size() > 1) {
return EmptyCallableMemberDescriptor.AMBIGUOUS_METHOD;
}
- return (CallableMemberDescriptor) maximals.getFirst();
+ return maximals.getFirst();
}
/**
@@ -174,7 +173,7 @@ final class ArgumentTypes {
* @return More than 0 if the first parameter list is preferred, less then 0 if the other is preferred,
* 0 if there's no decision
*/
- int compareParameterListPreferability(Class[] paramTypes1, Class[] paramTypes2, boolean varArg) {
+ int compareParameterListPreferability(Class<?>[] paramTypes1, Class<?>[] paramTypes2, boolean varArg) {
final int argTypesLen = types.length;
final int paramTypes1Len = paramTypes1.length;
final int paramTypes2Len = paramTypes2.length;
@@ -191,19 +190,19 @@ final class ArgumentTypes {
int paramList2VeryStrongWinCnt = 0;
int firstWinerParamList = 0;
for (int i = 0; i < argTypesLen; i++) {
- final Class paramType1 = getParamType(paramTypes1, paramTypes1Len, i, varArg);
- final Class paramType2 = getParamType(paramTypes2, paramTypes2Len, i, varArg);
+ final Class<?> paramType1 = getParamType(paramTypes1, paramTypes1Len, i, varArg);
+ final Class<?> paramType2 = getParamType(paramTypes2, paramTypes2Len, i, varArg);
final int winerParam; // 1 => paramType1; -1 => paramType2; 0 => draw
if (paramType1 == paramType2) {
winerParam = 0;
} else {
- final Class argType = types[i];
+ final Class<?> argType = types[i];
final boolean argIsNum = Number.class.isAssignableFrom(argType);
final int numConvPrice1;
if (argIsNum && ClassUtil.isNumerical(paramType1)) {
- final Class nonPrimParamType1 = paramType1.isPrimitive()
+ final Class<?> nonPrimParamType1 = paramType1.isPrimitive()
? ClassUtil.primitiveClassToBoxingClass(paramType1) : paramType1;
numConvPrice1 = OverloadedNumberUtil.getArgumentConversionPrice(argType, nonPrimParamType1);
} else {
@@ -215,7 +214,7 @@ final class ArgumentTypes {
final int numConvPrice2;
if (argIsNum && ClassUtil.isNumerical(paramType2)) {
- final Class nonPrimParamType2 = paramType2.isPrimitive()
+ final Class<?> nonPrimParamType2 = paramType2.isPrimitive()
? ClassUtil.primitiveClassToBoxingClass(paramType2) : paramType2;
numConvPrice2 = OverloadedNumberUtil.getArgumentConversionPrice(argType, nonPrimParamType2);
} else {
@@ -357,8 +356,8 @@ final class ArgumentTypes {
// index of the varargs parameter, like if we had a single varargs argument. However, this
// time we don't have an argument type, so we can only decide based on type specificity:
if (argTypesLen == paramTypes1Len - 1) {
- Class paramType1 = getParamType(paramTypes1, paramTypes1Len, argTypesLen, true);
- Class paramType2 = getParamType(paramTypes2, paramTypes2Len, argTypesLen, true);
+ Class<?> paramType1 = getParamType(paramTypes1, paramTypes1Len, argTypesLen, true);
+ Class<?> paramType2 = getParamType(paramTypes2, paramTypes2Len, argTypesLen, true);
if (ClassUtil.isNumerical(paramType1) && ClassUtil.isNumerical(paramType2)) {
int r = OverloadedNumberUtil.compareNumberTypeSpecificity(paramType1, paramType2);
if (r != 0) return r;
@@ -380,8 +379,8 @@ final class ArgumentTypes {
boolean paramTypes1HasAMoreSpecific = false;
boolean paramTypes2HasAMoreSpecific = false;
for (int i = 0; i < paramTypes1Len; ++i) {
- Class paramType1 = getParamType(paramTypes1, paramTypes1Len, i, varArg);
- Class paramType2 = getParamType(paramTypes2, paramTypes2Len, i, varArg);
+ Class<?> paramType1 = getParamType(paramTypes1, paramTypes1Len, i, varArg);
+ Class<?> paramType2 = getParamType(paramTypes2, paramTypes2Len, i, varArg);
if (paramType1 != paramType2) {
paramTypes1HasAMoreSpecific =
paramTypes1HasAMoreSpecific
@@ -408,12 +407,13 @@ final class ArgumentTypes {
* @return Less-than-0, 0, or more-than-0 depending on which side is more specific. The absolute value is 1 if
* the difference is only in primitive VS non-primitive, more otherwise.
*/
- private int compareParameterListPreferability_cmpTypeSpecificty(final Class paramType1, final Class paramType2) {
+ private int compareParameterListPreferability_cmpTypeSpecificty(
+ final Class<?> paramType1, final Class<?> paramType2) {
// The more specific (smaller) type wins.
- final Class nonPrimParamType1 = paramType1.isPrimitive()
+ final Class<?> nonPrimParamType1 = paramType1.isPrimitive()
? ClassUtil.primitiveClassToBoxingClass(paramType1) : paramType1;
- final Class nonPrimParamType2 = paramType2.isPrimitive()
+ final Class<?> nonPrimParamType2 = paramType2.isPrimitive()
? ClassUtil.primitiveClassToBoxingClass(paramType2) : paramType2;
if (nonPrimParamType1 == nonPrimParamType2) {
@@ -441,7 +441,7 @@ final class ArgumentTypes {
}
}
- private static Class getParamType(Class[] paramTypes, int paramTypesLen, int i, boolean varArg) {
+ private static Class<?> getParamType(Class<?>[] paramTypes, int paramTypesLen, int i, boolean varArg) {
return varArg && i >= paramTypesLen - 1
? paramTypes[paramTypesLen - 1].getComponentType()
: paramTypes[i];
@@ -451,11 +451,10 @@ final class ArgumentTypes {
* Returns all methods that are applicable to actual
* parameter types represented by this ArgumentTypes object.
*/
- LinkedList/*<ReflectionCallableMemberDescriptor>*/ getApplicables(
- List/*<ReflectionCallableMemberDescriptor>*/ memberDescs, boolean varArg) {
- LinkedList applicables = new LinkedList();
- for (Iterator it = memberDescs.iterator(); it.hasNext(); ) {
- ReflectionCallableMemberDescriptor memberDesc = (ReflectionCallableMemberDescriptor) it.next();
+ LinkedList<CallableMemberDescriptor> getApplicables(
+ List<ReflectionCallableMemberDescriptor> memberDescs, boolean varArg) {
+ LinkedList<CallableMemberDescriptor> applicables = new LinkedList<CallableMemberDescriptor>();
+ for (ReflectionCallableMemberDescriptor memberDesc : memberDescs) {
int difficulty = isApplicable(memberDesc, varArg);
if (difficulty != CONVERSION_DIFFICULTY_IMPOSSIBLE) {
if (difficulty == CONVERSION_DIFFICULTY_REFLECTION) {
@@ -478,7 +477,7 @@ final class ArgumentTypes {
* @return One of the <tt>CONVERSION_DIFFICULTY_...</tt> constants.
*/
private int isApplicable(ReflectionCallableMemberDescriptor memberDesc, boolean varArg) {
- final Class[] paramTypes = memberDesc.getParamTypes();
+ final Class<?>[] paramTypes = memberDesc.getParamTypes();
final int cl = types.length;
final int fl = paramTypes.length - (varArg ? 1 : 0);
if (varArg) {
@@ -502,7 +501,7 @@ final class ArgumentTypes {
}
}
if (varArg) {
- Class varArgParamType = paramTypes[fl].getComponentType();
+ Class<?> varArgParamType = paramTypes[fl].getComponentType();
for (int i = fl; i < cl; ++i) {
int difficulty = isMethodInvocationConvertible(varArgParamType, types[i]);
if (difficulty == CONVERSION_DIFFICULTY_IMPOSSIBLE) {
@@ -530,12 +529,12 @@ final class ArgumentTypes {
*
* @return One of the <tt>CONVERSION_DIFFICULTY_...</tt> constants.
*/
- private int isMethodInvocationConvertible(final Class formal, final Class actual) {
+ private int isMethodInvocationConvertible(final Class<?> formal, final Class<?> actual) {
// Check for identity or widening reference conversion
if (formal.isAssignableFrom(actual) && actual != CharacterOrString.class) {
return CONVERSION_DIFFICULTY_REFLECTION;
} else if (bugfixed) {
- final Class formalNP;
+ final Class<?> formalNP;
if (formal.isPrimitive()) {
if (actual == Null.class) {
return CONVERSION_DIFFICULTY_IMPOSSIBLE;
@@ -684,7 +683,7 @@ final class ArgumentTypes {
}
@Override
- Class[] getParamTypes() {
+ Class<?>[] getParamTypes() {
return callableMemberDesc.getParamTypes();
}
@@ -694,10 +693,10 @@ final class ArgumentTypes {
}
private void convertArgsToReflectionCompatible(BeansWrapper bw, Object[] args) throws TemplateModelException {
- Class[] paramTypes = callableMemberDesc.getParamTypes();
+ Class<?>[] paramTypes = callableMemberDesc.getParamTypes();
int ln = paramTypes.length;
for (int i = 0; i < ln; i++) {
- Class paramType = paramTypes[i];
+ Class<?> paramType = paramTypes[i];
final Object arg = args[i];
if (arg == null) continue;
@@ -712,7 +711,7 @@ final class ArgumentTypes {
// parameter, and that an array argument is applicable to a List parameter, so we end up with this
// situation.
if (paramType.isArray() && arg instanceof List) {
- args[i] = bw.listToArray((List) arg, paramType, null);
+ args[i] = bw.listToArray((List<?>) arg, paramType, null);
}
if (arg.getClass().isArray() && paramType.isAssignableFrom(List.class)) {
args[i] = bw.arrayToList(arg);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/277956d9/src/main/java/freemarker/ext/beans/BeanModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/BeanModel.java b/src/main/java/freemarker/ext/beans/BeanModel.java
index 794a66b..ba3dc62 100644
--- a/src/main/java/freemarker/ext/beans/BeanModel.java
+++ b/src/main/java/freemarker/ext/beans/BeanModel.java
@@ -143,8 +143,8 @@ implements
*/
public TemplateModel get(String key)
throws TemplateModelException {
- Class clazz = object.getClass();
- Map classInfo = wrapper.getClassIntrospector().get(clazz);
+ Class<?> clazz = object.getClass();
+ Map<Object, Object> classInfo = wrapper.getClassIntrospector().get(clazz);
TemplateModel retval = null;
try {
@@ -206,7 +206,7 @@ implements
return wrapper.getClassIntrospector().get(object.getClass()).get(ClassIntrospector.GENERIC_GET_KEY) != null;
}
- private TemplateModel invokeThroughDescriptor(Object desc, Map classInfo)
+ private TemplateModel invokeThroughDescriptor(Object desc, Map<Object, Object> classInfo)
throws IllegalAccessException,
InvocationTargetException,
TemplateModelException {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/277956d9/src/main/java/freemarker/ext/beans/BeansWrapper.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/BeansWrapper.java b/src/main/java/freemarker/ext/beans/BeansWrapper.java
index cf2d0c4..8b51238 100644
--- a/src/main/java/freemarker/ext/beans/BeansWrapper.java
+++ b/src/main/java/freemarker/ext/beans/BeansWrapper.java
@@ -31,6 +31,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
+import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -41,7 +42,6 @@ import freemarker.core.BugException;
import freemarker.core._DelayedFTLTypeDescription;
import freemarker.core._DelayedShortClassName;
import freemarker.core._TemplateModelException;
-import freemarker.ext.util.IdentityHashMap;
import freemarker.ext.util.ModelCache;
import freemarker.ext.util.ModelFactory;
import freemarker.ext.util.WrapperTemplateModel;
@@ -94,9 +94,9 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
@Deprecated
static final Object CAN_NOT_UNWRAP = ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS;
- private static final Class ITERABLE_CLASS;
+ private static final Class<?> ITERABLE_CLASS;
static {
- Class iterable;
+ Class<?> iterable;
try {
iterable = Class.forName("java.lang.Iterable");
} catch (ClassNotFoundException e) {
@@ -106,7 +106,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
ITERABLE_CLASS = iterable;
}
- private static final Constructor ENUMS_MODEL_CTOR = enumsModelCtor();
+ private static final Constructor<?> ENUMS_MODEL_CTOR = enumsModelCtor();
/**
* At this level of exposure, all methods and properties of the
@@ -296,7 +296,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
protected BeansWrapper(BeansWrapperConfiguration bwConf, boolean writeProtected, boolean finalizeConstruction) {
// Backward-compatibility hack for "finetuneMethodAppearance" overrides to work:
if (bwConf.getMethodAppearanceFineTuner() == null) {
- Class thisClass = this.getClass();
+ Class<?> thisClass = this.getClass();
boolean overridden = false;
boolean testFailed = false;
try {
@@ -306,7 +306,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
&& thisClass != SimpleObjectWrapper.class) {
try {
thisClass.getDeclaredMethod("finetuneMethodAppearance",
- new Class[] { Class.class, Method.class, MethodAppearanceDecision.class });
+ new Class<?>[] { Class.class, Method.class, MethodAppearanceDecision.class });
overridden = true;
} catch (NoSuchMethodException e) {
thisClass = thisClass.getSuperclass();
@@ -912,17 +912,17 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
private static final ModelFactory ITERATOR_FACTORY = new ModelFactory() {
public TemplateModel create(Object object, ObjectWrapper wrapper) {
- return new IteratorModel((Iterator) object, (BeansWrapper) wrapper);
+ return new IteratorModel((Iterator<?>) object, (BeansWrapper) wrapper);
}
};
private static final ModelFactory ENUMERATION_FACTORY = new ModelFactory() {
public TemplateModel create(Object object, ObjectWrapper wrapper) {
- return new EnumerationModel((Enumeration) object, (BeansWrapper) wrapper);
+ return new EnumerationModel((Enumeration<?>) object, (BeansWrapper) wrapper);
}
};
- protected ModelFactory getModelFactory(Class clazz) {
+ protected ModelFactory getModelFactory(Class<?> clazz) {
if (Map.class.isAssignableFrom(clazz)) {
return simpleMapWrapper ? SimpleMapModel.FACTORY : MapModel.FACTORY;
}
@@ -983,7 +983,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
*
* @see #tryUnwrapTo(TemplateModel, Class)
*/
- public Object unwrap(TemplateModel model, Class targetClass)
+ public Object unwrap(TemplateModel model, Class<?> targetClass)
throws TemplateModelException {
final Object obj = tryUnwrapTo(model, targetClass);
if (obj == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) {
@@ -996,7 +996,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
/**
* @since 2.3.22
*/
- public Object tryUnwrapTo(TemplateModel model, Class targetClass) throws TemplateModelException {
+ public Object tryUnwrapTo(TemplateModel model, Class<?> targetClass) throws TemplateModelException {
return tryUnwrapTo(model, targetClass, 0);
}
@@ -1007,7 +1007,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
* {@link #is2321Bugfixed()} is {@code false}.
* @return {@link ObjectWrapperAndUnwrapper#CANT_UNWRAP_TO_TARGET_CLASS} or the unwrapped object.
*/
- Object tryUnwrapTo(TemplateModel model, Class targetClass, int typeFlags)
+ Object tryUnwrapTo(TemplateModel model, Class<?> targetClass, int typeFlags)
throws TemplateModelException {
Object res = tryUnwrapTo(model, targetClass, typeFlags, null);
if ((typeFlags & TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT) != 0
@@ -1021,7 +1021,8 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
/**
* See {@try #tryUnwrap(TemplateModel, Class, int, boolean)}.
*/
- private Object tryUnwrapTo(final TemplateModel model, Class targetClass, final int typeFlags, final Map recursionStops)
+ private Object tryUnwrapTo(final TemplateModel model, Class<?> targetClass, final int typeFlags,
+ final Map<Object, Object> recursionStops)
throws TemplateModelException {
if (model == null || model == nullModel) {
return null;
@@ -1249,7 +1250,8 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
* {@link ObjectWrapperAndUnwrapper#CANT_UNWRAP_TO_TARGET_CLASS} instead of throwing a
* {@link TemplateModelException}.
*/
- Object unwrapSequenceToArray(TemplateSequenceModel seq, Class arrayClass, boolean tryOnly, Map recursionStops)
+ Object unwrapSequenceToArray(
+ TemplateSequenceModel seq, Class<?> arrayClass, boolean tryOnly, Map<Object, Object> recursionStops)
throws TemplateModelException {
if (recursionStops != null) {
Object retval = recursionStops.get(seq);
@@ -1257,9 +1259,9 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
return retval;
}
} else {
- recursionStops = new IdentityHashMap();
+ recursionStops = new IdentityHashMap<Object, Object>();
}
- Class componentType = arrayClass.getComponentType();
+ Class<?> componentType = arrayClass.getComponentType();
Object array = Array.newInstance(componentType, seq.size());
recursionStops.put(seq, array);
try {
@@ -1287,7 +1289,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
return array;
}
- Object listToArray(List list, Class arrayClass, Map recursionStops)
+ Object listToArray(List<?> list, Class<?> arrayClass, Map<Object, Object> recursionStops)
throws TemplateModelException {
if (list instanceof SequenceAdapter) {
return unwrapSequenceToArray(
@@ -1302,9 +1304,9 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
return retval;
}
} else {
- recursionStops = new IdentityHashMap();
+ recursionStops = new IdentityHashMap<Object, Object>();
}
- Class componentType = arrayClass.getComponentType();
+ Class<?> componentType = arrayClass.getComponentType();
Object array = Array.newInstance(componentType, list.size());
recursionStops.put(list, array);
try {
@@ -1312,7 +1314,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
boolean isComponentTypeNumerical = false; // will be filled on demand
boolean isComponentTypeList = false; // will be filled on demand
int i = 0;
- for (Iterator it = list.iterator(); it.hasNext(); ) {
+ for (Iterator<?> it = list.iterator(); it.hasNext(); ) {
Object listItem = it.next();
if (listItem != null && !componentType.isInstance(listItem)) {
// Type conversion is needed. If we can't do it, we just let it fail at Array.set later.
@@ -1333,7 +1335,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
}
} else if (componentType.isArray()) {
if (listItem instanceof List) {
- listItem = listToArray((List) listItem, componentType, recursionStops);
+ listItem = listToArray((List<?>) listItem, componentType, recursionStops);
} else if (listItem instanceof TemplateSequenceModel) {
listItem = unwrapSequenceToArray((TemplateSequenceModel) listItem, componentType, false, recursionStops);
}
@@ -1361,7 +1363,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
/**
* @param array Must be an array (of either a reference or primitive type)
*/
- List arrayToList(Object array) throws TemplateModelException {
+ List<?> arrayToList(Object array) throws TemplateModelException {
if (array instanceof Object[]) {
// Array of any non-primitive type.
// Note that an array of non-primitive type is always instanceof Object[].
@@ -1378,7 +1380,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
* @param n Non-{@code null}
* @return {@code null} if the conversion has failed.
*/
- static Number forceUnwrappedNumberToType(final Number n, final Class targetType, final boolean bugfixed) {
+ static Number forceUnwrappedNumberToType(final Number n, final Class<?> targetType, final boolean bugfixed) {
// We try to order the conditions by decreasing probability.
if (targetType == n.getClass()) {
return n;
@@ -1516,7 +1518,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
* @param arguments The list of {@link TemplateModel}-s to pass to the constructor after unwrapping them
* @return The instance created; it's not wrapped into {@link TemplateModel}.
*/
- public Object newInstance(Class clazz, List/*<TemplateModel>*/ arguments)
+ public Object newInstance(Class<?> clazz, List/*<? extends TemplateModel>*/ arguments)
throws TemplateModelException {
try {
Object ctors = classIntrospector.get(clazz).get(ClassIntrospector.CONSTRUCTORS_KEY);
@@ -1524,11 +1526,11 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
throw new TemplateModelException("Class " + clazz.getName() +
" has no public constructors.");
}
- Constructor ctor = null;
+ Constructor<?> ctor = null;
Object[] objargs;
if (ctors instanceof SimpleMethod) {
SimpleMethod sm = (SimpleMethod) ctors;
- ctor = (Constructor) sm.getMember();
+ ctor = (Constructor<?>) sm.getMember();
objargs = sm.unwrapArguments(arguments, this);
try {
return ctor.newInstance(objargs);
@@ -1565,7 +1567,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
*
* @since 2.3.20
*/
- public void removeFromClassIntrospectionCache(Class clazz) {
+ public void removeFromClassIntrospectionCache(Class<?> clazz) {
classIntrospector.remove(clazz);
}
@@ -1596,7 +1598,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
*/
@Deprecated
protected void finetuneMethodAppearance(
- Class clazz, Method m, MethodAppearanceDecision decision) {
+ Class<?> clazz, Method m, MethodAppearanceDecision decision) {
// left everything on its default; do nothing
}
@@ -1606,7 +1608,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
*/
// Unused?
public static void coerceBigDecimals(AccessibleObject callable, Object[] args) {
- Class[] formalTypes = null;
+ Class<?>[] formalTypes = null;
for (int i = 0; i < args.length; ++i) {
Object arg = args[i];
if (arg instanceof BigDecimal) {
@@ -1614,7 +1616,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
if (callable instanceof Method) {
formalTypes = ((Method) callable).getParameterTypes();
} else if (callable instanceof Constructor) {
- formalTypes = ((Constructor) callable).getParameterTypes();
+ formalTypes = ((Constructor<?>) callable).getParameterTypes();
} else {
throw new IllegalArgumentException("Expected method or "
+ " constructor; callable is " +
@@ -1627,10 +1629,10 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
}
/**
- * Converts any {@link BigDecimal}s in the passed array to the type of
- * the corresponding formal argument of the method.
+ * Converts any {@link BigDecimal}-s in the passed array to the type of
+ * the corresponding formal argument of the method via {@link #coerceBigDecimal(BigDecimal, Class)}.
*/
- public static void coerceBigDecimals(Class[] formalTypes, Object[] args) {
+ public static void coerceBigDecimals(Class<?>[] formalTypes, Object[] args) {
int typeLen = formalTypes.length;
int argsLen = args.length;
int min = Math.min(typeLen, argsLen);
@@ -1641,7 +1643,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
}
}
if (argsLen > typeLen) {
- Class varArgType = formalTypes[typeLen - 1];
+ Class<?> varArgType = formalTypes[typeLen - 1];
for (int i = typeLen; i < argsLen; ++i) {
Object arg = args[i];
if (arg instanceof BigDecimal) {
@@ -1651,7 +1653,12 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
}
}
- public static Object coerceBigDecimal(BigDecimal bd, Class formalType) {
+ /**
+ * Converts {@link BigDecimal} to the class given in the {@code formalType} argument if that's a known numerical
+ * type, returns the {@link BigDecimal} as is otherwise. Overflow and precision loss are possible, similarly as
+ * with casting in Java.
+ */
+ public static Object coerceBigDecimal(BigDecimal bd, Class<?> formalType) {
// int is expected in most situations, so we check it first
if (formalType == int.class || formalType == Integer.class) {
return Integer.valueOf(bd.intValue());
@@ -1774,19 +1781,17 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
}
/**
- * Used for
- * {@link MethodAppearanceFineTuner#process}
- * as input parameter; see there.
+ * Used for {@link MethodAppearanceFineTuner#process} as input parameter; see there.
*/
static public final class MethodAppearanceDecisionInput {
private Method method;
- private Class containingClass;
+ private Class<?> containingClass;
void setMethod(Method method) {
this.method = method;
}
- void setContainingClass(Class containingClass) {
+ void setContainingClass(Class<?> containingClass) {
this.containingClass = containingClass;
}
@@ -1794,7 +1799,7 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
return method;
}
- public Class getContainingClass() {
+ public Class/*<?>*/ getContainingClass() {
return containingClass;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/277956d9/src/main/java/freemarker/ext/beans/BeansWrapperBuilder.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/BeansWrapperBuilder.java b/src/main/java/freemarker/ext/beans/BeansWrapperBuilder.java
index 54090b9..f8cb545 100644
--- a/src/main/java/freemarker/ext/beans/BeansWrapperBuilder.java
+++ b/src/main/java/freemarker/ext/beans/BeansWrapperBuilder.java
@@ -20,6 +20,7 @@
package freemarker.ext.beans;
import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.WeakHashMap;
@@ -109,11 +110,13 @@ import freemarker.template.Version;
*/
public class BeansWrapperBuilder extends BeansWrapperConfiguration {
- private final static WeakHashMap/*<ClassLoader, Map<PropertyAssignments, WeakReference<BeansWrapper>>*/
- INSTANCE_CACHE = new WeakHashMap();
- private final static ReferenceQueue INSTANCE_CACHE_REF_QUEUE = new ReferenceQueue();
+ private final static Map<ClassLoader, Map<BeansWrapperConfiguration, WeakReference<BeansWrapper>>>
+ INSTANCE_CACHE = new WeakHashMap<
+ ClassLoader, Map<BeansWrapperConfiguration, WeakReference<BeansWrapper>>>();
+ private final static ReferenceQueue<BeansWrapper> INSTANCE_CACHE_REF_QUEUE = new ReferenceQueue<BeansWrapper>();
- private static class BeansWrapperFactory implements _BeansAPI._BeansWrapperSubclassFactory {
+ private static class BeansWrapperFactory
+ implements _BeansAPI._BeansWrapperSubclassFactory<BeansWrapper, BeansWrapperConfiguration> {
private static final BeansWrapperFactory INSTANCE = new BeansWrapperFactory();
@@ -137,8 +140,10 @@ public class BeansWrapperBuilder extends BeansWrapperConfiguration {
}
}
- /** For unit testing only */
- static Map getInstanceCache() {
+ /**
+ * For unit testing only
+ */
+ static Map<ClassLoader, Map<BeansWrapperConfiguration, WeakReference<BeansWrapper>>> getInstanceCache() {
return INSTANCE_CACHE;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/277956d9/src/main/java/freemarker/ext/beans/ClassIntrospector.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/ClassIntrospector.java b/src/main/java/freemarker/ext/beans/ClassIntrospector.java
index 6ccd872..c852636 100644
--- a/src/main/java/freemarker/ext/beans/ClassIntrospector.java
+++ b/src/main/java/freemarker/ext/beans/ClassIntrospector.java
@@ -41,6 +41,7 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -120,8 +121,11 @@ class ClassIntrospector {
// -----------------------------------------------------------------------------------------------------------------
// Introspection info Map keys:
- private static final Object ARGTYPES_KEY = new Object();
+ /** Key in the class info Map to the Map that maps method to argument type arrays */
+ private static final Object ARG_TYPES_BY_METHOD_KEY = new Object();
+ /** Key in the class info Map to the object that represents the constructors (one or multiple due to overloading) */
static final Object CONSTRUCTORS_KEY = new Object();
+ /** Key in the class info Map to the get(String|Object) Method */
static final Object GENERIC_GET_KEY = new Object();
// -----------------------------------------------------------------------------------------------------------------
@@ -145,12 +149,14 @@ class ClassIntrospector {
// State fields:
private final Object sharedLock;
- private final Map/* <Class, Map<String, Object>> */cache = new ConcurrentHashMap(0, 0.75f, 16);
- private final Set/* <String> */cacheClassNames = new HashSet(0);
- private final Set/* <Class> */classIntrospectionsInProgress = new HashSet(0);
+ private final Map<Class<?>, Map<Object, Object>> cache
+ = new ConcurrentHashMap<Class<?>, Map<Object, Object>>(0, 0.75f, 16);
+ private final Set<String> cacheClassNames = new HashSet<String>(0);
+ private final Set<Class<?>> classIntrospectionsInProgress = new HashSet<Class<?>>(0);
- private final List/* <WeakReference<ClassBasedModelFactory|ModelCache>> */modelFactories = new LinkedList();
- private final ReferenceQueue modelFactoriesRefQueue = new ReferenceQueue();
+ private final List<WeakReference<Object/*ClassBasedModelFactory|ModelCache>*/>> modelFactories
+ = new LinkedList<WeakReference<Object>>();
+ private final ReferenceQueue<Object> modelFactoriesRefQueue = new ReferenceQueue<Object>();
private int clearingCounter;
@@ -210,15 +216,15 @@ class ClassIntrospector {
* {@link #CONSTRUCTORS_KEY}), each value is a {@link PropertyDescriptor} or {@link Method} or
* {@link OverloadedMethods} or {@link Field} (but better check the source code...).
*/
- Map get(Class clazz) {
+ Map<Object, Object> get(Class<?> clazz) {
{
- Map introspData = (Map) cache.get(clazz);
+ Map<Object, Object> introspData = cache.get(clazz);
if (introspData != null) return introspData;
}
String className;
synchronized (sharedLock) {
- Map introspData = (Map) cache.get(clazz);
+ Map<Object, Object> introspData = cache.get(clazz);
if (introspData != null) return introspData;
className = clazz.getName();
@@ -231,7 +237,7 @@ class ClassIntrospector {
// waiting for its result.
try {
sharedLock.wait();
- introspData = (Map) cache.get(clazz);
+ introspData = cache.get(clazz);
} catch (InterruptedException e) {
throw new RuntimeException(
"Class inrospection data lookup aborded: " + e);
@@ -243,7 +249,7 @@ class ClassIntrospector {
classIntrospectionsInProgress.add(clazz);
}
try {
- Map introspData = createClassIntrospectionData(clazz);
+ Map<Object, Object> introspData = createClassIntrospectionData(clazz);
synchronized (sharedLock) {
cache.put(clazz, introspData);
cacheClassNames.add(className);
@@ -260,14 +266,14 @@ class ClassIntrospector {
/**
* Creates a {@link Map} with the content as described for the return value of {@link #get(Class)}.
*/
- private Map createClassIntrospectionData(Class clazz) {
- final Map introspData = new HashMap();
+ private Map<Object, Object> createClassIntrospectionData(Class<?> clazz) {
+ final Map<Object, Object> introspData = new HashMap<Object, Object>();
if (exposeFields) {
addFieldsToClassIntrospectionData(introspData, clazz);
}
- final Map accessibleMethods = discoverAccessibleMethods(clazz);
+ final Map<MethodSignature, List<Method>> accessibleMethods = discoverAccessibleMethods(clazz);
addGenericGetToClassIntrospectionData(introspData, accessibleMethods);
@@ -285,14 +291,14 @@ class ClassIntrospector {
if (introspData.size() > 1) {
return introspData;
} else if (introspData.size() == 0) {
- return Collections.EMPTY_MAP;
+ return Collections.emptyMap();
} else { // map.size() == 1
- Map.Entry e = (Map.Entry) introspData.entrySet().iterator().next();
+ Entry<Object, Object> e = introspData.entrySet().iterator().next();
return Collections.singletonMap(e.getKey(), e.getValue());
}
}
- private void addFieldsToClassIntrospectionData(Map introspData, Class clazz)
+ private void addFieldsToClassIntrospectionData(Map<Object, Object> introspData, Class<?> clazz)
throws SecurityException {
Field[] fields = clazz.getFields();
for (int i = 0; i < fields.length; i++) {
@@ -303,7 +309,8 @@ class ClassIntrospector {
}
}
- private void addBeanInfoToClassIntrospectionData(Map introspData, Class clazz, Map accessibleMethods)
+ private void addBeanInfoToClassIntrospectionData(
+ Map<Object, Object> introspData, Class<?> clazz, Map<MethodSignature, List<Method>> accessibleMethods)
throws IntrospectionException {
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
@@ -354,7 +361,7 @@ class ClassIntrospector {
overloadedMethods.addMethod(method);
introspData.put(methodKey, overloadedMethods);
// Remove parameter type information
- getArgTypes(introspData).remove(previous);
+ getArgTypesByMethod(introspData).remove(previous);
} else if (previous instanceof OverloadedMethods) {
// Already overloaded method - add new overload
((OverloadedMethods) previous).addMethod(method);
@@ -362,7 +369,7 @@ class ClassIntrospector {
|| !(previous instanceof PropertyDescriptor)) {
// Simple method (this far)
introspData.put(methodKey, method);
- getArgTypes(introspData).put(method,
+ getArgTypesByMethod(introspData).put(method,
method.getParameterTypes());
}
}
@@ -372,8 +379,8 @@ class ClassIntrospector {
} // end if (exposureLevel < EXPOSE_PROPERTIES_ONLY)
}
- private void addPropertyDescriptorToClassIntrospectionData(Map introspData,
- PropertyDescriptor pd, Class clazz, Map accessibleMethods) {
+ private void addPropertyDescriptorToClassIntrospectionData(Map<Object, Object> introspData,
+ PropertyDescriptor pd, Class<?> clazz, Map<MethodSignature, List<Method>> accessibleMethods) {
if (pd instanceof IndexedPropertyDescriptor) {
IndexedPropertyDescriptor ipd =
(IndexedPropertyDescriptor) pd;
@@ -388,7 +395,7 @@ class ClassIntrospector {
null);
}
introspData.put(ipd.getName(), ipd);
- getArgTypes(introspData).put(publicReadMethod, publicReadMethod.getParameterTypes());
+ getArgTypesByMethod(introspData).put(publicReadMethod, publicReadMethod.getParameterTypes());
} catch (IntrospectionException e) {
LOG.warn("Failed creating a publicly-accessible " +
"property descriptor for " + clazz.getName() +
@@ -417,8 +424,8 @@ class ClassIntrospector {
}
}
- private void addGenericGetToClassIntrospectionData(Map introspData,
- Map accessibleMethods) {
+ private void addGenericGetToClassIntrospectionData(Map<Object, Object> introspData,
+ Map<MethodSignature, List<Method>> accessibleMethods) {
Method genericGet = getFirstAccessibleMethod(
MethodSignature.GET_STRING_SIGNATURE, accessibleMethods);
if (genericGet == null) {
@@ -430,19 +437,19 @@ class ClassIntrospector {
}
}
- private void addConstructorsToClassIntrospectionData(final Map introspData,
- Class clazz) {
+ private void addConstructorsToClassIntrospectionData(final Map<Object, Object> introspData,
+ Class<?> clazz) {
try {
- Constructor[] ctors = clazz.getConstructors();
+ Constructor<?>[] ctors = clazz.getConstructors();
if (ctors.length == 1) {
- Constructor ctor = ctors[0];
+ Constructor<?> ctor = ctors[0];
introspData.put(CONSTRUCTORS_KEY, new SimpleMethod(ctor, ctor.getParameterTypes()));
} else if (ctors.length > 1) {
- OverloadedMethods ctorMap = new OverloadedMethods(bugfixed);
+ OverloadedMethods overloadedCtors = new OverloadedMethods(bugfixed);
for (int i = 0; i < ctors.length; i++) {
- ctorMap.addConstructor(ctors[i]);
+ overloadedCtors.addConstructor(ctors[i]);
}
- introspData.put(CONSTRUCTORS_KEY, ctorMap);
+ introspData.put(CONSTRUCTORS_KEY, overloadedCtors);
}
} catch (SecurityException e) {
LOG.warn("Can't discover constructors for class " + clazz.getName(), e);
@@ -454,13 +461,13 @@ class ClassIntrospector {
* class is not public, retrieves methods with same signature as its public methods from public superclasses and
* interfaces. Basically upcasts every method to the nearest accessible method.
*/
- private static Map discoverAccessibleMethods(Class clazz) {
- Map accessibles = new HashMap();
+ private static Map<MethodSignature, List<Method>> discoverAccessibleMethods(Class<?> clazz) {
+ Map<MethodSignature, List<Method>> accessibles = new HashMap<MethodSignature, List<Method>>();
discoverAccessibleMethods(clazz, accessibles);
return accessibles;
}
- private static void discoverAccessibleMethods(Class clazz, Map accessibles) {
+ private static void discoverAccessibleMethods(Class<?> clazz, Map<MethodSignature, List<Method>> accessibles) {
if (Modifier.isPublic(clazz.getModifiers())) {
try {
Method[] methods = clazz.getMethods();
@@ -478,9 +485,10 @@ class ClassIntrospector {
// public interface I<T> { T m(); }
// public class C implements I<Integer> { Integer m() { return 42; } }
// C.class will have both "Object m()" and "Integer m()" methods.
- List methodList = (List) accessibles.get(sig);
+ List<Method> methodList = accessibles.get(sig);
if (methodList == null) {
- methodList = new LinkedList();
+ // TODO Collection.singletonList is more efficient, though read only.
+ methodList = new LinkedList<Method>();
accessibles.put(sig, methodList);
}
methodList.add(method);
@@ -494,27 +502,26 @@ class ClassIntrospector {
}
}
- Class[] interfaces = clazz.getInterfaces();
+ Class<?>[] interfaces = clazz.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
discoverAccessibleMethods(interfaces[i], accessibles);
}
- Class superclass = clazz.getSuperclass();
+ Class<?> superclass = clazz.getSuperclass();
if (superclass != null) {
discoverAccessibleMethods(superclass, accessibles);
}
}
- private static Method getMatchingAccessibleMethod(Method m, Map accessibles) {
+ private static Method getMatchingAccessibleMethod(Method m, Map<MethodSignature, List<Method>> accessibles) {
if (m == null) {
return null;
}
MethodSignature sig = new MethodSignature(m);
- List l = (List) accessibles.get(sig);
- if (l == null) {
+ List<Method> ams = accessibles.get(sig);
+ if (ams == null) {
return null;
}
- for (Iterator iterator = l.iterator(); iterator.hasNext(); ) {
- Method am = (Method) iterator.next();
+ for (Method am : ams) {
if (am.getReturnType() == m.getReturnType()) {
return am;
}
@@ -522,12 +529,12 @@ class ClassIntrospector {
return null;
}
- private static Method getFirstAccessibleMethod(MethodSignature sig, Map accessibles) {
- List l = (List) accessibles.get(sig);
- if (l == null || l.isEmpty()) {
+ private static Method getFirstAccessibleMethod(MethodSignature sig, Map<MethodSignature, List<Method>> accessibles) {
+ List<Method> ams = accessibles.get(sig);
+ if (ams == null || ams.isEmpty()) {
return null;
}
- return (Method) l.iterator().next();
+ return ams.get(0);
}
/**
@@ -541,11 +548,12 @@ class ClassIntrospector {
return exposureLevel < BeansWrapper.EXPOSE_SAFE || !UnsafeMethods.isUnsafeMethod(method);
}
- private static Map getArgTypes(Map classMap) {
- Map argTypes = (Map) classMap.get(ARGTYPES_KEY);
+ private static Map<Method, Class<?>[]> getArgTypesByMethod(Map<Object, Object> classInfo) {
+ @SuppressWarnings("unchecked")
+ Map<Method, Class<?>[]> argTypes = (Map<Method, Class<?>[]>) classInfo.get(ARG_TYPES_BY_METHOD_KEY);
if (argTypes == null) {
- argTypes = new HashMap();
- classMap.put(ARGTYPES_KEY, argTypes);
+ argTypes = new HashMap<Method, Class<?>[]>();
+ classInfo.put(ARG_TYPES_BY_METHOD_KEY, argTypes);
}
return argTypes;
}
@@ -557,9 +565,9 @@ class ClassIntrospector {
new MethodSignature("get", new Class[] { Object.class });
private final String name;
- private final Class[] args;
+ private final Class<?>[] args;
- private MethodSignature(String name, Class[] args) {
+ private MethodSignature(String name, Class<?>[] args) {
this.name = name;
this.args = args;
}
@@ -606,8 +614,8 @@ class ClassIntrospector {
cacheClassNames.clear();
clearingCounter++;
- for (Iterator it = modelFactories.iterator(); it.hasNext(); ) {
- Object regedMf = ((WeakReference) it.next()).get();
+ for (WeakReference<Object> regedMfREf : modelFactories) {
+ Object regedMf = regedMfREf.get();
if (regedMf != null) {
if (regedMf instanceof ClassBasedModelFactory) {
((ClassBasedModelFactory) regedMf).clearCache();
@@ -628,14 +636,14 @@ class ClassIntrospector {
*
* @since 2.3.20
*/
- void remove(Class clazz) {
+ void remove(Class<?> clazz) {
synchronized (sharedLock) {
cache.remove(clazz);
cacheClassNames.remove(clazz.getName());
clearingCounter++;
- for (Iterator it = modelFactories.iterator(); it.hasNext(); ) {
- Object regedMf = ((WeakReference) it.next()).get();
+ for (WeakReference<Object> regedMfREf : modelFactories) {
+ Object regedMf = regedMfREf.get();
if (regedMf != null) {
if (regedMf instanceof ClassBasedModelFactory) {
((ClassBasedModelFactory) regedMf).removeFromCache(clazz);
@@ -688,7 +696,7 @@ class ClassIntrospector {
private void registerModelFactory(Object mf) {
// Note that this `synchronized (sharedLock)` is also need for the BeansWrapper constructor to work safely.
synchronized (sharedLock) {
- modelFactories.add(new WeakReference(mf, modelFactoriesRefQueue));
+ modelFactories.add(new WeakReference<Object>(mf, modelFactoriesRefQueue));
removeClearedModelFactoryReferences();
}
}
@@ -703,8 +711,8 @@ class ClassIntrospector {
void unregisterModelFactory(Object mf) {
synchronized (sharedLock) {
- for (Iterator it = modelFactories.iterator(); it.hasNext(); ) {
- Object regedMf = ((Reference) it.next()).get();
+ for (Iterator<WeakReference<Object>> it = modelFactories.iterator(); it.hasNext(); ) {
+ Object regedMf = it.next().get();
if (regedMf == mf) {
it.remove();
}
@@ -714,13 +722,13 @@ class ClassIntrospector {
}
private void removeClearedModelFactoryReferences() {
- Reference cleardRef;
+ Reference<?> cleardRef;
while ((cleardRef = modelFactoriesRefQueue.poll()) != null) {
synchronized (sharedLock) {
- findCleardRef: for (Iterator it = modelFactories.iterator(); it.hasNext(); ) {
+ findClearedRef: for (Iterator<WeakReference<Object>> it = modelFactories.iterator(); it.hasNext(); ) {
if (it.next() == cleardRef) {
it.remove();
- break findCleardRef;
+ break findClearedRef;
}
}
}
@@ -730,20 +738,22 @@ class ClassIntrospector {
// -----------------------------------------------------------------------------------------------------------------
// Extracting from introspection info:
- static Class[] getArgTypes(Map classMap, AccessibleObject methodOrCtor) {
- return (Class[]) ((Map) classMap.get(ARGTYPES_KEY)).get(methodOrCtor);
+ static Class<?>[] getArgTypes(Map<Object, Object> classInfo, Method method) {
+ @SuppressWarnings("unchecked")
+ Map<Method, Class<?>[]> argTypesByMethod = (Map<Method, Class<?>[]>) classInfo.get(ARG_TYPES_BY_METHOD_KEY);
+ return argTypesByMethod.get(method);
}
/**
* Returns the number of introspected methods/properties that should be available via the TemplateHashModel
* interface.
*/
- int keyCount(Class clazz) {
- Map map = get(clazz);
+ int keyCount(Class<?> clazz) {
+ Map<Object, Object> map = get(clazz);
int count = map.size();
if (map.containsKey(CONSTRUCTORS_KEY)) count--;
if (map.containsKey(GENERIC_GET_KEY)) count--;
- if (map.containsKey(ARGTYPES_KEY)) count--;
+ if (map.containsKey(ARG_TYPES_BY_METHOD_KEY)) count--;
return count;
}
@@ -751,11 +761,11 @@ class ClassIntrospector {
* Returns the Set of names of introspected methods/properties that should be available via the TemplateHashModel
* interface.
*/
- Set keySet(Class clazz) {
- Set set = new HashSet(get(clazz).keySet());
+ Set<Object> keySet(Class<?> clazz) {
+ Set<Object> set = new HashSet<Object>(get(clazz).keySet());
set.remove(CONSTRUCTORS_KEY);
set.remove(GENERIC_GET_KEY);
- set.remove(ARGTYPES_KEY);
+ set.remove(ARG_TYPES_BY_METHOD_KEY);
return set;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/277956d9/src/main/java/freemarker/ext/beans/_BeansAPI.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/_BeansAPI.java b/src/main/java/freemarker/ext/beans/_BeansAPI.java
index f469508..a2c648d 100644
--- a/src/main/java/freemarker/ext/beans/_BeansAPI.java
+++ b/src/main/java/freemarker/ext/beans/_BeansAPI.java
@@ -49,7 +49,7 @@ public class _BeansAPI {
return bm.getAsClassicCompatibleString();
}
- public static Object newInstance(Class pClass, Object[] args, BeansWrapper bw)
+ public static Object newInstance(Class<?> pClass, Object[] args, BeansWrapper bw)
throws NoSuchMethodException, IllegalArgumentException, InstantiationException,
IllegalAccessException, InvocationTargetException, TemplateModelException {
return newInstance(getConstructorDescriptor(pClass, args), args, bw);
@@ -60,15 +60,18 @@ public class _BeansAPI {
* than what the Java reflection API provides in that it can handle overloaded constructors. This re-uses the
* overloaded method selection logic of {@link BeansWrapper}.
*/
- private static CallableMemberDescriptor getConstructorDescriptor(Class pClass, Object[] args) throws NoSuchMethodException {
+ private static CallableMemberDescriptor getConstructorDescriptor(Class<?> pClass, Object[] args)
+ throws NoSuchMethodException {
if (args == null) args = CollectionUtils.EMPTY_OBJECT_ARRAY;
final ArgumentTypes argTypes = new ArgumentTypes(args, true);
- final List fixedArgMemberDescs = new ArrayList();
- final List varArgsMemberDescs = new ArrayList();
- final Constructor[] constrs = pClass.getConstructors();
+ final List<ReflectionCallableMemberDescriptor> fixedArgMemberDescs
+ = new ArrayList<ReflectionCallableMemberDescriptor>();
+ final List<ReflectionCallableMemberDescriptor> varArgsMemberDescs
+ = new ArrayList<ReflectionCallableMemberDescriptor>();
+ final Constructor<?>[] constrs = pClass.getConstructors();
for (int i = 0; i < constrs.length; i++) {
- Constructor constr = constrs[i];
+ Constructor<?> constr = constrs[i];
ReflectionCallableMemberDescriptor memberDesc = new ReflectionCallableMemberDescriptor(constr, constr.getParameterTypes());
if (!_MethodUtil.isVarargs(constr)) {
fixedArgMemberDescs.add(memberDesc);
@@ -108,7 +111,7 @@ public class _BeansAPI {
if (constrDesc.isVarargs()) {
// We have to put all the varargs arguments into a single array argument.
- final Class[] paramTypes = constrDesc.getParamTypes();
+ final Class<?>[] paramTypes = constrDesc.getParamTypes();
final int fixedArgCnt = paramTypes.length - 1;
packedArgs = new Object[fixedArgCnt + 1];
@@ -116,7 +119,7 @@ public class _BeansAPI {
packedArgs[i] = args[i];
}
- final Class compType = paramTypes[fixedArgCnt].getComponentType();
+ final Class<?> compType = paramTypes[fixedArgCnt].getComponentType();
final int varArgCnt = args.length - fixedArgCnt;
final Object varArgsArray = Array.newInstance(compType, varArgCnt);
for (int i = 0; i < varArgCnt; i++) {
@@ -136,47 +139,47 @@ public class _BeansAPI {
* @param beansWrapperSubclassFactory Creates a <em>new</em> read-only object wrapper of the desired
* {@link BeansWrapper} subclass.
*/
- public static BeansWrapper getBeansWrapperSubclassSingleton(
- BeansWrapperConfiguration settings,
- Map instanceCache,
- ReferenceQueue instanceCacheRefQue,
- _BeansWrapperSubclassFactory beansWrapperSubclassFactory) {
+ public static <BW extends BeansWrapper, BWC extends BeansWrapperConfiguration> BW getBeansWrapperSubclassSingleton(
+ BWC settings,
+ Map<ClassLoader, Map<BWC, WeakReference<BW>>> instanceCache,
+ ReferenceQueue<BW> instanceCacheRefQue,
+ _BeansWrapperSubclassFactory<BW, BWC> beansWrapperSubclassFactory) {
// BeansWrapper can't be cached across different Thread Context Class Loaders (TCCL), because the result of
// a class name (String) to Class mappings depends on it, and the staticModels and enumModels need that.
// (The ClassIntrospector doesn't have to consider the TCCL, as it only works with Class-es, not class
// names.)
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
- Reference instanceRef;
- Map/*<PropertyAssignments, WeakReference<BeansWrapper>>*/ tcclScopedCache;
+ Reference<BW> instanceRef;
+ Map<BWC, WeakReference<BW>> tcclScopedCache;
synchronized (instanceCache) {
- tcclScopedCache = (Map) instanceCache.get(tccl);
+ tcclScopedCache = instanceCache.get(tccl);
if (tcclScopedCache == null) {
- tcclScopedCache = new HashMap();
+ tcclScopedCache = new HashMap<BWC, WeakReference<BW>>();
instanceCache.put(tccl, tcclScopedCache);
instanceRef = null;
} else {
- instanceRef = (Reference) tcclScopedCache.get(settings);
+ instanceRef = tcclScopedCache.get(settings);
}
}
- BeansWrapper instance = instanceRef != null ? (BeansWrapper) instanceRef.get() : null;
+ BW instance = instanceRef != null ? instanceRef.get() : null;
if (instance != null) { // cache hit
return instance;
}
// cache miss
- settings = (BeansWrapperConfiguration) settings.clone(true); // prevent any aliasing issues
+ settings = clone(settings); // prevent any aliasing issues
instance = beansWrapperSubclassFactory.create(settings);
if (!instance.isWriteProtected()) {
throw new BugException();
}
synchronized (instanceCache) {
- instanceRef = (Reference) tcclScopedCache.get(settings);
- BeansWrapper concurrentInstance = instanceRef != null ? (BeansWrapper) instanceRef.get() : null;
+ instanceRef = tcclScopedCache.get(settings);
+ BW concurrentInstance = instanceRef != null ? instanceRef.get() : null;
if (concurrentInstance == null) {
- tcclScopedCache.put(settings, new WeakReference(instance, instanceCacheRefQue));
+ tcclScopedCache.put(settings, new WeakReference<BW>(instance, instanceCacheRefQue));
} else {
instance = concurrentInstance;
}
@@ -186,14 +189,21 @@ public class _BeansAPI {
return instance;
}
+
+ @SuppressWarnings("unchecked")
+ private static <BWC extends BeansWrapperConfiguration> BWC clone(BWC settings) {
+ return (BWC) settings.clone(true);
+ }
- private static void removeClearedReferencesFromCache(Map instanceCache, ReferenceQueue instanceCacheRefQue) {
- Reference clearedRef;
+ private static <BW extends BeansWrapper, BWC extends BeansWrapperConfiguration>
+ void removeClearedReferencesFromCache(
+ Map<ClassLoader, Map<BWC, WeakReference<BW>>> instanceCache,
+ ReferenceQueue<BW> instanceCacheRefQue) {
+ Reference<? extends BW> clearedRef;
while ((clearedRef = instanceCacheRefQue.poll()) != null) {
synchronized (instanceCache) {
- findClearedRef: for (Iterator it1 = instanceCache.values().iterator(); it1.hasNext(); ) {
- Map tcclScopedCache = (Map) it1.next();
- for (Iterator it2 = tcclScopedCache.values().iterator(); it2.hasNext(); ) {
+ findClearedRef: for (Map<BWC, WeakReference<BW>> tcclScopedCache : instanceCache.values()) {
+ for (Iterator<WeakReference<BW>> it2 = tcclScopedCache.values().iterator(); it2.hasNext(); ) {
if (it2.next() == clearedRef) {
it2.remove();
break findClearedRef;
@@ -207,10 +217,10 @@ public class _BeansAPI {
/**
* For internal use only; don't depend on this, there's no backward compatibility guarantee at all!
*/
- public interface _BeansWrapperSubclassFactory {
+ public interface _BeansWrapperSubclassFactory<BW extends BeansWrapper, BWC extends BeansWrapperConfiguration> {
/** Creates a new read-only {@link BeansWrapper}; used for {@link BeansWrapperBuilder} and such. */
- BeansWrapper create(BeansWrapperConfiguration sa);
+ BW create(BWC sa);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/277956d9/src/main/java/freemarker/ext/util/IdentityHashMap.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/util/IdentityHashMap.java b/src/main/java/freemarker/ext/util/IdentityHashMap.java
index 57bb9db..13e140f 100644
--- a/src/main/java/freemarker/ext/util/IdentityHashMap.java
+++ b/src/main/java/freemarker/ext/util/IdentityHashMap.java
@@ -30,11 +30,12 @@ import java.util.NoSuchElementException;
import java.util.Set;
/**
- * A variant of {@link java.util.HashMap} that uses
- * {@link System#identityHashCode(Object)} for hashing, and reference comparison
- * instead of {@link Object#equals(Object)}. Note that this applies only to keys,
- * and not to values, i.e. {@link #containsValue(Object)} still uses {@link Object#equals(Object)}.
+ * Was used instead of {@link java.util.IdentityHashMap} before that was added to Java itself in Java 1.4.
+ *
+ * @deprecated Use {@link java.util.IdentityHashMap} instead.
*/
+@SuppressWarnings("rawtypes")
+@Deprecated
public class IdentityHashMap
extends AbstractMap
implements Map, Cloneable, java.io.Serializable {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/277956d9/src/main/java/freemarker/ext/util/ModelCache.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/util/ModelCache.java b/src/main/java/freemarker/ext/util/ModelCache.java
index 5a4b3ad..52ac7d1 100644
--- a/src/main/java/freemarker/ext/util/ModelCache.java
+++ b/src/main/java/freemarker/ext/util/ModelCache.java
@@ -23,6 +23,8 @@ import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.Map;
+import java.util.IdentityHashMap;
+
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelAdapter;
@@ -32,8 +34,8 @@ import freemarker.template.TemplateModelAdapter;
*/
public abstract class ModelCache {
private boolean useCache = false;
- private Map modelCache = null;
- private ReferenceQueue refQueue = null;
+ private Map<Object, ModelReference> modelCache = null;
+ private ReferenceQueue<TemplateModel> refQueue = null;
protected ModelCache() {
}
@@ -46,8 +48,8 @@ public abstract class ModelCache {
public synchronized void setUseCache(boolean useCache) {
this.useCache = useCache;
if (useCache) {
- modelCache = new IdentityHashMap();
- refQueue = new ReferenceQueue();
+ modelCache = new IdentityHashMap<Object, ModelReference>();
+ refQueue = new ReferenceQueue<TemplateModel>();
} else {
modelCache = null;
refQueue = null;
@@ -97,7 +99,7 @@ public abstract class ModelCache {
// duplicate wrapper creation. However, this has no harmful side-effects and
// is a lesser performance hit.
synchronized (modelCache) {
- ref = (ModelReference) modelCache.get(object);
+ ref = modelCache.get(object);
}
if (ref != null)
@@ -111,8 +113,9 @@ public abstract class ModelCache {
// Remove cleared references
for (; ; ) {
ModelReference queuedRef = (ModelReference) refQueue.poll();
- if (queuedRef == null)
+ if (queuedRef == null) {
break;
+ }
modelCache.remove(queuedRef.object);
}
// Register new reference
@@ -125,10 +128,10 @@ public abstract class ModelCache {
* When it gets cleared (that is, the model became unreachable)
* it will remove itself from the model cache.
*/
- private static final class ModelReference extends SoftReference {
+ private static final class ModelReference extends SoftReference<TemplateModel> {
Object object;
- ModelReference(TemplateModel ref, Object object, ReferenceQueue refQueue) {
+ ModelReference(TemplateModel ref, Object object, ReferenceQueue<TemplateModel> refQueue) {
super(ref, refQueue);
this.object = object;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/277956d9/src/main/java/freemarker/template/DefaultObjectWrapper.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/DefaultObjectWrapper.java b/src/main/java/freemarker/template/DefaultObjectWrapper.java
index b2f5820..323e1dd 100644
--- a/src/main/java/freemarker/template/DefaultObjectWrapper.java
+++ b/src/main/java/freemarker/template/DefaultObjectWrapper.java
@@ -61,7 +61,7 @@ public class DefaultObjectWrapper extends freemarker.ext.beans.BeansWrapper {
@Deprecated
static final DefaultObjectWrapper instance = new DefaultObjectWrapper();
- static final private Class JYTHON_OBJ_CLASS;
+ static final private Class<?> JYTHON_OBJ_CLASS;
static final private ObjectWrapper JYTHON_WRAPPER;
@@ -133,7 +133,7 @@ public class DefaultObjectWrapper extends freemarker.ext.beans.BeansWrapper {
}
static {
- Class cl;
+ Class<?> cl;
ObjectWrapper ow;
try {
cl = Class.forName("org.python.core.PyObject");
@@ -191,7 +191,7 @@ public class DefaultObjectWrapper extends freemarker.ext.beans.BeansWrapper {
}
return new SimpleDate((java.util.Date) obj, getDefaultDateType());
}
- final Class objClass = obj.getClass();
+ final Class<?> objClass = obj.getClass();
if (objClass.isArray()) {
if (useAdaptersForContainers) {
return DefaultArrayAdapter.adapt(obj, this);
@@ -203,28 +203,28 @@ public class DefaultObjectWrapper extends freemarker.ext.beans.BeansWrapper {
if (obj instanceof Collection) {
if (useAdaptersForContainers) {
if (obj instanceof List) {
- return DefaultListAdapter.adapt((List) obj, this);
+ return DefaultListAdapter.adapt((List<?>) obj, this);
} else {
return forceLegacyNonListCollections
- ? (TemplateModel) new SimpleSequence((Collection) obj, this)
- : (TemplateModel) DefaultNonListCollectionAdapter.adapt((Collection) obj, this);
+ ? (TemplateModel) new SimpleSequence((Collection<?>) obj, this)
+ : (TemplateModel) DefaultNonListCollectionAdapter.adapt((Collection<?>) obj, this);
}
} else {
- return new SimpleSequence((Collection) obj, this);
+ return new SimpleSequence((Collection<?>) obj, this);
}
}
if (obj instanceof Map) {
return useAdaptersForContainers
- ? (TemplateModel) DefaultMapAdapter.adapt((Map) obj, this)
- : (TemplateModel) new SimpleHash((Map) obj, this);
+ ? (TemplateModel) DefaultMapAdapter.adapt((Map<?, ?>) obj, this)
+ : (TemplateModel) new SimpleHash((Map<?, ?>) obj, this);
}
if (obj instanceof Boolean) {
return obj.equals(Boolean.TRUE) ? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
if (obj instanceof Iterator) {
return useAdaptersForContainers
- ? (TemplateModel) DefaultIteratorAdapter.adapt((Iterator) obj, this)
- : (TemplateModel) new SimpleCollection((Iterator) obj, this);
+ ? (TemplateModel) DefaultIteratorAdapter.adapt((Iterator<?>) obj, this)
+ : (TemplateModel) new SimpleCollection((Iterator<?>) obj, this);
}
if (iterableSupport && obj instanceof Iterable) {
return DefaultIterableAdapter.adapt((Iterable<?>) obj, this);
@@ -261,6 +261,7 @@ public class DefaultObjectWrapper extends freemarker.ext.beans.BeansWrapper {
* Converts an array to a java.util.List.
*/
protected Object convertArray(Object arr) {
+ // FM 2.4: Use Arrays.asList instead
final int size = Array.getLength(arr);
ArrayList list = new ArrayList(size);
for (int i = 0; i < size; i++) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/277956d9/src/main/java/freemarker/template/DefaultObjectWrapperBuilder.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/DefaultObjectWrapperBuilder.java b/src/main/java/freemarker/template/DefaultObjectWrapperBuilder.java
index b8f89ba..7a6a027 100644
--- a/src/main/java/freemarker/template/DefaultObjectWrapperBuilder.java
+++ b/src/main/java/freemarker/template/DefaultObjectWrapperBuilder.java
@@ -20,11 +20,11 @@
package freemarker.template;
import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.Map;
import java.util.WeakHashMap;
-import freemarker.ext.beans.BeansWrapper;
import freemarker.ext.beans.BeansWrapperBuilder;
-import freemarker.ext.beans.BeansWrapperConfiguration;
import freemarker.ext.beans._BeansAPI;
/**
@@ -38,9 +38,11 @@ import freemarker.ext.beans._BeansAPI;
*/
public class DefaultObjectWrapperBuilder extends DefaultObjectWrapperConfiguration {
- private final static WeakHashMap/*<ClassLoader, Map<BeansWrapperSettings, WeakReference<DefaultObjectWrapper>>*/
- INSTANCE_CACHE = new WeakHashMap();
- private final static ReferenceQueue INSTANCE_CACHE_REF_QUEUE = new ReferenceQueue();
+ private final static Map<ClassLoader, Map<DefaultObjectWrapperConfiguration, WeakReference<DefaultObjectWrapper>>>
+ INSTANCE_CACHE = new WeakHashMap<
+ ClassLoader, Map<DefaultObjectWrapperConfiguration, WeakReference<DefaultObjectWrapper>>>();
+ private final static ReferenceQueue<DefaultObjectWrapper> INSTANCE_CACHE_REF_QUEUE
+ = new ReferenceQueue<DefaultObjectWrapper>();
/**
* Creates a builder that creates a {@link DefaultObjectWrapper} with the given {@code incompatibleImprovements};
@@ -63,16 +65,16 @@ public class DefaultObjectWrapperBuilder extends DefaultObjectWrapperConfigurati
* a singleton that is also in use elsewhere.
*/
public DefaultObjectWrapper build() {
- return (DefaultObjectWrapper) _BeansAPI.getBeansWrapperSubclassSingleton(
+ return _BeansAPI.getBeansWrapperSubclassSingleton(
this, INSTANCE_CACHE, INSTANCE_CACHE_REF_QUEUE, DefaultObjectWrapperFactory.INSTANCE);
}
private static class DefaultObjectWrapperFactory
- implements _BeansAPI._BeansWrapperSubclassFactory {
+ implements _BeansAPI._BeansWrapperSubclassFactory<DefaultObjectWrapper, DefaultObjectWrapperConfiguration> {
private static final DefaultObjectWrapperFactory INSTANCE = new DefaultObjectWrapperFactory();
- public BeansWrapper create(BeansWrapperConfiguration bwConf) {
+ public DefaultObjectWrapper create(DefaultObjectWrapperConfiguration bwConf) {
return new DefaultObjectWrapper(bwConf, true);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/277956d9/src/main/java/freemarker/template/ObjectWrapperAndUnwrapper.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/ObjectWrapperAndUnwrapper.java b/src/main/java/freemarker/template/ObjectWrapperAndUnwrapper.java
index b48fa5f..7ec4461 100644
--- a/src/main/java/freemarker/template/ObjectWrapperAndUnwrapper.java
+++ b/src/main/java/freemarker/template/ObjectWrapperAndUnwrapper.java
@@ -87,6 +87,6 @@ public interface ObjectWrapperAndUnwrapper extends ObjectWrapper {
*
* @since 2.3.22
*/
- Object tryUnwrapTo(TemplateModel tm, Class targetClass) throws TemplateModelException;
+ Object tryUnwrapTo(TemplateModel tm, Class<?> targetClass) throws TemplateModelException;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/277956d9/src/main/java/freemarker/template/_TemplateAPI.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/_TemplateAPI.java b/src/main/java/freemarker/template/_TemplateAPI.java
index 0fc702a..c55a113 100644
--- a/src/main/java/freemarker/template/_TemplateAPI.java
+++ b/src/main/java/freemarker/template/_TemplateAPI.java
@@ -19,8 +19,6 @@
package freemarker.template;
-import java.util.List;
-import java.util.Map;
import java.util.Set;
import freemarker.cache.CacheStorage;