| Method from freemarker.ext.beans.BeansWrapper Detail: |
public static Object coerceBigDecimal(BigDecimal bd,
Class formalType) {
// int is expected in most situations, so we check it first
if(formalType == Integer.TYPE || formalType == Integer.class) {
return new Integer(bd.intValue());
}
else if(formalType == Double.TYPE || formalType == Double.class) {
return new Double(bd.doubleValue());
}
else if(formalType == Long.TYPE || formalType == Long.class) {
return new Long(bd.longValue());
}
else if(formalType == Float.TYPE || formalType == Float.class) {
return new Float(bd.floatValue());
}
else if(formalType == Short.TYPE || formalType == Short.class) {
return new Short(bd.shortValue());
}
else if(formalType == Byte.TYPE || formalType == Byte.class) {
return new Byte(bd.byteValue());
}
else if(BIGINTEGER_CLASS.isAssignableFrom(formalType)) {
return bd.toBigInteger();
}
return bd;
}
|
public static void coerceBigDecimals(AccessibleObject callable,
Object[] args) {
Class[] formalTypes = null;
for(int i = 0; i < args.length; ++i) {
Object arg = args[i];
if(arg instanceof BigDecimal) {
if(formalTypes == null) {
if(callable instanceof Method) {
formalTypes = ((Method)callable).getParameterTypes();
}
else if(callable instanceof Constructor) {
formalTypes = ((Constructor)callable).getParameterTypes();
}
else {
throw new IllegalArgumentException("Expected method or "
+ " constructor; callable is " +
callable.getClass().getName());
}
}
args[i] = coerceBigDecimal((BigDecimal)arg, formalTypes[i]);
}
}
}
Converts any BigDecimal s in the passed array to the type of
the corresponding formal argument of the method. |
public static void coerceBigDecimals(Class[] formalTypes,
Object[] args) {
int typeLen = formalTypes.length;
int argsLen = args.length;
int min = Math.min(typeLen, argsLen);
for(int i = 0; i < min; ++i) {
Object arg = args[i];
if(arg instanceof BigDecimal) {
args[i] = coerceBigDecimal((BigDecimal)arg, formalTypes[i]);
}
}
if(argsLen > typeLen) {
Class varArgType = formalTypes[typeLen - 1];
for(int i = typeLen; i < argsLen; ++i) {
Object arg = args[i];
if(arg instanceof BigDecimal) {
args[i] = coerceBigDecimal((BigDecimal)arg, varArgType);
}
}
}
}
Converts any BigDecimal s in the passed array to the type of
the corresponding formal argument of the method. |
static Class[] getArgTypes(Map classMap,
AccessibleObject methodOrCtor) {
return (Class[])((Map)classMap.get(ARGTYPES)).get(methodOrCtor);
}
|
Map getClassKeyMap(Class clazz) {
Map map;
synchronized(classCache)
{
map = (Map)classCache.get(clazz);
if(map == null)
{
introspectClassInternal(clazz);
map = (Map)classCache.get(clazz);
}
}
return map;
}
|
protected int getDefaultDateType() {
return defaultDateType;
}
|
public static final BeansWrapper getDefaultInstance() {
return INSTANCE;
}
Returns the default instance of the wrapper. This instance is used
when you construct various bean models without explicitly specifying
a wrapper. It is also returned by
freemarker.template.ObjectWrapper#BEANS_WRAPPER
and this is the sole instance that is used by the JSP adapter.
You can modify the properties of the default instance (caching,
exposure level, null model) to affect its operation. By default, the
default instance is not caching, uses the EXPOSE_SAFE
exposure level, and uses null reference as the null model. |
public TemplateHashModel getEnumModels() {
if(enumModels == null) {
throw new UnsupportedOperationException(
"Enums not supported on pre-1.5 JRE");
}
return enumModels;
}
Returns a hash model that represents the so-called class enum models.
Every class' enum model is itself a hash through which you can access
enum value declared by the specified class, assuming that class is an
enumeration. To obtain an enum model for a class, get the element of this
hash with the fully qualified class name. For example, if you place this
hash model inside the root data model under name "enums", you can use
i.e. statics["java.math.RoundingMode"].UP to access the
java.math.RoundingMode#UP value. |
int getExposureLevel() {
return exposureLevel;
}
|
protected TemplateModel getInstance(Object object,
ModelFactory factory) {
return factory.create(object, this);
} Deprecated! override - #getModelFactory(Class) instead. Using this
method will now bypass wrapper caching (if it is enabled) and always
result in creation of a new wrapper. This method will be removed in 2.4
|
protected ModelFactory getModelFactory(Class clazz) {
if(Map.class.isAssignableFrom(clazz)) {
return simpleMapWrapper ? SimpleMapModel.FACTORY : MapModel.FACTORY;
}
if(Collection.class.isAssignableFrom(clazz)) {
return CollectionModel.FACTORY;
}
if(Number.class.isAssignableFrom(clazz)) {
return NumberModel.FACTORY;
}
if(Date.class.isAssignableFrom(clazz)) {
return DateModel.FACTORY;
}
if(Boolean.class == clazz) { // Boolean is final
return BOOLEAN_FACTORY;
}
if(ResourceBundle.class.isAssignableFrom(clazz)) {
return ResourceBundleModel.FACTORY;
}
if(Iterator.class.isAssignableFrom(clazz)) {
return ITERATOR_FACTORY;
}
if(Enumeration.class.isAssignableFrom(clazz)) {
return ENUMERATION_FACTORY;
}
if(clazz.isArray()) {
return ArrayModel.FACTORY;
}
return StringModel.FACTORY;
}
|
public ObjectWrapper getOuterIdentity() {
return outerIdentity;
}
|
public TemplateHashModel getStaticModels() {
return staticModels;
}
Returns a hash model that represents the so-called class static models.
Every class static model is itself a hash through which you can call
static methods on the specified class. To obtain a static model for a
class, get the element of this hash with the fully qualified class name.
For example, if you place this hash model inside the root data model
under name "statics", you can use i.e. statics["java.lang.
System"]. currentTimeMillis() to call the java.lang.System#currentTimeMillis() method. |
void introspectClass(Class clazz) {
synchronized(classCache)
{
if(!classCache.containsKey(clazz))
{
introspectClassInternal(clazz);
}
}
}
|
TemplateModel invokeMethod(Object object,
Method method,
Object[] args) throws InvocationTargetException, TemplateModelException, IllegalAccessException {
Object retval = method.invoke(object, args);
return
method.getReturnType() == Void.TYPE
? TemplateModel.NOTHING
: getOuterIdentity().wrap(retval);
}
Invokes the specified method, wrapping the return value. The specialty
of this method is that if the return value is null, and the return type
of the invoked method is void, TemplateModel#NOTHING is returned. |
public boolean isExposeFields() {
return exposeFields;
}
|
boolean isMethodsShadowItems() {
return methodsShadowItems;
}
|
boolean isSafeMethod(Method method) {
return exposureLevel < EXPOSE_SAFE || !UNSAFE_METHODS.contains(method);
}
|
public boolean isSimpleMapWrapper() {
return simpleMapWrapper;
}
|
public boolean isStrict() {
return strict;
}
|
int keyCount(Class clazz) {
Map map = getClassKeyMap(clazz);
int count = map.size();
if (map.containsKey(CONSTRUCTORS))
count--;
if (map.containsKey(GENERIC_GET_KEY))
count--;
if (map.containsKey(ARGTYPES))
count--;
return count;
}
|
Set keySet(Class clazz) {
Set set = new HashSet(getClassKeyMap(clazz).keySet());
set.remove(CONSTRUCTORS);
set.remove(GENERIC_GET_KEY);
set.remove(ARGTYPES);
return set;
}
|
public Object newInstance(Class clazz,
List arguments) throws TemplateModelException {
try
{
introspectClass(clazz);
Map classInfo = (Map)classCache.get(clazz);
Object ctors = classInfo.get(CONSTRUCTORS);
if(ctors == null)
{
throw new TemplateModelException("Class " + clazz.getName() +
" has no public constructors.");
}
Constructor ctor = null;
Object[] objargs;
if(ctors instanceof SimpleMemberModel)
{
SimpleMemberModel smm = (SimpleMemberModel)ctors;
ctor = (Constructor)smm.getMember();
objargs = smm.unwrapArguments(arguments, this);
}
else if(ctors instanceof MethodMap)
{
MethodMap methodMap = (MethodMap)ctors;
MemberAndArguments maa =
methodMap.getMemberAndArguments(arguments);
objargs = maa.getArgs();
ctor = (Constructor)maa.getMember();
}
else
{
// Cannot happen
throw new Error();
}
return ctor.newInstance(objargs);
}
catch (TemplateModelException e)
{
throw e;
}
catch (Exception e)
{
throw new TemplateModelException(
"Could not create instance of class " + clazz.getName(), e);
}
}
|
public synchronized void setDefaultDateType(int defaultDateType) {
this.defaultDateType = defaultDateType;
}
Sets the default date type to use for date models that result from
a plain java.util.Date instead of java.sql.Date or
java.sql.Time or java.sql.Timestamp. Default value is
TemplateDateModel#UNKNOWN . |
public void setExposeFields(boolean exposeFields) {
this.exposeFields = exposeFields;
}
Controls whether public instance fields of classes are exposed to
templates. |
public void setExposureLevel(int exposureLevel) {
if(exposureLevel < EXPOSE_ALL || exposureLevel > EXPOSE_NOTHING)
{
throw new IllegalArgumentException("Illegal exposure level " + exposureLevel);
}
this.exposureLevel = exposureLevel;
}
Sets the method exposure level. By default, set to EXPOSE_SAFE. |
public synchronized void setMethodsShadowItems(boolean methodsShadowItems) {
this.methodsShadowItems = methodsShadowItems;
}
Sets whether methods shadow items in beans. When true (this is the
default value), ${object.name} will first try to locate
a bean method or property with the specified name on the object, and
only if it doesn't find it will it try to call
object.get(name), the so-called "generic get method" that
is usually used to access items of a container (i.e. elements of a map).
When set to false, the lookup order is reversed and generic get method
is called first, and only if it returns null is method lookup attempted. |
public void setNullModel(TemplateModel nullModel) {
this.nullModel = nullModel;
}
Sets the null model. This model is returned from the
#wrap(Object) method whenever the underlying object
reference is null. It defaults to null reference, which is dealt
with quite strictly on engine level, however you can substitute an
arbitrary (perhaps more lenient) model, such as
freemarker.template.TemplateScalarModel#EMPTY_STRING . |
public void setOuterIdentity(ObjectWrapper outerIdentity) {
this.outerIdentity = outerIdentity;
}
When wrapping an object, the BeansWrapper commonly needs to wrap
"sub-objects", for example each element in a wrapped collection.
Normally it wraps these objects using itself. However, this makes
it difficult to delegate to a BeansWrapper as part of a custom
aggregate ObjectWrapper. This method lets you set the ObjectWrapper
which will be used to wrap the sub-objects. |
public void setSimpleMapWrapper(boolean simpleMapWrapper) {
this.simpleMapWrapper = simpleMapWrapper;
}
By default the BeansWrapper wraps classes implementing
java.util.Map using MapModel . Setting this flag will
cause it to use a SimpleMapModel instead. The biggest
difference is that when using a SimpleMapModel , the
map will be visible as TemplateHashModelEx,
and the subvariables will be the content of the map,
without the other methods and properties of the map object. |
public void setStrict(boolean strict) {
this.strict = strict;
}
Specifies if an attempt to read a bean property that doesn't exist in the
wrapped object should throw an InvalidPropertyException .
If this property is false (the default) then an attempt to read
a missing bean property is the same as reading an existing bean property whose
value is null. The template can't tell the difference, and thus always
can use ?default('something') and ?exists and similar built-ins
to handle the situation.
If this property is true then an attempt to read a bean propertly in
the template (like myBean.aProperty) that doesn't exist in the bean
object (as opposed to just holding null value) will cause
InvalidPropertyException , which can't be suppressed in the template
(not even with myBean.noSuchProperty?default('something')). This way
?default('something') and ?exists and similar built-ins can be used to
handle existing properties whose value is null, without the risk of
hiding typos in the property names. Typos will always cause error. But mind you, it
goes against the basic approach of FreeMarker, so use this feature only if you really
know what are you doing. |
public void setUseCache(boolean useCache) {
modelCache.setUseCache(useCache);
}
Sets whether this wrapper caches model instances. Default is false.
When set to true, calling #wrap(Object) multiple times for
the same object will likely return the same model (although there is
no guarantee as the cache items can be cleared anytime). |
public Object unwrap(TemplateModel model) throws TemplateModelException {
return unwrap(model, OBJECT_CLASS);
}
|
public Object unwrap(TemplateModel model,
Class hint) throws TemplateModelException {
return unwrap(model, hint, null);
}
|
public TemplateModel wrap(Object object) throws TemplateModelException {
if(object == null)
return nullModel;
return modelCache.getInstance(object);
}
Wraps the object with a template model that is most specific for the object's
class. Specifically:
- if the object is null, returns the null model ,
- if the object is a Number returns a NumberModel for it,
- if the object is a Date returns a DateModel for it,
- if the object is a Boolean returns
freemarker.template.TemplateBooleanModel#TRUE or
freemarker.template.TemplateBooleanModel#FALSE
- if the object is already a TemplateModel, returns it unchanged,
- if the object is an array, returns a ArrayModel for it
- if the object is a Map, returns a MapModel for it
- if the object is a Collection, returns a CollectionModel for it
- if the object is an Iterator, returns a IteratorModel for it
- if the object is an Enumeration, returns a EnumerationModel for it
- if the object is a String, returns a StringModel for it
- otherwise, returns a generic BeanModel for it.
|