package org.drools.decisiontable.parser;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.drools.template.model.SnippetBuilder;
/**
* This utility will build up a list of constraints for a column.
* For instance, the column has been spanned across multiple cells, and the cells below
* contain the constraints.
* @author Michael Neale
*
*/
public class LhsBuilder implements SourceBuilder {
private String column;
private Map<Integer, String> constraints;
private List<String> values;
private boolean hasValues;
private static Set<String> operators;
static {
operators = new HashSet<String>();
operators.add( "==" );
operators.add( "=" );
operators.add( "!=" );
operators.add( "<" );
operators.add( ">" );
operators.add( "<=" );
operators.add( ">=" );
operators.add( "contains" );
operators.add( "matches" );
}
/**
* @param colDefinition The initial column definition that is shared via merged cells.
*/
public LhsBuilder(String colDefinition) {
this.column = colDefinition == null ? "" : colDefinition;
this.constraints = new HashMap<Integer, String>();
this.values = new ArrayList<String>();
}
public void addTemplate(int column, String content) {
Integer key = new Integer( column );
content = content.trim();
if ( constraints.containsKey( key ) ) {
throw new IllegalArgumentException( "Internal error: Can't have a constraint added twice to one spreadsheet col." );
}
//we can wrap all values in quotes, it all works
FieldType fieldType = calcFieldType( content );
if (fieldType == FieldType.NORMAL_FIELD || !isMultipleConstraints()) {
constraints.put( key,
content );
} else if (fieldType == FieldType.SINGLE_FIELD) {
constraints.put( key, content + " == \"" + SnippetBuilder.PARAM_STRING + "\"" );
} else if (fieldType == FieldType.OPERATOR_FIELD) {
constraints.put( key, content + " \"" + SnippetBuilder.PARAM_STRING + "\"" );
}
}
public void clearValues() {
this.hasValues = false;
this.values.clear();
}
public void addCellValue(int col,
String value) {
this.hasValues = true;
Integer key = new Integer( col );
String content = (String) this.constraints.get( key );
SnippetBuilder snip = new SnippetBuilder( content );
String result = snip.build( value );
this.values.add( result );
}
public String getResult() {
StringBuffer buf = new StringBuffer();
if ( !isMultipleConstraints() ) {
for ( Iterator<String> iter = values.iterator(); iter.hasNext(); ) {
String content = iter.next();
buf.append( content );
if (iter.hasNext()) {
buf.append( '\n' );
}
}
return buf.toString();
} else {
buf.append( this.column );
buf.append( '(' );
for ( Iterator<String> iter = values.iterator(); iter.hasNext(); ) {
buf.append( iter.next());
if (iter.hasNext()) {
buf.append( ", " );
}
}
buf.append( ')' );
return buf.toString();
}
}
/** Returns true if this is building up multiple constraints as in:
* Foo(a ==b, c == d) etc...
* If not, then it it really just like the "classic" style DTs.
*/
boolean isMultipleConstraints() {
if ( "".equals( column ) ) {
return false;
} else {
if ( column.endsWith( ")" ) ) {
return false;
} else {
return true;
}
}
}
/**
* Work out the type of "field" that is being specified,
* as in :
* age
* age <
* age == $param
* age == $1 || age == $2
* forall{age < $}{,}
*
* etc. as we treat them all differently.
*/
public FieldType calcFieldType(String content) {
if (!SnippetBuilder.getType(content).equals(
SnippetBuilder.SnippetType.SINGLE)) {
return FieldType.NORMAL_FIELD;
}
for ( String op : operators ) {
if (content.endsWith( op )) {
return FieldType.OPERATOR_FIELD;
}
}
return FieldType.SINGLE_FIELD;
}
static class FieldType {
public static final FieldType SINGLE_FIELD = new FieldType();
public static final FieldType OPERATOR_FIELD = new FieldType();
public static final FieldType NORMAL_FIELD = new FieldType();
}
public boolean hasValues() {
return hasValues;
}
}