/** * i-net software provides programming examples for illustration only, without warranty * either expressed or implied, including, but not limited to, the implied warranties * of merchantability and/or fitness for a particular purpose. This programming example * assumes that you are familiar with the programming language being demonstrated and * the tools used to create and debug procedures. i-net software support professionals * can help explain the functionality of a particular procedure, but they will not modify * these examples to provide added functionality or construct procedures to meet your * specific needs. * * Copyright © 1999-2025 i-net software GmbH, Berlin, Germany. **/ package com.inet.samples.formula; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Properties; import java.util.regex.Pattern; import javax.imageio.ImageIO; import com.inet.report.Engine; import com.inet.report.formula.UserDefinedFunction; /** * This class shows the usage of user defined Java methods in formulas of an i-net Clear Reports report.
*
* You can find more information about user defined formulas in the section "Programming" of the i-net Clear Reports * documentation.
*
* i-net Clear Reports adds the methods of this class to the functions, that can be used in a formula, if you set the * fully qualified class name (e.g. samples.userdefined_formula.FormulaSample) of this class in the property * "Formula Expander Class". You can find it in the dialog "Customization" of the Configuration Manager.
*
* Also, it is necessary to add this class file to the classpath. You can do this, for example, by creating a jar file * containing this class and all help files (with command * "jar cf formula-sample.jar samples/userdefined_formula/FormulaSample.class samples/userdefined_formula/*.html") and * copying this jar file into the "lib" directory that is included in the installation directory of i-net Clear Reports * or i-net Designer.
*
* Since 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. */ public class FormulaSample implements UserDefinedFunction { /** * Calendar for date operations. You can see this user defined constant in the list of constants in the formula * editor. */ public static final GregorianCalendar GREGCALENDAR = new GregorianCalendar(); /** * Returns an array of length n containing the first even natural numbers, starting with 0. firstEvens(5) will * return [0,2,4,6,8]. * @param n length of returned list of even numbers. * @return Number[] containing the first even natural numbers */ public static Number[] firstEvens( Number n ) { int n_ = n.intValue(); Integer[] evens = new Integer[n_]; for( int i = 0; i < n_; i++ ) { evens[i] = 2 * i; } return evens; } /** * Returns an array of length n containing the first odd natural numbers, starting with 1. firstOdds(5) will return * [1,3,5,7,9]. * @param n length of returned list of odd numbers. * @return Number[] containing the first odd natural numbers */ public static Number[] firstOdds( Number n ) { int n_ = n.intValue(); Integer[] odds = new Integer[n_]; for( int i = 0; i < n_; i++ ) { odds[i] = 2 * i + 1; } return odds; } /** * Returns the factorial of n. Parameter n have to be less than 21. * @param n number to return factorial for * @return factorial of n * @throws IllegalArgumentException if n is 21 or greater */ public static Number factorial( Number n ) { if( !(n.intValue() <= 20) ) { throw new IllegalArgumentException(); } return Long.valueOf( factorial( n.intValue() ) ); } /** * Computes factorial of n. * @param n number to compute factorial for * @return factorial of n */ private static long factorial( int n ) { if( n == 0 ) { return 1; } return n * factorial( n - 1 ); } /** * Validates a alpha-numerical number string of formats ddddd-AAA-dddddd. * @param serialstring string to verify pattern for. * @return Boolean.TRUE if pattern matches, else Boolean.FALSE */ public static Boolean verify( String serialstring ) { return Pattern.matches( "[0-9]{5}-[A-Z]{3}-[0-9]{6}", serialstring ); } /** * Validates a string of formats regex. See Java Doc for details. * @param regex Regular expression to use to verify arg * @param arg string to verify * @return result of Pattern.matches(regex, arg) as Boolean */ public static Boolean verify( String regex, String arg ) { return Pattern.matches( regex, arg ); } /** * Returns if year is a leap year. Use for values of i-net Clear Reports type Date. * @param date date to check whether its year is a leap year. * @return whether the year of the given date is a leap year */ public static Boolean leapYear( java.sql.Date date ) { return GREGCALENDAR.isLeapYear( Calendar.getInstance().get( Calendar.YEAR ) - 1900 ); } /** * Returns if year is a leap year. Use for values of i-net Clear Reports type Datetime. * @param date date time to check whether its year is a leap year * @return whether the year of the given date time is a leap year */ public static Boolean leapYear( java.sql.Timestamp date ) { return GREGCALENDAR.isLeapYear( Calendar.getInstance().get( Calendar.YEAR ) - 1900 ); } /** * This function will roll up the hour field of the time value (in range between 0 and 23). * @param time time object to roll hour up for * @return time with hour rolled up by one */ public static java.sql.Time rollHour( java.sql.Time time ) { GregorianCalendar gCal = new GregorianCalendar( 1970, 1, 1, Calendar.getInstance().get( Calendar.HOUR_OF_DAY ), Calendar.getInstance().get( Calendar.MINUTE ), Calendar.getInstance().get( Calendar.SECOND ) ); gCal.roll( Calendar.HOUR, 1 ); return new java.sql.Time( gCal.getTimeInMillis() ); } /** * Returns true if parity of boolean array args is even. * @param args parameter expected to be a Boolean array * @return Boolean if Boolean array has an even parity * @throws IllegalArgumentException if args is not a Boolean array. */ public static Boolean evenParity( Object[] args ) { int count = 0; for( int i = 0; i < args.length; i++ ) { if( !(args[i] instanceof Boolean) ) { throw new IllegalArgumentException( "Boolean expected." ); } if( args[i].equals( Boolean.TRUE ) ) { count++; } } return count % 2 == 0; } /** * Draws a String "Demo" at Position (10,10) of the image in bytes. If an error occurs, the original * byte[] is returned. * @param bytes image data to draw into * @return the manipulated image; If manipulation fails the original image is returned. */ public static byte[] drawDemoToImage( byte[] bytes ) { try { ByteArrayInputStream bais = new ByteArrayInputStream( bytes ); BufferedImage img = ImageIO.read( bais ); Graphics2D g2d = img.createGraphics(); g2d.drawString( "Demo", 10, 10 ); ByteArrayOutputStream out = new ByteArrayOutputStream(); ImageIO.write( img, "png", out ); return out.toByteArray(); } catch( Exception e ) { e.printStackTrace(); } return bytes; } /** * Returns the value of a user property that has been set either with engine.setUserProperties(), checkProperties() * or in the report URL. * @param propertyKey the key of the property * @param engine the report engine instance * @return the user property value or an empty string, if it does not exists */ static public String getUserProperty( String propertyKey, Engine engine ) { Properties properties = engine.getUserProperties(); if( properties != null ) { return properties.getProperty( propertyKey, "" ); } else { return ""; } } }