package net.codjo.segmentation.server.util;
import net.codjo.variable.UnknownVariableException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
*/
public class CompilationUtil {
private static final String REPLACE_VARIABLES_PATTERN = "(.*)INC_\\$\\$(\\d*)\\$(\\w*)(.*)";
private static final String REPLACE_VARIABLES_SELECT
= "select FORMULA from PM_CLASSIFICATION_STRUCTURE where CLASSIFICATION_ID=? and SLEEVE_ROW_ID=?";
private CompilationUtil() {
}
public static String replaceVariables(String expressionToCompile, Connection connection)
throws SQLException, CyclicVariableException, UnknownVariableException {
Pattern pattern = Pattern.compile(REPLACE_VARIABLES_PATTERN);
PreparedStatement preparedStatement = connection.prepareStatement(REPLACE_VARIABLES_SELECT);
try {
return replaceVariables(expressionToCompile, pattern, preparedStatement, new ArrayList<String>());
}
finally {
preparedStatement.close();
}
}
private static String replaceVariables(String expressionToCompile,
Pattern pattern,
PreparedStatement preparedStatement, List<String> seenVariables)
throws SQLException, CyclicVariableException, UnknownVariableException {
Matcher matcher = pattern.matcher(expressionToCompile);
if (matcher.find()) {
String prefix = matcher.group(1);
String classificationId = matcher.group(2);
String sleeveRowId = matcher.group(3);
String suffix = matcher.group(4);
String variable = String.format("INC_$$%s$%s", classificationId, sleeveRowId);
if (seenVariables.contains(variable)) {
throw new CyclicVariableException(variable);
}
preparedStatement.setInt(1, Integer.parseInt(classificationId));
preparedStatement.setString(2, sleeveRowId);
ResultSet resultSet = preparedStatement.executeQuery();
if (!resultSet.next()) {
throw new UnknownVariableException(variable);
}
List<String> newSeenVariables = new ArrayList<String>(seenVariables);
newSeenVariables.add(variable);
String result = new StringBuilder()
.append(prefix)
.append(replaceVariables(resultSet.getString(1),
pattern,
preparedStatement,
newSeenVariables))
.append(suffix).toString();
return replaceVariables(result, pattern, preparedStatement, seenVariables);
}
else {
return expressionToCompile;
}
}
public static class CyclicVariableException extends Exception {
CyclicVariableException(String message) {
super(String.format("La variable '%s' est une r�f�rence cyclique.", message));
}
}
}