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

net.sf.mmm.util.pojo.path.api.PojoPathFunction Maven / Gradle / Ivy

There is a newer version: 8.7.0
Show newest version
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
 * http://www.apache.org/licenses/LICENSE-2.0 */
package net.sf.mmm.util.pojo.path.api;

/**
 * This is the call-back interface for a {@link PojoPathFunction} that allows to add custom functionality to a
 * {@link PojoPathNavigator}. 
* This can help for various use-cases such as retrieving objects from a database (an O/R-mapper), adding custom logic * for calculated or combined attributes, etc.
* A {@link PojoPathFunction} is {@link PojoPathFunctionManager#getFunction(String) registered} in a * {@link PojoPathFunctionManager} under a specific name ( {@code functionName}). The {@link PojoPathFunction} itself * does NOT contain that name and gets this name back as parameter when it is invoked. Therefore the same * {@link PojoPathFunction} instance can be {@link PojoPathFunctionManager#getFunction(String) registered} with * different names and can behave different according to the name it was invoked for.
* * @param is the generic {@link #getInputClass() input-type}. * @param is the generic {@link #getValueClass() value-type} * * @author Joerg Hohwiller (hohwille at users.sourceforge.net) * @since 1.1.0 */ public interface PojoPathFunction { /** * This is the prefix used to indicate a {@link PojoPathFunction} in a {@link PojoPath}. The value ({@value}) will * never change. It is NOT necessary to use this constant to construct a {@link PojoPath}.
* For example the {@link PojoPath#getSegment() segment} {@code @myFunction} as part of a {@link PojoPath} such as * {@code foo.bar.@myFunction} indicates that the {@link PojoPathFunction} * {@link PojoPathFunctionManager#getFunction(String) named} {@code myFunction} should be invoked to * {@link #get(Object, String, PojoPathContext) get}, {@link #create(Object, String, PojoPathContext) create} or * {@link #set(Object, String, Object, PojoPathContext) set} the value for {@code @myFunction} based on the result * retrieved for {@code foo.bar}. * * @see PojoPath#getFunction() */ char FUNCTION_NAME_PREFIX = '@'; /** * This method determines if this {@link PojoPathFunction} is deterministic. In this case it has to guarantee that * repetitive calls of {@link #get(Object, String, PojoPathContext) get} with the same (unmodified) actual * {@link net.sf.mmm.util.pojo.api.Pojo} will produce the same result.
* Typically a {@link PojoPathFunction} should be deterministic. However in some cases the calculation of a * {@link PojoPathFunction} may depend on the current time or a random value and will therefore be indeterministic. *
* If a {@link PojoPathFunction} is indeterministic, the {@link PojoPathContext#getCache() caching} will disabled for * its result and further traversals.
* Of course this method has to be deterministic and should always return the same boolean result for the same * instance. * * @return {@code true} if this function is deterministic, {@code false} otherwise. */ boolean isDeterministic(); /** * This method gets the input-type of this function. It is the type of the {@link net.sf.mmm.util.pojo.api.Pojo}s this * function operates on. * * @return the input class. */ Class getInputClass(); /** * This method gets the output-type (or return-type) of this function. It is the type of the value this function * traverses to, starting from the {@link #getInputClass() input}- {@link net.sf.mmm.util.pojo.api.Pojo}. * * @return the output class. */ Class getValueClass(); /** * This method gets the value of this function. It is invoked by {@link PojoPathNavigator}. * {@link PojoPathNavigator#get(Object, String, PojoPathMode, PojoPathContext) get} independent of the * {@link PojoPathMode}. A regular implementation should only return what is already there. However in specific cases * this may NOT (initially) be available from the given {@link net.sf.mmm.util.pojo.api.Pojo} {@code actual} and * therefore be retrieved from somewhere else (e.g. a database using a primary key given via a * {@link PojoPathContext#getProperties() property} of the given {@code context}). Further it can be legal to modify * the {@code actual} {@link net.sf.mmm.util.pojo.api.Pojo} e.g. by attaching the externally retrieved result. * * @param input is the actual {@link net.sf.mmm.util.pojo.api.Pojo} where this function is invoked on. Typically the * returned value should be retrieved via this object. * @param functionName is the name under which this {@link PojoPathFunction} was invoked via the * {@link PojoPathNavigator} excluding the {@link #FUNCTION_NAME_PREFIX}. * @param context is the {@link PojoPathContext} providing additional context information. Objects traversed between * {@code actual} and the returned value should be {@link PojoPathRecognizer#recognize(Object, PojoPath) * recognized} via the {@link PojoPathContext#getRecognizer() recognizer}. * @return the value of this function or {@code null} if NOT available. */ VALUE get(IN input, String functionName, PojoPathContext context); /** * This method creates an appropriate new value. It is invoked by {@link PojoPathNavigator}. * {@link PojoPathNavigator#get(Object, String, PojoPathMode, PojoPathContext) get} if the mode is * {@link PojoPathMode#CREATE_IF_NULL} after {@link #get(Object, String, PojoPathContext) get} returned {@code null}. *
* A typical implementation may create a new instance of <VALUE> via the {@link PojoPathContext#getPojoFactory() * pojo-factory}. Further in most cases the created value instance will be attached to the given {@code actual} * {@link net.sf.mmm.util.pojo.api.Pojo}. * * @param input is the actual {@link net.sf.mmm.util.pojo.api.Pojo} where this function is invoked on. Typically the * returned value should be retrieved via this object. * @param functionName is the name under which this {@link PojoPathFunction} was invoked via the * {@link PojoPathNavigator} excluding the {@link #FUNCTION_NAME_PREFIX}. * @param context is the {@link PojoPathContext} providing additional context information. Objects traversed between * {@code actual} and the returned value should be {@link PojoPathRecognizer#recognize(Object, PojoPath) * recognized} via the {@link PojoPathContext#getRecognizer() recognizer}. * @return the created value. It may be {@code null} if creation is NOT possible. However returning {@code null} here * will cause the {@link PojoPathNavigator} to fail with an exception. */ VALUE create(IN input, String functionName, PojoPathContext context); /** * This method sets the given {@code value} for the given {@code actual} {@link net.sf.mmm.util.pojo.api.Pojo}.
* After this method has been successfully invoked, the method {@link #get(Object, String, PojoPathContext) get} * should return the same {@code value} for identical arguments. * * @param input is the actual {@link net.sf.mmm.util.pojo.api.Pojo} where this function is invoked on. Typically the * given {@code value} should be set in this object. * @param functionName is the name under which this {@link PojoPathFunction} was invoked via the * {@link PojoPathNavigator} excluding the {@link #FUNCTION_NAME_PREFIX}. * @param value is the value to set. * @param context is the {@link PojoPathContext} providing additional context information. Objects traversed between * {@code actual} and the returned value should be {@link PojoPathRecognizer#recognize(Object, PojoPath) * recognized} via the {@link PojoPathContext#getRecognizer() recognizer}. * @return the previous value that has been replaced or {@code null}. */ VALUE set(IN input, String functionName, VALUE value, PojoPathContext context); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy