All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.klojang.templates.Accessor Maven / Gradle / Ivy

The newest version!
package org.klojang.templates;

import java.util.function.IntFunction;

/**
 * Accessors are used to extract values from objects. The {@link RenderSession} uses
 * them to extract values from the objects passed to
 * {@link RenderSession#insert(Object) insert()} and
 * {@link RenderSession#populate(String, Object) populate()}. Object
 * access is name-based and requires a mapping between template variables and bean
 * properties or map keys. By default, Klojang Templates assumes an as-is
 * mapping between the two, but you can use {@linkplain NameMapper name mappers} for
 * more sophisticated mappings.
 *
 * @param  the type of the source data object
 * @author Ayco Holleman
 * @see AccessorRegistry
 */
@FunctionalInterface
public interface Accessor {

  /**
   * 

* The value that should be returned by accessors if a template variable * cannot be mapped to a value in the source data object. {@code Accessor} * implementations should not throw an exception and they should not return * {@code null} in this case. *

*

Null vs. UNDEFINED

*

* There is a subtle difference in how a {@link RenderSession} treats {@code null} * values versus how it treats {@code UNDEFINED}. {@code null} is a valid and * legitimate value for a template variable. If the value of a bean property or map key * is {@code null}, the corresponding template variable will be set to * whatever {@code null} is stringified to —. The * {@linkplain Stringifier#DEFAULT default stringifier} stringifies {@code null} to an * empty string. If, on the other hand, the {@code RenderSession} receives * {@code UNDEFINED} as the value for a template variable, it will just skip * setting that variable. By itself this will make no difference when the template * is rendered. An unset variable will be replaced with "nothing" — * i.e. an empty string. However, it does make a difference * if you want to set all unset variables to some default value after you have * populated your template with model objects, hash maps, and/or anything else for * which you have defined an accessor: *

*
{@code
   * CompanyDao dao = new CompanyDao();
   * Template template = Template.fromResource(getClass(), "/views/companies.html");
   * RenderSession session = template.newRenderSession();
   * session.populate("companies", dao.list());
   * session.getAllUnsetVariables().forEach(var -> session.setPath(var, i -> "(unknown)");
   * }
*

* You can make the {@code RenderSession} treat {@code null} just like * {@code UNDEFINED}: *

*
{@code
   * AccessorRegistry accessors = AccessorRegistry.build()
   *    .nullEqualsUndefined(true);
   *    .freeze();
   * Template template = Template.fromResource(getClass(), "/views/companies.html");
   * RenderSession session = template.newRenderSession(accessors);
   * }
* * @see AccessorRegistry.Builder#nullEqualsUndefined(boolean) * @see RenderSession#setPath(String, IntFunction) */ Object UNDEFINED = new Object(); /** * Returns the value identified by the specified name from the specified source * data object. If the source data object is a {@code Map}, {@code name} would * likely be a map key; if it is a JavaBean, {@code name} would likely be a bean * property. However, it is up to individual {@code Accessor} implementations to * determine the type of objects they provide access to, and how names are to be * interpreted. * * @param data the data to be accessed * @param name the name by which to retrieve the desired value from the data * @return the value */ Object access(T data, String name); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy