// ============================================================================
//
// 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.dataquality.datamasking.semantic;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.regex.Pattern;
import org.talend.daikon.number.BigDecimalParser;
import org.talend.dataquality.datamasking.functions.NumericVariance;
public class FluctuateNumericString extends NumericVariance<String> {
private static final long serialVersionUID = -8029563336814263376L;
private static final Pattern patternInteger = Pattern.compile("^(\\+|-)?\\d+$");
@Override
protected String doGenerateMaskedField(String input) {
if (input == null || EMPTY_STRING.equals(input.trim())) {
return input;
} else {
init();
double rateToApply = rnd.nextDouble() * rate;
if (patternInteger.matcher(input).matches()) {
BigDecimal bigDecimal = new BigDecimal(input);
if (bigDecimal.abs().compareTo(new BigDecimal(Long.MAX_VALUE)) > 0) {
final BigDecimal result = bigDecimal.multiply(BigDecimal.valueOf(rateToApply + 100))
.divide(new BigDecimal(100));
return result.setScale(0, RoundingMode.HALF_UP).toString();
} else {
final long result = Math.round(Long.valueOf(input) * (rateToApply + 100) / 100);
return String.valueOf(result);
}
} else {
try {
BigDecimal bigDecimal = BigDecimalParser.toBigDecimal(input);
final int decimalLength = getDecimalPrecision(input);
if (bigDecimal.abs().compareTo(new BigDecimal(Long.MAX_VALUE)) > 0) {
final BigDecimal result = bigDecimal.multiply(BigDecimal.valueOf(rateToApply + 100))
.divide(new BigDecimal(100));
if (input.contains("e") || input.contains("E")) {
return String.valueOf(result.setScale(decimalLength, RoundingMode.HALF_UP).doubleValue());
} else {
return result.setScale(decimalLength, RoundingMode.HALF_UP).toString();
}
} else {
final Double doubleValue = bigDecimal.doubleValue() * (rateToApply + 100) / 100;
final BigDecimal result = new BigDecimal(doubleValue);
return String.valueOf(result.setScale(decimalLength, RoundingMode.HALF_UP).doubleValue());
}
} catch (NumberFormatException e) {
return ReplaceCharacterHelper.replaceCharacters(input, rnd);
}
}
}
}
private int getDecimalPrecision(final String input) {
String inputWithoutScientificPart = input;
if (input.contains("e")) {
inputWithoutScientificPart = input.substring(0, input.lastIndexOf("e"));
} else if (input.contains("E")) {
inputWithoutScientificPart = input.substring(0, input.lastIndexOf("E"));
}
String bigDecimalString = BigDecimalParser.toBigDecimal(inputWithoutScientificPart).toString();
int idx = bigDecimalString.lastIndexOf(".");
if (idx < 1) {
return 0;
} else {
return inputWithoutScientificPart.length() - bigDecimalString.lastIndexOf(".") - 1;
}
}
}