// ============================================================================ // // Copyright (C) 2006-2016 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.dq.indicators.preview.table; import java.sql.Types; import java.text.NumberFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.talend.cwm.relational.TdColumn; import org.talend.cwm.relational.TdTable; import org.talend.dataquality.PluginConstant; import org.talend.dataquality.helpers.IndicatorHelper; import org.talend.dataquality.indicators.Indicator; import org.talend.dataquality.indicators.IndicatorsPackage; import org.talend.dq.nodes.indicator.type.IndicatorEnum; import org.talend.utils.format.StringFormatUtil; import org.talend.utils.sql.Java2SqlType; import orgomg.cwm.objectmodel.core.ModelElement; /** * DOC zqin class global comment. Detailled comment */ public class ChartDataEntity { private static Logger log = Logger.getLogger(ChartDataEntity.class); private String label; private String value; protected Indicator indicator; private Double percent; private Boolean outOfRange = null; protected String range; private boolean labelNull; private boolean isPercent; // MOD mzhao 2009-03-24, feature 6307 Show soundex distinct count and count // label. private Object key = null; public ChartDataEntity() { } public ChartDataEntity(Indicator indicator, String label, String value) { this(indicator, label, value, null, false); } public ChartDataEntity(Indicator indicator, String label, String value, Double percent, boolean labelNull) { this.label = label; this.value = value; this.percent = percent; this.labelNull = labelNull; this.indicator = indicator; } /** * Getter for labelNull. * * @return true if the given label represents a null value */ public boolean isLabelNull() { return this.labelNull; } /** * Sets the labelNull. * * @param labelNull set to true if the label represents the null value */ public void setLabelNull(boolean labelNull) { this.labelNull = labelNull; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } // MOD mzhao 2009-03-24, feature 6307 Show soundex distinct count and count // label. public Object getKey() { return key; } // MOD mzhao 2009-03-24, feature 6307 Show soundex distinct count and count // label. public void setKey(Object key) { this.key = key; } public String getPersent() { if (percent != null) { // MOD qiongli 2011-4-25 bug 20670:if it is infinite,return N/A. if (Double.isNaN(percent) || Double.isInfinite(percent)) { return PluginConstant.NA_STRING; } else { return StringFormatUtil.format(percent, StringFormatUtil.PERCENT).toString(); } } else { return null; } } public void setPercent(Double percent) { this.percent = percent; } public Indicator getIndicator() { return indicator; } public void setIndicator(Indicator indicator) { this.indicator = indicator; } /** * Getter for isPercent. * * @return the isPercent */ public boolean isPercent() { return this.isPercent; } /** * check the inString is a validate value. * * @param inString * @return */ public boolean isOutOfValue(String inString) { if (inString.equals(PluginConstant.NA_STRING)) { // $NON-NLS-1$ return true; } boolean isOutOfValue = false; // the default value check isPercent = inString.indexOf('%') > 0; // $NON-NLS-1$ if (isPercent) { NumberFormat nFromat = NumberFormat.getPercentInstance(); try { Number number = nFromat.parse(inString); if (number instanceof Double) { Double doubleString = (Double) number; if (doubleString < 0 || doubleString > 1) { isOutOfValue = true; } } else if (number instanceof Long) { Long longString = (Long) number; if (longString < 0 || longString > 1) { isOutOfValue = true; } } } catch (ParseException e) { isOutOfValue = false; } } else { Double douString = Double.valueOf(inString); if (douString < 0) { isOutOfValue = true; } } return isOutOfValue; } /** * DOC Zqin Comment method "isOutOfRange". * * @return */ public boolean isOutOfRange(String inputValue) { outOfRange = false; if (inputValue == null || indicator == null) { return false; } IndicatorEnum indicatorEnum = IndicatorEnum.findIndicatorEnum(indicator.eClass()); if (indicatorEnum != null) { switch (indicatorEnum) { case ModeIndicatorEnum: String expectedValue = IndicatorHelper.getExpectedValue(indicator); if (expectedValue != null) { Boolean ignoreCaseOption = IndicatorHelper.ignoreCaseOption(indicator); // MOD sgandon 01/04/2010 bug 12086 : ignoreCaseOption was not checked for null value if (ignoreCaseOption != null && ignoreCaseOption) { outOfRange = !(ignoreCaseOption && StringUtils.equalsIgnoreCase(value, expectedValue)); } else { outOfRange = !StringUtils.equals(value, expectedValue); } } break; default: outOfRange = checkRange(inputValue); } } return outOfRange; } /** * Get threshold by the input string. * * @param inString * @return */ protected String[] getDefinedRange(String inString) { isPercent = inString.indexOf('%') > 0; // MOD qiongli 2011-11-25 TDQ-4033,don't need to get the DataThreshold. String[] threshold = isPercent ? IndicatorHelper.getIndicatorThresholdInPercent(indicator) : IndicatorHelper .getIndicatorThreshold(indicator); return threshold; } private boolean checkRange(String inString) { String[] definedRange = getDefinedRange(inString); if (definedRange != null && definedRange.length >= 2) { range = "[" + definedRange[0] + "," + definedRange[1] + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ ModelElement temp = indicator.getAnalyzedElement(); int sqltype = Types.INTEGER; if (null != temp) { int tempType = sqltype; if (temp instanceof TdColumn) { // MOD qiongli 2011-11-15,TDQ-3690.it should be set value to 'tempType' not 'sqltype' at here. tempType = ((TdColumn) temp).getSqlDataType().getJavaDataType(); } sqltype = temp instanceof TdTable ? Types.INTEGER : tempType; } boolean isChildOfRange = IndicatorsPackage.eINSTANCE.getValueIndicator().isSuperTypeOf(indicator.eClass()); if (Java2SqlType.isDateInSQL(sqltype) && isChildOfRange) { try { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); //$NON-NLS-1$ Date dValue = format.parse(value); if ("".equals(definedRange[0])) { //$NON-NLS-1$ Date max = format.parse(definedRange[1]); range = "[*, " + definedRange[1] + "]"; //$NON-NLS-1$ //$NON-NLS-2$ return dValue.after(max); } else if ("".equals(definedRange[1])) { //$NON-NLS-1$ Date min = format.parse(definedRange[0]); range = "[" + definedRange[0] + ", *]"; //$NON-NLS-1$ //$NON-NLS-2$ return dValue.before(min); } else { Date min = format.parse(definedRange[0]); Date max = format.parse(definedRange[1]); return dValue.after(max) || dValue.before(min); } } catch (Exception e) { log.error(e, e); return false; } } else { Double min = StringFormatUtil.formatFourDecimalDouble(definedRange[0]); Double max = StringFormatUtil.formatFourDecimalDouble(definedRange[1]); // handle min and max Double dValue = inString != null ? StringFormatUtil.parseDouble(inString) : Double.NaN; if (min == null || Double.isNaN(min)) { min = Double.NEGATIVE_INFINITY; } if (max == null || Double.isNaN(max)) { max = Double.POSITIVE_INFINITY; } if (isPercent) { return dValue < min * 100 || dValue > max * 100; } return dValue < min || dValue > max; } } return false; } /** * DOC Zqin Comment method "getRangeAsString". * * @return retrun the message when indicator value out the defined range. */ public String getRangeAsString() { StringBuilder msg = new StringBuilder(); if (indicator != null) { IndicatorEnum indicatorEnum = IndicatorEnum.findIndicatorEnum(indicator.eClass()); // TDQ-10785: when the data is too long, add a tooltip to show the first 200 characters. if (indicatorEnum == IndicatorEnum.PatternFreqIndicatorEnum || indicatorEnum == IndicatorEnum.PatternLowFreqIndicatorEnum || indicatorEnum == IndicatorEnum.FrequencyIndicatorEnum || indicatorEnum == IndicatorEnum.LowFrequencyIndicatorEnum || indicatorEnum == IndicatorEnum.SoundexIndicatorEnum || indicatorEnum == IndicatorEnum.SoundexLowIndicatorEnum || indicatorEnum == IndicatorEnum.EastAsiaPatternLowFreqIndicatorEnum || indicatorEnum == IndicatorEnum.EastAsiaPatternFreqIndicatorEnum) { if (key != null && key.toString().length() > 30) { msg.append(key.toString().length() > 200 ? key.toString().substring(0, 200) + "...(" + key.toString().length() + " characters)" : key.toString()); //$NON-NLS-1$ //$NON-NLS-2$ } } else if (indicatorEnum == IndicatorEnum.ModeIndicatorEnum) { msg.append("This value differs from the expected value: \"" + IndicatorHelper.getExpectedValue(indicator) + "\""); //$NON-NLS-1$ //$NON-NLS-2$ } else if (indicatorEnum == IndicatorEnum.BoxIIndicatorEnum) { if (isOutOfRange(getValue())) { msg.append("This value is outside the expected data's thresholds: " + range); //$NON-NLS-1$ } } else { if (isOutOfRange(getValue())) { msg.append("This value is outside the expected indicator's thresholds: " + range); //$NON-NLS-1$ msg.append("\n"); //$NON-NLS-1$ } if (isOutOfRange(getPersent())) { msg.append("This value is outside the expected indicator's thresholds in percent: " + range); //$NON-NLS-1$ } } } return msg.length() == 0 ? null : msg.toString(); } }