{{sidenavigation.sidenavigationExpandLabel}}
{{getMsg('Help_YouAreHere')}}: {{page.title}} {{page.title}}
{{$root.getMsg("downLoadHelpAsPdf")}} {{helpModel.downloadHelpPdfDataStatus}}

Formula Expander Classes - Formula Functions

It is possible to use your own functions in a formula of a report, if these functions are implemented as methods in public (formula expander) Java class(es). To use such "User Defined Functions" in a formula, the following steps are required:

The best practice case is to write a plugin and to register your classes with the marker interface com.inet.report.formula.UserDefinedFunction in the ServerPluginManager. Details on writing a plugin can be found in the chapter Plugins. The following example shows how to register a custom formula expander class.

import com.inet.plugin.*;
import com.inet.userdefined.formular.MyFunction;
...
public void registerExtension( ServerPluginManager spm ) {
    if( spm.isPluginLoaded( "reporting" ) ) {
        spm.register( com.inet.report.formula.UserDefinedFunction.class, new MyFunction() );
    }
}

Alternatively you can use a regular jar file:

  • Copy this jar file into the "lib" directory in the installation directory of i-net Clear Reports.
  • Open the Configuration Manager and add the <classname> to the property 'Formula Expander Class(es)', where classname means the fully qualified name of your class. This property can as well be a semicolon separated list of class names. Please check the classpath used by i-net Clear Reports and the package structure in case ClassNotFoundException occurs at runtime. Alternatively you can use the API to modify the configuration in use.

Now you can write a formula using your user-defined functions by calling them by name. You can create a formula using i-net Designer or i-net Clear Reports API (RDC).

Note: The methods in the specified class have to be public and could be static. In case of non-static methods, a default Constructor without parameters is required.

Note: The return value and the parameter values of the methods have to be one of the following types:

  • com.inet.report.FormulaRange
  • java.lang.Number
  • java.lang.Boolean
  • java.lang.String
  • java.sql.Date
  • java.sql.Time
  • java.sql.Timestamp
  • Object[] of these types

As of version 13 it is possible to use one or more of the following hidden parameters as method parameter in the formula expander class: Engine, HttpSession and HttpServletRequest. This can be useful, for example, to use the Engine API to get user-defined parameters from the report engine. Please note that HttpServletRequest does not work in the i-net Designer.

Formula Optimization

By default, all user-defined functions with static or no parameters are always called once to optimize the internal formula tree. This allows users to use the user-defined function in the record selection, e.g. for i18n - which is stable per locale.

However, the downside of running the user-defined formula is, that statements that should only be called once and only by when actually running the report for a user, e.g. sending an email, also get triggered.

To mitigate this issue, you can use the annotation @DoNotOptimize. Using this annotation, the user-defined function is only run when actually hit in a formula of the report. The downside of using the annotation is, that you can't use this user-defined function in a record selection formula for filtering report data anymore.

Examples

static public String aFunction(String str) {
	return "[" + str + "]"; 
}
 
static public String getUserProperty(String propKey, Engine engine) {
        Properties properties;
	String userProperty = "";
        try {
            properties = engine.getUserProperties();
            if (properties != null) {
                userProperty = (String)properties.get(propertyKey);
            }
        } catch( ReportException e ) {
            e.printStackTrace();
        }
        return userProperty;
}
 
static public Number aFunction(Number d) {
	return new Double( 2.0 * d.doubleValue()); 
}
 
static public String aFunctionToo( Object obj) {
	if (obj instanceof String) {
		return ((String) obj) + " Ha"; 
	} else {
		return null;
	}
}
 
static public Number aFunction(Number i) {
	return new Integer(i.intValue() * 2); 
}
 
public Object[] aFunction(Object[] i){
	Object[] o = new Object[i.length];
	for (int k=0;k<i.length;k++) {
		o[k] = i[i.length-k-1];
	}
	return o;
}
 
@DoNotOptimize
public Boolean aFunction( Number i, FormulaRange range ){
	double lower = ((Number)range.getFrom()).doubleValue();
	double upper = ((Number)range.getTo()).doubleValue();
	double n = i.doubleValue();
 
	if( range.isLowLimitIncluded() ? n < lower : n <= lower ){
		return Boolean.FALSE;
	}
	if( range.isHighLimitIncluded() ? n > upper : n >= upper ){
		return Boolean.FALSE;
	}
		return Boolean.TRUE;
	}
}
 
// Note: This function should do a type check on the range bounds first.

You can find more samples in the Java code samples.

i-net Clear Reports
This application uses cookies to allow login. By continuing to use this application, you agree to the use of cookies.


Help - Formula Expander Classes - Formula Functions