Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*******************************************************************************
* Copyright (c) 2004, 2009 Actuate Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Actuate Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.birt.core.data;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;
import java.text.ParseException;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.TimeZone;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.regex.Pattern;
import javax.sql.rowset.serial.SerialBlob;
import org.eclipse.birt.core.exception.BirtException;
import org.eclipse.birt.core.exception.CoreException;
import org.eclipse.birt.core.format.DateFormatter;
import org.eclipse.birt.core.i18n.ResourceConstants;
import org.eclipse.birt.core.i18n.ResourceHandle;
import org.eclipse.birt.core.script.JavascriptEvalUtil;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.util.ULocale;
/**
* A utility function The convert method converts the source object, which can
* be any supported data type, into an object given specified type. If no
* reasonable conversion can be made, throw a BirtException.
*/
public final class DataTypeUtil
{
// Defalult Locale, if we have any problem parse string to date for Locale.getDefault()
// we will try to parse it for Locale.US
private static ULocale DEFAULT_LOCALE = ULocale.US;
private static ULocale JRE_DEFAULT_LOCALE = ULocale.getDefault( );
private static SimpleDateFormat MysqlUSDateFormatter = new SimpleDateFormat( "M/d/yyyy HH:mm" );
private static Pattern p1 = Pattern.compile( ".*[0-9]+:[0-9]+:[0-9]+.*" );
private static Pattern p2 = Pattern.compile( ".*[0-9]+:[0-9]+.*" );
// cache DateFormatter of ICU
private static Map dfMap = new HashMap( );
private static Map nfMap = new HashMap( );
// Default Date/Time Style
private static int DEFAULT_DATE_STYLE = DateFormat.FULL;
// resource bundle for exception messages
public static ResourceBundle resourceBundle = ( new ResourceHandle( JRE_DEFAULT_LOCALE ) ).getUResourceBundle( );
public static long count = 0;
/**
* convert an object to given type
* Types supported:
* DataType.INTEGER_TYPE
* DataType.DECIMAL_TYPE
* DataType.BOOLEAN_TYPE
* DataType.DATE_TYPE
* DataType.DOUBLE_TYPE
* DataType.STRING_TYPE
* DataType.BLOB_TYPE
* DataType.SQL_DATE_TYPE
* DataType.SQL_TIME_TYPE
* @param source
* @param toType
* @return
* @throws BirtException
*/
public static Object convert( Object source, int toType )
throws BirtException
{
source = JavascriptEvalUtil.convertJavascriptValue( source );
// here we assume the efficiency of if else is higher than switch case
if ( toType == DataType.UNKNOWN_TYPE || toType == DataType.ANY_TYPE )
return source;
switch ( toType )
{
case DataType.INTEGER_TYPE :
return toInteger( source );
case DataType.DECIMAL_TYPE :
return toBigDecimal( source );
case DataType.BOOLEAN_TYPE :
return toBoolean( source );
case DataType.DATE_TYPE :
return toDate( source );
case DataType.DOUBLE_TYPE :
return toDouble( source );
case DataType.STRING_TYPE :
return toString( source );
case DataType.BLOB_TYPE :
return toBytes( source );
case DataType.BINARY_TYPE :
return toBytes( source );
case DataType.SQL_DATE_TYPE:
return toSqlDate( source );
case DataType.SQL_TIME_TYPE:
return toSqlTime( source );
case DataType.JAVA_OBJECT_TYPE:
return source;
default :
throw new CoreException( ResourceConstants.INVALID_TYPE,
resourceBundle );
}
}
/**
* convert a object to given class
* Classes supported:
* Integer.class
* BigDecimal.class
* Boolean.class
* Time.class
* Date.class
* Double.class
* String.class
* Blob.class
* @param source
* @param toTypeClass
* @return
* @throws BirtException
*/
public static Object convert( Object source, Class toTypeClass )
throws BirtException
{
if ( source!= null && source.getClass( ) == toTypeClass )
{
return source;
}
if ( toTypeClass == DataType.getClass( DataType.ANY_TYPE ) )
return source;
if ( toTypeClass == Integer.class )
return toInteger( source );
if ( toTypeClass == BigDecimal.class )
return toBigDecimal( source );
if ( toTypeClass == Boolean.class )
return toBoolean( source );
if ( toTypeClass == Time.class )
return toSqlTime( source );
if ( toTypeClass == java.sql.Date.class)
return toSqlDate( source );
if ( toTypeClass == java.sql.Timestamp.class )
return toTimestamp( source );
if ( toTypeClass == Date.class )
return toDate( source );
if ( toTypeClass == Double.class )
return toDouble( source );
if ( toTypeClass == String.class )
return toString( source );
if ( toTypeClass == Blob.class )
{
if ( source instanceof byte[] )
return source;
else
return toBlob( source );
}
if ( toTypeClass == byte[].class )
return source;
if ( toTypeClass == Object.class )
{
return source;
}
throw new CoreException( ResourceConstants.INVALID_TYPE,
resourceBundle );
}
/**
* Boolean -> Integer
* true -> 1
* others -> 0
* Date -> Integer
* Date.getTime();
* String -> Integer
* Integer.valueOf();
* @param source
* @return
* @throws BirtException
*/
public static Integer toInteger( Object source ) throws BirtException
{
if ( source == null )
return null;
if ( source instanceof Integer )
{
return (Integer) source;
}
else if ( source instanceof Number )
{
// This takes care of BigDecimal, BigInteger, Byte, Double,
// Float, Long, Short
if ( !isConvertableToInteger( (Number) source ) )
{
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Integer"
} );
}
int intValue = ( (Number) source ).intValue( );
return Integer.valueOf( intValue );
}
else if ( source instanceof Boolean )
{
if ( true == ( (Boolean) source ).booleanValue( ) )
return Integer.valueOf( 1 );
return Integer.valueOf( 0 );
}
else if ( source instanceof Date )
{
long longValue = ( (Date) source ).getTime( );
if ( !isConvertableToInteger( Long.valueOf( longValue ) ))
{
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Integer"
} );
}
return Integer.valueOf( (int) longValue );
}
else if ( source instanceof CharSequence )
{
source = source.toString( );
try
{
return Integer.valueOf( (String) source );
}
catch ( NumberFormatException e )
{
try
{
Number number = NumberFormat.getInstance( JRE_DEFAULT_LOCALE ).parse( (String)source );
if( number != null )
{
if ( !isConvertableToInteger( number ))
{
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Integer"
} );
}
return Integer.valueOf( number.intValue( ));
}
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Integer"
} );
}
catch ( ParseException e1 )
{
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Integer"
} );
}
}
}
else
{
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Integer"
} );
}
}
/**
* Boolean -> BigDecimal
* true -> 1
* others -> 0
* Date -> BigDecimal
* Date.getTime();
* String -> BigDecimal
* new BigDecimal(String);
* @param source
* @return
* @throws BirtException
*/
public static BigDecimal toBigDecimal( Object source ) throws BirtException
{
if ( source == null )
return null;
if ( source instanceof BigDecimal )
{
return (BigDecimal) source;
}
else if ( source instanceof Number )
{
// This takes care of BigDecimal, BigInteger, Byte, Double,
// Float, Long, Short, Integer
// An intermediate conversion using String is preferrable per JavaDoc
// comment in BigDecimal(String) constructor
if ( source instanceof Double
&& ( ( (Double) source ).isInfinite( ) || ( (Double) source ).isNaN( ) ) )
return null;
else if ( source instanceof Float
&& ( ( (Float) source ).isInfinite( ) || ( (Float) source ).isNaN( ) ) )
return null;
String str = ( (Number) source ).toString( );
try
{
return new BigDecimal( str );
}
catch ( NumberFormatException e )
{
throw new CoreException(
ResourceConstants.CONVERT_FAILS,
new Object[]{
str, "BigDecimal"
} );
}
}
else if ( source instanceof Boolean )
{
if ( true == ( (Boolean) source ).booleanValue( ) )
return BigDecimal.ONE;
return BigDecimal.ZERO;
}
else if ( source instanceof Date )
{
long longValue = ( (Date) source ).getTime( );
return new BigDecimal( longValue );
}
else if ( source instanceof CharSequence )
{
//if empty string, return null
source = source.toString( );
if( ( (String) source ).length( )==0 )
{
return null;
}
try
{
return new BigDecimal( (String) source );
}
catch ( NumberFormatException e )
{
try
{
Number number = NumberFormat.getInstance( JRE_DEFAULT_LOCALE )
.parse( (String) source );
if( number != null )
return new BigDecimal( number.toString( ) );
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "BigDecimal"
} );
}
catch ( ParseException e1 )
{
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "BigDecimal"
} );
}
}
}
else
{
throw new CoreException(
ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "BigDecimal"
} );
}
}
/**
* Number -> Boolean
* 0 -> false
* others -> true
* String -> Boolean
* "true" -> true (ignore case)
* "false" -> false (ignore case)
* other string will throw an exception
* Date -> Boolean
* throw exception
* @param source
* @return
* @throws BirtException
*/
public static Boolean toBoolean( Object source ) throws BirtException
{
if ( source == null )
return null;
if ( source instanceof Boolean )
{
return (Boolean) source;
}
else if ( source instanceof Number )
{
// Takes care of all numeric types
if ( ( (Number) source ).doubleValue( ) == 0 )
return Boolean.FALSE;
return Boolean.TRUE;
}
else if ( source instanceof CharSequence )
{
source = source.toString( );
if ( ( (String) source ).equalsIgnoreCase( "true" ) )
return Boolean.TRUE;
else if ( ( (String) source ).equalsIgnoreCase( "false" ) )
return Boolean.FALSE;
else
{
try
{
if ( Double.parseDouble( (String) source ) == 0 )
return Boolean.FALSE;
else
return Boolean.TRUE;
}
catch ( NumberFormatException e )
{
throw new CoreException(
ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Boolean"
} );
}
}
}
else
{
throw new CoreException(
ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Boolean"
});
}
}
/**
* Number -> Date
* new Date((long)Number)
* String -> Date
* toDate(String)
* @param source
* @return
* @throws BirtException
*/
public static Date toDate( Object source ) throws BirtException
{
if ( source == null )
return null;
if ( source instanceof Date )
{
return new Date( ( (Date) source ).getTime( ) );
}
else if ( source instanceof CharSequence )
{
return toDate( source.toString( ) );
}
else if ( source instanceof Double )
{
// Rounding Double to the nearest Long.
// This should be a relatively safe operation since this type
// of conversion is usually done for representing aggregate
// function results as Date.
return new Date( Math.round( (Double) source ) );
}
else
{
throw new CoreException(
ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Date"
});
}
}
/**
*
* @param source
* @return
* @throws BirtException
*/
public static Timestamp toTimestamp( Object source ) throws BirtException
{
Date date = toDate( source );
if( date == null )
return null;
return new Timestamp( date.getTime( ));
}
/**
* Date -> Time
* String -> Time
* @param source
* @return
* @throws BirtException
*/
public static Time toSqlTime( Object source ) throws BirtException
{
if ( source == null )
return null;
if ( source instanceof Date )
{
return toSqlTime( (Date)source);
}
else if ( source instanceof CharSequence )
{
source = source.toString( );
try
{
return toSqlTime( toDate((String ) source) );
}
catch( Exception e )
{
try
{
return toSqlTime( (String)source );
}
catch ( Exception e1 )
{
}
}
}
else if ( source instanceof Double )
{
// Rounding to the nearest Long is safe here since the Long value
// represents milliseconds
return toSqlTime( new Date( Math.round( (Double) source ) ) );
}
throw new CoreException(
ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Time"
} );
}
/**
*
* @param value
* @return
*/
private static Time toSqlTime( String s )
{
int hour;
int addHour;
int minute;
int second;
int firstColon;
int secondColon;
int marker;
if ( s == null )
throw new java.lang.IllegalArgumentException( );
firstColon = s.indexOf( ':' );
secondColon = s.indexOf( ':', firstColon + 1 );
for ( marker = secondColon + 1; marker < s.length( ); marker++ )
{
if ( !isDigitTen( s.charAt( marker ) ) )
break;
}
addHour = 0;
String markerValue = null;
String aMarker = null;
if ( marker < s.length( ) )
{
markerValue = s.substring( marker ).trim( );
if ( "am".compareToIgnoreCase( markerValue ) == 0 )
{
addHour = 0;
aMarker = "am";
}
else if ( "pm".compareToIgnoreCase( markerValue ) == 0 )
{
addHour = 12;
aMarker = "pm";
}
else
{
throw new java.lang.IllegalArgumentException( );
}
}
if ( firstColon <= 0 ||
secondColon <= 0 || secondColon >= s.length( ) - 1 )
{
throw new java.lang.IllegalArgumentException( );
}
hour = Integer.parseInt( s.substring( 0, firstColon ) );
minute = Integer.parseInt( s.substring( firstColon + 1, secondColon ) );
if( minute < 0 || minute > 60 )
throw new java.lang.IllegalArgumentException( );
if ( marker < s.length( ) )
second = Integer.parseInt( s.substring( secondColon + 1, marker ) );
else
second = Integer.parseInt( s.substring( secondColon + 1 ) );
if( second < 0 || second > 60 )
throw new java.lang.IllegalArgumentException( );
if( hour == 12 && minute == 0 && second == 0 && aMarker != null )
{
if ( "am".equals( aMarker ) )
{
hour = 24;
}
else
{
hour = 12;
}
}
else
{
if ( hour < 0 ||
( hour > 12 && markerValue != null && markerValue.length( ) > 0 ) )
throw new java.lang.IllegalArgumentException( );
hour += addHour;
if( hour > 24 )
throw new java.lang.IllegalArgumentException( );
}
return toSqlTime( hour, minute, second );
}
/**
*
* @param hour
* @param minute
* @param second
* @return
*/
private static Time toSqlTime( int hour, int minute, int second )
{
Calendar calendar = Calendar.getInstance( );
calendar.clear( );
calendar.set( Calendar.HOUR_OF_DAY, hour );
calendar.set( Calendar.MINUTE, minute );
calendar.set( Calendar.SECOND, second );
return new java.sql.Time( calendar.getTimeInMillis( ) );
}
/**
*
* @param c
* @return
*/
private static boolean isDigitTen( char c )
{
if ( c <= '9' && c >= '0' )
return true;
return false;
}
/**
*
* @param date
* @return
*/
private static java.sql.Time toSqlTime( Date date )
{
Calendar calendar = Calendar.getInstance( );
calendar.clear( );
calendar.setTimeInMillis( date.getTime( ) );
calendar.set( Calendar.YEAR, 1970 );
calendar.set( Calendar.MONTH, 0 );
calendar.set( Calendar.DAY_OF_MONTH, 1 );
return new java.sql.Time( calendar.getTimeInMillis( ) );
}
/**
* Date -> Time
* String -> Time
* @param source
* @return
* @throws BirtException
*/
public static java.sql.Date toSqlDate( Object source ) throws BirtException
{
if ( source == null )
return null;
if ( source instanceof java.sql.Date )
{
return maskSQLDate( ( java.sql.Date )source );
}
else if ( source instanceof Date )
{
return toSqlDate( (Date)source );
}
else if ( source instanceof CharSequence )
{
source = source.toString( );
try
{
return toSqlDate( toDate((String ) source) );
}
catch( Exception e )
{
try
{
return java.sql.Date.valueOf( (String)source );
}
catch ( Exception e1 )
{
}
}
}
else if ( source instanceof Double )
{
// Rounding to the nearest Long is safe here since the Long value
// represents milliseconds
return toSqlDate( new Date( Math.round( (Double) source ) ) );
}
throw new CoreException(
ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "java.sql.Date"
} );
}
/**
*
* @param date
* @return
*/
private static java.sql.Date toSqlDate( Date date )
{
Calendar calendar = Calendar.getInstance( );
calendar.clear( );
calendar.setTimeInMillis( date.getTime( ) );
calendar.set( Calendar.HOUR_OF_DAY, 0 );
calendar.set( Calendar.MINUTE, 0 );
calendar.set( Calendar.SECOND, 0 );
calendar.set( Calendar.MILLISECOND, 0 );
return new java.sql.Date( calendar.getTimeInMillis( ) );
}
/**
* mask out time info for sql Date
* @param date
* @return
*/
private static java.sql.Date maskSQLDate( java.sql.Date date )
{
Calendar calendar = Calendar.getInstance( );
calendar.clear( );
calendar.setTimeInMillis( date.getTime( ) );
calendar.set( Calendar.HOUR_OF_DAY, 0 );
calendar.set( Calendar.MINUTE, 0 );
calendar.set( Calendar.SECOND, 0 );
calendar.set( Calendar.MILLISECOND, 0 );
return new java.sql.Date( calendar.getTimeInMillis( ) );
}
/**
* A temp solution to the adoption of ICU4J to BIRT. Simply delegate
* toDate( String, Locale) method.
*
* @param source
* the String to be convert
* @param locate
* the locate of the string
* @return result Date
*/
public static Date toDate( String source, Locale locale )
throws BirtException
{
return toDate( source, ULocale.forLocale( locale ) );
}
/**
* convert String with the specified locale to java.util.Date
*
* @param source
* the String to be convert
* @param locate
* the locate of the string
* @return result Date
*/
public static Date toDate( String source, ULocale locale )
throws BirtException
{
return toDate( source, locale, null );
}
/**
* Parses a date/time string
*
* @param source
* @param locale
* @param timeZone
* @return
* @throws BirtException
*/
public static Date toDate( String source, ULocale locale, TimeZone timeZone )
throws BirtException
{
DateFormat dateFormat = getDateFormatObject( source, locale, timeZone );
Date resultDate = null;
try
{
resultDate = dateFormat.parse( source );
return resultDate;
}
catch ( ParseException e )
{
throw new CoreException(
ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Date"
} );
}
}
/**
* @deprecated use getDateFormatObject instead
*/
public static DateFormat getDateFormat( String source, ULocale locale, TimeZone timeZone )
throws BirtException
{
return getDateFormatObject( source, locale, timeZone );
}
/**
* Retrieve date format object that matches the given date/time string
* @since 4.8
*
* @param source
* @param locale
* @param timeZone
* @return
* @throws BirtException
*/
public static DateFormat getDateFormatObject( String source, ULocale locale, TimeZone timeZone )
throws BirtException
{
if ( source == null )
return null;
DateFormat dateFormat = null;
Date resultDate = null;
boolean existTime = p1.matcher( source ).matches( )
|| p2.matcher( source ).matches( );
for ( int i = DEFAULT_DATE_STYLE; i <= DateFormat.SHORT; i++ )
{
for ( int j = DEFAULT_DATE_STYLE; j <= DateFormat.SHORT; j++ )
{
dateFormat = DateFormatFactory.getDateTimeInstance( i, j, locale );
TimeZone savedTimeZone = null;
if( timeZone != null )
{
savedTimeZone = dateFormat.getTimeZone( );
dateFormat.setTimeZone( timeZone );
}
try
{
resultDate = dateFormat.parse( source );
return dateFormat;
}
catch ( ParseException e1 )
{
}
finally
{
if( savedTimeZone != null )
dateFormat.setTimeZone( savedTimeZone );
}
}
// only Date, no Time
if ( !existTime )
{
dateFormat = DateFormatFactory.getDateInstance( i, locale );
TimeZone savedTimeZone = null;
if( timeZone != null )
{
savedTimeZone = dateFormat.getTimeZone( );
dateFormat.setTimeZone( timeZone );
}
try
{
resultDate = dateFormat.parse( source );
return dateFormat;
}
catch ( ParseException e1 )
{
}
finally
{
if( savedTimeZone != null )
dateFormat.setTimeZone( savedTimeZone );
}
}
}
// for the String can not be parsed, throws a BirtException
if ( resultDate == null )
{
throw new CoreException(
ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Date"
} );
}
// never access here
return dateFormat;
}
/**
* Convert a string to a Date instance according to the TimeZone value
*
* @param source
* @param timeZone
* @return
* @throws BirtException
*/
public static Date toDate( String source, TimeZone timeZone ) throws BirtException
{
assert timeZone != null;
try
{
return toDateISO8601( source, timeZone );
}
catch ( BirtException e )
{
try
{
// format the String for JRE default locale
return toDate( source, JRE_DEFAULT_LOCALE, timeZone );
}
catch ( BirtException use )
{
// format the String for Locale.US
return toDate( source, DEFAULT_LOCALE, timeZone );
}
}
}
/**
* A temp solution to the adoption of ICU4J in BIRT. It is a simple
* delegation to toDateWithCheck( String, Locale ).
*
* @param source
* @param locale
* @return Date
* @throws BirtException
*/
public static Date toDateWithCheck( String source, Locale locale )
throws BirtException
{
return toDateWithCheck( source, ULocale.forLocale( locale ) );
}
/**
* Convert string to date with check.
* JDK may do incorrect converse, for example:
* 2005/1/1 Local.US, format pattern is MM/dd/YY.
* Above conversion can be done without error, but obviously
* the result is not right. This method will do such a simple check,
* in DateFormat.SHORT case instead of all cases.
* Year is not lower than 0.
* Month is from 1 to 12.
* Day is from 1 to 31.
* @param source
* @param locale
* @return Date
* @throws BirtException
*/
public static Date toDateWithCheck( String source, ULocale locale )
throws BirtException
{
DateFormat dateFormat = DateFormatFactory.getDateInstance( DateFormat.SHORT,
locale );
Date resultDate = null;
try
{
resultDate = dateFormat.parse( source );
}
catch ( ParseException e )
{
return toDate( source, locale );
}
// check whether conversion is correct
if ( DateUtil.checkValid( dateFormat, source ) == false )
{
throw new CoreException(
ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Date"
});
}
return resultDate;
}
public static Double toDouble( Object source, Locale locale ) throws CoreException
{
return toDouble( source, ULocale.forLocale( locale ));
}
public static Double toDouble( Object source, ULocale locale ) throws CoreException
{
if ( source == null )
return null;
if ( source instanceof Double )
{
return (Double) source;
}
else if ( source instanceof Number )
{
if ( !isConvertableToDouble( (Number) source ) )
{
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Double"
} );
}
double doubleValue = ( (Number) source ).doubleValue( );
return new Double( doubleValue );
}
else if ( source instanceof Boolean )
{
if ( true == ( (Boolean) source ).booleanValue( ) )
return new Double( 1d );
return new Double( 0d );
}
else if ( source instanceof Date )
{
double doubleValue = ( (Date) source ).getTime( );
return new Double( doubleValue );
}
else if ( source instanceof CharSequence )
{
source = source.toString( );
try
{
return Double.valueOf( (String) source );
}
catch ( NumberFormatException e )
{
try
{
Number number = NumberFormat.getInstance( locale == null
? JRE_DEFAULT_LOCALE : locale )
.parse( (String) source );
if( number != null )
{
if ( !isConvertableToDouble( number ) )
{
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Double"
} );
}
return new Double( number.doubleValue( ));
}
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Double"
} );
}
catch ( ParseException e1 )
{
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Double"
} );
}
}
}
else
{
throw new CoreException(
ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Double"
});
}
}
/**
* Boolean -> Double
* true -> 1
* others -> 0
* Date -> Double
* Date.getTime();
* String -> Double
* Double.valueOf(String);
* @param source
* @return
* @throws BirtException
*/
public static Double toDouble( Object source ) throws BirtException
{
return toDouble( source, JRE_DEFAULT_LOCALE );
}
/**
* Number -> String
* Number.toString()
* Boolean -> String
* Boolean.toString()
* Date -> String
* toString(Date)
* @param source
* @return
* @throws BirtException
*/
public static String toString( Object source ) throws BirtException
{
return toString( source, JRE_DEFAULT_LOCALE );
}
/**
* A temp solution to the adoption of ICU4J. It is a simple delegation
* to toString( Object, Locale ).
* @param source
* @return
* @throws BirtException
*/
public static String toString( Object source, Locale locale )
throws BirtException
{
return toString( source, ULocale.forLocale( locale ) );
}
/**
* Convert an object to an locale neutral String value. For Date values we will convert to ISO8601 format.
* User can specify the time zone to output.
*
* @param source
* @param zone
* @return
* @throws BirtException
*/
public static String toLocaleNeutralString( Object source, TimeZone zone ) throws BirtException
{
if ( source == null )
return null;
if ( source instanceof Time )
{
return toLocaleNeutralString( source );
}
else if ( source instanceof java.sql.Date )
{
return toLocaleNeutralString( source );
}
else if ( source instanceof Timestamp )
{
return toLocaleNeutralString( source );
}
else if ( source instanceof Date )
{
return DateFormatISO8601.format( (Date) source, zone );
}
else
{
return toLocaleNeutralString( source );
}
}
/**
* Convert an object to an locale neutral String value. For Date values we will convert to ISO8601 format.
* This will always output default(current) time zone.
*
* @param source
* @return
* @throws BirtException
*/
public static String toLocaleNeutralString( Object source ) throws BirtException
{
if ( source == null )
return null;
if ( source instanceof Time )
{
return ((Time) source).toString( );
}
else if ( source instanceof java.sql.Date )
{
return ((java.sql.Date) source).toString( );
}
else if ( source instanceof Timestamp )
{
return ((java.sql.Timestamp) source).toString( );
}
else if ( source instanceof Date )
{
return DateFormatISO8601.format( (Date) source );
}
else if ( source instanceof Number )
{
return ((Number) source).toString( );
}
else
{
return toLimitedSizeString( source );
}
}
/**
* Number -> String
* Number.toString()
* Boolean -> String
* Boolean.toString()
* Date -> String
* toString(Date,locale)
* @param source
* @return
* @throws BirtException
*/
public static String toString( Object source, ULocale locale )
throws BirtException
{
if ( source == null )
return null;
if ( source instanceof Time )
{
return toString( (Date) source, locale );
}
else if ( source instanceof java.sql.Date )
{
return ((java.sql.Date) source).toString( );
}
else if ( source instanceof Timestamp )
{
return ((java.sql.Timestamp) source).toString( );
}
else if ( source instanceof Date )
{
return toString( (Date) source, locale );
}
else if ( source instanceof Number )
{
return toString( (Number) source, locale );
}
else
{
return toLimitedSizeString( source );
}
}
/**
*
* @param source
* @return
*/
private static String toLimitedSizeString( Object source )
{
if ( source instanceof byte[] )
{
StringBuffer buf = new StringBuffer( );
final int strLength = 8;
byte[] sourceValue = (byte[]) source;
int length = Math.min( sourceValue.length, strLength );
for ( int i = 0; i < length; i++ )
{
buf.append( Integer.toHexString( sourceValue[i] ).toUpperCase( ) );
buf.append( " " );
}
if ( sourceValue.length > strLength )
{
buf.append( "..." );
}
return buf.toString( );
}
else
{
return source.toString( );
}
}
/**
*
* @param source
* @param locale
* @return
*/
private static String toString( Number source, ULocale locale )
{
NumberFormat nf = (NumberFormat)nfMap.get( locale );
if( nf == null )
{
synchronized( nfMap )
{
nf = (NumberFormat)nfMap.get( locale );
if( nf == null )
{
nf = NumberFormat.getInstance( locale );
nfMap.put( locale, nf );
}
}
}
return nf.format( source );
}
/**
* Converting Blob to/from other types is not currently supported
* @param source
* @return
* @throws BirtException
*/
public static Blob toBlob( Object source ) throws BirtException
{
// Converting Blob to/from other types is not currently supported
if ( source == null )
return null;
if ( source instanceof Blob )
return (Blob) source;
else if ( source instanceof byte[] )
{
try
{
return new SerialBlob( (byte[]) source );
}
catch ( Exception e )
{
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Blob"
} );
}
}
else
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Blob"
} );
}
/**
* @param source
* @return byte array
* @throws BirtException
*/
public static byte[] toBytes( Object source ) throws BirtException
{
// Converting Blob to/from other types is not currently supported
if ( source == null )
return null;
if ( source instanceof byte[] )
return (byte[]) source;
else if ( source instanceof Blob )
{
try
{
return ( (Blob) source ).getBytes( (long) 1,
(int) ( (Blob) source ).length( ) );
}
catch ( SQLException e )
{
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Binary"
} );
}
}
else
throw new CoreException( ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Binary"
} );
}
/**
* Converts a Java class to its corresponding data type constant
* defined in DataType
*/
public static int toApiDataType( Class clazz )
{
if ( clazz == null )
return DataType.UNKNOWN_TYPE;
if ( clazz == DataType.AnyType.class )
return DataType.ANY_TYPE;
else if ( Integer.class.isAssignableFrom( clazz ) )
return DataType.INTEGER_TYPE;
else if ( Double.class.isAssignableFrom( clazz ) )
return DataType.DOUBLE_TYPE;
else if ( String.class.isAssignableFrom( clazz ) )
return DataType.STRING_TYPE;
else if ( BigDecimal.class.isAssignableFrom( clazz ) )
return DataType.DECIMAL_TYPE;
else if ( clazz == java.sql.Date.class )
return DataType.SQL_DATE_TYPE;
else if ( clazz == java.sql.Time.class )
return DataType.SQL_TIME_TYPE;
else if ( Date.class.isAssignableFrom( clazz ) )
return DataType.DATE_TYPE;
else if ( byte[].class.isAssignableFrom( clazz ) )
return DataType.BINARY_TYPE;
else if ( Clob.class.isAssignableFrom( clazz )
|| clazz.getName( )
.equals( "org.eclipse.datatools.connectivity.oda.IClob" ) )
return DataType.STRING_TYPE;
else if ( Blob.class.isAssignableFrom( clazz )
|| clazz.getName( )
.equals( "org.eclipse.datatools.connectivity.oda.IBlob" ) )
return DataType.BLOB_TYPE;
else if ( clazz == Boolean.class )
return DataType.BOOLEAN_TYPE;
else if ( clazz == Object.class )
return DataType.JAVA_OBJECT_TYPE;
// any other types are not recognized nor supported;
return DataType.UNKNOWN_TYPE;
}
public static Class fromApiDataTypeToJavaClass( int apiDataType )
{
switch ( apiDataType )
{
case DataType.ANY_TYPE:
return DataType.AnyType.class;
case DataType.INTEGER_TYPE:
return Integer.class;
case DataType.DOUBLE_TYPE:
return Double.class;
case DataType.STRING_TYPE:
return String.class;
case DataType.DECIMAL_TYPE:
return BigDecimal.class;
case DataType.SQL_DATE_TYPE:
return java.sql.Date.class;
case DataType.SQL_TIME_TYPE:
return java.sql.Time.class;
case DataType.DATE_TYPE:
return java.util.Date.class;
case DataType.BINARY_TYPE:
return byte[].class;
case DataType.BOOLEAN_TYPE:
return Boolean.class;
case DataType.JAVA_OBJECT_TYPE:
return Object.class;
case DataType.BLOB_TYPE:
try
{
Class c = Class.forName("org.eclipse.datatools.connectivity.oda.IBlob");
return c;
}catch(Exception exp)
{
}
default:
return DataType.AnyType.class;
}
}
/**
* Converts an ODA data type code to its
* corresponding Data Engine API data type constant
* defined in DataType.
* @param odaDataTypeCode an ODA data type code
* @throws BirtException if the specified ODA data type code
* is not a supported type
*/
public static int toApiDataType( int odaDataTypeCode ) throws BirtException
{
Class odiTypeClass = toOdiTypeClass( odaDataTypeCode );
return toApiDataType( odiTypeClass );
}
/**
* Convert object to a suitable type from its value
* Object -> Integer -> Double -> BigDecimal -> Date -> String
*/
public static Object toAutoValue( Object evaValue )
{
if ( evaValue == null )
return null;
Object value = null;
if ( evaValue instanceof CharSequence )
{
// 1: to Integer
String stringValue = evaValue.toString( );
value = toIntegerValue( evaValue );
if ( value == null )
{
try
{
// 2: to Double
value = Double.valueOf( stringValue );
}
catch ( NumberFormatException e1 )
{
try
{
// 3: to BigDecimal
value = new BigDecimal( stringValue );
}
catch ( NumberFormatException e2 )
{
try
{
// 4: to Date
value = toDate( stringValue );
}
catch ( BirtException e3 )
{
value = evaValue;
}
}
}
}
}
return value;
}
/**
* convert object to Integer. If fails, return null.
* Object -> Integer
*/
public static Integer toIntegerValue( Object evaValue )
{
// to Integer
Integer value = null;
if ( evaValue instanceof CharSequence )
{
String stringValue = evaValue.toString( );
try
{
// 1: to Integer
value = Integer.valueOf( stringValue );
}
catch ( NumberFormatException e1 )
{
try
{
Double ddValue = Double.valueOf( stringValue );
int intValue = ddValue.intValue( );
double doubleValue = ddValue.doubleValue( );
// TODO: improve this implementation
// here examine whether the two values are equal.1.0e-5
if ( Math.abs( intValue - doubleValue ) < 0.0000001 )
{
value = Integer.valueOf( String.valueOf( intValue ) );
}
else
{
value = null;
}
}
catch ( NumberFormatException e2 )
{
value = null;
}
}
}
return value;
}
/**
* Convert String without specified locale to java.util.Date
* Try to format the given String for JRE default Locale,
* if it fails, try to format the String for Locale.US
* @param source
* the String to be convert
* @param locate
* the locate of the string
* @return result Date
*/
private static Date toDate( String source ) throws BirtException
{
source = source.trim( );
try
{
return toDateISO8601( source, null );
}
catch ( BirtException e )
{
try
{
// format the String for JRE default locale
return toDate( source, JRE_DEFAULT_LOCALE );
}
catch ( BirtException use )
{
try
{
// format the String for Locale.US
return toDate( source, DEFAULT_LOCALE );
}
catch ( BirtException de )
{
return toDateForSpecialFormat( source );
}
}
}
}
/**
* convert String with ISO8601 date format to java.util.Date
*
* @param source
* the String to be convert
* @param locate
* the locate of the string
* @return result Date
*/
private static Date toDateISO8601( String source, TimeZone timeZone ) throws BirtException
{
Date resultDate = null;
try
{
resultDate = DateFormatISO8601.parse( source, timeZone );
return resultDate;
}
catch ( ParseException e1 )
{
throw new CoreException(
ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Date"
} );
}
}
private static Date toDateForSpecialFormat( String source ) throws BirtException
{
try
{
return MysqlUSDateFormatter.parse( source );
}
catch ( ParseException e1 )
{
throw new CoreException(
ResourceConstants.CONVERT_FAILS,
new Object[]{
source.toString( ), "Date"
} );
}
}
/**
* Find the date format pattern string for a given datetime string without specified locale.
* If a suitable date format cannot be found or the pattern string cannot be retrieved, returns null
* @since 4.8
*
* @param source
* @return
* @throws BirtException
*/
public static String getDateFormat( String source ) throws BirtException
{
source = source.trim( );
SimpleDateFormat sdf = null;
try
{
sdf = DateFormatISO8601.getSimpleDateFormat( source, null );
}
catch ( BirtException e )
{
try
{
DateFormat dateformat = getDateFormatObject( source, JRE_DEFAULT_LOCALE, null );
sdf = (SimpleDateFormat) dateformat;
}
catch ( BirtException use )
{
try
{
DateFormat dateformat = getDateFormatObject( source, DEFAULT_LOCALE, null );
sdf = (SimpleDateFormat) dateformat;
}
catch ( BirtException de )
{
try {
MysqlUSDateFormatter.parse( source );
return "M/d/yyyy HH:mm";
}
catch ( ParseException e1 )
{
}
}
}
catch ( ClassCastException ce )
{
// If a DateFormat cannot be cast to SimpleDateFormat, then
// it will not be able to return its format pattern string
}
}
if ( sdf != null )
return sdf.toPattern();
return null;
}
/**
* Call org.eclipse.birt.core.format.DateFormatter
*
* @param source
* @return
*/
private static String toString( Date source, ULocale locale )
{
DateFormatter df = null;
// avoid any multi-thread issue
df = (DateFormatter) ( dfMap.get( locale ) );
if ( df == null )
{
synchronized ( dfMap )
{
df = (DateFormatter) ( dfMap.get( locale ) );
if ( df == null )
{
df = new DateFormatter( locale );
dfMap.put( locale, df );
}
}
}
return df.format( (Date) source );
}
/**
* Converts an ODA data type code to the Java class
* of its corresponding Data Engine ODI data type.
* ODA Data Type -> ODI Type Class
* Integer -> java.lang.Integer
* Double -> java.lang.Double
* Character -> java.lang.String
* Decimal -> java.math.BigDecimal
* Date -> java.sql.Date
* Time -> java.sql.Time
* Timestamp -> java.sql.Timestamp
* Blob -> java.sql.Blob
* Clob -> java.sql.Clob
* Boolean -> java.lang.Boolean
* JavaObject -> java.lang.Object
*
* @param odaDataTypeCode an ODA data type code
* @return the ODI type class that corresponds with
* the specified ODA data type
* @throws BirtException if the specified ODA data type is not a supported type
*/
public static Class toOdiTypeClass( int odaDataTypeCode )
throws BirtException
{
if ( odaDataTypeCode != Types.CHAR
&& odaDataTypeCode != Types.INTEGER
&& odaDataTypeCode != Types.DOUBLE
&& odaDataTypeCode != Types.DECIMAL
&& odaDataTypeCode != Types.DATE
&& odaDataTypeCode != Types.TIME
&& odaDataTypeCode != Types.TIMESTAMP
&& odaDataTypeCode != Types.BLOB
&& odaDataTypeCode != Types.CLOB
&& odaDataTypeCode != Types.BOOLEAN
&& odaDataTypeCode != Types.JAVA_OBJECT
&& odaDataTypeCode != Types.NULL )
{
throw new CoreException( ResourceConstants.INVALID_TYPE);
}
Class fieldClass = null;
switch ( odaDataTypeCode )
{
case Types.CHAR :
fieldClass = String.class;
break;
case Types.INTEGER :
fieldClass = Integer.class;
break;
case Types.DOUBLE :
fieldClass = Double.class;
break;
case Types.DECIMAL :
fieldClass = BigDecimal.class;
break;
case Types.DATE :
fieldClass = java.sql.Date.class;
break;
case Types.TIME :
fieldClass = Time.class;
break;
case Types.TIMESTAMP :
fieldClass = Timestamp.class;
break;
case Types.BLOB :
fieldClass = Blob.class;
break;
case Types.CLOB :
fieldClass = Clob.class;
break;
case Types.BOOLEAN :
fieldClass = Boolean.class;
break;
case Types.JAVA_OBJECT :
fieldClass = Object.class;
break;
case Types.NULL :
fieldClass = null;
break;
}
return fieldClass;
}
/**
* Converts an ODI type class to its corresponding
* ODA data type code.
* ODI Type Class -> ODA Data Type
* java.lang.Integer -> Integer
* java.lang.Double -> Double
* java.lang.String -> Character
* java.math.BigDecimal -> Decimal
* java.util.Date -> Timestamp
* java.sql.Date -> Date
* java.sql.Time -> Time
* java.sql.Timestamp -> Timestamp
* java.sql.Blob -> Blob
* java.sql.Clob -> Clob
* java.lang.Boolean -> Boolean
* java.lang.Object -> JavaObject
*
* All other type classes are mapped to the ODA String data type.
* @param odiTypeClass a type class used by the Data Engine ODI component
* @return the ODA data type that maps to the ODI type class.
*/
public static int toOdaDataType( Class odiTypeClass )
{
int odaType = Types.CHAR; // default
if ( odiTypeClass == null )
odaType = Types.CHAR;
else if ( odiTypeClass == String.class )
odaType = Types.CHAR;
else if ( odiTypeClass == Integer.class )
odaType = Types.INTEGER;
else if ( odiTypeClass == Double.class )
odaType = Types.DOUBLE;
else if ( odiTypeClass == BigDecimal.class )
odaType = Types.DECIMAL;
else if ( odiTypeClass == Time.class )
odaType = Types.TIME;
else if ( odiTypeClass == Timestamp.class )
odaType = Types.TIMESTAMP;
else if ( odiTypeClass == java.sql.Date.class )
odaType = Types.DATE;
else if ( odiTypeClass == java.util.Date.class )
odaType = Types.TIMESTAMP;
else if ( odiTypeClass == Blob.class )
odaType = Types.BLOB;
else if ( odiTypeClass == Clob.class )
odaType = Types.CLOB;
else if ( odiTypeClass == Boolean.class )
odaType = Types.BOOLEAN;
else if ( odiTypeClass == Object.class )
odaType = Types.JAVA_OBJECT;
return odaType;
}
private static boolean isConvertableToInteger( Number n )
{
assert n != null;
long longValue = n.longValue( );
return longValue >= Integer.MIN_VALUE && longValue <= Integer.MAX_VALUE;
}
private static boolean isConvertableToDouble( Number n )
{
assert n != null;
double doubleValue = n.doubleValue( );
return !Double.isInfinite( doubleValue );
}
}