Interface MemberAccessPolicy

All Known Implementing Classes:
BlacklistMemberAccessPolicy, DefaultMemberAccessPolicy, LegacyDefaultMemberAccessPolicy, MemberSelectorListMemberAccessPolicy, WhitelistMemberAccessPolicy

public interface MemberAccessPolicy
Implement this to restrict what class members (methods, fields, constructors) are accessible from templates. Note, however, that BeansWrapper and its subclasses doesn't discover all members on the first place, and the MemberAccessPolicy just removes from that set of members, never adds to it. Practically speaking, it's the last filter in the chain.

MemberAccessPolicy-s meant to be used inside ObjectWrapper-s, and their existence is transparent for the rest of the system. The instance is usually set via BeansWrapperConfiguration.setMemberAccessPolicy(MemberAccessPolicy) (or if you use DefaultObjectWrapper, with BeansWrapperConfiguration.setMemberAccessPolicy(MemberAccessPolicy)).

As BeansWrapper, and its subclasses, like DefaultObjectWrapper, only discover public members, it's pointless to whitelist non-public members. (Also, while public members declared in non-public classes are discovered by BeansWrapper, Java reflection will not allow accessing those normally, so generally it's not useful to whitelist those either.)

Note BeansWrapper, and its subclasses, like DefaultObjectWrapper, also have an exposureLevel a setting that's applied before the MemberAccessPolicy, also, with BeansWrapper.EXPOSE_ALL the MemberAccessPolicy will be ignored.

Note that if you add TemplateModel-s directly to the data-model, those are not wrapped by the ObjectWrapper (from Configurable.getObjectWrapper()), and so the MemberAccessPolicy won't affect those.

The MemberAccessPolicy is only used during the class introspection phase (which discovers the members of a type, and decides if, and how will they be exposed to templates), and the result of that is cached. So, the speed of an MemberAccessPolicy implementation is usually not too important, as it won't play a role during template execution.

Implementations must be thread-safe, and instances generally should be singletons on JVM level. FreeMarker caches its class metadata in a global (static, JVM-scope) cache for shared use, and the MemberAccessPolicy used is part of the cache key. Thus MemberAccessPolicy instances used at different places in the JVM should be equal according to Object.equals(Object), as far as they implement exactly the same policy. It's not recommended to override Object.equals(Object); use singletons and the default Object.equals(Object) implementation if possible.

Since:
2.3.30
See Also:
DefaultMemberAccessPolicy, WhitelistMemberAccessPolicy, LegacyDefaultMemberAccessPolicy
  • Method Details

    • forClass

      ClassMemberAccessPolicy forClass(Class<?> contextClass)
      Returns the ClassMemberAccessPolicy that encapsulates the member access policy for a given class. ClassMemberAccessPolicy implementations need not be thread-safe. Because class introspection results are cached, and so this method is usually only called once for a given class, the ClassMemberAccessPolicy instances shouldn't be cached by the implementation of this method.
      Parameters:
      contextClass - The exact class of object from which members will be get in the templates.
    • isToStringAlwaysExposed

      boolean isToStringAlwaysExposed()
      If this returns true, we won't invoke the probably more expensive lookup to figure out if Object.toString() (including its overridden variants) is exposed for a given object. If this returns false, then no such optimization is made. This method was introduced as Object.toString() is called frequently, as it's used whenever an object is converted to string, like printed to the output, and it's not even a reflection-based call (we just call Object.toString() in Java). So we try to avoid the overhead of a more generic method call.