// ============================================================================ // // Copyright (C) 2006-2012 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package org.talend.core.model.metadata.types; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.oro.text.regex.MalformedPatternException; import org.apache.oro.text.regex.Pattern; import org.apache.oro.text.regex.Perl5Compiler; import org.apache.oro.text.regex.Perl5Matcher; /** * DataTypeManager is used to determine the Java Type or the Talend Type of a string. TODO : This class don't determine * the type DATE. * * $Id: DataTypeHelper.java 1155 2006-12-21 09:51:10Z amaumont $ * */ public final class JavaDataTypeHelper { /** * Default Constructor. Must not be used. */ private JavaDataTypeHelper() { } /** * Constant to define the min and the max of type Int Float Double. */ private static final int INT_MIN = -2147483648; private static final int INT_MAX = 2147483647; private static final float FLOAT_MIN = -1.4E-45f; private static final float FLOAT_MAX = 3.4E38f; private static final double DOUBLE_MIN = 4.9E-324d; private static final double DOUBLE_MAX = 1.7E308d; /** * getTypeOfValue return STRING, CHAR, NUMBER, LONG, FLOAT, DOUBLE. * * @param value * @return string or null if the value.equals("") */ public static String getTalendTypeOfValue(final String value) { String javaType = getJavaTypeOfValue(value); if (javaType == null) { // if (javaType.equals("Integer")) { // return "NUMBER"; // } else if (javaType.equals("Character")) { // return "CHAR"; // } // } else { return JavaTypesManager.STRING.getId(); } return javaType; } /** * getTypeOfValue return String, Character, Integer, Long, Float, Double. * * @param value * @return string or null if the value.equals("") */ public static String getJavaTypeOfValue(final String value) { // empty value => type is undef if (value.equals("")) { //$NON-NLS-1$ return null; } // only 1 char => type is char or int if (value.length() == 1) { try { // * int Entier -2 147 483 648 � 2 147 483 647 Integer nbr = Integer.parseInt(value); if ((nbr >= INT_MIN) && (nbr <= INT_MAX)) { return JavaTypesManager.INTEGER.getId(); } } catch (Exception e) { // } return JavaTypesManager.CHARACTER.getId(); } // see the bug "6680",qli comment. if (value.equals(JavaTypesManager.DEFAULT_BOOLEAN) || value.equals(JavaTypesManager.ANOTHER_BOOLEAN)) { return JavaTypesManager.BOOLEAN.getId(); } if (isDateOne(value) || isDateTwo(value)) { return JavaTypesManager.DATE.getId(); } // SPECIFIQUE USE CASE (integer begin by 0; multiple dot use ; use of char E in scientific notation) // if (!isNumber(value)) { // Warning : 1.7E38 is interpreted like a float ! return JavaTypesManager.STRING.getId(); } // // first char is 0 and no dot just after => force type String needed if (value.substring(0, 1).equals("0") && (!value.substring(1, 2).equals("."))) { //$NON-NLS-1$ //$NON-NLS-2$ return JavaTypesManager.STRING.getId(); } // // content more one dot => String if (value.contains(".")) { //$NON-NLS-1$ if (value.substring(value.indexOf(".") + 1, value.length()).contains(".")) { //$NON-NLS-1$ //$NON-NLS-2$ return JavaTypesManager.STRING.getId(); } } // END SPECIFIQUE USE CASE // content only a dot => float or double if (value.contains(".")) { //$NON-NLS-1$ try { Float nbrFloat = Float.parseFloat(value); if ((!nbrFloat.toString().equals("Infinity")) && (!nbrFloat.toString().equals("-Infinity"))) { //$NON-NLS-1$ //$NON-NLS-2$ if ((nbrFloat >= FLOAT_MIN) && (nbrFloat <= FLOAT_MAX)) { return JavaTypesManager.FLOAT.getId(); } } try { // * double flottant double 4.9*10 -324 � 1.7*10 308 Double nbrDouble = Double.parseDouble(value); if ((!nbrDouble.toString().equals("Infinity")) && (!nbrDouble.toString().equals("-Infinity"))) { //$NON-NLS-1$ //$NON-NLS-2$ if ((nbrDouble >= DOUBLE_MIN) && (nbrDouble <= DOUBLE_MAX)) { return JavaTypesManager.DOUBLE.getId(); } } } catch (Exception e) { // } } catch (Exception e) { // } } // is not a char, not a float : parseMethod is usable try { Integer.parseInt(value); return JavaTypesManager.INTEGER.getId(); } catch (Exception e) { // } try { Long.parseLong(value); return JavaTypesManager.LONG.getId(); } catch (Exception e) { // } try { Double.parseDouble(value); return JavaTypesManager.DOUBLE.getId(); } catch (Exception e) { // } // by default the type is string return JavaTypesManager.STRING.getId(); } /** * * qli comment the method "isDateOne". * * @param value * * @return boolean */ private static boolean isDateOne(String value) { if (value != null) { try { String dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS Z";//$NON-NLS-1$ value = value.replace("Z", " UTC");//$NON-NLS-1$//$NON-NLS-2$ SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat); Date dt = simpleDateFormat.parse(value); simpleDateFormat.format(dt); return true; } catch (ParseException pe) { return false; } } else return false; } /** * * qli comment the method "isDateTwo". * * @param value * * @return boolean */ private static boolean isDateTwo(String value) { if (value != null) { try { String dateFormat = "yyyy-MM-dd";//$NON-NLS-1$ SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat); Date dt = simpleDateFormat.parse(value); simpleDateFormat.format(dt); return true; } catch (ParseException pe) { return false; } } else return false; } /** * getGlobalType compare two type and determine the common Type. * * @param type1 * @param type2 * @return */ public static String getCommonType(final String type1, final String type2) { return getTypeByPriority(type1, type2); // JavaType idType = null; // // String // idType = getCommonType(type1, type2, JavaTypesManager.STRING); // if (idType != null) { // return idType.getId(); // } // // Integer // idType = getCommonType(type1, type2, JavaTypesManager.INTEGER); // if (idType != null) { // return idType.getId(); // } // // Double // idType = getCommonType(type1, type2, JavaTypesManager.DOUBLE); // if (idType != null) { // return idType.getId(); // } // // float // idType = getCommonType(type1, type2, JavaTypesManager.FLOAT); // if (idType != null) { // return idType.getId(); // } // // Long // idType = getCommonType(type1, type2, JavaTypesManager.LONG); // if (idType != null) { // return idType.getId(); // } // // Character // idType = getCommonType(type1, type2, JavaTypesManager.CHARACTER); // if (idType != null) { // return idType.getId(); // } // return JavaTypesManager.STRING.getId(); } private static JavaType getCommonType(final String type1, final String type2, JavaType testType) { if ((type1 == testType.getLabel()) || (type2 == testType.getLabel()) || (type1 == testType.getId()) || (type2 == testType.getId())) { return testType; } return null; } // Function to test whether the string is valid number or not public static boolean isNumber(String value) { Perl5Compiler compiler = new Perl5Compiler(); Perl5Matcher matcher = new Perl5Matcher(); Pattern pattern = null; String strValidRealPattern = "^([-]|[.]|[-.]|[0-9])[0-9]*[.]*[0-9]+$"; //$NON-NLS-1$ String strValidIntegerPattern = "^([-]|[0-9])[0-9]*$"; //$NON-NLS-1$ String regex = "(" + strValidRealPattern + ")|(" + strValidIntegerPattern + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ try { pattern = compiler.compile(regex); if (matcher.contains(value, pattern)) { return matcher.matches(value, pattern); } } catch (MalformedPatternException e) { // do nothing } return false; } public static String getTypeByPriority(String type1, String type2) { EJavaTypePriority priority1 = EJavaTypePriority.getJavaTypePriority(type1); EJavaTypePriority priority2 = EJavaTypePriority.getJavaTypePriority(type2); if (priority1.isNumberType() != priority2.isNumberType()) { return EJavaTypePriority.STRING.getIdName(); } if (priority1.getPriority() > priority2.getPriority()) { return priority1.getIdName(); } else { return priority2.getIdName(); } } /** * DOC nrousseau GuessSchemaUtil class global comment. Detailled comment */ private enum EJavaTypePriority { STRING("id_String", 10, false), //$NON-NLS-1$ BOOLEAN("id_Boolean", 9, false), //$NON-NLS-1$ INTEGER("id_Integer", 1, true), //$NON-NLS-1$ LONG("id_Long", 2, true), //$NON-NLS-1$ CHARACTER("id_Character", 1, false), //$NON-NLS-1$ DATE("id_Date", 9, false), //$NON-NLS-1$ FLOAT("id_Float", 3, true), //$NON-NLS-1$ DOUBLE("id_Double", 4, true), //$NON-NLS-1$ BIGDECIMAL("id_BigDecimal", 5, true); //$NON-NLS-1$ private String idName; private int priority; private boolean numberType; private EJavaTypePriority(String name, int priority, boolean numberType) { this.idName = name; this.priority = priority; this.numberType = numberType; } private static EJavaTypePriority getJavaTypePriority(String idName) { for (EJavaTypePriority type : EJavaTypePriority.values()) { if (type.getIdName().equals(idName)) { return type; } } return STRING; } /** * Getter for idName. * * @return the idName */ public String getIdName() { return this.idName; } /** * Sets the idName. * * @param idName the idName to set */ public void setIdName(String idName) { this.idName = idName; } /** * Getter for priority. * * @return the priority */ public int getPriority() { return this.priority; } /** * Sets the priority. * * @param priority the priority to set */ public void setPriority(int priority) { this.priority = priority; } /** * Getter for numberType. * * @return the numberType */ public boolean isNumberType() { return this.numberType; } /** * Sets the numberType. * * @param numberType the numberType to set */ public void setNumberType(boolean numberType) { this.numberType = numberType; } }; }