/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2001 - 2013 Object Refinery Ltd, Pentaho Corporation and Contributors.. All rights reserved.
*/
package org.pentaho.reporting.engine.classic.core.filter.types;
import org.pentaho.reporting.engine.classic.core.AttributeNames;
import org.pentaho.reporting.engine.classic.core.ReportElement;
import org.pentaho.reporting.engine.classic.core.ResourceBundleFactory;
import org.pentaho.reporting.engine.classic.core.function.ExpressionRuntime;
import org.pentaho.reporting.libraries.base.util.IOUtils;
import org.pentaho.reporting.libraries.base.util.StringUtils;
import org.pentaho.reporting.libraries.formula.EvaluationException;
import org.pentaho.reporting.libraries.formula.typing.ArrayCallback;
import org.pentaho.reporting.libraries.xmlns.common.ParserUtil;
import java.math.BigDecimal;
import java.sql.Clob;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
public class ElementTypeUtils {
private static final Number[] EMPTY_NUMBERS = new Number[0];
private ElementTypeUtils() {
}
public static Object queryFieldName( final ReportElement element ) {
if ( element == null ) {
throw new NullPointerException( "Element must never be null." );
}
final Object attribute = element.getAttribute( AttributeNames.Core.NAMESPACE, AttributeNames.Core.FIELD );
if ( attribute != null ) {
return attribute;
}
return null;
}
public static Object queryStaticValue( final ReportElement element ) {
if ( element == null ) {
throw new NullPointerException( "Element must never be null." );
}
final Object attribute = element.getAttribute( AttributeNames.Core.NAMESPACE, AttributeNames.Core.VALUE );
if ( attribute != null ) {
return attribute;
}
return null;
}
public static Object queryFieldOrValue( final ExpressionRuntime runtime, final ReportElement element ) {
if ( runtime == null ) {
throw new NullPointerException( "Runtime must never be null." );
}
if ( element == null ) {
throw new NullPointerException( "Element must never be null." );
}
// This has been possibly computed by the system using a formula or other attribute-expression.
final Object value = element.getAttribute( AttributeNames.Core.NAMESPACE, AttributeNames.Core.VALUE );
if ( value != null ) {
return value;
}
final Object field = element.getAttribute( AttributeNames.Core.NAMESPACE, AttributeNames.Core.FIELD );
if ( field != null ) {
return runtime.getDataRow().get( String.valueOf( field ) );
}
return null;
}
public static String queryResourceId( final ExpressionRuntime runtime, final ReportElement element ) {
if ( runtime == null ) {
throw new NullPointerException( "Runtime must never be null." );
}
if ( element == null ) {
throw new NullPointerException( "Element must never be null." );
}
final Object resourceId =
element.getAttribute( AttributeNames.Core.NAMESPACE, AttributeNames.Core.RESOURCE_IDENTIFIER );
if ( resourceId != null ) {
return String.valueOf( resourceId );
}
return runtime.getConfiguration().getConfigProperty( ResourceBundleFactory.DEFAULT_RESOURCE_BUNDLE_CONFIG_KEY );
}
public static String toString( final Object object ) {
if ( object == null ) {
return null;
}
if ( object instanceof String ) {
return (String) object;
}
if ( object instanceof Clob ) {
final Clob clob = (Clob) object;
try {
return IOUtils.getInstance().readClob( clob );
} catch ( Exception e ) {
return null;
}
}
if ( object.getClass().isArray() ) {
if ( object instanceof char[] ) {
return new String( (char[]) object );
}
if ( object instanceof Object[] ) {
final StringBuilder b = new StringBuilder();
final Object[] array = (Object[]) object;
for ( int i = 0; i < array.length; i++ ) {
if ( i != 0 ) {
b.append( ", " );
}
b.append( toString( array[i] ) );
}
return b.toString();
}
if ( object instanceof byte[] ) {
final StringBuilder b = new StringBuilder();
final byte[] array = (byte[]) object;
for ( int i = 0; i < array.length; i++ ) {
if ( i != 0 ) {
b.append( ", " );
}
b.append( array[i] );
}
return b.toString();
}
if ( object instanceof short[] ) {
final StringBuilder b = new StringBuilder();
final short[] array = (short[]) object;
for ( int i = 0; i < array.length; i++ ) {
if ( i != 0 ) {
b.append( ", " );
}
b.append( array[i] );
}
return b.toString();
}
if ( object instanceof boolean[] ) {
final StringBuilder b = new StringBuilder();
final boolean[] array = (boolean[]) object;
for ( int i = 0; i < array.length; i++ ) {
if ( i != 0 ) {
b.append( ", " );
}
b.append( array[i] );
}
return b.toString();
}
if ( object instanceof int[] ) {
final StringBuilder b = new StringBuilder();
final int[] array = (int[]) object;
for ( int i = 0; i < array.length; i++ ) {
if ( i != 0 ) {
b.append( ", " );
}
b.append( array[i] );
}
return b.toString();
}
if ( object instanceof long[] ) {
final StringBuilder b = new StringBuilder();
final long[] array = (long[]) object;
for ( int i = 0; i < array.length; i++ ) {
if ( i != 0 ) {
b.append( ", " );
}
b.append( array[i] );
}
return b.toString();
}
if ( object instanceof float[] ) {
final StringBuilder b = new StringBuilder();
final float[] array = (float[]) object;
for ( int i = 0; i < array.length; i++ ) {
if ( i != 0 ) {
b.append( ", " );
}
b.append( array[i] );
}
return b.toString();
}
if ( object instanceof double[] ) {
final StringBuilder b = new StringBuilder();
final double[] array = (double[]) object;
for ( int i = 0; i < array.length; i++ ) {
if ( i != 0 ) {
b.append( ", " );
}
b.append( array[i] );
}
return b.toString();
}
}
return String.valueOf( object );
}
public static Number getNumberAttribute( final ReportElement e, final String namespace, final String name,
final Number defaultValue ) {
final Object val = e.getAttribute( namespace, name );
if ( val == null ) {
return defaultValue;
}
if ( val instanceof Number ) {
return (Number) val;
}
return defaultValue;
}
public static int getIntAttribute( final ReportElement e, final String namespace, final String name,
final int defaultValue ) {
final Object val = e.getAttribute( namespace, name );
if ( val == null ) {
return defaultValue;
}
if ( val instanceof Number ) {
final Number nval = (Number) val;
return nval.intValue();
}
return ParserUtil.parseInt( String.valueOf( val ), defaultValue );
}
public static String getStringAttribute( final ReportElement e, final String namespace, final String name,
final String defaultValue ) {
final Object val = e.getAttribute( namespace, name );
if ( val == null ) {
return defaultValue;
}
return String.valueOf( val );
}
public static boolean getBooleanAttribute( final ReportElement e, final String namespace, final String name,
final boolean defaultValue ) {
final Object val = e.getAttribute( namespace, name );
if ( val == null ) {
return defaultValue;
}
if ( val instanceof Boolean ) {
final Boolean nval = (Boolean) val;
return nval.booleanValue();
}
return ParserUtil.parseBoolean( String.valueOf( val ), defaultValue );
}
public static Number[] getData( final Object o ) {
final ArrayList<Number> numbers = new ArrayList<Number>();
try {
if ( o instanceof ArrayCallback ) {
final ArrayCallback acb = (ArrayCallback) o;
final int rowCount = acb.getRowCount();
final int colCount = acb.getColumnCount();
for ( int row = 0; row < rowCount; row++ ) {
for ( int column = 0; column < colCount; column++ ) {
numbers.add( (Number) acb.getValue( row, column ) );
}
}
return numbers.toArray( new Number[numbers.size()] );
}
if ( o instanceof List ) {
final List<?> l = (List<?>) o;
for ( int i = 0; i < l.size(); i++ ) {
final Object value = l.get( i );
if ( value instanceof Number ) {
numbers.add( (Number) value );
} else if ( value instanceof String ) {
numbers.add( new BigDecimal( (String) value ) );
}
}
return numbers.toArray( new Number[numbers.size()] );
}
if ( o instanceof Object[] ) {
final Object[] l = (Object[]) o;
arrayToList( numbers, l );
return numbers.toArray( new Number[numbers.size()] );
}
if ( o instanceof String ) {
return toBigDecimalList( (String) o, "," );
}
if ( o instanceof Number ) {
numbers.add( (Number) o );
return numbers.toArray( new Number[numbers.size()] );
}
} catch ( final NumberFormatException nfe ) {
// fall through...
} catch ( EvaluationException e ) {
// ignore ..
}
return null;
}
private static void arrayToList( final ArrayList<Number> numbers, final Object[] l ) {
for ( int i = 0; i < l.length; i++ ) {
final Object value = l[i];
if ( value instanceof Number ) {
numbers.add( (Number) value );
} else if ( value instanceof String ) {
numbers.add( new BigDecimal( (String) value ) );
} else if ( value instanceof Object[] ) {
final Object[] innerArray = (Object[]) value;
arrayToList( numbers, innerArray );
}
}
}
/**
* Converts the given string into a array of <code>BigDecimal</code> numbers using the given separator as splitting
* argument.<br/>
* Take care that <code>BigDecimal</code> string constructor do not support inputs like "10f", "5d" ...
*
* @param s
* the string to be converted.
* @param sep
* the separator, usually a comma.
* @return the array of numbers produced from the string.
*/
private static Number[] toBigDecimalList( final String s, final String sep ) {
if ( StringUtils.isEmpty( s ) ) {
return EMPTY_NUMBERS;
}
final StringTokenizer stringTokenizer = new StringTokenizer( s, sep );
final Number[] ret = new Number[stringTokenizer.countTokens()];
int i = 0;
while ( stringTokenizer.hasMoreTokens() ) {
final String val = stringTokenizer.nextToken().trim();
ret[i] = new BigDecimal( val );
i += 1;
}
return ret;
}
}