package org.apache.poi.xssf.usermodel;
import java.util.Arrays;
import java.util.regex.Pattern;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationType;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationOperator.Enum;
public class XSSFDataValidationConstraint implements DataValidationConstraint {
private static final String LIST_SEPARATOR = ",";
private static final Pattern LIST_SPLIT_REGEX = Pattern.compile("\\s*" + LIST_SEPARATOR + "\\s*");
private static final String QUOTE = "\"";
private String formula1;
private String formula2;
private int validationType = -1;
private int operator = -1;
private String[] explicitListOfValues;
public XSSFDataValidationConstraint(String[] explicitListOfValues) {
if( explicitListOfValues==null || explicitListOfValues.length==0) {
throw new IllegalArgumentException("List validation with explicit values must specify at least one value");
}
this.validationType = ValidationType.LIST;
setExplicitListValues(explicitListOfValues);
validate();
}
public XSSFDataValidationConstraint(int validationType, String formula1) {
super();
setFormula1(formula1);
this.validationType = validationType;
validate();
}
public XSSFDataValidationConstraint(int validationType, int operator, String formula1) {
super();
setFormula1(formula1);
this.validationType = validationType;
this.operator = operator;
validate();
}
public XSSFDataValidationConstraint(int validationType, int operator, String formula1, String formula2) {
super();
setFormula1(formula1);
setFormula2(formula2);
this.validationType = validationType;
this.operator = operator;
validate();
if ( ValidationType.LIST == validationType
&& this.formula1 != null
&& isQuoted(this.formula1) ) {
explicitListOfValues = LIST_SPLIT_REGEX.split(unquote(this.formula1));
}
}
public String[] getExplicitListValues() {
return explicitListOfValues;
}
public String getFormula1() {
return formula1;
}
public String getFormula2() {
return formula2;
}
public int getOperator() {
return operator;
}
public int getValidationType() {
return validationType;
}
public void setExplicitListValues(String[] explicitListValues) {
this.explicitListOfValues = explicitListValues;
if ( explicitListOfValues!=null && explicitListOfValues.length > 0 ) {
StringBuilder builder = new StringBuilder(QUOTE);
for (int i = 0; i < explicitListValues.length; i++) {
String string = explicitListValues[i];
if (builder.length() > 1) {
builder.append(LIST_SEPARATOR);
}
builder.append(string);
}
builder.append(QUOTE);
setFormula1(builder.toString());
}
}
public void setFormula1(String formula1) {
this.formula1 = removeLeadingEquals(formula1);
}
protected static String removeLeadingEquals(String formula1) {
return isFormulaEmpty(formula1) ? formula1 : formula1.charAt(0)=='=' ? formula1.substring(1) : formula1;
}
private static boolean isQuoted(String s) {
return s.startsWith(QUOTE) && s.endsWith(QUOTE);
}
private static String unquote(String s) {
if (isQuoted(s)) {
return s.substring(1, s.length()-1);
}
return s;
}
protected static boolean isFormulaEmpty(String formula1) {
return formula1 == null || formula1.trim().length()==0;
}
public void setFormula2(String formula2) {
this.formula2 = removeLeadingEquals(formula2);
}
public void setOperator(int operator) {
this.operator = operator;
}
public void validate() {
if (validationType==ValidationType.ANY) {
return;
}
if (validationType==ValidationType.LIST ) {
if (isFormulaEmpty(formula1)) {
throw new IllegalArgumentException("A valid formula or a list of values must be specified for list validation.");
}
} else {
if( isFormulaEmpty(formula1) ) {
throw new IllegalArgumentException("Formula is not specified. Formula is required for all validation types except explicit list validation.");
}
if( validationType!= ValidationType.FORMULA ) {
if (operator==-1) {
throw new IllegalArgumentException("This validation type requires an operator to be specified.");
} else if (( operator==OperatorType.BETWEEN || operator==OperatorType.NOT_BETWEEN) && isFormulaEmpty(formula2)) {
throw new IllegalArgumentException("Between and not between comparisons require two formulae to be specified.");
}
}
}
}
public String prettyPrint() {
StringBuilder builder = new StringBuilder();
STDataValidationType.Enum vt = XSSFDataValidation.validationTypeMappings.get(validationType);
Enum ot = XSSFDataValidation.operatorTypeMappings.get(operator);
builder.append(vt);
builder.append(' ');
if (validationType!=ValidationType.ANY) {
if (validationType != ValidationType.LIST
&& validationType != ValidationType.FORMULA) {
builder.append(LIST_SEPARATOR).append(ot).append(", ");
}
final String NOQUOTE = "";
if (validationType == ValidationType.LIST && explicitListOfValues != null) {
builder.append(NOQUOTE).append(Arrays.asList(explicitListOfValues)).append(NOQUOTE).append(' ');
} else {
builder.append(NOQUOTE).append(formula1).append(NOQUOTE).append(' ');
}
if (formula2 != null) {
builder.append(NOQUOTE).append(formula2).append(NOQUOTE).append(' ');
}
}
return builder.toString();
}
}